Completed
Branch sideload-all-language-files (d12b05)
by
unknown
24:43 queued 16:49
created
core/domain/services/pue/Config.php 1 patch
Indentation   +127 added lines, -127 removed lines patch added patch discarded remove patch
@@ -16,131 +16,131 @@
 block discarded – undo
16 16
  */
17 17
 class Config
18 18
 {
19
-    /**
20
-     * @var EE_Network_Config
21
-     */
22
-    private $network_config;
23
-
24
-
25
-    /**
26
-     * @var EE_Config
27
-     */
28
-    private $ee_config;
29
-
30
-
31
-    public function __construct(EE_Network_Config $network_config, EE_Config $ee_config)
32
-    {
33
-        $this->network_config = $network_config;
34
-        $this->ee_config = $ee_config;
35
-    }
36
-
37
-
38
-    /**
39
-     * Get the site license key for the site.
40
-     */
41
-    public function siteLicenseKey()
42
-    {
43
-        return $this->network_config->core->site_license_key;
44
-    }
45
-
46
-
47
-    public function i18nDomain()
48
-    {
49
-        return 'event_espresso';
50
-    }
51
-
52
-
53
-    public function checkPeriod()
54
-    {
55
-        return 24;
56
-    }
57
-
58
-
59
-    public function optionKey()
60
-    {
61
-        return 'ee_site_license_key';
62
-    }
63
-
64
-
65
-    public function optionsPageSlug()
66
-    {
67
-        return 'espresso_general_settings';
68
-    }
69
-
70
-
71
-    public function hostServerUrl()
72
-    {
73
-        return defined('PUE_UPDATES_ENDPOINT')
74
-            ? PUE_UPDATES_ENDPOINT
75
-            : 'https://eventespresso.com';
76
-    }
77
-
78
-
79
-    public function pluginSlug()
80
-    {
81
-        // Note: PUE uses a simple preg_match to determine what type is currently installed based on version number.
82
-        //  So it's important that you use a key for the version type that is unique and not found in another key.
83
-        // For example:
84
-        // $plugin_slug['premium']['p'] = 'some-premium-slug';
85
-        // $plugin_slug['prerelease']['pr'] = 'some-pre-release-slug';
86
-        // The above would not work because "p" is found in both keys for the version type. ( i.e 1.0.p vs 1.0.pr )
87
-        // so doing something like:
88
-        // $plugin_slug['premium']['p'] = 'some-premium-slug';
89
-        // $plugin_slug['prerelease']['b'] = 'some-pre-release-slug';
90
-        // ..WOULD work!
91
-        return array(
92
-            'free'       => array('decaf' => 'event-espresso-core-decaf'),
93
-            'premium'    => array('p' => 'event-espresso-core-reg'),
94
-            'prerelease' => array('beta' => 'event-espresso-core-pr'),
95
-        );
96
-    }
97
-
98
-
99
-    /**
100
-     * Return whether the site is opted in for UXIP or not.
101
-     *
102
-     * @return bool
103
-     */
104
-    public function isOptedInForUxip()
105
-    {
106
-        return filter_var($this->ee_config->core->ee_ueip_optin, FILTER_VALIDATE_BOOLEAN);
107
-    }
108
-
109
-
110
-    /**
111
-     * Return whether the site has been notified about UXIP or not.
112
-     *
113
-     * @return bool
114
-     */
115
-    public function hasNotifiedForUxip()
116
-    {
117
-        return filter_var($this->ee_config->core->ee_ueip_has_notified, FILTER_VALIDATE_BOOLEAN);
118
-    }
119
-
120
-
121
-    /**
122
-     * Set the site opted in for UXIP.
123
-     */
124
-    public function setHasOptedInForUxip()
125
-    {
126
-        $this->ee_config->core->ee_ueip_optin = true;
127
-        $this->ee_config->update_espresso_config(false, false);
128
-    }
129
-
130
-
131
-    /**
132
-     * Set the site opted out for UXIP
133
-     */
134
-    public function setHasOptedOutForUxip()
135
-    {
136
-        $this->ee_config->core->ee_ueip_optin = false;
137
-        $this->ee_config->update_espresso_config(false, false);
138
-    }
139
-
140
-
141
-    public function setHasNotifiedAboutUxip()
142
-    {
143
-        $this->ee_config->core->ee_ueip_has_notified = true;
144
-        $this->ee_config->update_espresso_config(false, false);
145
-    }
19
+	/**
20
+	 * @var EE_Network_Config
21
+	 */
22
+	private $network_config;
23
+
24
+
25
+	/**
26
+	 * @var EE_Config
27
+	 */
28
+	private $ee_config;
29
+
30
+
31
+	public function __construct(EE_Network_Config $network_config, EE_Config $ee_config)
32
+	{
33
+		$this->network_config = $network_config;
34
+		$this->ee_config = $ee_config;
35
+	}
36
+
37
+
38
+	/**
39
+	 * Get the site license key for the site.
40
+	 */
41
+	public function siteLicenseKey()
42
+	{
43
+		return $this->network_config->core->site_license_key;
44
+	}
45
+
46
+
47
+	public function i18nDomain()
48
+	{
49
+		return 'event_espresso';
50
+	}
51
+
52
+
53
+	public function checkPeriod()
54
+	{
55
+		return 24;
56
+	}
57
+
58
+
59
+	public function optionKey()
60
+	{
61
+		return 'ee_site_license_key';
62
+	}
63
+
64
+
65
+	public function optionsPageSlug()
66
+	{
67
+		return 'espresso_general_settings';
68
+	}
69
+
70
+
71
+	public function hostServerUrl()
72
+	{
73
+		return defined('PUE_UPDATES_ENDPOINT')
74
+			? PUE_UPDATES_ENDPOINT
75
+			: 'https://eventespresso.com';
76
+	}
77
+
78
+
79
+	public function pluginSlug()
80
+	{
81
+		// Note: PUE uses a simple preg_match to determine what type is currently installed based on version number.
82
+		//  So it's important that you use a key for the version type that is unique and not found in another key.
83
+		// For example:
84
+		// $plugin_slug['premium']['p'] = 'some-premium-slug';
85
+		// $plugin_slug['prerelease']['pr'] = 'some-pre-release-slug';
86
+		// The above would not work because "p" is found in both keys for the version type. ( i.e 1.0.p vs 1.0.pr )
87
+		// so doing something like:
88
+		// $plugin_slug['premium']['p'] = 'some-premium-slug';
89
+		// $plugin_slug['prerelease']['b'] = 'some-pre-release-slug';
90
+		// ..WOULD work!
91
+		return array(
92
+			'free'       => array('decaf' => 'event-espresso-core-decaf'),
93
+			'premium'    => array('p' => 'event-espresso-core-reg'),
94
+			'prerelease' => array('beta' => 'event-espresso-core-pr'),
95
+		);
96
+	}
97
+
98
+
99
+	/**
100
+	 * Return whether the site is opted in for UXIP or not.
101
+	 *
102
+	 * @return bool
103
+	 */
104
+	public function isOptedInForUxip()
105
+	{
106
+		return filter_var($this->ee_config->core->ee_ueip_optin, FILTER_VALIDATE_BOOLEAN);
107
+	}
108
+
109
+
110
+	/**
111
+	 * Return whether the site has been notified about UXIP or not.
112
+	 *
113
+	 * @return bool
114
+	 */
115
+	public function hasNotifiedForUxip()
116
+	{
117
+		return filter_var($this->ee_config->core->ee_ueip_has_notified, FILTER_VALIDATE_BOOLEAN);
118
+	}
119
+
120
+
121
+	/**
122
+	 * Set the site opted in for UXIP.
123
+	 */
124
+	public function setHasOptedInForUxip()
125
+	{
126
+		$this->ee_config->core->ee_ueip_optin = true;
127
+		$this->ee_config->update_espresso_config(false, false);
128
+	}
129
+
130
+
131
+	/**
132
+	 * Set the site opted out for UXIP
133
+	 */
134
+	public function setHasOptedOutForUxip()
135
+	{
136
+		$this->ee_config->core->ee_ueip_optin = false;
137
+		$this->ee_config->update_espresso_config(false, false);
138
+	}
139
+
140
+
141
+	public function setHasNotifiedAboutUxip()
142
+	{
143
+		$this->ee_config->core->ee_ueip_has_notified = true;
144
+		$this->ee_config->update_espresso_config(false, false);
145
+	}
146 146
 }
Please login to merge, or discard this patch.
core/libraries/plugin_api/EE_Register_Addon.lib.php 2 patches
Indentation   +1161 added lines, -1161 removed lines patch added patch discarded remove patch
@@ -22,1225 +22,1225 @@
 block discarded – undo
22 22
 class EE_Register_Addon implements EEI_Plugin_API
23 23
 {
24 24
 
25
-    /**
26
-     * possibly truncated version of the EE core version string
27
-     *
28
-     * @var string
29
-     */
30
-    protected static $_core_version = '';
25
+	/**
26
+	 * possibly truncated version of the EE core version string
27
+	 *
28
+	 * @var string
29
+	 */
30
+	protected static $_core_version = '';
31 31
 
32
-    /**
33
-     * Holds values for registered addons
34
-     *
35
-     * @var array
36
-     */
37
-    protected static $_settings = array();
32
+	/**
33
+	 * Holds values for registered addons
34
+	 *
35
+	 * @var array
36
+	 */
37
+	protected static $_settings = array();
38 38
 
39
-    /**
40
-     * @var  array $_incompatible_addons keys are addon SLUGS
41
-     * (first argument passed to EE_Register_Addon::register()), keys are
42
-     * their MINIMUM VERSION (with all 5 parts. Eg 1.2.3.rc.004).
43
-     * Generally this should be used sparingly, as we don't want to muddle up
44
-     * EE core with knowledge of ALL the addons out there.
45
-     * If you want NO versions of an addon to run with a certain version of core,
46
-     * it's usually best to define the addon's "min_core_version" as part of its call
47
-     * to EE_Register_Addon::register(), rather than using this array with a super high value for its
48
-     * minimum plugin version.
49
-     * @access    protected
50
-     */
51
-    protected static $_incompatible_addons = array(
52
-        'Multi_Event_Registration' => '2.0.11.rc.002',
53
-        'Promotions'               => '1.0.0.rc.084',
54
-    );
39
+	/**
40
+	 * @var  array $_incompatible_addons keys are addon SLUGS
41
+	 * (first argument passed to EE_Register_Addon::register()), keys are
42
+	 * their MINIMUM VERSION (with all 5 parts. Eg 1.2.3.rc.004).
43
+	 * Generally this should be used sparingly, as we don't want to muddle up
44
+	 * EE core with knowledge of ALL the addons out there.
45
+	 * If you want NO versions of an addon to run with a certain version of core,
46
+	 * it's usually best to define the addon's "min_core_version" as part of its call
47
+	 * to EE_Register_Addon::register(), rather than using this array with a super high value for its
48
+	 * minimum plugin version.
49
+	 * @access    protected
50
+	 */
51
+	protected static $_incompatible_addons = array(
52
+		'Multi_Event_Registration' => '2.0.11.rc.002',
53
+		'Promotions'               => '1.0.0.rc.084',
54
+	);
55 55
 
56 56
 
57
-    /**
58
-     * We should always be comparing core to a version like '4.3.0.rc.000',
59
-     * not just '4.3.0'.
60
-     * So if the addon developer doesn't provide that full version string,
61
-     * fill in the blanks for them
62
-     *
63
-     * @param string $min_core_version
64
-     * @return string always like '4.3.0.rc.000'
65
-     */
66
-    protected static function _effective_version($min_core_version)
67
-    {
68
-        // versions: 4 . 3 . 1 . p . 123
69
-        // offsets:    0 . 1 . 2 . 3 . 4
70
-        $version_parts = explode('.', $min_core_version);
71
-        // check they specified the micro version (after 2nd period)
72
-        if (! isset($version_parts[2])) {
73
-            $version_parts[2] = '0';
74
-        }
75
-        // if they didn't specify the 'p', or 'rc' part. Just assume the lowest possible
76
-        // soon we can assume that's 'rc', but this current version is 'alpha'
77
-        if (! isset($version_parts[3])) {
78
-            $version_parts[3] = 'dev';
79
-        }
80
-        if (! isset($version_parts[4])) {
81
-            $version_parts[4] = '000';
82
-        }
83
-        return implode('.', $version_parts);
84
-    }
57
+	/**
58
+	 * We should always be comparing core to a version like '4.3.0.rc.000',
59
+	 * not just '4.3.0'.
60
+	 * So if the addon developer doesn't provide that full version string,
61
+	 * fill in the blanks for them
62
+	 *
63
+	 * @param string $min_core_version
64
+	 * @return string always like '4.3.0.rc.000'
65
+	 */
66
+	protected static function _effective_version($min_core_version)
67
+	{
68
+		// versions: 4 . 3 . 1 . p . 123
69
+		// offsets:    0 . 1 . 2 . 3 . 4
70
+		$version_parts = explode('.', $min_core_version);
71
+		// check they specified the micro version (after 2nd period)
72
+		if (! isset($version_parts[2])) {
73
+			$version_parts[2] = '0';
74
+		}
75
+		// if they didn't specify the 'p', or 'rc' part. Just assume the lowest possible
76
+		// soon we can assume that's 'rc', but this current version is 'alpha'
77
+		if (! isset($version_parts[3])) {
78
+			$version_parts[3] = 'dev';
79
+		}
80
+		if (! isset($version_parts[4])) {
81
+			$version_parts[4] = '000';
82
+		}
83
+		return implode('.', $version_parts);
84
+	}
85 85
 
86 86
 
87
-    /**
88
-     * Returns whether or not the min core version requirement of the addon is met
89
-     *
90
-     * @param string $min_core_version    the minimum core version required by the addon
91
-     * @param string $actual_core_version the actual core version, optional
92
-     * @return boolean
93
-     */
94
-    public static function _meets_min_core_version_requirement(
95
-        $min_core_version,
96
-        $actual_core_version = EVENT_ESPRESSO_VERSION
97
-    ) {
98
-        return version_compare(
99
-            self::_effective_version($actual_core_version),
100
-            self::_effective_version($min_core_version),
101
-            '>='
102
-        );
103
-    }
87
+	/**
88
+	 * Returns whether or not the min core version requirement of the addon is met
89
+	 *
90
+	 * @param string $min_core_version    the minimum core version required by the addon
91
+	 * @param string $actual_core_version the actual core version, optional
92
+	 * @return boolean
93
+	 */
94
+	public static function _meets_min_core_version_requirement(
95
+		$min_core_version,
96
+		$actual_core_version = EVENT_ESPRESSO_VERSION
97
+	) {
98
+		return version_compare(
99
+			self::_effective_version($actual_core_version),
100
+			self::_effective_version($min_core_version),
101
+			'>='
102
+		);
103
+	}
104 104
 
105 105
 
106
-    /**
107
-     * Method for registering new EE_Addons.
108
-     * Should be called AFTER AHEE__EE_System__load_espresso_addons but BEFORE
109
-     * AHEE__EE_System___detect_if_activation_or_upgrade__begin in order to register all its components. However, it
110
-     * may also be called after the 'activate_plugin' action (when an addon is activated), because an activating addon
111
-     * won't be loaded by WP until after AHEE__EE_System__load_espresso_addons has fired. If its called after
112
-     * 'activate_plugin', it registers the addon still, but its components are not registered
113
-     * (they shouldn't be needed anyways, because it's just an activation request and they won't have a chance to do
114
-     * anything anyways). Instead, it just sets the newly-activated addon's activation indicator wp option and returns
115
-     * (so that we can detect that the addon has activated on the subsequent request)
116
-     *
117
-     * @since    4.3.0
118
-     * @param string                  $addon_name                       [Required] the EE_Addon's name.
119
-     * @param  array                  $setup_args                       {
120
-     *                                                                  An array of arguments provided for registering
121
-     *                                                                  the message type.
122
-     * @type  string                  $class_name                       the addon's main file name.
123
-     *                                                                  If left blank, generated from the addon name,
124
-     *                                                                  changes something like "calendar" to
125
-     *                                                                  "EE_Calendar"
126
-     * @type string                   $min_core_version                 the minimum version of EE Core that the
127
-     *                                                                  addon will work with. eg "4.8.1.rc.084"
128
-     * @type string                   $version                          the "software" version for the addon. eg
129
-     *                                                                  "1.0.0.p" for a first stable release, or
130
-     *                                                                  "1.0.0.rc.043" for a version in progress
131
-     * @type string                   $main_file_path                   the full server path to the main file
132
-     *                                                                  loaded directly by WP
133
-     * @type DomainInterface $domain                                    child class of
134
-     *                                                                  EventEspresso\core\domain\DomainBase
135
-     * @type string                   $domain_fqcn                      Fully Qualified Class Name
136
-     *                                                                  for the addon's Domain class
137
-     *                                                                  (see EventEspresso\core\domain\Domain)
138
-     * @type string                   $admin_path                       full server path to the folder where the
139
-     *                                                                  addon\'s admin files reside
140
-     * @type string                   $admin_callback                   a method to be called when the EE Admin is
141
-     *                                                                  first invoked, can be used for hooking into
142
-     *                                                                  any admin page
143
-     * @type string                   $config_section                   the section name for this addon's
144
-     *                                                                  configuration settings section
145
-     *                                                                  (defaults to "addons")
146
-     * @type string                   $config_class                     the class name for this addon's
147
-     *                                                                  configuration settings object
148
-     * @type string                   $config_name                      the class name for this addon's
149
-     *                                                                  configuration settings object
150
-     * @type string                   $autoloader_paths                 [Required] an array of class names and the full
151
-     *                                                                  server paths to those files.
152
-     * @type string                   $autoloader_folders               an array of  "full server paths" for any
153
-     *                                                                  folders containing classes that might be
154
-     *                                                                  invoked by the addon
155
-     * @type string                   $dms_paths                        [Required] an array of full server paths to
156
-     *                                                                  folders that contain data migration scripts.
157
-     *                                                                  The key should be the EE_Addon class name that
158
-     *                                                                  this set of data migration scripts belongs to.
159
-     *                                                                  If the EE_Addon class is namespaced, then this
160
-     *                                                                  needs to be the Fully Qualified Class Name
161
-     * @type string                   $module_paths                     an array of full server paths to any
162
-     *                                                                  EED_Modules used by the addon
163
-     * @type string                   $shortcode_paths                  an array of full server paths to folders
164
-     *                                                                  that contain EES_Shortcodes
165
-     * @type string                   $widget_paths                     an array of full server paths to folders
166
-     *                                                                  that contain WP_Widgets
167
-     * @type string                   $pue_options
168
-     * @type array                    $capabilities                     an array indexed by role name
169
-     *                                                                  (i.e administrator,author ) and the values
170
-     *                                                                  are an array of caps to add to the role.
171
-     *                                                                  'administrator' => array(
172
-     *                                                                  'read_addon',
173
-     *                                                                  'edit_addon',
174
-     *                                                                  etc.
175
-     *                                                                  ).
176
-     * @type EE_Meta_Capability_Map[] $capability_maps                  an array of EE_Meta_Capability_Map object
177
-     *                                                                  for any addons that need to register any
178
-     *                                                                  special meta mapped capabilities.  Should
179
-     *                                                                  be indexed where the key is the
180
-     *                                                                  EE_Meta_Capability_Map class name and the
181
-     *                                                                  values are the arguments sent to the class.
182
-     * @type array                    $model_paths                      array of folders containing DB models
183
-     * @see      EE_Register_Model
184
-     * @type array                    $class_paths                      array of folders containing DB classes
185
-     * @see      EE_Register_Model
186
-     * @type array                    $model_extension_paths            array of folders containing DB model
187
-     *                                                                  extensions
188
-     * @see      EE_Register_Model_Extension
189
-     * @type array                    $class_extension_paths            array of folders containing DB class
190
-     *                                                                  extensions
191
-     * @see      EE_Register_Model_Extension
192
-     * @type array message_types {
193
-     *                                                                  An array of message types with the key as
194
-     *                                                                  the message type name and the values as
195
-     *                                                                  below:
196
-     * @type string                   $mtfilename                       [Required] The filename of the message type
197
-     *                                                                  being registered. This will be the main
198
-     *                                                                  EE_{Message Type Name}_message_type class.
199
-     *                                                                  for example:
200
-     *                                                                  EE_Declined_Registration_message_type.class.php
201
-     * @type array                    $autoloadpaths                    [Required] An array of paths to add to the
202
-     *                                                                  messages autoloader for the new message type.
203
-     * @type array                    $messengers_to_activate_with      An array of messengers that this message
204
-     *                                                                  type should activate with. Each value in
205
-     *                                                                  the
206
-     *                                                                  array
207
-     *                                                                  should match the name property of a
208
-     *                                                                  EE_messenger. Optional.
209
-     * @type array                    $messengers_to_validate_with      An array of messengers that this message
210
-     *                                                                  type should validate with. Each value in
211
-     *                                                                  the
212
-     *                                                                  array
213
-     *                                                                  should match the name property of an
214
-     *                                                                  EE_messenger.
215
-     *                                                                  Optional.
216
-     *                                                                  }
217
-     * @type array                    $custom_post_types
218
-     * @type array                    $custom_taxonomies
219
-     * @type array                    $payment_method_paths             each element is the folder containing the
220
-     *                                                                  EE_PMT_Base child class
221
-     *                                                                  (eg,
222
-     *                                                                  '/wp-content/plugins/my_plugin/Payomatic/'
223
-     *                                                                  which contains the files
224
-     *                                                                  EE_PMT_Payomatic.pm.php)
225
-     * @type array                    $default_terms
226
-     * @type array                    $namespace                        {
227
-     *                                                                  An array with two items for registering the
228
-     *                                                                  addon's namespace. (If, for some reason, you
229
-     *                                                                  require additional namespaces,
230
-     *                                                                  use
231
-     *                                                                  EventEspresso\core\Psr4Autoloader::addNamespace()
232
-     *                                                                  directly)
233
-     * @see      EventEspresso\core\Psr4Autoloader::addNamespace()
234
-     * @type string                   $FQNS                             the namespace prefix
235
-     * @type string                   $DIR                              a base directory for class files in the
236
-     *                                                                  namespace.
237
-     *                                                                  }
238
-     *                                                                  }
239
-     * @type string                   $privacy_policies                 FQNSs (namespaces, each of which contains only
240
-     *                                                                  privacy policy classes) or FQCNs (specific
241
-     *                                                                  classnames of privacy policy classes)
242
-     * @type string                   $personal_data_exporters          FQNSs (namespaces, each of which contains only
243
-     *                                                                  privacy policy classes) or FQCNs (specific
244
-     *                                                                  classnames of privacy policy classes)
245
-     * @type string                   $personal_data_erasers            FQNSs (namespaces, each of which contains only
246
-     *                                                                  privacy policy classes) or FQCNs (specific
247
-     *                                                                  classnames of privacy policy classes)
248
-     * @return void
249
-     * @throws DomainException
250
-     * @throws EE_Error
251
-     * @throws InvalidArgumentException
252
-     * @throws ReflectionException
253
-     * @throws InvalidDataTypeException
254
-     * @throws InvalidInterfaceException
255
-     */
256
-    public static function register($addon_name = '', $setup_args = array())
257
-    {
258
-        // required fields MUST be present, so let's make sure they are.
259
-        EE_Register_Addon::_verify_parameters($addon_name, $setup_args);
260
-        // get class name for addon
261
-        $class_name = EE_Register_Addon::_parse_class_name($addon_name, $setup_args);
262
-        // setup $_settings array from incoming values.
263
-        $addon_settings = EE_Register_Addon::_get_addon_settings($class_name, $setup_args);
264
-        // setup PUE
265
-        EE_Register_Addon::_parse_pue_options($addon_name, $class_name, $setup_args);
266
-        // does this addon work with this version of core or WordPress ?
267
-        if (! EE_Register_Addon::_addon_is_compatible($addon_name, $addon_settings)) {
268
-            return;
269
-        }
270
-        // register namespaces
271
-        EE_Register_Addon::_setup_namespaces($addon_settings);
272
-        // check if this is an activation request
273
-        if (EE_Register_Addon::_addon_activation($addon_name, $addon_settings)) {
274
-            // dont bother setting up the rest of the addon atm
275
-            return;
276
-        }
277
-        // we need cars
278
-        EE_Register_Addon::_setup_autoloaders($addon_name);
279
-        // register new models and extensions
280
-        EE_Register_Addon::_register_models_and_extensions($addon_name);
281
-        // setup DMS
282
-        EE_Register_Addon::_register_data_migration_scripts($addon_name);
283
-        // if config_class is present let's register config.
284
-        EE_Register_Addon::_register_config($addon_name);
285
-        // register admin pages
286
-        EE_Register_Addon::_register_admin_pages($addon_name);
287
-        // add to list of modules to be registered
288
-        EE_Register_Addon::_register_modules($addon_name);
289
-        // add to list of shortcodes to be registered
290
-        EE_Register_Addon::_register_shortcodes($addon_name);
291
-        // add to list of widgets to be registered
292
-        EE_Register_Addon::_register_widgets($addon_name);
293
-        // register capability related stuff.
294
-        EE_Register_Addon::_register_capabilities($addon_name);
295
-        // any message type to register?
296
-        EE_Register_Addon::_register_message_types($addon_name);
297
-        // any custom post type/ custom capabilities or default terms to register
298
-        EE_Register_Addon::_register_custom_post_types($addon_name);
299
-        // and any payment methods
300
-        EE_Register_Addon::_register_payment_methods($addon_name);
301
-        // and privacy policy generators
302
-        EE_Register_Addon::registerPrivacyPolicies($addon_name);
303
-        // and privacy policy generators
304
-        EE_Register_Addon::registerPersonalDataExporters($addon_name);
305
-        // and privacy policy generators
306
-        EE_Register_Addon::registerPersonalDataErasers($addon_name);
307
-        // load and instantiate main addon class
308
-        $addon = EE_Register_Addon::_load_and_init_addon_class($addon_name);
309
-        // delay calling after_registration hook on each addon until after all add-ons have been registered.
310
-        add_action('AHEE__EE_System__load_espresso_addons__complete', array($addon, 'after_registration'), 999);
311
-    }
106
+	/**
107
+	 * Method for registering new EE_Addons.
108
+	 * Should be called AFTER AHEE__EE_System__load_espresso_addons but BEFORE
109
+	 * AHEE__EE_System___detect_if_activation_or_upgrade__begin in order to register all its components. However, it
110
+	 * may also be called after the 'activate_plugin' action (when an addon is activated), because an activating addon
111
+	 * won't be loaded by WP until after AHEE__EE_System__load_espresso_addons has fired. If its called after
112
+	 * 'activate_plugin', it registers the addon still, but its components are not registered
113
+	 * (they shouldn't be needed anyways, because it's just an activation request and they won't have a chance to do
114
+	 * anything anyways). Instead, it just sets the newly-activated addon's activation indicator wp option and returns
115
+	 * (so that we can detect that the addon has activated on the subsequent request)
116
+	 *
117
+	 * @since    4.3.0
118
+	 * @param string                  $addon_name                       [Required] the EE_Addon's name.
119
+	 * @param  array                  $setup_args                       {
120
+	 *                                                                  An array of arguments provided for registering
121
+	 *                                                                  the message type.
122
+	 * @type  string                  $class_name                       the addon's main file name.
123
+	 *                                                                  If left blank, generated from the addon name,
124
+	 *                                                                  changes something like "calendar" to
125
+	 *                                                                  "EE_Calendar"
126
+	 * @type string                   $min_core_version                 the minimum version of EE Core that the
127
+	 *                                                                  addon will work with. eg "4.8.1.rc.084"
128
+	 * @type string                   $version                          the "software" version for the addon. eg
129
+	 *                                                                  "1.0.0.p" for a first stable release, or
130
+	 *                                                                  "1.0.0.rc.043" for a version in progress
131
+	 * @type string                   $main_file_path                   the full server path to the main file
132
+	 *                                                                  loaded directly by WP
133
+	 * @type DomainInterface $domain                                    child class of
134
+	 *                                                                  EventEspresso\core\domain\DomainBase
135
+	 * @type string                   $domain_fqcn                      Fully Qualified Class Name
136
+	 *                                                                  for the addon's Domain class
137
+	 *                                                                  (see EventEspresso\core\domain\Domain)
138
+	 * @type string                   $admin_path                       full server path to the folder where the
139
+	 *                                                                  addon\'s admin files reside
140
+	 * @type string                   $admin_callback                   a method to be called when the EE Admin is
141
+	 *                                                                  first invoked, can be used for hooking into
142
+	 *                                                                  any admin page
143
+	 * @type string                   $config_section                   the section name for this addon's
144
+	 *                                                                  configuration settings section
145
+	 *                                                                  (defaults to "addons")
146
+	 * @type string                   $config_class                     the class name for this addon's
147
+	 *                                                                  configuration settings object
148
+	 * @type string                   $config_name                      the class name for this addon's
149
+	 *                                                                  configuration settings object
150
+	 * @type string                   $autoloader_paths                 [Required] an array of class names and the full
151
+	 *                                                                  server paths to those files.
152
+	 * @type string                   $autoloader_folders               an array of  "full server paths" for any
153
+	 *                                                                  folders containing classes that might be
154
+	 *                                                                  invoked by the addon
155
+	 * @type string                   $dms_paths                        [Required] an array of full server paths to
156
+	 *                                                                  folders that contain data migration scripts.
157
+	 *                                                                  The key should be the EE_Addon class name that
158
+	 *                                                                  this set of data migration scripts belongs to.
159
+	 *                                                                  If the EE_Addon class is namespaced, then this
160
+	 *                                                                  needs to be the Fully Qualified Class Name
161
+	 * @type string                   $module_paths                     an array of full server paths to any
162
+	 *                                                                  EED_Modules used by the addon
163
+	 * @type string                   $shortcode_paths                  an array of full server paths to folders
164
+	 *                                                                  that contain EES_Shortcodes
165
+	 * @type string                   $widget_paths                     an array of full server paths to folders
166
+	 *                                                                  that contain WP_Widgets
167
+	 * @type string                   $pue_options
168
+	 * @type array                    $capabilities                     an array indexed by role name
169
+	 *                                                                  (i.e administrator,author ) and the values
170
+	 *                                                                  are an array of caps to add to the role.
171
+	 *                                                                  'administrator' => array(
172
+	 *                                                                  'read_addon',
173
+	 *                                                                  'edit_addon',
174
+	 *                                                                  etc.
175
+	 *                                                                  ).
176
+	 * @type EE_Meta_Capability_Map[] $capability_maps                  an array of EE_Meta_Capability_Map object
177
+	 *                                                                  for any addons that need to register any
178
+	 *                                                                  special meta mapped capabilities.  Should
179
+	 *                                                                  be indexed where the key is the
180
+	 *                                                                  EE_Meta_Capability_Map class name and the
181
+	 *                                                                  values are the arguments sent to the class.
182
+	 * @type array                    $model_paths                      array of folders containing DB models
183
+	 * @see      EE_Register_Model
184
+	 * @type array                    $class_paths                      array of folders containing DB classes
185
+	 * @see      EE_Register_Model
186
+	 * @type array                    $model_extension_paths            array of folders containing DB model
187
+	 *                                                                  extensions
188
+	 * @see      EE_Register_Model_Extension
189
+	 * @type array                    $class_extension_paths            array of folders containing DB class
190
+	 *                                                                  extensions
191
+	 * @see      EE_Register_Model_Extension
192
+	 * @type array message_types {
193
+	 *                                                                  An array of message types with the key as
194
+	 *                                                                  the message type name and the values as
195
+	 *                                                                  below:
196
+	 * @type string                   $mtfilename                       [Required] The filename of the message type
197
+	 *                                                                  being registered. This will be the main
198
+	 *                                                                  EE_{Message Type Name}_message_type class.
199
+	 *                                                                  for example:
200
+	 *                                                                  EE_Declined_Registration_message_type.class.php
201
+	 * @type array                    $autoloadpaths                    [Required] An array of paths to add to the
202
+	 *                                                                  messages autoloader for the new message type.
203
+	 * @type array                    $messengers_to_activate_with      An array of messengers that this message
204
+	 *                                                                  type should activate with. Each value in
205
+	 *                                                                  the
206
+	 *                                                                  array
207
+	 *                                                                  should match the name property of a
208
+	 *                                                                  EE_messenger. Optional.
209
+	 * @type array                    $messengers_to_validate_with      An array of messengers that this message
210
+	 *                                                                  type should validate with. Each value in
211
+	 *                                                                  the
212
+	 *                                                                  array
213
+	 *                                                                  should match the name property of an
214
+	 *                                                                  EE_messenger.
215
+	 *                                                                  Optional.
216
+	 *                                                                  }
217
+	 * @type array                    $custom_post_types
218
+	 * @type array                    $custom_taxonomies
219
+	 * @type array                    $payment_method_paths             each element is the folder containing the
220
+	 *                                                                  EE_PMT_Base child class
221
+	 *                                                                  (eg,
222
+	 *                                                                  '/wp-content/plugins/my_plugin/Payomatic/'
223
+	 *                                                                  which contains the files
224
+	 *                                                                  EE_PMT_Payomatic.pm.php)
225
+	 * @type array                    $default_terms
226
+	 * @type array                    $namespace                        {
227
+	 *                                                                  An array with two items for registering the
228
+	 *                                                                  addon's namespace. (If, for some reason, you
229
+	 *                                                                  require additional namespaces,
230
+	 *                                                                  use
231
+	 *                                                                  EventEspresso\core\Psr4Autoloader::addNamespace()
232
+	 *                                                                  directly)
233
+	 * @see      EventEspresso\core\Psr4Autoloader::addNamespace()
234
+	 * @type string                   $FQNS                             the namespace prefix
235
+	 * @type string                   $DIR                              a base directory for class files in the
236
+	 *                                                                  namespace.
237
+	 *                                                                  }
238
+	 *                                                                  }
239
+	 * @type string                   $privacy_policies                 FQNSs (namespaces, each of which contains only
240
+	 *                                                                  privacy policy classes) or FQCNs (specific
241
+	 *                                                                  classnames of privacy policy classes)
242
+	 * @type string                   $personal_data_exporters          FQNSs (namespaces, each of which contains only
243
+	 *                                                                  privacy policy classes) or FQCNs (specific
244
+	 *                                                                  classnames of privacy policy classes)
245
+	 * @type string                   $personal_data_erasers            FQNSs (namespaces, each of which contains only
246
+	 *                                                                  privacy policy classes) or FQCNs (specific
247
+	 *                                                                  classnames of privacy policy classes)
248
+	 * @return void
249
+	 * @throws DomainException
250
+	 * @throws EE_Error
251
+	 * @throws InvalidArgumentException
252
+	 * @throws ReflectionException
253
+	 * @throws InvalidDataTypeException
254
+	 * @throws InvalidInterfaceException
255
+	 */
256
+	public static function register($addon_name = '', $setup_args = array())
257
+	{
258
+		// required fields MUST be present, so let's make sure they are.
259
+		EE_Register_Addon::_verify_parameters($addon_name, $setup_args);
260
+		// get class name for addon
261
+		$class_name = EE_Register_Addon::_parse_class_name($addon_name, $setup_args);
262
+		// setup $_settings array from incoming values.
263
+		$addon_settings = EE_Register_Addon::_get_addon_settings($class_name, $setup_args);
264
+		// setup PUE
265
+		EE_Register_Addon::_parse_pue_options($addon_name, $class_name, $setup_args);
266
+		// does this addon work with this version of core or WordPress ?
267
+		if (! EE_Register_Addon::_addon_is_compatible($addon_name, $addon_settings)) {
268
+			return;
269
+		}
270
+		// register namespaces
271
+		EE_Register_Addon::_setup_namespaces($addon_settings);
272
+		// check if this is an activation request
273
+		if (EE_Register_Addon::_addon_activation($addon_name, $addon_settings)) {
274
+			// dont bother setting up the rest of the addon atm
275
+			return;
276
+		}
277
+		// we need cars
278
+		EE_Register_Addon::_setup_autoloaders($addon_name);
279
+		// register new models and extensions
280
+		EE_Register_Addon::_register_models_and_extensions($addon_name);
281
+		// setup DMS
282
+		EE_Register_Addon::_register_data_migration_scripts($addon_name);
283
+		// if config_class is present let's register config.
284
+		EE_Register_Addon::_register_config($addon_name);
285
+		// register admin pages
286
+		EE_Register_Addon::_register_admin_pages($addon_name);
287
+		// add to list of modules to be registered
288
+		EE_Register_Addon::_register_modules($addon_name);
289
+		// add to list of shortcodes to be registered
290
+		EE_Register_Addon::_register_shortcodes($addon_name);
291
+		// add to list of widgets to be registered
292
+		EE_Register_Addon::_register_widgets($addon_name);
293
+		// register capability related stuff.
294
+		EE_Register_Addon::_register_capabilities($addon_name);
295
+		// any message type to register?
296
+		EE_Register_Addon::_register_message_types($addon_name);
297
+		// any custom post type/ custom capabilities or default terms to register
298
+		EE_Register_Addon::_register_custom_post_types($addon_name);
299
+		// and any payment methods
300
+		EE_Register_Addon::_register_payment_methods($addon_name);
301
+		// and privacy policy generators
302
+		EE_Register_Addon::registerPrivacyPolicies($addon_name);
303
+		// and privacy policy generators
304
+		EE_Register_Addon::registerPersonalDataExporters($addon_name);
305
+		// and privacy policy generators
306
+		EE_Register_Addon::registerPersonalDataErasers($addon_name);
307
+		// load and instantiate main addon class
308
+		$addon = EE_Register_Addon::_load_and_init_addon_class($addon_name);
309
+		// delay calling after_registration hook on each addon until after all add-ons have been registered.
310
+		add_action('AHEE__EE_System__load_espresso_addons__complete', array($addon, 'after_registration'), 999);
311
+	}
312 312
 
313 313
 
314
-    /**
315
-     * @param string $addon_name
316
-     * @param array  $setup_args
317
-     * @return void
318
-     * @throws EE_Error
319
-     */
320
-    private static function _verify_parameters($addon_name, array $setup_args)
321
-    {
322
-        // required fields MUST be present, so let's make sure they are.
323
-        if (empty($addon_name) || ! is_array($setup_args)) {
324
-            throw new EE_Error(
325
-                __(
326
-                    'In order to register an EE_Addon with EE_Register_Addon::register(), you must include the "addon_name" (the name of the addon), and an array of arguments.',
327
-                    'event_espresso'
328
-                )
329
-            );
330
-        }
331
-        if (! isset($setup_args['main_file_path']) || empty($setup_args['main_file_path'])) {
332
-            throw new EE_Error(
333
-                sprintf(
334
-                    __(
335
-                        'When registering an addon, you didn\'t provide the "main_file_path", which is the full path to the main file loaded directly by Wordpress. You only provided %s',
336
-                        'event_espresso'
337
-                    ),
338
-                    implode(',', array_keys($setup_args))
339
-                )
340
-            );
341
-        }
342
-        // check that addon has not already been registered with that name
343
-        if (isset(self::$_settings[ $addon_name ]) && ! did_action('activate_plugin')) {
344
-            throw new EE_Error(
345
-                sprintf(
346
-                    __(
347
-                        'An EE_Addon with the name "%s" has already been registered and each EE_Addon requires a unique name.',
348
-                        'event_espresso'
349
-                    ),
350
-                    $addon_name
351
-                )
352
-            );
353
-        }
354
-    }
314
+	/**
315
+	 * @param string $addon_name
316
+	 * @param array  $setup_args
317
+	 * @return void
318
+	 * @throws EE_Error
319
+	 */
320
+	private static function _verify_parameters($addon_name, array $setup_args)
321
+	{
322
+		// required fields MUST be present, so let's make sure they are.
323
+		if (empty($addon_name) || ! is_array($setup_args)) {
324
+			throw new EE_Error(
325
+				__(
326
+					'In order to register an EE_Addon with EE_Register_Addon::register(), you must include the "addon_name" (the name of the addon), and an array of arguments.',
327
+					'event_espresso'
328
+				)
329
+			);
330
+		}
331
+		if (! isset($setup_args['main_file_path']) || empty($setup_args['main_file_path'])) {
332
+			throw new EE_Error(
333
+				sprintf(
334
+					__(
335
+						'When registering an addon, you didn\'t provide the "main_file_path", which is the full path to the main file loaded directly by Wordpress. You only provided %s',
336
+						'event_espresso'
337
+					),
338
+					implode(',', array_keys($setup_args))
339
+				)
340
+			);
341
+		}
342
+		// check that addon has not already been registered with that name
343
+		if (isset(self::$_settings[ $addon_name ]) && ! did_action('activate_plugin')) {
344
+			throw new EE_Error(
345
+				sprintf(
346
+					__(
347
+						'An EE_Addon with the name "%s" has already been registered and each EE_Addon requires a unique name.',
348
+						'event_espresso'
349
+					),
350
+					$addon_name
351
+				)
352
+			);
353
+		}
354
+	}
355 355
 
356 356
 
357
-    /**
358
-     * @param string $addon_name
359
-     * @param array  $setup_args
360
-     * @return string
361
-     */
362
-    private static function _parse_class_name($addon_name, array $setup_args)
363
-    {
364
-        if (empty($setup_args['class_name'])) {
365
-            // generate one by first separating name with spaces
366
-            $class_name = str_replace(array('-', '_'), ' ', trim($addon_name));
367
-            // capitalize, then replace spaces with underscores
368
-            $class_name = str_replace(' ', '_', ucwords($class_name));
369
-        } else {
370
-            $class_name = $setup_args['class_name'];
371
-        }
372
-        // check if classname is fully  qualified or is a legacy classname already prefixed with 'EE_'
373
-        return strpos($class_name, '\\') || strpos($class_name, 'EE_') === 0
374
-            ? $class_name
375
-            : 'EE_' . $class_name;
376
-    }
357
+	/**
358
+	 * @param string $addon_name
359
+	 * @param array  $setup_args
360
+	 * @return string
361
+	 */
362
+	private static function _parse_class_name($addon_name, array $setup_args)
363
+	{
364
+		if (empty($setup_args['class_name'])) {
365
+			// generate one by first separating name with spaces
366
+			$class_name = str_replace(array('-', '_'), ' ', trim($addon_name));
367
+			// capitalize, then replace spaces with underscores
368
+			$class_name = str_replace(' ', '_', ucwords($class_name));
369
+		} else {
370
+			$class_name = $setup_args['class_name'];
371
+		}
372
+		// check if classname is fully  qualified or is a legacy classname already prefixed with 'EE_'
373
+		return strpos($class_name, '\\') || strpos($class_name, 'EE_') === 0
374
+			? $class_name
375
+			: 'EE_' . $class_name;
376
+	}
377 377
 
378 378
 
379
-    /**
380
-     * @param string $class_name
381
-     * @param array  $setup_args
382
-     * @return array
383
-     */
384
-    private static function _get_addon_settings($class_name, array $setup_args)
385
-    {
386
-        // setup $_settings array from incoming values.
387
-        $addon_settings = array(
388
-            // generated from the addon name, changes something like "calendar" to "EE_Calendar"
389
-            'class_name'            => $class_name,
390
-            // the addon slug for use in URLs, etc
391
-            'plugin_slug'           => isset($setup_args['plugin_slug'])
392
-                ? (string) $setup_args['plugin_slug']
393
-                : '',
394
-            // page slug to be used when generating the "Settings" link on the WP plugin page
395
-            'plugin_action_slug'    => isset($setup_args['plugin_action_slug'])
396
-                ? (string) $setup_args['plugin_action_slug']
397
-                : '',
398
-            // the "software" version for the addon
399
-            'version'               => isset($setup_args['version'])
400
-                ? (string) $setup_args['version']
401
-                : '',
402
-            // the minimum version of EE Core that the addon will work with
403
-            'min_core_version'      => isset($setup_args['min_core_version'])
404
-                ? (string) $setup_args['min_core_version']
405
-                : '',
406
-            // the minimum version of WordPress that the addon will work with
407
-            'min_wp_version'        => isset($setup_args['min_wp_version'])
408
-                ? (string) $setup_args['min_wp_version']
409
-                : EE_MIN_WP_VER_REQUIRED,
410
-            // full server path to main file (file loaded directly by WP)
411
-            'main_file_path'        => isset($setup_args['main_file_path'])
412
-                ? (string) $setup_args['main_file_path']
413
-                : '',
414
-            // instance of \EventEspresso\core\domain\DomainInterface
415
-            'domain'                => isset($setup_args['domain']) && $setup_args['domain'] instanceof DomainInterface
416
-                ? $setup_args['domain']
417
-                : null,
418
-            // Fully Qualified Class Name for the addon's Domain class
419
-            'domain_fqcn'           => isset($setup_args['domain_fqcn'])
420
-                ? (string) $setup_args['domain_fqcn']
421
-                : '',
422
-            // path to folder containing files for integrating with the EE core admin and/or setting up EE admin pages
423
-            'admin_path'            => isset($setup_args['admin_path'])
424
-                ? (string) $setup_args['admin_path'] : '',
425
-            // a method to be called when the EE Admin is first invoked, can be used for hooking into any admin page
426
-            'admin_callback'        => isset($setup_args['admin_callback'])
427
-                ? (string) $setup_args['admin_callback']
428
-                : '',
429
-            // the section name for this addon's configuration settings section (defaults to "addons")
430
-            'config_section'        => isset($setup_args['config_section'])
431
-                ? (string) $setup_args['config_section']
432
-                : 'addons',
433
-            // the class name for this addon's configuration settings object
434
-            'config_class'          => isset($setup_args['config_class'])
435
-                ? (string) $setup_args['config_class'] : '',
436
-            // the name given to the config for this addons' configuration settings object (optional)
437
-            'config_name'           => isset($setup_args['config_name'])
438
-                ? (string) $setup_args['config_name'] : '',
439
-            // an array of "class names" => "full server paths" for any classes that might be invoked by the addon
440
-            'autoloader_paths'      => isset($setup_args['autoloader_paths'])
441
-                ? (array) $setup_args['autoloader_paths']
442
-                : array(),
443
-            // an array of  "full server paths" for any folders containing classes that might be invoked by the addon
444
-            'autoloader_folders'    => isset($setup_args['autoloader_folders'])
445
-                ? (array) $setup_args['autoloader_folders']
446
-                : array(),
447
-            // array of full server paths to any EE_DMS data migration scripts used by the addon.
448
-            // The key should be the EE_Addon class name that this set of data migration scripts belongs to.
449
-            // If the EE_Addon class is namespaced, then this needs to be the Fully Qualified Class Name
450
-            'dms_paths'             => isset($setup_args['dms_paths'])
451
-                ? (array) $setup_args['dms_paths']
452
-                : array(),
453
-            // array of full server paths to any EED_Modules used by the addon
454
-            'module_paths'          => isset($setup_args['module_paths'])
455
-                ? (array) $setup_args['module_paths']
456
-                : array(),
457
-            // array of full server paths to any EES_Shortcodes used by the addon
458
-            'shortcode_paths'       => isset($setup_args['shortcode_paths'])
459
-                ? (array) $setup_args['shortcode_paths']
460
-                : array(),
461
-            'shortcode_fqcns'       => isset($setup_args['shortcode_fqcns'])
462
-                ? (array) $setup_args['shortcode_fqcns']
463
-                : array(),
464
-            // array of full server paths to any WP_Widgets used by the addon
465
-            'widget_paths'          => isset($setup_args['widget_paths'])
466
-                ? (array) $setup_args['widget_paths']
467
-                : array(),
468
-            // array of PUE options used by the addon
469
-            'pue_options'           => isset($setup_args['pue_options'])
470
-                ? (array) $setup_args['pue_options']
471
-                : array(),
472
-            'message_types'         => isset($setup_args['message_types'])
473
-                ? (array) $setup_args['message_types']
474
-                : array(),
475
-            'capabilities'          => isset($setup_args['capabilities'])
476
-                ? (array) $setup_args['capabilities']
477
-                : array(),
478
-            'capability_maps'       => isset($setup_args['capability_maps'])
479
-                ? (array) $setup_args['capability_maps']
480
-                : array(),
481
-            'model_paths'           => isset($setup_args['model_paths'])
482
-                ? (array) $setup_args['model_paths']
483
-                : array(),
484
-            'class_paths'           => isset($setup_args['class_paths'])
485
-                ? (array) $setup_args['class_paths']
486
-                : array(),
487
-            'model_extension_paths' => isset($setup_args['model_extension_paths'])
488
-                ? (array) $setup_args['model_extension_paths']
489
-                : array(),
490
-            'class_extension_paths' => isset($setup_args['class_extension_paths'])
491
-                ? (array) $setup_args['class_extension_paths']
492
-                : array(),
493
-            'custom_post_types'     => isset($setup_args['custom_post_types'])
494
-                ? (array) $setup_args['custom_post_types']
495
-                : array(),
496
-            'custom_taxonomies'     => isset($setup_args['custom_taxonomies'])
497
-                ? (array) $setup_args['custom_taxonomies']
498
-                : array(),
499
-            'payment_method_paths'  => isset($setup_args['payment_method_paths'])
500
-                ? (array) $setup_args['payment_method_paths']
501
-                : array(),
502
-            'default_terms'         => isset($setup_args['default_terms'])
503
-                ? (array) $setup_args['default_terms']
504
-                : array(),
505
-            // if not empty, inserts a new table row after this plugin's row on the WP Plugins page
506
-            // that can be used for adding upgrading/marketing info
507
-            'plugins_page_row'      => isset($setup_args['plugins_page_row'])
508
-                ? $setup_args['plugins_page_row']
509
-                : '',
510
-            'namespace'             => isset(
511
-                $setup_args['namespace']['FQNS'],
512
-                $setup_args['namespace']['DIR']
513
-            )
514
-                ? (array) $setup_args['namespace']
515
-                : array(),
516
-            'privacy_policies'      => isset($setup_args['privacy_policies'])
517
-                ? (array) $setup_args['privacy_policies']
518
-                : '',
519
-        );
520
-        // if plugin_action_slug is NOT set, but an admin page path IS set,
521
-        // then let's just use the plugin_slug since that will be used for linking to the admin page
522
-        $addon_settings['plugin_action_slug'] = empty($addon_settings['plugin_action_slug'])
523
-                                                && ! empty($addon_settings['admin_path'])
524
-            ? $addon_settings['plugin_slug']
525
-            : $addon_settings['plugin_action_slug'];
526
-        // full server path to main file (file loaded directly by WP)
527
-        $addon_settings['plugin_basename'] = plugin_basename($addon_settings['main_file_path']);
528
-        return $addon_settings;
529
-    }
379
+	/**
380
+	 * @param string $class_name
381
+	 * @param array  $setup_args
382
+	 * @return array
383
+	 */
384
+	private static function _get_addon_settings($class_name, array $setup_args)
385
+	{
386
+		// setup $_settings array from incoming values.
387
+		$addon_settings = array(
388
+			// generated from the addon name, changes something like "calendar" to "EE_Calendar"
389
+			'class_name'            => $class_name,
390
+			// the addon slug for use in URLs, etc
391
+			'plugin_slug'           => isset($setup_args['plugin_slug'])
392
+				? (string) $setup_args['plugin_slug']
393
+				: '',
394
+			// page slug to be used when generating the "Settings" link on the WP plugin page
395
+			'plugin_action_slug'    => isset($setup_args['plugin_action_slug'])
396
+				? (string) $setup_args['plugin_action_slug']
397
+				: '',
398
+			// the "software" version for the addon
399
+			'version'               => isset($setup_args['version'])
400
+				? (string) $setup_args['version']
401
+				: '',
402
+			// the minimum version of EE Core that the addon will work with
403
+			'min_core_version'      => isset($setup_args['min_core_version'])
404
+				? (string) $setup_args['min_core_version']
405
+				: '',
406
+			// the minimum version of WordPress that the addon will work with
407
+			'min_wp_version'        => isset($setup_args['min_wp_version'])
408
+				? (string) $setup_args['min_wp_version']
409
+				: EE_MIN_WP_VER_REQUIRED,
410
+			// full server path to main file (file loaded directly by WP)
411
+			'main_file_path'        => isset($setup_args['main_file_path'])
412
+				? (string) $setup_args['main_file_path']
413
+				: '',
414
+			// instance of \EventEspresso\core\domain\DomainInterface
415
+			'domain'                => isset($setup_args['domain']) && $setup_args['domain'] instanceof DomainInterface
416
+				? $setup_args['domain']
417
+				: null,
418
+			// Fully Qualified Class Name for the addon's Domain class
419
+			'domain_fqcn'           => isset($setup_args['domain_fqcn'])
420
+				? (string) $setup_args['domain_fqcn']
421
+				: '',
422
+			// path to folder containing files for integrating with the EE core admin and/or setting up EE admin pages
423
+			'admin_path'            => isset($setup_args['admin_path'])
424
+				? (string) $setup_args['admin_path'] : '',
425
+			// a method to be called when the EE Admin is first invoked, can be used for hooking into any admin page
426
+			'admin_callback'        => isset($setup_args['admin_callback'])
427
+				? (string) $setup_args['admin_callback']
428
+				: '',
429
+			// the section name for this addon's configuration settings section (defaults to "addons")
430
+			'config_section'        => isset($setup_args['config_section'])
431
+				? (string) $setup_args['config_section']
432
+				: 'addons',
433
+			// the class name for this addon's configuration settings object
434
+			'config_class'          => isset($setup_args['config_class'])
435
+				? (string) $setup_args['config_class'] : '',
436
+			// the name given to the config for this addons' configuration settings object (optional)
437
+			'config_name'           => isset($setup_args['config_name'])
438
+				? (string) $setup_args['config_name'] : '',
439
+			// an array of "class names" => "full server paths" for any classes that might be invoked by the addon
440
+			'autoloader_paths'      => isset($setup_args['autoloader_paths'])
441
+				? (array) $setup_args['autoloader_paths']
442
+				: array(),
443
+			// an array of  "full server paths" for any folders containing classes that might be invoked by the addon
444
+			'autoloader_folders'    => isset($setup_args['autoloader_folders'])
445
+				? (array) $setup_args['autoloader_folders']
446
+				: array(),
447
+			// array of full server paths to any EE_DMS data migration scripts used by the addon.
448
+			// The key should be the EE_Addon class name that this set of data migration scripts belongs to.
449
+			// If the EE_Addon class is namespaced, then this needs to be the Fully Qualified Class Name
450
+			'dms_paths'             => isset($setup_args['dms_paths'])
451
+				? (array) $setup_args['dms_paths']
452
+				: array(),
453
+			// array of full server paths to any EED_Modules used by the addon
454
+			'module_paths'          => isset($setup_args['module_paths'])
455
+				? (array) $setup_args['module_paths']
456
+				: array(),
457
+			// array of full server paths to any EES_Shortcodes used by the addon
458
+			'shortcode_paths'       => isset($setup_args['shortcode_paths'])
459
+				? (array) $setup_args['shortcode_paths']
460
+				: array(),
461
+			'shortcode_fqcns'       => isset($setup_args['shortcode_fqcns'])
462
+				? (array) $setup_args['shortcode_fqcns']
463
+				: array(),
464
+			// array of full server paths to any WP_Widgets used by the addon
465
+			'widget_paths'          => isset($setup_args['widget_paths'])
466
+				? (array) $setup_args['widget_paths']
467
+				: array(),
468
+			// array of PUE options used by the addon
469
+			'pue_options'           => isset($setup_args['pue_options'])
470
+				? (array) $setup_args['pue_options']
471
+				: array(),
472
+			'message_types'         => isset($setup_args['message_types'])
473
+				? (array) $setup_args['message_types']
474
+				: array(),
475
+			'capabilities'          => isset($setup_args['capabilities'])
476
+				? (array) $setup_args['capabilities']
477
+				: array(),
478
+			'capability_maps'       => isset($setup_args['capability_maps'])
479
+				? (array) $setup_args['capability_maps']
480
+				: array(),
481
+			'model_paths'           => isset($setup_args['model_paths'])
482
+				? (array) $setup_args['model_paths']
483
+				: array(),
484
+			'class_paths'           => isset($setup_args['class_paths'])
485
+				? (array) $setup_args['class_paths']
486
+				: array(),
487
+			'model_extension_paths' => isset($setup_args['model_extension_paths'])
488
+				? (array) $setup_args['model_extension_paths']
489
+				: array(),
490
+			'class_extension_paths' => isset($setup_args['class_extension_paths'])
491
+				? (array) $setup_args['class_extension_paths']
492
+				: array(),
493
+			'custom_post_types'     => isset($setup_args['custom_post_types'])
494
+				? (array) $setup_args['custom_post_types']
495
+				: array(),
496
+			'custom_taxonomies'     => isset($setup_args['custom_taxonomies'])
497
+				? (array) $setup_args['custom_taxonomies']
498
+				: array(),
499
+			'payment_method_paths'  => isset($setup_args['payment_method_paths'])
500
+				? (array) $setup_args['payment_method_paths']
501
+				: array(),
502
+			'default_terms'         => isset($setup_args['default_terms'])
503
+				? (array) $setup_args['default_terms']
504
+				: array(),
505
+			// if not empty, inserts a new table row after this plugin's row on the WP Plugins page
506
+			// that can be used for adding upgrading/marketing info
507
+			'plugins_page_row'      => isset($setup_args['plugins_page_row'])
508
+				? $setup_args['plugins_page_row']
509
+				: '',
510
+			'namespace'             => isset(
511
+				$setup_args['namespace']['FQNS'],
512
+				$setup_args['namespace']['DIR']
513
+			)
514
+				? (array) $setup_args['namespace']
515
+				: array(),
516
+			'privacy_policies'      => isset($setup_args['privacy_policies'])
517
+				? (array) $setup_args['privacy_policies']
518
+				: '',
519
+		);
520
+		// if plugin_action_slug is NOT set, but an admin page path IS set,
521
+		// then let's just use the plugin_slug since that will be used for linking to the admin page
522
+		$addon_settings['plugin_action_slug'] = empty($addon_settings['plugin_action_slug'])
523
+												&& ! empty($addon_settings['admin_path'])
524
+			? $addon_settings['plugin_slug']
525
+			: $addon_settings['plugin_action_slug'];
526
+		// full server path to main file (file loaded directly by WP)
527
+		$addon_settings['plugin_basename'] = plugin_basename($addon_settings['main_file_path']);
528
+		return $addon_settings;
529
+	}
530 530
 
531 531
 
532
-    /**
533
-     * @param string $addon_name
534
-     * @param array  $addon_settings
535
-     * @return boolean
536
-     */
537
-    private static function _addon_is_compatible($addon_name, array $addon_settings)
538
-    {
539
-        global $wp_version;
540
-        $incompatibility_message = '';
541
-        // check whether this addon version is compatible with EE core
542
-        if (isset(EE_Register_Addon::$_incompatible_addons[ $addon_name ])
543
-            && ! self::_meets_min_core_version_requirement(
544
-                EE_Register_Addon::$_incompatible_addons[ $addon_name ],
545
-                $addon_settings['version']
546
-            )
547
-        ) {
548
-            $incompatibility_message = sprintf(
549
-                __(
550
-                    '%4$sIMPORTANT!%5$sThe Event Espresso "%1$s" addon is not compatible with this version of Event Espresso.%2$sPlease upgrade your "%1$s" addon to version %3$s or newer to resolve this issue.',
551
-                    'event_espresso'
552
-                ),
553
-                $addon_name,
554
-                '<br />',
555
-                EE_Register_Addon::$_incompatible_addons[ $addon_name ],
556
-                '<span style="font-weight: bold; color: #D54E21;">',
557
-                '</span><br />'
558
-            );
559
-        } elseif (! self::_meets_min_core_version_requirement($addon_settings['min_core_version'], espresso_version())
560
-        ) {
561
-            $incompatibility_message = sprintf(
562
-                __(
563
-                    '%5$sIMPORTANT!%6$sThe Event Espresso "%1$s" addon requires Event Espresso Core version "%2$s" or higher in order to run.%4$sYour version of Event Espresso Core is currently at "%3$s". Please upgrade Event Espresso Core first and then re-activate "%1$s".',
564
-                    'event_espresso'
565
-                ),
566
-                $addon_name,
567
-                self::_effective_version($addon_settings['min_core_version']),
568
-                self::_effective_version(espresso_version()),
569
-                '<br />',
570
-                '<span style="font-weight: bold; color: #D54E21;">',
571
-                '</span><br />'
572
-            );
573
-        } elseif (version_compare($wp_version, $addon_settings['min_wp_version'], '<')) {
574
-            $incompatibility_message = sprintf(
575
-                __(
576
-                    '%4$sIMPORTANT!%5$sThe Event Espresso "%1$s" addon requires WordPress version "%2$s" or greater.%3$sPlease update your version of WordPress to use the "%1$s" addon and to keep your site secure.',
577
-                    'event_espresso'
578
-                ),
579
-                $addon_name,
580
-                $addon_settings['min_wp_version'],
581
-                '<br />',
582
-                '<span style="font-weight: bold; color: #D54E21;">',
583
-                '</span><br />'
584
-            );
585
-        }
586
-        if (! empty($incompatibility_message)) {
587
-            // remove 'activate' from the REQUEST
588
-            // so WP doesn't erroneously tell the user the plugin activated fine when it didn't
589
-            unset($_GET['activate'], $_REQUEST['activate']);
590
-            if (current_user_can('activate_plugins')) {
591
-                // show an error message indicating the plugin didn't activate properly
592
-                EE_Error::add_error($incompatibility_message, __FILE__, __FUNCTION__, __LINE__);
593
-            }
594
-            // BAIL FROM THE ADDON REGISTRATION PROCESS
595
-            return false;
596
-        }
597
-        // addon IS compatible
598
-        return true;
599
-    }
532
+	/**
533
+	 * @param string $addon_name
534
+	 * @param array  $addon_settings
535
+	 * @return boolean
536
+	 */
537
+	private static function _addon_is_compatible($addon_name, array $addon_settings)
538
+	{
539
+		global $wp_version;
540
+		$incompatibility_message = '';
541
+		// check whether this addon version is compatible with EE core
542
+		if (isset(EE_Register_Addon::$_incompatible_addons[ $addon_name ])
543
+			&& ! self::_meets_min_core_version_requirement(
544
+				EE_Register_Addon::$_incompatible_addons[ $addon_name ],
545
+				$addon_settings['version']
546
+			)
547
+		) {
548
+			$incompatibility_message = sprintf(
549
+				__(
550
+					'%4$sIMPORTANT!%5$sThe Event Espresso "%1$s" addon is not compatible with this version of Event Espresso.%2$sPlease upgrade your "%1$s" addon to version %3$s or newer to resolve this issue.',
551
+					'event_espresso'
552
+				),
553
+				$addon_name,
554
+				'<br />',
555
+				EE_Register_Addon::$_incompatible_addons[ $addon_name ],
556
+				'<span style="font-weight: bold; color: #D54E21;">',
557
+				'</span><br />'
558
+			);
559
+		} elseif (! self::_meets_min_core_version_requirement($addon_settings['min_core_version'], espresso_version())
560
+		) {
561
+			$incompatibility_message = sprintf(
562
+				__(
563
+					'%5$sIMPORTANT!%6$sThe Event Espresso "%1$s" addon requires Event Espresso Core version "%2$s" or higher in order to run.%4$sYour version of Event Espresso Core is currently at "%3$s". Please upgrade Event Espresso Core first and then re-activate "%1$s".',
564
+					'event_espresso'
565
+				),
566
+				$addon_name,
567
+				self::_effective_version($addon_settings['min_core_version']),
568
+				self::_effective_version(espresso_version()),
569
+				'<br />',
570
+				'<span style="font-weight: bold; color: #D54E21;">',
571
+				'</span><br />'
572
+			);
573
+		} elseif (version_compare($wp_version, $addon_settings['min_wp_version'], '<')) {
574
+			$incompatibility_message = sprintf(
575
+				__(
576
+					'%4$sIMPORTANT!%5$sThe Event Espresso "%1$s" addon requires WordPress version "%2$s" or greater.%3$sPlease update your version of WordPress to use the "%1$s" addon and to keep your site secure.',
577
+					'event_espresso'
578
+				),
579
+				$addon_name,
580
+				$addon_settings['min_wp_version'],
581
+				'<br />',
582
+				'<span style="font-weight: bold; color: #D54E21;">',
583
+				'</span><br />'
584
+			);
585
+		}
586
+		if (! empty($incompatibility_message)) {
587
+			// remove 'activate' from the REQUEST
588
+			// so WP doesn't erroneously tell the user the plugin activated fine when it didn't
589
+			unset($_GET['activate'], $_REQUEST['activate']);
590
+			if (current_user_can('activate_plugins')) {
591
+				// show an error message indicating the plugin didn't activate properly
592
+				EE_Error::add_error($incompatibility_message, __FILE__, __FUNCTION__, __LINE__);
593
+			}
594
+			// BAIL FROM THE ADDON REGISTRATION PROCESS
595
+			return false;
596
+		}
597
+		// addon IS compatible
598
+		return true;
599
+	}
600 600
 
601 601
 
602
-    /**
603
-     * if plugin update engine is being used for auto-updates,
604
-     * then let's set that up now before going any further so that ALL addons can be updated
605
-     * (not needed if PUE is not being used)
606
-     *
607
-     * @param string $addon_name
608
-     * @param string $class_name
609
-     * @param array  $setup_args
610
-     * @return void
611
-     */
612
-    private static function _parse_pue_options($addon_name, $class_name, array $setup_args)
613
-    {
614
-        if (! empty($setup_args['pue_options'])) {
615
-            self::$_settings[ $addon_name ]['pue_options'] = array(
616
-                'pue_plugin_slug' => isset($setup_args['pue_options']['pue_plugin_slug'])
617
-                    ? (string) $setup_args['pue_options']['pue_plugin_slug']
618
-                    : 'espresso_' . strtolower($class_name),
619
-                'plugin_basename' => isset($setup_args['pue_options']['plugin_basename'])
620
-                    ? (string) $setup_args['pue_options']['plugin_basename']
621
-                    : plugin_basename($setup_args['main_file_path']),
622
-                'checkPeriod'     => isset($setup_args['pue_options']['checkPeriod'])
623
-                    ? (string) $setup_args['pue_options']['checkPeriod']
624
-                    : '24',
625
-                'use_wp_update'   => isset($setup_args['pue_options']['use_wp_update'])
626
-                    ? (string) $setup_args['pue_options']['use_wp_update']
627
-                    : false,
628
-            );
629
-            add_action(
630
-                'AHEE__EE_System__brew_espresso__after_pue_init',
631
-                array('EE_Register_Addon', 'load_pue_update')
632
-            );
633
-        }
634
-    }
602
+	/**
603
+	 * if plugin update engine is being used for auto-updates,
604
+	 * then let's set that up now before going any further so that ALL addons can be updated
605
+	 * (not needed if PUE is not being used)
606
+	 *
607
+	 * @param string $addon_name
608
+	 * @param string $class_name
609
+	 * @param array  $setup_args
610
+	 * @return void
611
+	 */
612
+	private static function _parse_pue_options($addon_name, $class_name, array $setup_args)
613
+	{
614
+		if (! empty($setup_args['pue_options'])) {
615
+			self::$_settings[ $addon_name ]['pue_options'] = array(
616
+				'pue_plugin_slug' => isset($setup_args['pue_options']['pue_plugin_slug'])
617
+					? (string) $setup_args['pue_options']['pue_plugin_slug']
618
+					: 'espresso_' . strtolower($class_name),
619
+				'plugin_basename' => isset($setup_args['pue_options']['plugin_basename'])
620
+					? (string) $setup_args['pue_options']['plugin_basename']
621
+					: plugin_basename($setup_args['main_file_path']),
622
+				'checkPeriod'     => isset($setup_args['pue_options']['checkPeriod'])
623
+					? (string) $setup_args['pue_options']['checkPeriod']
624
+					: '24',
625
+				'use_wp_update'   => isset($setup_args['pue_options']['use_wp_update'])
626
+					? (string) $setup_args['pue_options']['use_wp_update']
627
+					: false,
628
+			);
629
+			add_action(
630
+				'AHEE__EE_System__brew_espresso__after_pue_init',
631
+				array('EE_Register_Addon', 'load_pue_update')
632
+			);
633
+		}
634
+	}
635 635
 
636 636
 
637
-    /**
638
-     * register namespaces right away before any other files or classes get loaded, but AFTER the version checks
639
-     *
640
-     * @param array $addon_settings
641
-     * @return void
642
-     */
643
-    private static function _setup_namespaces(array $addon_settings)
644
-    {
645
-        //
646
-        if (isset(
647
-            $addon_settings['namespace']['FQNS'],
648
-            $addon_settings['namespace']['DIR']
649
-        )) {
650
-            EE_Psr4AutoloaderInit::psr4_loader()->addNamespace(
651
-                $addon_settings['namespace']['FQNS'],
652
-                $addon_settings['namespace']['DIR']
653
-            );
654
-        }
655
-    }
637
+	/**
638
+	 * register namespaces right away before any other files or classes get loaded, but AFTER the version checks
639
+	 *
640
+	 * @param array $addon_settings
641
+	 * @return void
642
+	 */
643
+	private static function _setup_namespaces(array $addon_settings)
644
+	{
645
+		//
646
+		if (isset(
647
+			$addon_settings['namespace']['FQNS'],
648
+			$addon_settings['namespace']['DIR']
649
+		)) {
650
+			EE_Psr4AutoloaderInit::psr4_loader()->addNamespace(
651
+				$addon_settings['namespace']['FQNS'],
652
+				$addon_settings['namespace']['DIR']
653
+			);
654
+		}
655
+	}
656 656
 
657 657
 
658
-    /**
659
-     * @param string $addon_name
660
-     * @param array  $addon_settings
661
-     * @return bool
662
-     * @throws EE_Error
663
-     * @throws InvalidArgumentException
664
-     * @throws ReflectionException
665
-     * @throws InvalidDataTypeException
666
-     * @throws InvalidInterfaceException
667
-     */
668
-    private static function _addon_activation($addon_name, array $addon_settings)
669
-    {
670
-        // this is an activation request
671
-        if (did_action(
672
-            'activate_plugin'
673
-        )) {// to find if THIS is the addon that was activated, just check if we have already registered it or not
674
-            // (as the newly-activated addon wasn't around the first time addons were registered).
675
-            // Note: the presence of pue_options in the addon registration options will initialize the $_settings
676
-            // property for the add-on, but the add-on is only partially initialized.  Hence, the additional check.
677
-            if (! isset(self::$_settings[ $addon_name ])
678
-                || (isset(self::$_settings[ $addon_name ])
679
-                    && ! isset(self::$_settings[ $addon_name ]['class_name'])
680
-                )
681
-            ) {
682
-                self::$_settings[ $addon_name ] = $addon_settings;
683
-                $addon = self::_load_and_init_addon_class($addon_name);
684
-                $addon->set_activation_indicator_option();
685
-                // dont bother setting up the rest of the addon.
686
-                // we know it was just activated and the request will end soon
687
-            }
688
-            return true;
689
-        }
690
-        // make sure this was called in the right place!
691
-        if (! did_action('AHEE__EE_System__load_espresso_addons')
692
-            || did_action('AHEE__EE_System___detect_if_activation_or_upgrade__begin')
693
-        ) {
694
-            EE_Error::doing_it_wrong(
695
-                __METHOD__,
696
-                sprintf(
697
-                    __(
698
-                        'An attempt to register an EE_Addon named "%s" has failed because it was not registered at the correct time.  Please use the "AHEE__EE_System__load_espresso_addons" hook to register addons.',
699
-                        'event_espresso'
700
-                    ),
701
-                    $addon_name
702
-                ),
703
-                '4.3.0'
704
-            );
705
-        }
706
-        // make sure addon settings are set correctly without overwriting anything existing
707
-        if (isset(self::$_settings[ $addon_name ])) {
708
-            self::$_settings[ $addon_name ] += $addon_settings;
709
-        } else {
710
-            self::$_settings[ $addon_name ] = $addon_settings;
711
-        }
712
-        return false;
713
-    }
658
+	/**
659
+	 * @param string $addon_name
660
+	 * @param array  $addon_settings
661
+	 * @return bool
662
+	 * @throws EE_Error
663
+	 * @throws InvalidArgumentException
664
+	 * @throws ReflectionException
665
+	 * @throws InvalidDataTypeException
666
+	 * @throws InvalidInterfaceException
667
+	 */
668
+	private static function _addon_activation($addon_name, array $addon_settings)
669
+	{
670
+		// this is an activation request
671
+		if (did_action(
672
+			'activate_plugin'
673
+		)) {// to find if THIS is the addon that was activated, just check if we have already registered it or not
674
+			// (as the newly-activated addon wasn't around the first time addons were registered).
675
+			// Note: the presence of pue_options in the addon registration options will initialize the $_settings
676
+			// property for the add-on, but the add-on is only partially initialized.  Hence, the additional check.
677
+			if (! isset(self::$_settings[ $addon_name ])
678
+				|| (isset(self::$_settings[ $addon_name ])
679
+					&& ! isset(self::$_settings[ $addon_name ]['class_name'])
680
+				)
681
+			) {
682
+				self::$_settings[ $addon_name ] = $addon_settings;
683
+				$addon = self::_load_and_init_addon_class($addon_name);
684
+				$addon->set_activation_indicator_option();
685
+				// dont bother setting up the rest of the addon.
686
+				// we know it was just activated and the request will end soon
687
+			}
688
+			return true;
689
+		}
690
+		// make sure this was called in the right place!
691
+		if (! did_action('AHEE__EE_System__load_espresso_addons')
692
+			|| did_action('AHEE__EE_System___detect_if_activation_or_upgrade__begin')
693
+		) {
694
+			EE_Error::doing_it_wrong(
695
+				__METHOD__,
696
+				sprintf(
697
+					__(
698
+						'An attempt to register an EE_Addon named "%s" has failed because it was not registered at the correct time.  Please use the "AHEE__EE_System__load_espresso_addons" hook to register addons.',
699
+						'event_espresso'
700
+					),
701
+					$addon_name
702
+				),
703
+				'4.3.0'
704
+			);
705
+		}
706
+		// make sure addon settings are set correctly without overwriting anything existing
707
+		if (isset(self::$_settings[ $addon_name ])) {
708
+			self::$_settings[ $addon_name ] += $addon_settings;
709
+		} else {
710
+			self::$_settings[ $addon_name ] = $addon_settings;
711
+		}
712
+		return false;
713
+	}
714 714
 
715 715
 
716
-    /**
717
-     * @param string $addon_name
718
-     * @return void
719
-     * @throws EE_Error
720
-     */
721
-    private static function _setup_autoloaders($addon_name)
722
-    {
723
-        if (! empty(self::$_settings[ $addon_name ]['autoloader_paths'])) {
724
-            // setup autoloader for single file
725
-            EEH_Autoloader::instance()->register_autoloader(self::$_settings[ $addon_name ]['autoloader_paths']);
726
-        }
727
-        // setup autoloaders for folders
728
-        if (! empty(self::$_settings[ $addon_name ]['autoloader_folders'])) {
729
-            foreach ((array) self::$_settings[ $addon_name ]['autoloader_folders'] as $autoloader_folder) {
730
-                EEH_Autoloader::register_autoloaders_for_each_file_in_folder($autoloader_folder);
731
-            }
732
-        }
733
-    }
716
+	/**
717
+	 * @param string $addon_name
718
+	 * @return void
719
+	 * @throws EE_Error
720
+	 */
721
+	private static function _setup_autoloaders($addon_name)
722
+	{
723
+		if (! empty(self::$_settings[ $addon_name ]['autoloader_paths'])) {
724
+			// setup autoloader for single file
725
+			EEH_Autoloader::instance()->register_autoloader(self::$_settings[ $addon_name ]['autoloader_paths']);
726
+		}
727
+		// setup autoloaders for folders
728
+		if (! empty(self::$_settings[ $addon_name ]['autoloader_folders'])) {
729
+			foreach ((array) self::$_settings[ $addon_name ]['autoloader_folders'] as $autoloader_folder) {
730
+				EEH_Autoloader::register_autoloaders_for_each_file_in_folder($autoloader_folder);
731
+			}
732
+		}
733
+	}
734 734
 
735 735
 
736
-    /**
737
-     * register new models and extensions
738
-     *
739
-     * @param string $addon_name
740
-     * @return void
741
-     * @throws EE_Error
742
-     */
743
-    private static function _register_models_and_extensions($addon_name)
744
-    {
745
-        // register new models
746
-        if (! empty(self::$_settings[ $addon_name ]['model_paths'])
747
-            || ! empty(self::$_settings[ $addon_name ]['class_paths'])
748
-        ) {
749
-            EE_Register_Model::register(
750
-                $addon_name,
751
-                array(
752
-                    'model_paths' => self::$_settings[ $addon_name ]['model_paths'],
753
-                    'class_paths' => self::$_settings[ $addon_name ]['class_paths'],
754
-                )
755
-            );
756
-        }
757
-        // register model extensions
758
-        if (! empty(self::$_settings[ $addon_name ]['model_extension_paths'])
759
-            || ! empty(self::$_settings[ $addon_name ]['class_extension_paths'])
760
-        ) {
761
-            EE_Register_Model_Extensions::register(
762
-                $addon_name,
763
-                array(
764
-                    'model_extension_paths' => self::$_settings[ $addon_name ]['model_extension_paths'],
765
-                    'class_extension_paths' => self::$_settings[ $addon_name ]['class_extension_paths'],
766
-                )
767
-            );
768
-        }
769
-    }
736
+	/**
737
+	 * register new models and extensions
738
+	 *
739
+	 * @param string $addon_name
740
+	 * @return void
741
+	 * @throws EE_Error
742
+	 */
743
+	private static function _register_models_and_extensions($addon_name)
744
+	{
745
+		// register new models
746
+		if (! empty(self::$_settings[ $addon_name ]['model_paths'])
747
+			|| ! empty(self::$_settings[ $addon_name ]['class_paths'])
748
+		) {
749
+			EE_Register_Model::register(
750
+				$addon_name,
751
+				array(
752
+					'model_paths' => self::$_settings[ $addon_name ]['model_paths'],
753
+					'class_paths' => self::$_settings[ $addon_name ]['class_paths'],
754
+				)
755
+			);
756
+		}
757
+		// register model extensions
758
+		if (! empty(self::$_settings[ $addon_name ]['model_extension_paths'])
759
+			|| ! empty(self::$_settings[ $addon_name ]['class_extension_paths'])
760
+		) {
761
+			EE_Register_Model_Extensions::register(
762
+				$addon_name,
763
+				array(
764
+					'model_extension_paths' => self::$_settings[ $addon_name ]['model_extension_paths'],
765
+					'class_extension_paths' => self::$_settings[ $addon_name ]['class_extension_paths'],
766
+				)
767
+			);
768
+		}
769
+	}
770 770
 
771 771
 
772
-    /**
773
-     * @param string $addon_name
774
-     * @return void
775
-     * @throws EE_Error
776
-     */
777
-    private static function _register_data_migration_scripts($addon_name)
778
-    {
779
-        // setup DMS
780
-        if (! empty(self::$_settings[ $addon_name ]['dms_paths'])) {
781
-            EE_Register_Data_Migration_Scripts::register(
782
-                $addon_name,
783
-                array('dms_paths' => self::$_settings[ $addon_name ]['dms_paths'])
784
-            );
785
-        }
786
-    }
772
+	/**
773
+	 * @param string $addon_name
774
+	 * @return void
775
+	 * @throws EE_Error
776
+	 */
777
+	private static function _register_data_migration_scripts($addon_name)
778
+	{
779
+		// setup DMS
780
+		if (! empty(self::$_settings[ $addon_name ]['dms_paths'])) {
781
+			EE_Register_Data_Migration_Scripts::register(
782
+				$addon_name,
783
+				array('dms_paths' => self::$_settings[ $addon_name ]['dms_paths'])
784
+			);
785
+		}
786
+	}
787 787
 
788 788
 
789
-    /**
790
-     * @param string $addon_name
791
-     * @return void
792
-     * @throws EE_Error
793
-     */
794
-    private static function _register_config($addon_name)
795
-    {
796
-        // if config_class is present let's register config.
797
-        if (! empty(self::$_settings[ $addon_name ]['config_class'])) {
798
-            EE_Register_Config::register(
799
-                self::$_settings[ $addon_name ]['config_class'],
800
-                array(
801
-                    'config_section' => self::$_settings[ $addon_name ]['config_section'],
802
-                    'config_name'    => self::$_settings[ $addon_name ]['config_name'],
803
-                )
804
-            );
805
-        }
806
-    }
789
+	/**
790
+	 * @param string $addon_name
791
+	 * @return void
792
+	 * @throws EE_Error
793
+	 */
794
+	private static function _register_config($addon_name)
795
+	{
796
+		// if config_class is present let's register config.
797
+		if (! empty(self::$_settings[ $addon_name ]['config_class'])) {
798
+			EE_Register_Config::register(
799
+				self::$_settings[ $addon_name ]['config_class'],
800
+				array(
801
+					'config_section' => self::$_settings[ $addon_name ]['config_section'],
802
+					'config_name'    => self::$_settings[ $addon_name ]['config_name'],
803
+				)
804
+			);
805
+		}
806
+	}
807 807
 
808 808
 
809
-    /**
810
-     * @param string $addon_name
811
-     * @return void
812
-     * @throws EE_Error
813
-     */
814
-    private static function _register_admin_pages($addon_name)
815
-    {
816
-        if (! empty(self::$_settings[ $addon_name ]['admin_path'])) {
817
-            EE_Register_Admin_Page::register(
818
-                $addon_name,
819
-                array('page_path' => self::$_settings[ $addon_name ]['admin_path'])
820
-            );
821
-        }
822
-    }
809
+	/**
810
+	 * @param string $addon_name
811
+	 * @return void
812
+	 * @throws EE_Error
813
+	 */
814
+	private static function _register_admin_pages($addon_name)
815
+	{
816
+		if (! empty(self::$_settings[ $addon_name ]['admin_path'])) {
817
+			EE_Register_Admin_Page::register(
818
+				$addon_name,
819
+				array('page_path' => self::$_settings[ $addon_name ]['admin_path'])
820
+			);
821
+		}
822
+	}
823 823
 
824 824
 
825
-    /**
826
-     * @param string $addon_name
827
-     * @return void
828
-     * @throws EE_Error
829
-     */
830
-    private static function _register_modules($addon_name)
831
-    {
832
-        if (! empty(self::$_settings[ $addon_name ]['module_paths'])) {
833
-            EE_Register_Module::register(
834
-                $addon_name,
835
-                array('module_paths' => self::$_settings[ $addon_name ]['module_paths'])
836
-            );
837
-        }
838
-    }
825
+	/**
826
+	 * @param string $addon_name
827
+	 * @return void
828
+	 * @throws EE_Error
829
+	 */
830
+	private static function _register_modules($addon_name)
831
+	{
832
+		if (! empty(self::$_settings[ $addon_name ]['module_paths'])) {
833
+			EE_Register_Module::register(
834
+				$addon_name,
835
+				array('module_paths' => self::$_settings[ $addon_name ]['module_paths'])
836
+			);
837
+		}
838
+	}
839 839
 
840 840
 
841
-    /**
842
-     * @param string $addon_name
843
-     * @return void
844
-     * @throws EE_Error
845
-     */
846
-    private static function _register_shortcodes($addon_name)
847
-    {
848
-        if (! empty(self::$_settings[ $addon_name ]['shortcode_paths'])
849
-            || ! empty(self::$_settings[ $addon_name ]['shortcode_fqcns'])
850
-        ) {
851
-            EE_Register_Shortcode::register(
852
-                $addon_name,
853
-                array(
854
-                    'shortcode_paths' => isset(self::$_settings[ $addon_name ]['shortcode_paths'])
855
-                        ? self::$_settings[ $addon_name ]['shortcode_paths']
856
-                        : array(),
857
-                    'shortcode_fqcns' => isset(self::$_settings[ $addon_name ]['shortcode_fqcns'])
858
-                        ? self::$_settings[ $addon_name ]['shortcode_fqcns']
859
-                        : array(),
860
-                )
861
-            );
862
-        }
863
-    }
841
+	/**
842
+	 * @param string $addon_name
843
+	 * @return void
844
+	 * @throws EE_Error
845
+	 */
846
+	private static function _register_shortcodes($addon_name)
847
+	{
848
+		if (! empty(self::$_settings[ $addon_name ]['shortcode_paths'])
849
+			|| ! empty(self::$_settings[ $addon_name ]['shortcode_fqcns'])
850
+		) {
851
+			EE_Register_Shortcode::register(
852
+				$addon_name,
853
+				array(
854
+					'shortcode_paths' => isset(self::$_settings[ $addon_name ]['shortcode_paths'])
855
+						? self::$_settings[ $addon_name ]['shortcode_paths']
856
+						: array(),
857
+					'shortcode_fqcns' => isset(self::$_settings[ $addon_name ]['shortcode_fqcns'])
858
+						? self::$_settings[ $addon_name ]['shortcode_fqcns']
859
+						: array(),
860
+				)
861
+			);
862
+		}
863
+	}
864 864
 
865 865
 
866
-    /**
867
-     * @param string $addon_name
868
-     * @return void
869
-     * @throws EE_Error
870
-     */
871
-    private static function _register_widgets($addon_name)
872
-    {
873
-        if (! empty(self::$_settings[ $addon_name ]['widget_paths'])) {
874
-            EE_Register_Widget::register(
875
-                $addon_name,
876
-                array('widget_paths' => self::$_settings[ $addon_name ]['widget_paths'])
877
-            );
878
-        }
879
-    }
866
+	/**
867
+	 * @param string $addon_name
868
+	 * @return void
869
+	 * @throws EE_Error
870
+	 */
871
+	private static function _register_widgets($addon_name)
872
+	{
873
+		if (! empty(self::$_settings[ $addon_name ]['widget_paths'])) {
874
+			EE_Register_Widget::register(
875
+				$addon_name,
876
+				array('widget_paths' => self::$_settings[ $addon_name ]['widget_paths'])
877
+			);
878
+		}
879
+	}
880 880
 
881 881
 
882
-    /**
883
-     * @param string $addon_name
884
-     * @return void
885
-     * @throws EE_Error
886
-     */
887
-    private static function _register_capabilities($addon_name)
888
-    {
889
-        if (! empty(self::$_settings[ $addon_name ]['capabilities'])) {
890
-            EE_Register_Capabilities::register(
891
-                $addon_name,
892
-                array(
893
-                    'capabilities'    => self::$_settings[ $addon_name ]['capabilities'],
894
-                    'capability_maps' => self::$_settings[ $addon_name ]['capability_maps'],
895
-                )
896
-            );
897
-        }
898
-    }
882
+	/**
883
+	 * @param string $addon_name
884
+	 * @return void
885
+	 * @throws EE_Error
886
+	 */
887
+	private static function _register_capabilities($addon_name)
888
+	{
889
+		if (! empty(self::$_settings[ $addon_name ]['capabilities'])) {
890
+			EE_Register_Capabilities::register(
891
+				$addon_name,
892
+				array(
893
+					'capabilities'    => self::$_settings[ $addon_name ]['capabilities'],
894
+					'capability_maps' => self::$_settings[ $addon_name ]['capability_maps'],
895
+				)
896
+			);
897
+		}
898
+	}
899 899
 
900 900
 
901
-    /**
902
-     * @param string $addon_name
903
-     * @return void
904
-     * @throws EE_Error
905
-     */
906
-    private static function _register_message_types($addon_name)
907
-    {
908
-        if (! empty(self::$_settings[ $addon_name ]['message_types'])) {
909
-            add_action(
910
-                'EE_Brewing_Regular___messages_caf',
911
-                array('EE_Register_Addon', 'register_message_types')
912
-            );
913
-        }
914
-    }
901
+	/**
902
+	 * @param string $addon_name
903
+	 * @return void
904
+	 * @throws EE_Error
905
+	 */
906
+	private static function _register_message_types($addon_name)
907
+	{
908
+		if (! empty(self::$_settings[ $addon_name ]['message_types'])) {
909
+			add_action(
910
+				'EE_Brewing_Regular___messages_caf',
911
+				array('EE_Register_Addon', 'register_message_types')
912
+			);
913
+		}
914
+	}
915 915
 
916 916
 
917
-    /**
918
-     * @param string $addon_name
919
-     * @return void
920
-     * @throws EE_Error
921
-     */
922
-    private static function _register_custom_post_types($addon_name)
923
-    {
924
-        if (! empty(self::$_settings[ $addon_name ]['custom_post_types'])
925
-            || ! empty(self::$_settings[ $addon_name ]['custom_taxonomies'])
926
-        ) {
927
-            EE_Register_CPT::register(
928
-                $addon_name,
929
-                array(
930
-                    'cpts'          => self::$_settings[ $addon_name ]['custom_post_types'],
931
-                    'cts'           => self::$_settings[ $addon_name ]['custom_taxonomies'],
932
-                    'default_terms' => self::$_settings[ $addon_name ]['default_terms'],
933
-                )
934
-            );
935
-        }
936
-    }
917
+	/**
918
+	 * @param string $addon_name
919
+	 * @return void
920
+	 * @throws EE_Error
921
+	 */
922
+	private static function _register_custom_post_types($addon_name)
923
+	{
924
+		if (! empty(self::$_settings[ $addon_name ]['custom_post_types'])
925
+			|| ! empty(self::$_settings[ $addon_name ]['custom_taxonomies'])
926
+		) {
927
+			EE_Register_CPT::register(
928
+				$addon_name,
929
+				array(
930
+					'cpts'          => self::$_settings[ $addon_name ]['custom_post_types'],
931
+					'cts'           => self::$_settings[ $addon_name ]['custom_taxonomies'],
932
+					'default_terms' => self::$_settings[ $addon_name ]['default_terms'],
933
+				)
934
+			);
935
+		}
936
+	}
937 937
 
938 938
 
939
-    /**
940
-     * @param string $addon_name
941
-     * @return void
942
-     * @throws InvalidArgumentException
943
-     * @throws InvalidInterfaceException
944
-     * @throws InvalidDataTypeException
945
-     * @throws DomainException
946
-     * @throws EE_Error
947
-     */
948
-    private static function _register_payment_methods($addon_name)
949
-    {
950
-        if (! empty(self::$_settings[ $addon_name ]['payment_method_paths'])) {
951
-            EE_Register_Payment_Method::register(
952
-                $addon_name,
953
-                array('payment_method_paths' => self::$_settings[ $addon_name ]['payment_method_paths'])
954
-            );
955
-        }
956
-    }
939
+	/**
940
+	 * @param string $addon_name
941
+	 * @return void
942
+	 * @throws InvalidArgumentException
943
+	 * @throws InvalidInterfaceException
944
+	 * @throws InvalidDataTypeException
945
+	 * @throws DomainException
946
+	 * @throws EE_Error
947
+	 */
948
+	private static function _register_payment_methods($addon_name)
949
+	{
950
+		if (! empty(self::$_settings[ $addon_name ]['payment_method_paths'])) {
951
+			EE_Register_Payment_Method::register(
952
+				$addon_name,
953
+				array('payment_method_paths' => self::$_settings[ $addon_name ]['payment_method_paths'])
954
+			);
955
+		}
956
+	}
957 957
 
958 958
 
959
-    /**
960
-     * @param string $addon_name
961
-     * @return void
962
-     * @throws InvalidArgumentException
963
-     * @throws InvalidInterfaceException
964
-     * @throws InvalidDataTypeException
965
-     * @throws DomainException
966
-     * @throws EE_Error
967
-     */
968
-    private static function registerPrivacyPolicies($addon_name)
969
-    {
970
-        if (! empty(self::$_settings[ $addon_name ]['privacy_policies'])) {
971
-            EE_Register_Privacy_Policy::register(
972
-                $addon_name,
973
-                self::$_settings[ $addon_name ]['privacy_policies']
974
-            );
975
-        }
976
-    }
959
+	/**
960
+	 * @param string $addon_name
961
+	 * @return void
962
+	 * @throws InvalidArgumentException
963
+	 * @throws InvalidInterfaceException
964
+	 * @throws InvalidDataTypeException
965
+	 * @throws DomainException
966
+	 * @throws EE_Error
967
+	 */
968
+	private static function registerPrivacyPolicies($addon_name)
969
+	{
970
+		if (! empty(self::$_settings[ $addon_name ]['privacy_policies'])) {
971
+			EE_Register_Privacy_Policy::register(
972
+				$addon_name,
973
+				self::$_settings[ $addon_name ]['privacy_policies']
974
+			);
975
+		}
976
+	}
977 977
 
978 978
 
979
-    /**
980
-     * @param string $addon_name
981
-     * @return void
982
-     */
983
-    private static function registerPersonalDataExporters($addon_name)
984
-    {
985
-        if (! empty(self::$_settings[ $addon_name ]['personal_data_exporters'])) {
986
-            EE_Register_Personal_Data_Eraser::register(
987
-                $addon_name,
988
-                self::$_settings[ $addon_name ]['personal_data_exporters']
989
-            );
990
-        }
991
-    }
979
+	/**
980
+	 * @param string $addon_name
981
+	 * @return void
982
+	 */
983
+	private static function registerPersonalDataExporters($addon_name)
984
+	{
985
+		if (! empty(self::$_settings[ $addon_name ]['personal_data_exporters'])) {
986
+			EE_Register_Personal_Data_Eraser::register(
987
+				$addon_name,
988
+				self::$_settings[ $addon_name ]['personal_data_exporters']
989
+			);
990
+		}
991
+	}
992 992
 
993 993
 
994
-    /**
995
-     * @param string $addon_name
996
-     * @return void
997
-     */
998
-    private static function registerPersonalDataErasers($addon_name)
999
-    {
1000
-        if (! empty(self::$_settings[ $addon_name ]['personal_data_erasers'])) {
1001
-            EE_Register_Personal_Data_Eraser::register(
1002
-                $addon_name,
1003
-                self::$_settings[ $addon_name ]['personal_data_erasers']
1004
-            );
1005
-        }
1006
-    }
994
+	/**
995
+	 * @param string $addon_name
996
+	 * @return void
997
+	 */
998
+	private static function registerPersonalDataErasers($addon_name)
999
+	{
1000
+		if (! empty(self::$_settings[ $addon_name ]['personal_data_erasers'])) {
1001
+			EE_Register_Personal_Data_Eraser::register(
1002
+				$addon_name,
1003
+				self::$_settings[ $addon_name ]['personal_data_erasers']
1004
+			);
1005
+		}
1006
+	}
1007 1007
 
1008 1008
 
1009
-    /**
1010
-     * Loads and instantiates the EE_Addon class and adds it onto the registry
1011
-     *
1012
-     * @param string $addon_name
1013
-     * @return EE_Addon
1014
-     * @throws InvalidArgumentException
1015
-     * @throws InvalidInterfaceException
1016
-     * @throws InvalidDataTypeException
1017
-     * @throws ReflectionException
1018
-     * @throws EE_Error
1019
-     */
1020
-    private static function _load_and_init_addon_class($addon_name)
1021
-    {
1022
-        $loader = EventEspresso\core\services\loaders\LoaderFactory::getLoader();
1023
-        $addon = $loader->getShared(
1024
-            self::$_settings[ $addon_name ]['class_name'],
1025
-            array('EE_Registry::create(addon)' => true)
1026
-        );
1027
-        // setter inject dep map if required
1028
-        if ($addon instanceof RequiresDependencyMapInterface && $addon->dependencyMap() === null) {
1029
-            $addon->setDependencyMap($loader->getShared('EE_Dependency_Map'));
1030
-        }
1031
-        // setter inject domain if required
1032
-        if ($addon instanceof RequiresDomainInterface
1033
-            && $addon->domain() === null
1034
-        ) {
1035
-            // using supplied Domain object
1036
-            $domain = self::$_settings[ $addon_name ]['domain'] instanceof DomainInterface
1037
-                ? self::$_settings[ $addon_name ]['domain']
1038
-                : null;
1039
-            // or construct one using Domain FQCN
1040
-            if ($domain === null && self::$_settings[ $addon_name ]['domain_fqcn'] !== '') {
1041
-                $domain = $loader->getShared(
1042
-                    self::$_settings[ $addon_name ]['domain_fqcn'],
1043
-                    array(
1044
-                        new EventEspresso\core\domain\values\FilePath(
1045
-                            self::$_settings[ $addon_name ]['main_file_path']
1046
-                        ),
1047
-                        EventEspresso\core\domain\values\Version::fromString(
1048
-                            self::$_settings[ $addon_name ]['version']
1049
-                        ),
1050
-                    )
1051
-                );
1052
-            }
1053
-            if ($domain instanceof DomainInterface) {
1054
-                $addon->setDomain($domain);
1055
-            }
1056
-        }
1057
-        $addon->set_name($addon_name);
1058
-        $addon->set_plugin_slug(self::$_settings[ $addon_name ]['plugin_slug']);
1059
-        $addon->set_plugin_basename(self::$_settings[ $addon_name ]['plugin_basename']);
1060
-        $addon->set_main_plugin_file(self::$_settings[ $addon_name ]['main_file_path']);
1061
-        $addon->set_plugin_action_slug(self::$_settings[ $addon_name ]['plugin_action_slug']);
1062
-        $addon->set_plugins_page_row(self::$_settings[ $addon_name ]['plugins_page_row']);
1063
-        $addon->set_version(self::$_settings[ $addon_name ]['version']);
1064
-        $addon->set_min_core_version(self::_effective_version(self::$_settings[ $addon_name ]['min_core_version']));
1065
-        $addon->set_config_section(self::$_settings[ $addon_name ]['config_section']);
1066
-        $addon->set_config_class(self::$_settings[ $addon_name ]['config_class']);
1067
-        $addon->set_config_name(self::$_settings[ $addon_name ]['config_name']);
1068
-        // unfortunately this can't be hooked in upon construction, because we don't have
1069
-        // the plugin mainfile's path upon construction.
1070
-        register_deactivation_hook($addon->get_main_plugin_file(), array($addon, 'deactivation'));
1071
-        // call any additional admin_callback functions during load_admin_controller hook
1072
-        if (! empty(self::$_settings[ $addon_name ]['admin_callback'])) {
1073
-            add_action(
1074
-                'AHEE__EE_System__load_controllers__load_admin_controllers',
1075
-                array($addon, self::$_settings[ $addon_name ]['admin_callback'])
1076
-            );
1077
-        }
1078
-        return $addon;
1079
-    }
1009
+	/**
1010
+	 * Loads and instantiates the EE_Addon class and adds it onto the registry
1011
+	 *
1012
+	 * @param string $addon_name
1013
+	 * @return EE_Addon
1014
+	 * @throws InvalidArgumentException
1015
+	 * @throws InvalidInterfaceException
1016
+	 * @throws InvalidDataTypeException
1017
+	 * @throws ReflectionException
1018
+	 * @throws EE_Error
1019
+	 */
1020
+	private static function _load_and_init_addon_class($addon_name)
1021
+	{
1022
+		$loader = EventEspresso\core\services\loaders\LoaderFactory::getLoader();
1023
+		$addon = $loader->getShared(
1024
+			self::$_settings[ $addon_name ]['class_name'],
1025
+			array('EE_Registry::create(addon)' => true)
1026
+		);
1027
+		// setter inject dep map if required
1028
+		if ($addon instanceof RequiresDependencyMapInterface && $addon->dependencyMap() === null) {
1029
+			$addon->setDependencyMap($loader->getShared('EE_Dependency_Map'));
1030
+		}
1031
+		// setter inject domain if required
1032
+		if ($addon instanceof RequiresDomainInterface
1033
+			&& $addon->domain() === null
1034
+		) {
1035
+			// using supplied Domain object
1036
+			$domain = self::$_settings[ $addon_name ]['domain'] instanceof DomainInterface
1037
+				? self::$_settings[ $addon_name ]['domain']
1038
+				: null;
1039
+			// or construct one using Domain FQCN
1040
+			if ($domain === null && self::$_settings[ $addon_name ]['domain_fqcn'] !== '') {
1041
+				$domain = $loader->getShared(
1042
+					self::$_settings[ $addon_name ]['domain_fqcn'],
1043
+					array(
1044
+						new EventEspresso\core\domain\values\FilePath(
1045
+							self::$_settings[ $addon_name ]['main_file_path']
1046
+						),
1047
+						EventEspresso\core\domain\values\Version::fromString(
1048
+							self::$_settings[ $addon_name ]['version']
1049
+						),
1050
+					)
1051
+				);
1052
+			}
1053
+			if ($domain instanceof DomainInterface) {
1054
+				$addon->setDomain($domain);
1055
+			}
1056
+		}
1057
+		$addon->set_name($addon_name);
1058
+		$addon->set_plugin_slug(self::$_settings[ $addon_name ]['plugin_slug']);
1059
+		$addon->set_plugin_basename(self::$_settings[ $addon_name ]['plugin_basename']);
1060
+		$addon->set_main_plugin_file(self::$_settings[ $addon_name ]['main_file_path']);
1061
+		$addon->set_plugin_action_slug(self::$_settings[ $addon_name ]['plugin_action_slug']);
1062
+		$addon->set_plugins_page_row(self::$_settings[ $addon_name ]['plugins_page_row']);
1063
+		$addon->set_version(self::$_settings[ $addon_name ]['version']);
1064
+		$addon->set_min_core_version(self::_effective_version(self::$_settings[ $addon_name ]['min_core_version']));
1065
+		$addon->set_config_section(self::$_settings[ $addon_name ]['config_section']);
1066
+		$addon->set_config_class(self::$_settings[ $addon_name ]['config_class']);
1067
+		$addon->set_config_name(self::$_settings[ $addon_name ]['config_name']);
1068
+		// unfortunately this can't be hooked in upon construction, because we don't have
1069
+		// the plugin mainfile's path upon construction.
1070
+		register_deactivation_hook($addon->get_main_plugin_file(), array($addon, 'deactivation'));
1071
+		// call any additional admin_callback functions during load_admin_controller hook
1072
+		if (! empty(self::$_settings[ $addon_name ]['admin_callback'])) {
1073
+			add_action(
1074
+				'AHEE__EE_System__load_controllers__load_admin_controllers',
1075
+				array($addon, self::$_settings[ $addon_name ]['admin_callback'])
1076
+			);
1077
+		}
1078
+		return $addon;
1079
+	}
1080 1080
 
1081 1081
 
1082
-    /**
1083
-     *    load_pue_update - Update notifications
1084
-     *
1085
-     * @return void
1086
-     * @throws InvalidArgumentException
1087
-     * @throws InvalidDataTypeException
1088
-     * @throws InvalidInterfaceException
1089
-     */
1090
-    public static function load_pue_update()
1091
-    {
1092
-        // load PUE client
1093
-        require_once EE_THIRD_PARTY . 'pue' . DS . 'pue-client.php';
1094
-        $license_server = defined('PUE_UPDATES_ENDPOINT') ? PUE_UPDATES_ENDPOINT : 'https://eventespresso.com';
1095
-        // cycle thru settings
1096
-        foreach (self::$_settings as $settings) {
1097
-            if (! empty($settings['pue_options'])) {
1098
-                // initiate the class and start the plugin update engine!
1099
-                new PluginUpdateEngineChecker(
1100
-                    // host file URL
1101
-                    $license_server,
1102
-                    // plugin slug(s)
1103
-                    array(
1104
-                        'premium'    => array('p' => $settings['pue_options']['pue_plugin_slug']),
1105
-                        'prerelease' => array('beta' => $settings['pue_options']['pue_plugin_slug'] . '-pr'),
1106
-                    ),
1107
-                    // options
1108
-                    array(
1109
-                        'apikey'            => EE_Registry::instance()->NET_CFG->core->site_license_key,
1110
-                        'lang_domain'       => 'event_espresso',
1111
-                        'checkPeriod'       => $settings['pue_options']['checkPeriod'],
1112
-                        'option_key'        => 'ee_site_license_key',
1113
-                        'options_page_slug' => 'event_espresso',
1114
-                        'plugin_basename'   => $settings['pue_options']['plugin_basename'],
1115
-                        // if use_wp_update is TRUE it means you want FREE versions of the plugin to be updated from WP
1116
-                        'use_wp_update'     => $settings['pue_options']['use_wp_update'],
1117
-                    )
1118
-                );
1119
-            }
1120
-        }
1121
-    }
1082
+	/**
1083
+	 *    load_pue_update - Update notifications
1084
+	 *
1085
+	 * @return void
1086
+	 * @throws InvalidArgumentException
1087
+	 * @throws InvalidDataTypeException
1088
+	 * @throws InvalidInterfaceException
1089
+	 */
1090
+	public static function load_pue_update()
1091
+	{
1092
+		// load PUE client
1093
+		require_once EE_THIRD_PARTY . 'pue' . DS . 'pue-client.php';
1094
+		$license_server = defined('PUE_UPDATES_ENDPOINT') ? PUE_UPDATES_ENDPOINT : 'https://eventespresso.com';
1095
+		// cycle thru settings
1096
+		foreach (self::$_settings as $settings) {
1097
+			if (! empty($settings['pue_options'])) {
1098
+				// initiate the class and start the plugin update engine!
1099
+				new PluginUpdateEngineChecker(
1100
+					// host file URL
1101
+					$license_server,
1102
+					// plugin slug(s)
1103
+					array(
1104
+						'premium'    => array('p' => $settings['pue_options']['pue_plugin_slug']),
1105
+						'prerelease' => array('beta' => $settings['pue_options']['pue_plugin_slug'] . '-pr'),
1106
+					),
1107
+					// options
1108
+					array(
1109
+						'apikey'            => EE_Registry::instance()->NET_CFG->core->site_license_key,
1110
+						'lang_domain'       => 'event_espresso',
1111
+						'checkPeriod'       => $settings['pue_options']['checkPeriod'],
1112
+						'option_key'        => 'ee_site_license_key',
1113
+						'options_page_slug' => 'event_espresso',
1114
+						'plugin_basename'   => $settings['pue_options']['plugin_basename'],
1115
+						// if use_wp_update is TRUE it means you want FREE versions of the plugin to be updated from WP
1116
+						'use_wp_update'     => $settings['pue_options']['use_wp_update'],
1117
+					)
1118
+				);
1119
+			}
1120
+		}
1121
+	}
1122 1122
 
1123 1123
 
1124
-    /**
1125
-     * Callback for EE_Brewing_Regular__messages_caf hook used to register message types.
1126
-     *
1127
-     * @since 4.4.0
1128
-     * @return void
1129
-     * @throws EE_Error
1130
-     */
1131
-    public static function register_message_types()
1132
-    {
1133
-        foreach (self::$_settings as $addon_name => $settings) {
1134
-            if (! empty($settings['message_types'])) {
1135
-                foreach ((array) $settings['message_types'] as $message_type => $message_type_settings) {
1136
-                    EE_Register_Message_Type::register($message_type, $message_type_settings);
1137
-                }
1138
-            }
1139
-        }
1140
-    }
1124
+	/**
1125
+	 * Callback for EE_Brewing_Regular__messages_caf hook used to register message types.
1126
+	 *
1127
+	 * @since 4.4.0
1128
+	 * @return void
1129
+	 * @throws EE_Error
1130
+	 */
1131
+	public static function register_message_types()
1132
+	{
1133
+		foreach (self::$_settings as $addon_name => $settings) {
1134
+			if (! empty($settings['message_types'])) {
1135
+				foreach ((array) $settings['message_types'] as $message_type => $message_type_settings) {
1136
+					EE_Register_Message_Type::register($message_type, $message_type_settings);
1137
+				}
1138
+			}
1139
+		}
1140
+	}
1141 1141
 
1142 1142
 
1143
-    /**
1144
-     * This deregisters an addon that was previously registered with a specific addon_name.
1145
-     *
1146
-     * @since    4.3.0
1147
-     * @param string $addon_name the name for the addon that was previously registered
1148
-     * @throws DomainException
1149
-     * @throws EE_Error
1150
-     * @throws InvalidArgumentException
1151
-     * @throws InvalidDataTypeException
1152
-     * @throws InvalidInterfaceException
1153
-     */
1154
-    public static function deregister($addon_name = null)
1155
-    {
1156
-        if (isset(self::$_settings[ $addon_name ]['class_name'])) {
1157
-            try {
1158
-                do_action('AHEE__EE_Register_Addon__deregister__before', $addon_name);
1159
-                $class_name = self::$_settings[ $addon_name ]['class_name'];
1160
-                if (! empty(self::$_settings[ $addon_name ]['dms_paths'])) {
1161
-                    // setup DMS
1162
-                    EE_Register_Data_Migration_Scripts::deregister($addon_name);
1163
-                }
1164
-                if (! empty(self::$_settings[ $addon_name ]['admin_path'])) {
1165
-                    // register admin page
1166
-                    EE_Register_Admin_Page::deregister($addon_name);
1167
-                }
1168
-                if (! empty(self::$_settings[ $addon_name ]['module_paths'])) {
1169
-                    // add to list of modules to be registered
1170
-                    EE_Register_Module::deregister($addon_name);
1171
-                }
1172
-                if (! empty(self::$_settings[ $addon_name ]['shortcode_paths'])
1173
-                    || ! empty(self::$_settings[ $addon_name ]['shortcode_fqcns'])
1174
-                ) {
1175
-                    // add to list of shortcodes to be registered
1176
-                    EE_Register_Shortcode::deregister($addon_name);
1177
-                }
1178
-                if (! empty(self::$_settings[ $addon_name ]['config_class'])) {
1179
-                    // if config_class present let's register config.
1180
-                    EE_Register_Config::deregister(self::$_settings[ $addon_name ]['config_class']);
1181
-                }
1182
-                if (! empty(self::$_settings[ $addon_name ]['widget_paths'])) {
1183
-                    // add to list of widgets to be registered
1184
-                    EE_Register_Widget::deregister($addon_name);
1185
-                }
1186
-                if (! empty(self::$_settings[ $addon_name ]['model_paths'])
1187
-                    || ! empty(self::$_settings[ $addon_name ]['class_paths'])
1188
-                ) {
1189
-                    // add to list of shortcodes to be registered
1190
-                    EE_Register_Model::deregister($addon_name);
1191
-                }
1192
-                if (! empty(self::$_settings[ $addon_name ]['model_extension_paths'])
1193
-                    || ! empty(self::$_settings[ $addon_name ]['class_extension_paths'])
1194
-                ) {
1195
-                    // add to list of shortcodes to be registered
1196
-                    EE_Register_Model_Extensions::deregister($addon_name);
1197
-                }
1198
-                if (! empty(self::$_settings[ $addon_name ]['message_types'])) {
1199
-                    foreach ((array) self::$_settings[ $addon_name ]['message_types'] as $message_type => $message_type_settings) {
1200
-                        EE_Register_Message_Type::deregister($message_type);
1201
-                    }
1202
-                }
1203
-                // deregister capabilities for addon
1204
-                if (! empty(self::$_settings[ $addon_name ]['capabilities'])
1205
-                    || ! empty(self::$_settings[ $addon_name ]['capability_maps'])
1206
-                ) {
1207
-                    EE_Register_Capabilities::deregister($addon_name);
1208
-                }
1209
-                // deregister custom_post_types for addon
1210
-                if (! empty(self::$_settings[ $addon_name ]['custom_post_types'])) {
1211
-                    EE_Register_CPT::deregister($addon_name);
1212
-                }
1213
-                if (! empty(self::$_settings[ $addon_name ]['payment_method_paths'])) {
1214
-                    EE_Register_Payment_Method::deregister($addon_name);
1215
-                }
1216
-                $addon = EE_Registry::instance()->getAddon($class_name);
1217
-                if ($addon instanceof EE_Addon) {
1218
-                    remove_action(
1219
-                        'deactivate_' . $addon->get_main_plugin_file_basename(),
1220
-                        array($addon, 'deactivation')
1221
-                    );
1222
-                    remove_action(
1223
-                        'AHEE__EE_System__perform_activations_upgrades_and_migrations',
1224
-                        array($addon, 'initialize_db_if_no_migrations_required')
1225
-                    );
1226
-                    // remove `after_registration` call
1227
-                    remove_action(
1228
-                        'AHEE__EE_System__load_espresso_addons__complete',
1229
-                        array($addon, 'after_registration'),
1230
-                        999
1231
-                    );
1232
-                }
1233
-                EE_Registry::instance()->removeAddon($class_name);
1234
-            } catch (OutOfBoundsException $addon_not_yet_registered_exception) {
1235
-                // the add-on was not yet registered in the registry,
1236
-                // so RegistryContainer::__get() throws this exception.
1237
-                // also no need to worry about this or log it,
1238
-                // it's ok to deregister an add-on before its registered in the registry
1239
-            } catch (Exception $e) {
1240
-                new ExceptionLogger($e);
1241
-            }
1242
-            unset(self::$_settings[ $addon_name ]);
1243
-            do_action('AHEE__EE_Register_Addon__deregister__after', $addon_name);
1244
-        }
1245
-    }
1143
+	/**
1144
+	 * This deregisters an addon that was previously registered with a specific addon_name.
1145
+	 *
1146
+	 * @since    4.3.0
1147
+	 * @param string $addon_name the name for the addon that was previously registered
1148
+	 * @throws DomainException
1149
+	 * @throws EE_Error
1150
+	 * @throws InvalidArgumentException
1151
+	 * @throws InvalidDataTypeException
1152
+	 * @throws InvalidInterfaceException
1153
+	 */
1154
+	public static function deregister($addon_name = null)
1155
+	{
1156
+		if (isset(self::$_settings[ $addon_name ]['class_name'])) {
1157
+			try {
1158
+				do_action('AHEE__EE_Register_Addon__deregister__before', $addon_name);
1159
+				$class_name = self::$_settings[ $addon_name ]['class_name'];
1160
+				if (! empty(self::$_settings[ $addon_name ]['dms_paths'])) {
1161
+					// setup DMS
1162
+					EE_Register_Data_Migration_Scripts::deregister($addon_name);
1163
+				}
1164
+				if (! empty(self::$_settings[ $addon_name ]['admin_path'])) {
1165
+					// register admin page
1166
+					EE_Register_Admin_Page::deregister($addon_name);
1167
+				}
1168
+				if (! empty(self::$_settings[ $addon_name ]['module_paths'])) {
1169
+					// add to list of modules to be registered
1170
+					EE_Register_Module::deregister($addon_name);
1171
+				}
1172
+				if (! empty(self::$_settings[ $addon_name ]['shortcode_paths'])
1173
+					|| ! empty(self::$_settings[ $addon_name ]['shortcode_fqcns'])
1174
+				) {
1175
+					// add to list of shortcodes to be registered
1176
+					EE_Register_Shortcode::deregister($addon_name);
1177
+				}
1178
+				if (! empty(self::$_settings[ $addon_name ]['config_class'])) {
1179
+					// if config_class present let's register config.
1180
+					EE_Register_Config::deregister(self::$_settings[ $addon_name ]['config_class']);
1181
+				}
1182
+				if (! empty(self::$_settings[ $addon_name ]['widget_paths'])) {
1183
+					// add to list of widgets to be registered
1184
+					EE_Register_Widget::deregister($addon_name);
1185
+				}
1186
+				if (! empty(self::$_settings[ $addon_name ]['model_paths'])
1187
+					|| ! empty(self::$_settings[ $addon_name ]['class_paths'])
1188
+				) {
1189
+					// add to list of shortcodes to be registered
1190
+					EE_Register_Model::deregister($addon_name);
1191
+				}
1192
+				if (! empty(self::$_settings[ $addon_name ]['model_extension_paths'])
1193
+					|| ! empty(self::$_settings[ $addon_name ]['class_extension_paths'])
1194
+				) {
1195
+					// add to list of shortcodes to be registered
1196
+					EE_Register_Model_Extensions::deregister($addon_name);
1197
+				}
1198
+				if (! empty(self::$_settings[ $addon_name ]['message_types'])) {
1199
+					foreach ((array) self::$_settings[ $addon_name ]['message_types'] as $message_type => $message_type_settings) {
1200
+						EE_Register_Message_Type::deregister($message_type);
1201
+					}
1202
+				}
1203
+				// deregister capabilities for addon
1204
+				if (! empty(self::$_settings[ $addon_name ]['capabilities'])
1205
+					|| ! empty(self::$_settings[ $addon_name ]['capability_maps'])
1206
+				) {
1207
+					EE_Register_Capabilities::deregister($addon_name);
1208
+				}
1209
+				// deregister custom_post_types for addon
1210
+				if (! empty(self::$_settings[ $addon_name ]['custom_post_types'])) {
1211
+					EE_Register_CPT::deregister($addon_name);
1212
+				}
1213
+				if (! empty(self::$_settings[ $addon_name ]['payment_method_paths'])) {
1214
+					EE_Register_Payment_Method::deregister($addon_name);
1215
+				}
1216
+				$addon = EE_Registry::instance()->getAddon($class_name);
1217
+				if ($addon instanceof EE_Addon) {
1218
+					remove_action(
1219
+						'deactivate_' . $addon->get_main_plugin_file_basename(),
1220
+						array($addon, 'deactivation')
1221
+					);
1222
+					remove_action(
1223
+						'AHEE__EE_System__perform_activations_upgrades_and_migrations',
1224
+						array($addon, 'initialize_db_if_no_migrations_required')
1225
+					);
1226
+					// remove `after_registration` call
1227
+					remove_action(
1228
+						'AHEE__EE_System__load_espresso_addons__complete',
1229
+						array($addon, 'after_registration'),
1230
+						999
1231
+					);
1232
+				}
1233
+				EE_Registry::instance()->removeAddon($class_name);
1234
+			} catch (OutOfBoundsException $addon_not_yet_registered_exception) {
1235
+				// the add-on was not yet registered in the registry,
1236
+				// so RegistryContainer::__get() throws this exception.
1237
+				// also no need to worry about this or log it,
1238
+				// it's ok to deregister an add-on before its registered in the registry
1239
+			} catch (Exception $e) {
1240
+				new ExceptionLogger($e);
1241
+			}
1242
+			unset(self::$_settings[ $addon_name ]);
1243
+			do_action('AHEE__EE_Register_Addon__deregister__after', $addon_name);
1244
+		}
1245
+	}
1246 1246
 }
Please login to merge, or discard this patch.
Spacing   +115 added lines, -115 removed lines patch added patch discarded remove patch
@@ -69,15 +69,15 @@  discard block
 block discarded – undo
69 69
         // offsets:    0 . 1 . 2 . 3 . 4
70 70
         $version_parts = explode('.', $min_core_version);
71 71
         // check they specified the micro version (after 2nd period)
72
-        if (! isset($version_parts[2])) {
72
+        if ( ! isset($version_parts[2])) {
73 73
             $version_parts[2] = '0';
74 74
         }
75 75
         // if they didn't specify the 'p', or 'rc' part. Just assume the lowest possible
76 76
         // soon we can assume that's 'rc', but this current version is 'alpha'
77
-        if (! isset($version_parts[3])) {
77
+        if ( ! isset($version_parts[3])) {
78 78
             $version_parts[3] = 'dev';
79 79
         }
80
-        if (! isset($version_parts[4])) {
80
+        if ( ! isset($version_parts[4])) {
81 81
             $version_parts[4] = '000';
82 82
         }
83 83
         return implode('.', $version_parts);
@@ -264,7 +264,7 @@  discard block
 block discarded – undo
264 264
         // setup PUE
265 265
         EE_Register_Addon::_parse_pue_options($addon_name, $class_name, $setup_args);
266 266
         // does this addon work with this version of core or WordPress ?
267
-        if (! EE_Register_Addon::_addon_is_compatible($addon_name, $addon_settings)) {
267
+        if ( ! EE_Register_Addon::_addon_is_compatible($addon_name, $addon_settings)) {
268 268
             return;
269 269
         }
270 270
         // register namespaces
@@ -328,7 +328,7 @@  discard block
 block discarded – undo
328 328
                 )
329 329
             );
330 330
         }
331
-        if (! isset($setup_args['main_file_path']) || empty($setup_args['main_file_path'])) {
331
+        if ( ! isset($setup_args['main_file_path']) || empty($setup_args['main_file_path'])) {
332 332
             throw new EE_Error(
333 333
                 sprintf(
334 334
                     __(
@@ -340,7 +340,7 @@  discard block
 block discarded – undo
340 340
             );
341 341
         }
342 342
         // check that addon has not already been registered with that name
343
-        if (isset(self::$_settings[ $addon_name ]) && ! did_action('activate_plugin')) {
343
+        if (isset(self::$_settings[$addon_name]) && ! did_action('activate_plugin')) {
344 344
             throw new EE_Error(
345 345
                 sprintf(
346 346
                     __(
@@ -372,7 +372,7 @@  discard block
 block discarded – undo
372 372
         // check if classname is fully  qualified or is a legacy classname already prefixed with 'EE_'
373 373
         return strpos($class_name, '\\') || strpos($class_name, 'EE_') === 0
374 374
             ? $class_name
375
-            : 'EE_' . $class_name;
375
+            : 'EE_'.$class_name;
376 376
     }
377 377
 
378 378
 
@@ -539,9 +539,9 @@  discard block
 block discarded – undo
539 539
         global $wp_version;
540 540
         $incompatibility_message = '';
541 541
         // check whether this addon version is compatible with EE core
542
-        if (isset(EE_Register_Addon::$_incompatible_addons[ $addon_name ])
542
+        if (isset(EE_Register_Addon::$_incompatible_addons[$addon_name])
543 543
             && ! self::_meets_min_core_version_requirement(
544
-                EE_Register_Addon::$_incompatible_addons[ $addon_name ],
544
+                EE_Register_Addon::$_incompatible_addons[$addon_name],
545 545
                 $addon_settings['version']
546 546
             )
547 547
         ) {
@@ -552,11 +552,11 @@  discard block
 block discarded – undo
552 552
                 ),
553 553
                 $addon_name,
554 554
                 '<br />',
555
-                EE_Register_Addon::$_incompatible_addons[ $addon_name ],
555
+                EE_Register_Addon::$_incompatible_addons[$addon_name],
556 556
                 '<span style="font-weight: bold; color: #D54E21;">',
557 557
                 '</span><br />'
558 558
             );
559
-        } elseif (! self::_meets_min_core_version_requirement($addon_settings['min_core_version'], espresso_version())
559
+        } elseif ( ! self::_meets_min_core_version_requirement($addon_settings['min_core_version'], espresso_version())
560 560
         ) {
561 561
             $incompatibility_message = sprintf(
562 562
                 __(
@@ -583,7 +583,7 @@  discard block
 block discarded – undo
583 583
                 '</span><br />'
584 584
             );
585 585
         }
586
-        if (! empty($incompatibility_message)) {
586
+        if ( ! empty($incompatibility_message)) {
587 587
             // remove 'activate' from the REQUEST
588 588
             // so WP doesn't erroneously tell the user the plugin activated fine when it didn't
589 589
             unset($_GET['activate'], $_REQUEST['activate']);
@@ -611,11 +611,11 @@  discard block
 block discarded – undo
611 611
      */
612 612
     private static function _parse_pue_options($addon_name, $class_name, array $setup_args)
613 613
     {
614
-        if (! empty($setup_args['pue_options'])) {
615
-            self::$_settings[ $addon_name ]['pue_options'] = array(
614
+        if ( ! empty($setup_args['pue_options'])) {
615
+            self::$_settings[$addon_name]['pue_options'] = array(
616 616
                 'pue_plugin_slug' => isset($setup_args['pue_options']['pue_plugin_slug'])
617 617
                     ? (string) $setup_args['pue_options']['pue_plugin_slug']
618
-                    : 'espresso_' . strtolower($class_name),
618
+                    : 'espresso_'.strtolower($class_name),
619 619
                 'plugin_basename' => isset($setup_args['pue_options']['plugin_basename'])
620 620
                     ? (string) $setup_args['pue_options']['plugin_basename']
621 621
                     : plugin_basename($setup_args['main_file_path']),
@@ -674,12 +674,12 @@  discard block
 block discarded – undo
674 674
             // (as the newly-activated addon wasn't around the first time addons were registered).
675 675
             // Note: the presence of pue_options in the addon registration options will initialize the $_settings
676 676
             // property for the add-on, but the add-on is only partially initialized.  Hence, the additional check.
677
-            if (! isset(self::$_settings[ $addon_name ])
678
-                || (isset(self::$_settings[ $addon_name ])
679
-                    && ! isset(self::$_settings[ $addon_name ]['class_name'])
677
+            if ( ! isset(self::$_settings[$addon_name])
678
+                || (isset(self::$_settings[$addon_name])
679
+                    && ! isset(self::$_settings[$addon_name]['class_name'])
680 680
                 )
681 681
             ) {
682
-                self::$_settings[ $addon_name ] = $addon_settings;
682
+                self::$_settings[$addon_name] = $addon_settings;
683 683
                 $addon = self::_load_and_init_addon_class($addon_name);
684 684
                 $addon->set_activation_indicator_option();
685 685
                 // dont bother setting up the rest of the addon.
@@ -688,7 +688,7 @@  discard block
 block discarded – undo
688 688
             return true;
689 689
         }
690 690
         // make sure this was called in the right place!
691
-        if (! did_action('AHEE__EE_System__load_espresso_addons')
691
+        if ( ! did_action('AHEE__EE_System__load_espresso_addons')
692 692
             || did_action('AHEE__EE_System___detect_if_activation_or_upgrade__begin')
693 693
         ) {
694 694
             EE_Error::doing_it_wrong(
@@ -704,10 +704,10 @@  discard block
 block discarded – undo
704 704
             );
705 705
         }
706 706
         // make sure addon settings are set correctly without overwriting anything existing
707
-        if (isset(self::$_settings[ $addon_name ])) {
708
-            self::$_settings[ $addon_name ] += $addon_settings;
707
+        if (isset(self::$_settings[$addon_name])) {
708
+            self::$_settings[$addon_name] += $addon_settings;
709 709
         } else {
710
-            self::$_settings[ $addon_name ] = $addon_settings;
710
+            self::$_settings[$addon_name] = $addon_settings;
711 711
         }
712 712
         return false;
713 713
     }
@@ -720,13 +720,13 @@  discard block
 block discarded – undo
720 720
      */
721 721
     private static function _setup_autoloaders($addon_name)
722 722
     {
723
-        if (! empty(self::$_settings[ $addon_name ]['autoloader_paths'])) {
723
+        if ( ! empty(self::$_settings[$addon_name]['autoloader_paths'])) {
724 724
             // setup autoloader for single file
725
-            EEH_Autoloader::instance()->register_autoloader(self::$_settings[ $addon_name ]['autoloader_paths']);
725
+            EEH_Autoloader::instance()->register_autoloader(self::$_settings[$addon_name]['autoloader_paths']);
726 726
         }
727 727
         // setup autoloaders for folders
728
-        if (! empty(self::$_settings[ $addon_name ]['autoloader_folders'])) {
729
-            foreach ((array) self::$_settings[ $addon_name ]['autoloader_folders'] as $autoloader_folder) {
728
+        if ( ! empty(self::$_settings[$addon_name]['autoloader_folders'])) {
729
+            foreach ((array) self::$_settings[$addon_name]['autoloader_folders'] as $autoloader_folder) {
730 730
                 EEH_Autoloader::register_autoloaders_for_each_file_in_folder($autoloader_folder);
731 731
             }
732 732
         }
@@ -743,26 +743,26 @@  discard block
 block discarded – undo
743 743
     private static function _register_models_and_extensions($addon_name)
744 744
     {
745 745
         // register new models
746
-        if (! empty(self::$_settings[ $addon_name ]['model_paths'])
747
-            || ! empty(self::$_settings[ $addon_name ]['class_paths'])
746
+        if ( ! empty(self::$_settings[$addon_name]['model_paths'])
747
+            || ! empty(self::$_settings[$addon_name]['class_paths'])
748 748
         ) {
749 749
             EE_Register_Model::register(
750 750
                 $addon_name,
751 751
                 array(
752
-                    'model_paths' => self::$_settings[ $addon_name ]['model_paths'],
753
-                    'class_paths' => self::$_settings[ $addon_name ]['class_paths'],
752
+                    'model_paths' => self::$_settings[$addon_name]['model_paths'],
753
+                    'class_paths' => self::$_settings[$addon_name]['class_paths'],
754 754
                 )
755 755
             );
756 756
         }
757 757
         // register model extensions
758
-        if (! empty(self::$_settings[ $addon_name ]['model_extension_paths'])
759
-            || ! empty(self::$_settings[ $addon_name ]['class_extension_paths'])
758
+        if ( ! empty(self::$_settings[$addon_name]['model_extension_paths'])
759
+            || ! empty(self::$_settings[$addon_name]['class_extension_paths'])
760 760
         ) {
761 761
             EE_Register_Model_Extensions::register(
762 762
                 $addon_name,
763 763
                 array(
764
-                    'model_extension_paths' => self::$_settings[ $addon_name ]['model_extension_paths'],
765
-                    'class_extension_paths' => self::$_settings[ $addon_name ]['class_extension_paths'],
764
+                    'model_extension_paths' => self::$_settings[$addon_name]['model_extension_paths'],
765
+                    'class_extension_paths' => self::$_settings[$addon_name]['class_extension_paths'],
766 766
                 )
767 767
             );
768 768
         }
@@ -777,10 +777,10 @@  discard block
 block discarded – undo
777 777
     private static function _register_data_migration_scripts($addon_name)
778 778
     {
779 779
         // setup DMS
780
-        if (! empty(self::$_settings[ $addon_name ]['dms_paths'])) {
780
+        if ( ! empty(self::$_settings[$addon_name]['dms_paths'])) {
781 781
             EE_Register_Data_Migration_Scripts::register(
782 782
                 $addon_name,
783
-                array('dms_paths' => self::$_settings[ $addon_name ]['dms_paths'])
783
+                array('dms_paths' => self::$_settings[$addon_name]['dms_paths'])
784 784
             );
785 785
         }
786 786
     }
@@ -794,12 +794,12 @@  discard block
 block discarded – undo
794 794
     private static function _register_config($addon_name)
795 795
     {
796 796
         // if config_class is present let's register config.
797
-        if (! empty(self::$_settings[ $addon_name ]['config_class'])) {
797
+        if ( ! empty(self::$_settings[$addon_name]['config_class'])) {
798 798
             EE_Register_Config::register(
799
-                self::$_settings[ $addon_name ]['config_class'],
799
+                self::$_settings[$addon_name]['config_class'],
800 800
                 array(
801
-                    'config_section' => self::$_settings[ $addon_name ]['config_section'],
802
-                    'config_name'    => self::$_settings[ $addon_name ]['config_name'],
801
+                    'config_section' => self::$_settings[$addon_name]['config_section'],
802
+                    'config_name'    => self::$_settings[$addon_name]['config_name'],
803 803
                 )
804 804
             );
805 805
         }
@@ -813,10 +813,10 @@  discard block
 block discarded – undo
813 813
      */
814 814
     private static function _register_admin_pages($addon_name)
815 815
     {
816
-        if (! empty(self::$_settings[ $addon_name ]['admin_path'])) {
816
+        if ( ! empty(self::$_settings[$addon_name]['admin_path'])) {
817 817
             EE_Register_Admin_Page::register(
818 818
                 $addon_name,
819
-                array('page_path' => self::$_settings[ $addon_name ]['admin_path'])
819
+                array('page_path' => self::$_settings[$addon_name]['admin_path'])
820 820
             );
821 821
         }
822 822
     }
@@ -829,10 +829,10 @@  discard block
 block discarded – undo
829 829
      */
830 830
     private static function _register_modules($addon_name)
831 831
     {
832
-        if (! empty(self::$_settings[ $addon_name ]['module_paths'])) {
832
+        if ( ! empty(self::$_settings[$addon_name]['module_paths'])) {
833 833
             EE_Register_Module::register(
834 834
                 $addon_name,
835
-                array('module_paths' => self::$_settings[ $addon_name ]['module_paths'])
835
+                array('module_paths' => self::$_settings[$addon_name]['module_paths'])
836 836
             );
837 837
         }
838 838
     }
@@ -845,17 +845,17 @@  discard block
 block discarded – undo
845 845
      */
846 846
     private static function _register_shortcodes($addon_name)
847 847
     {
848
-        if (! empty(self::$_settings[ $addon_name ]['shortcode_paths'])
849
-            || ! empty(self::$_settings[ $addon_name ]['shortcode_fqcns'])
848
+        if ( ! empty(self::$_settings[$addon_name]['shortcode_paths'])
849
+            || ! empty(self::$_settings[$addon_name]['shortcode_fqcns'])
850 850
         ) {
851 851
             EE_Register_Shortcode::register(
852 852
                 $addon_name,
853 853
                 array(
854
-                    'shortcode_paths' => isset(self::$_settings[ $addon_name ]['shortcode_paths'])
855
-                        ? self::$_settings[ $addon_name ]['shortcode_paths']
854
+                    'shortcode_paths' => isset(self::$_settings[$addon_name]['shortcode_paths'])
855
+                        ? self::$_settings[$addon_name]['shortcode_paths']
856 856
                         : array(),
857
-                    'shortcode_fqcns' => isset(self::$_settings[ $addon_name ]['shortcode_fqcns'])
858
-                        ? self::$_settings[ $addon_name ]['shortcode_fqcns']
857
+                    'shortcode_fqcns' => isset(self::$_settings[$addon_name]['shortcode_fqcns'])
858
+                        ? self::$_settings[$addon_name]['shortcode_fqcns']
859 859
                         : array(),
860 860
                 )
861 861
             );
@@ -870,10 +870,10 @@  discard block
 block discarded – undo
870 870
      */
871 871
     private static function _register_widgets($addon_name)
872 872
     {
873
-        if (! empty(self::$_settings[ $addon_name ]['widget_paths'])) {
873
+        if ( ! empty(self::$_settings[$addon_name]['widget_paths'])) {
874 874
             EE_Register_Widget::register(
875 875
                 $addon_name,
876
-                array('widget_paths' => self::$_settings[ $addon_name ]['widget_paths'])
876
+                array('widget_paths' => self::$_settings[$addon_name]['widget_paths'])
877 877
             );
878 878
         }
879 879
     }
@@ -886,12 +886,12 @@  discard block
 block discarded – undo
886 886
      */
887 887
     private static function _register_capabilities($addon_name)
888 888
     {
889
-        if (! empty(self::$_settings[ $addon_name ]['capabilities'])) {
889
+        if ( ! empty(self::$_settings[$addon_name]['capabilities'])) {
890 890
             EE_Register_Capabilities::register(
891 891
                 $addon_name,
892 892
                 array(
893
-                    'capabilities'    => self::$_settings[ $addon_name ]['capabilities'],
894
-                    'capability_maps' => self::$_settings[ $addon_name ]['capability_maps'],
893
+                    'capabilities'    => self::$_settings[$addon_name]['capabilities'],
894
+                    'capability_maps' => self::$_settings[$addon_name]['capability_maps'],
895 895
                 )
896 896
             );
897 897
         }
@@ -905,7 +905,7 @@  discard block
 block discarded – undo
905 905
      */
906 906
     private static function _register_message_types($addon_name)
907 907
     {
908
-        if (! empty(self::$_settings[ $addon_name ]['message_types'])) {
908
+        if ( ! empty(self::$_settings[$addon_name]['message_types'])) {
909 909
             add_action(
910 910
                 'EE_Brewing_Regular___messages_caf',
911 911
                 array('EE_Register_Addon', 'register_message_types')
@@ -921,15 +921,15 @@  discard block
 block discarded – undo
921 921
      */
922 922
     private static function _register_custom_post_types($addon_name)
923 923
     {
924
-        if (! empty(self::$_settings[ $addon_name ]['custom_post_types'])
925
-            || ! empty(self::$_settings[ $addon_name ]['custom_taxonomies'])
924
+        if ( ! empty(self::$_settings[$addon_name]['custom_post_types'])
925
+            || ! empty(self::$_settings[$addon_name]['custom_taxonomies'])
926 926
         ) {
927 927
             EE_Register_CPT::register(
928 928
                 $addon_name,
929 929
                 array(
930
-                    'cpts'          => self::$_settings[ $addon_name ]['custom_post_types'],
931
-                    'cts'           => self::$_settings[ $addon_name ]['custom_taxonomies'],
932
-                    'default_terms' => self::$_settings[ $addon_name ]['default_terms'],
930
+                    'cpts'          => self::$_settings[$addon_name]['custom_post_types'],
931
+                    'cts'           => self::$_settings[$addon_name]['custom_taxonomies'],
932
+                    'default_terms' => self::$_settings[$addon_name]['default_terms'],
933 933
                 )
934 934
             );
935 935
         }
@@ -947,10 +947,10 @@  discard block
 block discarded – undo
947 947
      */
948 948
     private static function _register_payment_methods($addon_name)
949 949
     {
950
-        if (! empty(self::$_settings[ $addon_name ]['payment_method_paths'])) {
950
+        if ( ! empty(self::$_settings[$addon_name]['payment_method_paths'])) {
951 951
             EE_Register_Payment_Method::register(
952 952
                 $addon_name,
953
-                array('payment_method_paths' => self::$_settings[ $addon_name ]['payment_method_paths'])
953
+                array('payment_method_paths' => self::$_settings[$addon_name]['payment_method_paths'])
954 954
             );
955 955
         }
956 956
     }
@@ -967,10 +967,10 @@  discard block
 block discarded – undo
967 967
      */
968 968
     private static function registerPrivacyPolicies($addon_name)
969 969
     {
970
-        if (! empty(self::$_settings[ $addon_name ]['privacy_policies'])) {
970
+        if ( ! empty(self::$_settings[$addon_name]['privacy_policies'])) {
971 971
             EE_Register_Privacy_Policy::register(
972 972
                 $addon_name,
973
-                self::$_settings[ $addon_name ]['privacy_policies']
973
+                self::$_settings[$addon_name]['privacy_policies']
974 974
             );
975 975
         }
976 976
     }
@@ -982,10 +982,10 @@  discard block
 block discarded – undo
982 982
      */
983 983
     private static function registerPersonalDataExporters($addon_name)
984 984
     {
985
-        if (! empty(self::$_settings[ $addon_name ]['personal_data_exporters'])) {
985
+        if ( ! empty(self::$_settings[$addon_name]['personal_data_exporters'])) {
986 986
             EE_Register_Personal_Data_Eraser::register(
987 987
                 $addon_name,
988
-                self::$_settings[ $addon_name ]['personal_data_exporters']
988
+                self::$_settings[$addon_name]['personal_data_exporters']
989 989
             );
990 990
         }
991 991
     }
@@ -997,10 +997,10 @@  discard block
 block discarded – undo
997 997
      */
998 998
     private static function registerPersonalDataErasers($addon_name)
999 999
     {
1000
-        if (! empty(self::$_settings[ $addon_name ]['personal_data_erasers'])) {
1000
+        if ( ! empty(self::$_settings[$addon_name]['personal_data_erasers'])) {
1001 1001
             EE_Register_Personal_Data_Eraser::register(
1002 1002
                 $addon_name,
1003
-                self::$_settings[ $addon_name ]['personal_data_erasers']
1003
+                self::$_settings[$addon_name]['personal_data_erasers']
1004 1004
             );
1005 1005
         }
1006 1006
     }
@@ -1021,7 +1021,7 @@  discard block
 block discarded – undo
1021 1021
     {
1022 1022
         $loader = EventEspresso\core\services\loaders\LoaderFactory::getLoader();
1023 1023
         $addon = $loader->getShared(
1024
-            self::$_settings[ $addon_name ]['class_name'],
1024
+            self::$_settings[$addon_name]['class_name'],
1025 1025
             array('EE_Registry::create(addon)' => true)
1026 1026
         );
1027 1027
         // setter inject dep map if required
@@ -1033,19 +1033,19 @@  discard block
 block discarded – undo
1033 1033
             && $addon->domain() === null
1034 1034
         ) {
1035 1035
             // using supplied Domain object
1036
-            $domain = self::$_settings[ $addon_name ]['domain'] instanceof DomainInterface
1037
-                ? self::$_settings[ $addon_name ]['domain']
1036
+            $domain = self::$_settings[$addon_name]['domain'] instanceof DomainInterface
1037
+                ? self::$_settings[$addon_name]['domain']
1038 1038
                 : null;
1039 1039
             // or construct one using Domain FQCN
1040
-            if ($domain === null && self::$_settings[ $addon_name ]['domain_fqcn'] !== '') {
1040
+            if ($domain === null && self::$_settings[$addon_name]['domain_fqcn'] !== '') {
1041 1041
                 $domain = $loader->getShared(
1042
-                    self::$_settings[ $addon_name ]['domain_fqcn'],
1042
+                    self::$_settings[$addon_name]['domain_fqcn'],
1043 1043
                     array(
1044 1044
                         new EventEspresso\core\domain\values\FilePath(
1045
-                            self::$_settings[ $addon_name ]['main_file_path']
1045
+                            self::$_settings[$addon_name]['main_file_path']
1046 1046
                         ),
1047 1047
                         EventEspresso\core\domain\values\Version::fromString(
1048
-                            self::$_settings[ $addon_name ]['version']
1048
+                            self::$_settings[$addon_name]['version']
1049 1049
                         ),
1050 1050
                     )
1051 1051
                 );
@@ -1055,24 +1055,24 @@  discard block
 block discarded – undo
1055 1055
             }
1056 1056
         }
1057 1057
         $addon->set_name($addon_name);
1058
-        $addon->set_plugin_slug(self::$_settings[ $addon_name ]['plugin_slug']);
1059
-        $addon->set_plugin_basename(self::$_settings[ $addon_name ]['plugin_basename']);
1060
-        $addon->set_main_plugin_file(self::$_settings[ $addon_name ]['main_file_path']);
1061
-        $addon->set_plugin_action_slug(self::$_settings[ $addon_name ]['plugin_action_slug']);
1062
-        $addon->set_plugins_page_row(self::$_settings[ $addon_name ]['plugins_page_row']);
1063
-        $addon->set_version(self::$_settings[ $addon_name ]['version']);
1064
-        $addon->set_min_core_version(self::_effective_version(self::$_settings[ $addon_name ]['min_core_version']));
1065
-        $addon->set_config_section(self::$_settings[ $addon_name ]['config_section']);
1066
-        $addon->set_config_class(self::$_settings[ $addon_name ]['config_class']);
1067
-        $addon->set_config_name(self::$_settings[ $addon_name ]['config_name']);
1058
+        $addon->set_plugin_slug(self::$_settings[$addon_name]['plugin_slug']);
1059
+        $addon->set_plugin_basename(self::$_settings[$addon_name]['plugin_basename']);
1060
+        $addon->set_main_plugin_file(self::$_settings[$addon_name]['main_file_path']);
1061
+        $addon->set_plugin_action_slug(self::$_settings[$addon_name]['plugin_action_slug']);
1062
+        $addon->set_plugins_page_row(self::$_settings[$addon_name]['plugins_page_row']);
1063
+        $addon->set_version(self::$_settings[$addon_name]['version']);
1064
+        $addon->set_min_core_version(self::_effective_version(self::$_settings[$addon_name]['min_core_version']));
1065
+        $addon->set_config_section(self::$_settings[$addon_name]['config_section']);
1066
+        $addon->set_config_class(self::$_settings[$addon_name]['config_class']);
1067
+        $addon->set_config_name(self::$_settings[$addon_name]['config_name']);
1068 1068
         // unfortunately this can't be hooked in upon construction, because we don't have
1069 1069
         // the plugin mainfile's path upon construction.
1070 1070
         register_deactivation_hook($addon->get_main_plugin_file(), array($addon, 'deactivation'));
1071 1071
         // call any additional admin_callback functions during load_admin_controller hook
1072
-        if (! empty(self::$_settings[ $addon_name ]['admin_callback'])) {
1072
+        if ( ! empty(self::$_settings[$addon_name]['admin_callback'])) {
1073 1073
             add_action(
1074 1074
                 'AHEE__EE_System__load_controllers__load_admin_controllers',
1075
-                array($addon, self::$_settings[ $addon_name ]['admin_callback'])
1075
+                array($addon, self::$_settings[$addon_name]['admin_callback'])
1076 1076
             );
1077 1077
         }
1078 1078
         return $addon;
@@ -1090,11 +1090,11 @@  discard block
 block discarded – undo
1090 1090
     public static function load_pue_update()
1091 1091
     {
1092 1092
         // load PUE client
1093
-        require_once EE_THIRD_PARTY . 'pue' . DS . 'pue-client.php';
1093
+        require_once EE_THIRD_PARTY.'pue'.DS.'pue-client.php';
1094 1094
         $license_server = defined('PUE_UPDATES_ENDPOINT') ? PUE_UPDATES_ENDPOINT : 'https://eventespresso.com';
1095 1095
         // cycle thru settings
1096 1096
         foreach (self::$_settings as $settings) {
1097
-            if (! empty($settings['pue_options'])) {
1097
+            if ( ! empty($settings['pue_options'])) {
1098 1098
                 // initiate the class and start the plugin update engine!
1099 1099
                 new PluginUpdateEngineChecker(
1100 1100
                     // host file URL
@@ -1102,7 +1102,7 @@  discard block
 block discarded – undo
1102 1102
                     // plugin slug(s)
1103 1103
                     array(
1104 1104
                         'premium'    => array('p' => $settings['pue_options']['pue_plugin_slug']),
1105
-                        'prerelease' => array('beta' => $settings['pue_options']['pue_plugin_slug'] . '-pr'),
1105
+                        'prerelease' => array('beta' => $settings['pue_options']['pue_plugin_slug'].'-pr'),
1106 1106
                     ),
1107 1107
                     // options
1108 1108
                     array(
@@ -1131,7 +1131,7 @@  discard block
 block discarded – undo
1131 1131
     public static function register_message_types()
1132 1132
     {
1133 1133
         foreach (self::$_settings as $addon_name => $settings) {
1134
-            if (! empty($settings['message_types'])) {
1134
+            if ( ! empty($settings['message_types'])) {
1135 1135
                 foreach ((array) $settings['message_types'] as $message_type => $message_type_settings) {
1136 1136
                     EE_Register_Message_Type::register($message_type, $message_type_settings);
1137 1137
                 }
@@ -1153,70 +1153,70 @@  discard block
 block discarded – undo
1153 1153
      */
1154 1154
     public static function deregister($addon_name = null)
1155 1155
     {
1156
-        if (isset(self::$_settings[ $addon_name ]['class_name'])) {
1156
+        if (isset(self::$_settings[$addon_name]['class_name'])) {
1157 1157
             try {
1158 1158
                 do_action('AHEE__EE_Register_Addon__deregister__before', $addon_name);
1159
-                $class_name = self::$_settings[ $addon_name ]['class_name'];
1160
-                if (! empty(self::$_settings[ $addon_name ]['dms_paths'])) {
1159
+                $class_name = self::$_settings[$addon_name]['class_name'];
1160
+                if ( ! empty(self::$_settings[$addon_name]['dms_paths'])) {
1161 1161
                     // setup DMS
1162 1162
                     EE_Register_Data_Migration_Scripts::deregister($addon_name);
1163 1163
                 }
1164
-                if (! empty(self::$_settings[ $addon_name ]['admin_path'])) {
1164
+                if ( ! empty(self::$_settings[$addon_name]['admin_path'])) {
1165 1165
                     // register admin page
1166 1166
                     EE_Register_Admin_Page::deregister($addon_name);
1167 1167
                 }
1168
-                if (! empty(self::$_settings[ $addon_name ]['module_paths'])) {
1168
+                if ( ! empty(self::$_settings[$addon_name]['module_paths'])) {
1169 1169
                     // add to list of modules to be registered
1170 1170
                     EE_Register_Module::deregister($addon_name);
1171 1171
                 }
1172
-                if (! empty(self::$_settings[ $addon_name ]['shortcode_paths'])
1173
-                    || ! empty(self::$_settings[ $addon_name ]['shortcode_fqcns'])
1172
+                if ( ! empty(self::$_settings[$addon_name]['shortcode_paths'])
1173
+                    || ! empty(self::$_settings[$addon_name]['shortcode_fqcns'])
1174 1174
                 ) {
1175 1175
                     // add to list of shortcodes to be registered
1176 1176
                     EE_Register_Shortcode::deregister($addon_name);
1177 1177
                 }
1178
-                if (! empty(self::$_settings[ $addon_name ]['config_class'])) {
1178
+                if ( ! empty(self::$_settings[$addon_name]['config_class'])) {
1179 1179
                     // if config_class present let's register config.
1180
-                    EE_Register_Config::deregister(self::$_settings[ $addon_name ]['config_class']);
1180
+                    EE_Register_Config::deregister(self::$_settings[$addon_name]['config_class']);
1181 1181
                 }
1182
-                if (! empty(self::$_settings[ $addon_name ]['widget_paths'])) {
1182
+                if ( ! empty(self::$_settings[$addon_name]['widget_paths'])) {
1183 1183
                     // add to list of widgets to be registered
1184 1184
                     EE_Register_Widget::deregister($addon_name);
1185 1185
                 }
1186
-                if (! empty(self::$_settings[ $addon_name ]['model_paths'])
1187
-                    || ! empty(self::$_settings[ $addon_name ]['class_paths'])
1186
+                if ( ! empty(self::$_settings[$addon_name]['model_paths'])
1187
+                    || ! empty(self::$_settings[$addon_name]['class_paths'])
1188 1188
                 ) {
1189 1189
                     // add to list of shortcodes to be registered
1190 1190
                     EE_Register_Model::deregister($addon_name);
1191 1191
                 }
1192
-                if (! empty(self::$_settings[ $addon_name ]['model_extension_paths'])
1193
-                    || ! empty(self::$_settings[ $addon_name ]['class_extension_paths'])
1192
+                if ( ! empty(self::$_settings[$addon_name]['model_extension_paths'])
1193
+                    || ! empty(self::$_settings[$addon_name]['class_extension_paths'])
1194 1194
                 ) {
1195 1195
                     // add to list of shortcodes to be registered
1196 1196
                     EE_Register_Model_Extensions::deregister($addon_name);
1197 1197
                 }
1198
-                if (! empty(self::$_settings[ $addon_name ]['message_types'])) {
1199
-                    foreach ((array) self::$_settings[ $addon_name ]['message_types'] as $message_type => $message_type_settings) {
1198
+                if ( ! empty(self::$_settings[$addon_name]['message_types'])) {
1199
+                    foreach ((array) self::$_settings[$addon_name]['message_types'] as $message_type => $message_type_settings) {
1200 1200
                         EE_Register_Message_Type::deregister($message_type);
1201 1201
                     }
1202 1202
                 }
1203 1203
                 // deregister capabilities for addon
1204
-                if (! empty(self::$_settings[ $addon_name ]['capabilities'])
1205
-                    || ! empty(self::$_settings[ $addon_name ]['capability_maps'])
1204
+                if ( ! empty(self::$_settings[$addon_name]['capabilities'])
1205
+                    || ! empty(self::$_settings[$addon_name]['capability_maps'])
1206 1206
                 ) {
1207 1207
                     EE_Register_Capabilities::deregister($addon_name);
1208 1208
                 }
1209 1209
                 // deregister custom_post_types for addon
1210
-                if (! empty(self::$_settings[ $addon_name ]['custom_post_types'])) {
1210
+                if ( ! empty(self::$_settings[$addon_name]['custom_post_types'])) {
1211 1211
                     EE_Register_CPT::deregister($addon_name);
1212 1212
                 }
1213
-                if (! empty(self::$_settings[ $addon_name ]['payment_method_paths'])) {
1213
+                if ( ! empty(self::$_settings[$addon_name]['payment_method_paths'])) {
1214 1214
                     EE_Register_Payment_Method::deregister($addon_name);
1215 1215
                 }
1216 1216
                 $addon = EE_Registry::instance()->getAddon($class_name);
1217 1217
                 if ($addon instanceof EE_Addon) {
1218 1218
                     remove_action(
1219
-                        'deactivate_' . $addon->get_main_plugin_file_basename(),
1219
+                        'deactivate_'.$addon->get_main_plugin_file_basename(),
1220 1220
                         array($addon, 'deactivation')
1221 1221
                     );
1222 1222
                     remove_action(
@@ -1239,7 +1239,7 @@  discard block
 block discarded – undo
1239 1239
             } catch (Exception $e) {
1240 1240
                 new ExceptionLogger($e);
1241 1241
             }
1242
-            unset(self::$_settings[ $addon_name ]);
1242
+            unset(self::$_settings[$addon_name]);
1243 1243
             do_action('AHEE__EE_Register_Addon__deregister__after', $addon_name);
1244 1244
         }
1245 1245
     }
Please login to merge, or discard this patch.
core/libraries/rest_api/ModelDataTranslator.php 1 patch
Indentation   +832 added lines, -832 removed lines patch added patch discarded remove patch
@@ -32,836 +32,836 @@
 block discarded – undo
32 32
 class ModelDataTranslator
33 33
 {
34 34
 
35
-    /**
36
-     * We used to use -1 for infinity in the rest api, but that's ambiguous for
37
-     * fields that COULD contain -1; so we use null
38
-     */
39
-    const EE_INF_IN_REST = null;
40
-
41
-
42
-    /**
43
-     * Prepares a possible array of input values from JSON for use by the models
44
-     *
45
-     * @param EE_Model_Field_Base $field_obj
46
-     * @param mixed               $original_value_maybe_array
47
-     * @param string              $requested_version
48
-     * @param string              $timezone_string treat values as being in this timezone
49
-     * @return mixed
50
-     * @throws RestException
51
-     */
52
-    public static function prepareFieldValuesFromJson(
53
-        $field_obj,
54
-        $original_value_maybe_array,
55
-        $requested_version,
56
-        $timezone_string = 'UTC'
57
-    ) {
58
-        if (is_array($original_value_maybe_array)
59
-            && ! $field_obj instanceof EE_Serialized_Text_Field
60
-        ) {
61
-            $new_value_maybe_array = array();
62
-            foreach ($original_value_maybe_array as $array_key => $array_item) {
63
-                $new_value_maybe_array[ $array_key ] = ModelDataTranslator::prepareFieldValueFromJson(
64
-                    $field_obj,
65
-                    $array_item,
66
-                    $requested_version,
67
-                    $timezone_string
68
-                );
69
-            }
70
-        } else {
71
-            $new_value_maybe_array = ModelDataTranslator::prepareFieldValueFromJson(
72
-                $field_obj,
73
-                $original_value_maybe_array,
74
-                $requested_version,
75
-                $timezone_string
76
-            );
77
-        }
78
-        return $new_value_maybe_array;
79
-    }
80
-
81
-
82
-    /**
83
-     * Prepares an array of field values FOR use in JSON/REST API
84
-     *
85
-     * @param EE_Model_Field_Base $field_obj
86
-     * @param mixed               $original_value_maybe_array
87
-     * @param string              $request_version (eg 4.8.36)
88
-     * @return array
89
-     */
90
-    public static function prepareFieldValuesForJson($field_obj, $original_value_maybe_array, $request_version)
91
-    {
92
-        if (is_array($original_value_maybe_array)) {
93
-            $new_value = array();
94
-            foreach ($original_value_maybe_array as $key => $value) {
95
-                $new_value[ $key ] = ModelDataTranslator::prepareFieldValuesForJson(
96
-                    $field_obj,
97
-                    $value,
98
-                    $request_version
99
-                );
100
-            }
101
-        } else {
102
-            $new_value = ModelDataTranslator::prepareFieldValueForJson(
103
-                $field_obj,
104
-                $original_value_maybe_array,
105
-                $request_version
106
-            );
107
-        }
108
-        return $new_value;
109
-    }
110
-
111
-
112
-    /**
113
-     * Prepares incoming data from the json or $_REQUEST parameters for the models'
114
-     * "$query_params".
115
-     *
116
-     * @param EE_Model_Field_Base $field_obj
117
-     * @param mixed               $original_value
118
-     * @param string              $requested_version
119
-     * @param string              $timezone_string treat values as being in this timezone
120
-     * @return mixed
121
-     * @throws RestException
122
-     * @throws DomainException
123
-     * @throws EE_Error
124
-     */
125
-    public static function prepareFieldValueFromJson(
126
-        $field_obj,
127
-        $original_value,
128
-        $requested_version,
129
-        $timezone_string = 'UTC' // UTC
130
-    ) {
131
-        // check if they accidentally submitted an error value. If so throw an exception
132
-        if (is_array($original_value)
133
-            && isset($original_value['error_code'], $original_value['error_message'])) {
134
-            throw new RestException(
135
-                'rest_submitted_error_value',
136
-                sprintf(
137
-                    esc_html__(
138
-                        'You tried to submit a JSON error object as a value for %1$s. That\'s not allowed.',
139
-                        'event_espresso'
140
-                    ),
141
-                    $field_obj->get_name()
142
-                ),
143
-                array(
144
-                    'status' => 400,
145
-                )
146
-            );
147
-        }
148
-        // double-check for serialized PHP. We never accept serialized PHP. No way Jose.
149
-        ModelDataTranslator::throwExceptionIfContainsSerializedData($original_value);
150
-        $timezone_string = $timezone_string !== '' ? $timezone_string : get_option('timezone_string', '');
151
-        $new_value = null;
152
-        // walk through the submitted data and double-check for serialized PHP. We never accept serialized PHP. No
153
-        // way Jose.
154
-        ModelDataTranslator::throwExceptionIfContainsSerializedData($original_value);
155
-        if ($field_obj instanceof EE_Infinite_Integer_Field
156
-            && in_array($original_value, array(null, ''), true)
157
-        ) {
158
-            $new_value = EE_INF;
159
-        } elseif ($field_obj instanceof EE_Datetime_Field) {
160
-            $new_value = rest_parse_date(
161
-                self::getTimestampWithTimezoneOffset($original_value, $field_obj, $timezone_string)
162
-            );
163
-            if ($new_value === false) {
164
-                throw new RestException(
165
-                    'invalid_format_for_timestamp',
166
-                    sprintf(
167
-                        esc_html__(
168
-                            'Timestamps received on a request as the value for Date and Time fields must be in %1$s/%2$s format.  The timestamp provided (%3$s) is not that format.',
169
-                            'event_espresso'
170
-                        ),
171
-                        'RFC3339',
172
-                        'ISO8601',
173
-                        $original_value
174
-                    ),
175
-                    array(
176
-                        'status' => 400,
177
-                    )
178
-                );
179
-            }
180
-        } else {
181
-            $new_value = $original_value;
182
-        }
183
-        return $new_value;
184
-    }
185
-
186
-
187
-    /**
188
-     * This checks if the incoming timestamp has timezone information already on it and if it doesn't then adds timezone
189
-     * information via details obtained from the host site.
190
-     *
191
-     * @param string            $original_timestamp
192
-     * @param EE_Datetime_Field $datetime_field
193
-     * @param                   $timezone_string
194
-     * @return string
195
-     * @throws DomainException
196
-     */
197
-    private static function getTimestampWithTimezoneOffset(
198
-        $original_timestamp,
199
-        EE_Datetime_Field $datetime_field,
200
-        $timezone_string
201
-    ) {
202
-        // already have timezone information?
203
-        if (preg_match('/Z|(\+|\-)(\d{2}:\d{2})/', $original_timestamp)) {
204
-            // yes, we're ignoring the timezone.
205
-            return $original_timestamp;
206
-        }
207
-        // need to append timezone
208
-        list($offset_sign, $offset_secs) = self::parseTimezoneOffset(
209
-            $datetime_field->get_timezone_offset(
210
-                new \DateTimeZone($timezone_string),
211
-                $original_timestamp
212
-            )
213
-        );
214
-        $offset_string =
215
-            str_pad(
216
-                floor($offset_secs / HOUR_IN_SECONDS),
217
-                2,
218
-                '0',
219
-                STR_PAD_LEFT
220
-            )
221
-            . ':'
222
-            . str_pad(
223
-                ($offset_secs % HOUR_IN_SECONDS) / MINUTE_IN_SECONDS,
224
-                2,
225
-                '0',
226
-                STR_PAD_LEFT
227
-            );
228
-        return $original_timestamp . $offset_sign . $offset_string;
229
-    }
230
-
231
-
232
-    /**
233
-     * Throws an exception if $data is a serialized PHP string (or somehow an actually PHP object, although I don't
234
-     * think that can happen). If $data is an array, recurses into its keys and values
235
-     *
236
-     * @param mixed $data
237
-     * @throws RestException
238
-     * @return void
239
-     */
240
-    public static function throwExceptionIfContainsSerializedData($data)
241
-    {
242
-        if (is_array($data)) {
243
-            foreach ($data as $key => $value) {
244
-                ModelDataTranslator::throwExceptionIfContainsSerializedData($key);
245
-                ModelDataTranslator::throwExceptionIfContainsSerializedData($value);
246
-            }
247
-        } else {
248
-            if (is_serialized($data) || is_object($data)) {
249
-                throw new RestException(
250
-                    'serialized_data_submission_prohibited',
251
-                    esc_html__(
252
-                    // @codingStandardsIgnoreStart
253
-                        'You tried to submit a string of serialized text. Serialized PHP is prohibited over the EE4 REST API.',
254
-                        // @codingStandardsIgnoreEnd
255
-                        'event_espresso'
256
-                    )
257
-                );
258
-            }
259
-        }
260
-    }
261
-
262
-
263
-    /**
264
-     * determines what's going on with them timezone strings
265
-     *
266
-     * @param int $timezone_offset
267
-     * @return array
268
-     */
269
-    private static function parseTimezoneOffset($timezone_offset)
270
-    {
271
-        $first_char = substr((string) $timezone_offset, 0, 1);
272
-        if ($first_char === '+' || $first_char === '-') {
273
-            $offset_sign = $first_char;
274
-            $offset_secs = substr((string) $timezone_offset, 1);
275
-        } else {
276
-            $offset_sign = '+';
277
-            $offset_secs = $timezone_offset;
278
-        }
279
-        return array($offset_sign, $offset_secs);
280
-    }
281
-
282
-
283
-    /**
284
-     * Prepares a field's value for display in the API
285
-     *
286
-     * @param EE_Model_Field_Base $field_obj
287
-     * @param mixed               $original_value
288
-     * @param string              $requested_version
289
-     * @return mixed
290
-     */
291
-    public static function prepareFieldValueForJson($field_obj, $original_value, $requested_version)
292
-    {
293
-        if ($original_value === EE_INF) {
294
-            $new_value = ModelDataTranslator::EE_INF_IN_REST;
295
-        } elseif ($field_obj instanceof EE_Datetime_Field) {
296
-            if (is_string($original_value)) {
297
-                // did they submit a string of a unix timestamp?
298
-                if (is_numeric($original_value)) {
299
-                    $datetime_obj = new \DateTime();
300
-                    $datetime_obj->setTimestamp((int) $original_value);
301
-                } else {
302
-                    // first, check if its a MySQL timestamp in GMT
303
-                    $datetime_obj = \DateTime::createFromFormat('Y-m-d H:i:s', $original_value);
304
-                }
305
-                if (! $datetime_obj instanceof \DateTime) {
306
-                    // so it's not a unix timestamp or a MySQL timestamp. Maybe its in the field's date/time format?
307
-                    $datetime_obj = $field_obj->prepare_for_set($original_value);
308
-                }
309
-                $original_value = $datetime_obj;
310
-            }
311
-            if ($original_value instanceof \DateTime) {
312
-                $new_value = $original_value->format('Y-m-d H:i:s');
313
-            } elseif (is_int($original_value) || is_float($original_value)) {
314
-                $new_value = date('Y-m-d H:i:s', $original_value);
315
-            } elseif ($original_value === null || $original_value === '') {
316
-                $new_value = null;
317
-            } else {
318
-                // so it's not a datetime object, unix timestamp (as string or int),
319
-                // MySQL timestamp, or even a string in the field object's format. So no idea what it is
320
-                throw new \EE_Error(
321
-                    sprintf(
322
-                        esc_html__(
323
-                        // @codingStandardsIgnoreStart
324
-                            'The value "%1$s" for the field "%2$s" on model "%3$s" could not be understood. It should be a PHP DateTime, unix timestamp, MySQL date, or string in the format "%4$s".',
325
-                            // @codingStandardsIgnoreEnd
326
-                            'event_espresso'
327
-                        ),
328
-                        $original_value,
329
-                        $field_obj->get_name(),
330
-                        $field_obj->get_model_name(),
331
-                        $field_obj->get_time_format() . ' ' . $field_obj->get_time_format()
332
-                    )
333
-                );
334
-            }
335
-            if ($new_value !== null) {
336
-                $new_value = mysql_to_rfc3339($new_value);
337
-            }
338
-        } else {
339
-            $new_value = $original_value;
340
-        }
341
-        // are we about to send an object? just don't. We have no good way to represent it in JSON.
342
-        // can't just check using is_object() because that missed PHP incomplete objects
343
-        if (! ModelDataTranslator::isRepresentableInJson($new_value)) {
344
-            $new_value = array(
345
-                'error_code'    => 'php_object_not_return',
346
-                'error_message' => esc_html__(
347
-                    'The value of this field in the database is a PHP object, which can\'t be represented in JSON.',
348
-                    'event_espresso'
349
-                ),
350
-            );
351
-        }
352
-        return apply_filters(
353
-            'FHEE__EventEspresso\core\libraries\rest_api\Model_Data_Translator__prepare_field_for_rest_api',
354
-            $new_value,
355
-            $field_obj,
356
-            $original_value,
357
-            $requested_version
358
-        );
359
-    }
360
-
361
-
362
-    /**
363
-     * Prepares condition-query-parameters (like what's in where and having) from
364
-     * the format expected in the API to use in the models
365
-     *
366
-     * @param array    $inputted_query_params_of_this_type
367
-     * @param EEM_Base $model
368
-     * @param string   $requested_version
369
-     * @param boolean  $writing whether this data will be written to the DB, or if we're just building a query.
370
-     *                          If we're writing to the DB, we don't expect any operators, or any logic query
371
-     *                          parameters, and we also won't accept serialized data unless the current user has
372
-     *                          unfiltered_html.
373
-     * @return array
374
-     * @throws DomainException
375
-     * @throws RestException
376
-     * @throws EE_Error
377
-     */
378
-    public static function prepareConditionsQueryParamsForModels(
379
-        $inputted_query_params_of_this_type,
380
-        EEM_Base $model,
381
-        $requested_version,
382
-        $writing = false
383
-    ) {
384
-        $query_param_for_models = array();
385
-        $valid_operators = $model->valid_operators();
386
-        foreach ($inputted_query_params_of_this_type as $query_param_key => $query_param_value) {
387
-            $is_gmt_datetime_field = false;
388
-            $query_param_sans_stars = ModelDataTranslator::removeStarsAndAnythingAfterFromConditionQueryParamKey(
389
-                $query_param_key
390
-            );
391
-            $field = ModelDataTranslator::deduceFieldFromQueryParam(
392
-                $query_param_sans_stars,
393
-                $model
394
-            );
395
-            // double-check is it a *_gmt field?
396
-            if (! $field instanceof EE_Model_Field_Base
397
-                && ModelDataTranslator::isGmtDateFieldName($query_param_sans_stars)
398
-            ) {
399
-                // yep, take off '_gmt', and find the field
400
-                $query_param_key = ModelDataTranslator::removeGmtFromFieldName($query_param_sans_stars);
401
-                $field = ModelDataTranslator::deduceFieldFromQueryParam(
402
-                    $query_param_key,
403
-                    $model
404
-                );
405
-                $timezone = 'UTC';
406
-                $is_gmt_datetime_field = true;
407
-            } elseif ($field instanceof EE_Datetime_Field) {
408
-                // so it's not a GMT field. Set the timezone on the model to the default
409
-                $timezone = \EEH_DTT_Helper::get_valid_timezone_string();
410
-            } else {
411
-                // just keep using what's already set for the timezone
412
-                $timezone = $model->get_timezone();
413
-            }
414
-            if ($field instanceof EE_Model_Field_Base) {
415
-                if (! $writing && is_array($query_param_value)) {
416
-                    if (! \EEH_Array::is_array_numerically_and_sequentially_indexed($query_param_value)) {
417
-                        if (defined('EE_REST_API_DEBUG_MODE') && EE_REST_API_DEBUG_MODE) {
418
-                            throw new RestException(
419
-                                'numerically_indexed_array_of_values_only',
420
-                                sprintf(
421
-                                    esc_html__(
422
-                                        'The array provided for the parameter "%1$s" should be numerically indexed.',
423
-                                        'event_espresso'
424
-                                    ),
425
-                                    $query_param_key
426
-                                ),
427
-                                array(
428
-                                    'status' => 400,
429
-                                )
430
-                            );
431
-                        }
432
-                    }
433
-                    // did they specify an operator?
434
-                    if (isset($query_param_value[0])
435
-                        && isset($valid_operators[ $query_param_value[0] ])
436
-                    ) {
437
-                        $op = $query_param_value[0];
438
-                        $translated_value = array($op);
439
-                        if (array_key_exists($op, $model->valid_in_style_operators())
440
-                            && isset($query_param_value[1])
441
-                            && ! isset($query_param_value[2])
442
-                        ) {
443
-                            $translated_value[] = ModelDataTranslator::prepareFieldValuesFromJson(
444
-                                $field,
445
-                                $query_param_value[1],
446
-                                $requested_version,
447
-                                $timezone
448
-                            );
449
-                        } elseif (array_key_exists($op, $model->valid_between_style_operators())
450
-                                  && isset($query_param_value[1])
451
-                                  && is_array($query_param_value[1])
452
-                                  && isset($query_param_key[1][0], $query_param_value[1][1])
453
-                                  && ! isset($query_param_value[1][2])
454
-                                  && ! isset($query_param_value[2])
455
-                        ) {
456
-                            $translated_value[] = array(
457
-                                ModelDataTranslator::prepareFieldValuesFromJson(
458
-                                    $field,
459
-                                    $query_param_value[1][0],
460
-                                    $requested_version,
461
-                                    $timezone
462
-                                ),
463
-                                ModelDataTranslator::prepareFieldValuesFromJson(
464
-                                    $field,
465
-                                    $query_param_value[1][1],
466
-                                    $requested_version,
467
-                                    $timezone
468
-                                )
469
-                            );
470
-                        } elseif (array_key_exists($op, $model->valid_like_style_operators())
471
-                                  && isset($query_param_value[1])
472
-                                  && ! isset($query_param_value[2])
473
-                        ) {
474
-                            // we want to leave this value mostly-as-is (eg don't force it to be a float
475
-                            // or a boolean or an enum value. Leave it as-is with wildcards etc)
476
-                            // but do verify it at least doesn't have any serialized data
477
-                            ModelDataTranslator::throwExceptionIfContainsSerializedData($query_param_value[1]);
478
-                            $translated_value[] = $query_param_value[1];
479
-                        } elseif (array_key_exists($op, $model->valid_null_style_operators())
480
-                                  && ! isset($query_param_value[1])) {
481
-                            // no arguments should have been provided, so don't look for any
482
-                        } elseif (isset($query_param_value[1])
483
-                                  && ! isset($query_param_value[2])
484
-                                  && ! array_key_exists(
485
-                                      $op,
486
-                                      array_merge(
487
-                                          $model->valid_in_style_operators(),
488
-                                          $model->valid_null_style_operators(),
489
-                                          $model->valid_like_style_operators(),
490
-                                          $model->valid_between_style_operators()
491
-                                      )
492
-                                  )
493
-                        ) {
494
-                            // it's a valid operator, but none of the exceptions. Treat it normally.
495
-                            $translated_value[] = ModelDataTranslator::prepareFieldValuesFromJson(
496
-                                $field,
497
-                                $query_param_value[1],
498
-                                $requested_version,
499
-                                $timezone
500
-                            );
501
-                        } else {
502
-                            // so they provided a valid operator, but wrong number of arguments
503
-                            if (defined('EE_REST_API_DEBUG_MODE') && EE_REST_API_DEBUG_MODE) {
504
-                                throw new RestException(
505
-                                    'wrong_number_of_arguments',
506
-                                    sprintf(
507
-                                        esc_html__(
508
-                                            'The operator you provided, "%1$s" had the wrong number of arguments',
509
-                                            'event_espresso'
510
-                                        ),
511
-                                        $op
512
-                                    ),
513
-                                    array(
514
-                                        'status' => 400,
515
-                                    )
516
-                                );
517
-                            }
518
-                            $translated_value = null;
519
-                        }
520
-                    } else {
521
-                        // so they didn't provide a valid operator
522
-                        if (defined('EE_REST_API_DEBUG_MODE') && EE_REST_API_DEBUG_MODE) {
523
-                            throw new RestException(
524
-                                'invalid_operator',
525
-                                sprintf(
526
-                                    esc_html__(
527
-                                        'You provided an invalid parameter, with key "%1$s" and value "%2$s"',
528
-                                        'event_espresso'
529
-                                    ),
530
-                                    $query_param_key,
531
-                                    $query_param_value
532
-                                ),
533
-                                array(
534
-                                    'status' => 400,
535
-                                )
536
-                            );
537
-                        }
538
-                        // if we aren't in debug mode, then just try our best to fulfill the user's request
539
-                        $translated_value = null;
540
-                    }
541
-                } else {
542
-                    $translated_value = ModelDataTranslator::prepareFieldValueFromJson(
543
-                        $field,
544
-                        $query_param_value,
545
-                        $requested_version,
546
-                        $timezone
547
-                    );
548
-                }
549
-                if ((isset($query_param_for_models[ $query_param_key ]) && $is_gmt_datetime_field)
550
-                    || $translated_value === null
551
-                ) {
552
-                    // they have already provided a non-gmt field, ignore the gmt one. That's what WP core
553
-                    // currently does (they might change it though). See https://core.trac.wordpress.org/ticket/39954
554
-                    // OR we couldn't create a translated value from their input
555
-                    continue;
556
-                }
557
-                $query_param_for_models[ $query_param_key ] = $translated_value;
558
-            } else {
559
-                // so this param doesn't correspond to a field eh?
560
-                if ($writing) {
561
-                    // always tell API clients about invalid parameters when they're creating data. Otherwise,
562
-                    // they are probably going to create invalid data
563
-                    throw new RestException(
564
-                        'invalid_field',
565
-                        sprintf(
566
-                            esc_html__('You have provided an invalid parameter: "%1$s"', 'event_espresso'),
567
-                            $query_param_key
568
-                        )
569
-                    );
570
-                } else {
571
-                    // so it's not for a field, is it a logic query param key?
572
-                    if (in_array(
573
-                        $query_param_sans_stars,
574
-                        $model->logic_query_param_keys()
575
-                    )) {
576
-                        $query_param_for_models[ $query_param_key ] = ModelDataTranslator::prepareConditionsQueryParamsForModels(
577
-                            $query_param_value,
578
-                            $model,
579
-                            $requested_version
580
-                        );
581
-                    } elseif (defined('EE_REST_API_DEBUG_MODE') && EE_REST_API_DEBUG_MODE) {
582
-                        // only tell API clients they got it wrong if we're in debug mode
583
-                        // otherwise try our best ot fulfill their request by ignoring this invalid data
584
-                        throw new RestException(
585
-                            'invalid_parameter',
586
-                            sprintf(
587
-                                esc_html__(
588
-                                    'You provided an invalid parameter, with key "%1$s"',
589
-                                    'event_espresso'
590
-                                ),
591
-                                $query_param_sans_stars
592
-                            ),
593
-                            array(
594
-                                'status' => 400,
595
-                            )
596
-                        );
597
-                    }
598
-                }
599
-            }
600
-        }
601
-        return $query_param_for_models;
602
-    }
603
-
604
-
605
-    /**
606
-     * Mostly checks if the last 4 characters are "_gmt", indicating its a
607
-     * gmt date field name
608
-     *
609
-     * @param string $field_name
610
-     * @return boolean
611
-     */
612
-    public static function isGmtDateFieldName($field_name)
613
-    {
614
-        return substr(
615
-            ModelDataTranslator::removeStarsAndAnythingAfterFromConditionQueryParamKey($field_name),
616
-            -4,
617
-            4
618
-        ) === '_gmt';
619
-    }
620
-
621
-
622
-    /**
623
-     * Removes the last "_gmt" part of a field name (and if there is no "_gmt" at the end, leave it alone)
624
-     *
625
-     * @param string $field_name
626
-     * @return string
627
-     */
628
-    public static function removeGmtFromFieldName($field_name)
629
-    {
630
-        if (! ModelDataTranslator::isGmtDateFieldName($field_name)) {
631
-            return $field_name;
632
-        }
633
-        $query_param_sans_stars = ModelDataTranslator::removeStarsAndAnythingAfterFromConditionQueryParamKey(
634
-            $field_name
635
-        );
636
-        $query_param_sans_gmt_and_sans_stars = substr(
637
-            $query_param_sans_stars,
638
-            0,
639
-            strrpos(
640
-                $field_name,
641
-                '_gmt'
642
-            )
643
-        );
644
-        return str_replace($query_param_sans_stars, $query_param_sans_gmt_and_sans_stars, $field_name);
645
-    }
646
-
647
-
648
-    /**
649
-     * Takes a field name from the REST API and prepares it for the model querying
650
-     *
651
-     * @param string $field_name
652
-     * @return string
653
-     */
654
-    public static function prepareFieldNameFromJson($field_name)
655
-    {
656
-        if (ModelDataTranslator::isGmtDateFieldName($field_name)) {
657
-            return ModelDataTranslator::removeGmtFromFieldName($field_name);
658
-        }
659
-        return $field_name;
660
-    }
661
-
662
-
663
-    /**
664
-     * Takes array of field names from REST API and prepares for models
665
-     *
666
-     * @param array $field_names
667
-     * @return array of field names (possibly include model prefixes)
668
-     */
669
-    public static function prepareFieldNamesFromJson(array $field_names)
670
-    {
671
-        $new_array = array();
672
-        foreach ($field_names as $key => $field_name) {
673
-            $new_array[ $key ] = ModelDataTranslator::prepareFieldNameFromJson($field_name);
674
-        }
675
-        return $new_array;
676
-    }
677
-
678
-
679
-    /**
680
-     * Takes array where array keys are field names (possibly with model path prefixes)
681
-     * from the REST API and prepares them for model querying
682
-     *
683
-     * @param array $field_names_as_keys
684
-     * @return array
685
-     */
686
-    public static function prepareFieldNamesInArrayKeysFromJson(array $field_names_as_keys)
687
-    {
688
-        $new_array = array();
689
-        foreach ($field_names_as_keys as $field_name => $value) {
690
-            $new_array[ ModelDataTranslator::prepareFieldNameFromJson($field_name) ] = $value;
691
-        }
692
-        return $new_array;
693
-    }
694
-
695
-
696
-    /**
697
-     * Prepares an array of model query params for use in the REST API
698
-     *
699
-     * @param array    $model_query_params
700
-     * @param EEM_Base $model
701
-     * @param string   $requested_version  eg "4.8.36". If null is provided, defaults to the latest release of the EE4
702
-     *                                     REST API
703
-     * @return array which can be passed into the EE4 REST API when querying a model resource
704
-     * @throws EE_Error
705
-     */
706
-    public static function prepareQueryParamsForRestApi(
707
-        array $model_query_params,
708
-        EEM_Base $model,
709
-        $requested_version = null
710
-    ) {
711
-        if ($requested_version === null) {
712
-            $requested_version = \EED_Core_Rest_Api::latest_rest_api_version();
713
-        }
714
-        $rest_query_params = $model_query_params;
715
-        if (isset($model_query_params[0])) {
716
-            $rest_query_params['where'] = ModelDataTranslator::prepareConditionsQueryParamsForRestApi(
717
-                $model_query_params[0],
718
-                $model,
719
-                $requested_version
720
-            );
721
-            unset($rest_query_params[0]);
722
-        }
723
-        if (isset($model_query_params['having'])) {
724
-            $rest_query_params['having'] = ModelDataTranslator::prepareConditionsQueryParamsForRestApi(
725
-                $model_query_params['having'],
726
-                $model,
727
-                $requested_version
728
-            );
729
-        }
730
-        return apply_filters(
731
-            'FHEE__EventEspresso\core\libraries\rest_api\Model_Data_Translator__prepare_query_params_for_rest_api',
732
-            $rest_query_params,
733
-            $model_query_params,
734
-            $model,
735
-            $requested_version
736
-        );
737
-    }
738
-
739
-
740
-    /**
741
-     * Prepares all the sub-conditions query parameters (eg having or where conditions) for use in the rest api
742
-     *
743
-     * @param array    $inputted_query_params_of_this_type  eg like the "where" or "having" conditions query params
744
-     *                                                      passed into EEM_Base::get_all()
745
-     * @param EEM_Base $model
746
-     * @param string   $requested_version                   eg "4.8.36"
747
-     * @return array ready for use in the rest api query params
748
-     * @throws EE_Error
749
-     * @throws ObjectDetectedException if somehow a PHP object were in the query params' values,
750
-     *                                                      (which would be really unusual)
751
-     */
752
-    public static function prepareConditionsQueryParamsForRestApi(
753
-        $inputted_query_params_of_this_type,
754
-        EEM_Base $model,
755
-        $requested_version
756
-    ) {
757
-        $query_param_for_models = array();
758
-        foreach ($inputted_query_params_of_this_type as $query_param_key => $query_param_value) {
759
-            $field = ModelDataTranslator::deduceFieldFromQueryParam(
760
-                ModelDataTranslator::removeStarsAndAnythingAfterFromConditionQueryParamKey($query_param_key),
761
-                $model
762
-            );
763
-            if ($field instanceof EE_Model_Field_Base) {
764
-                // did they specify an operator?
765
-                if (is_array($query_param_value)) {
766
-                    $op = $query_param_value[0];
767
-                    $translated_value = array($op);
768
-                    if (isset($query_param_value[1])) {
769
-                        $value = $query_param_value[1];
770
-                        $translated_value[1] = ModelDataTranslator::prepareFieldValuesForJson(
771
-                            $field,
772
-                            $value,
773
-                            $requested_version
774
-                        );
775
-                    }
776
-                } else {
777
-                    $translated_value = ModelDataTranslator::prepareFieldValueForJson(
778
-                        $field,
779
-                        $query_param_value,
780
-                        $requested_version
781
-                    );
782
-                }
783
-                $query_param_for_models[ $query_param_key ] = $translated_value;
784
-            } else {
785
-                // so it's not for a field, assume it's a logic query param key
786
-                $query_param_for_models[ $query_param_key ] = ModelDataTranslator::prepareConditionsQueryParamsForRestApi(
787
-                    $query_param_value,
788
-                    $model,
789
-                    $requested_version
790
-                );
791
-            }
792
-        }
793
-        return $query_param_for_models;
794
-    }
795
-
796
-
797
-    /**
798
-     * @param $condition_query_param_key
799
-     * @return string
800
-     */
801
-    public static function removeStarsAndAnythingAfterFromConditionQueryParamKey($condition_query_param_key)
802
-    {
803
-        $pos_of_star = strpos($condition_query_param_key, '*');
804
-        if ($pos_of_star === false) {
805
-            return $condition_query_param_key;
806
-        } else {
807
-            $condition_query_param_sans_star = substr($condition_query_param_key, 0, $pos_of_star);
808
-            return $condition_query_param_sans_star;
809
-        }
810
-    }
811
-
812
-
813
-    /**
814
-     * Takes the input parameter and finds the model field that it indicates.
815
-     *
816
-     * @param string   $query_param_name like Registration.Transaction.TXN_ID, Event.Datetime.start_time, or REG_ID
817
-     * @param EEM_Base $model
818
-     * @return EE_Model_Field_Base
819
-     * @throws EE_Error
820
-     */
821
-    public static function deduceFieldFromQueryParam($query_param_name, EEM_Base $model)
822
-    {
823
-        // ok, now proceed with deducing which part is the model's name, and which is the field's name
824
-        // which will help us find the database table and column
825
-        $query_param_parts = explode('.', $query_param_name);
826
-        if (empty($query_param_parts)) {
827
-            throw new EE_Error(
828
-                sprintf(
829
-                    __(
830
-                        '_extract_column_name is empty when trying to extract column and table name from %s',
831
-                        'event_espresso'
832
-                    ),
833
-                    $query_param_name
834
-                )
835
-            );
836
-        }
837
-        $number_of_parts = count($query_param_parts);
838
-        $last_query_param_part = $query_param_parts[ count($query_param_parts) - 1 ];
839
-        if ($number_of_parts === 1) {
840
-            $field_name = $last_query_param_part;
841
-        } else {// $number_of_parts >= 2
842
-            // the last part is the column name, and there are only 2parts. therefore...
843
-            $field_name = $last_query_param_part;
844
-            $model = \EE_Registry::instance()->load_model($query_param_parts[ $number_of_parts - 2 ]);
845
-        }
846
-        try {
847
-            return $model->field_settings_for($field_name, false);
848
-        } catch (EE_Error $e) {
849
-            return null;
850
-        }
851
-    }
852
-
853
-
854
-    /**
855
-     * Returns true if $data can be easily represented in JSON.
856
-     * Basically, objects and resources can't be represented in JSON easily.
857
-     *
858
-     * @param mixed $data
859
-     * @return bool
860
-     */
861
-    protected static function isRepresentableInJson($data)
862
-    {
863
-        return is_scalar($data)
864
-               || is_array($data)
865
-               || is_null($data);
866
-    }
35
+	/**
36
+	 * We used to use -1 for infinity in the rest api, but that's ambiguous for
37
+	 * fields that COULD contain -1; so we use null
38
+	 */
39
+	const EE_INF_IN_REST = null;
40
+
41
+
42
+	/**
43
+	 * Prepares a possible array of input values from JSON for use by the models
44
+	 *
45
+	 * @param EE_Model_Field_Base $field_obj
46
+	 * @param mixed               $original_value_maybe_array
47
+	 * @param string              $requested_version
48
+	 * @param string              $timezone_string treat values as being in this timezone
49
+	 * @return mixed
50
+	 * @throws RestException
51
+	 */
52
+	public static function prepareFieldValuesFromJson(
53
+		$field_obj,
54
+		$original_value_maybe_array,
55
+		$requested_version,
56
+		$timezone_string = 'UTC'
57
+	) {
58
+		if (is_array($original_value_maybe_array)
59
+			&& ! $field_obj instanceof EE_Serialized_Text_Field
60
+		) {
61
+			$new_value_maybe_array = array();
62
+			foreach ($original_value_maybe_array as $array_key => $array_item) {
63
+				$new_value_maybe_array[ $array_key ] = ModelDataTranslator::prepareFieldValueFromJson(
64
+					$field_obj,
65
+					$array_item,
66
+					$requested_version,
67
+					$timezone_string
68
+				);
69
+			}
70
+		} else {
71
+			$new_value_maybe_array = ModelDataTranslator::prepareFieldValueFromJson(
72
+				$field_obj,
73
+				$original_value_maybe_array,
74
+				$requested_version,
75
+				$timezone_string
76
+			);
77
+		}
78
+		return $new_value_maybe_array;
79
+	}
80
+
81
+
82
+	/**
83
+	 * Prepares an array of field values FOR use in JSON/REST API
84
+	 *
85
+	 * @param EE_Model_Field_Base $field_obj
86
+	 * @param mixed               $original_value_maybe_array
87
+	 * @param string              $request_version (eg 4.8.36)
88
+	 * @return array
89
+	 */
90
+	public static function prepareFieldValuesForJson($field_obj, $original_value_maybe_array, $request_version)
91
+	{
92
+		if (is_array($original_value_maybe_array)) {
93
+			$new_value = array();
94
+			foreach ($original_value_maybe_array as $key => $value) {
95
+				$new_value[ $key ] = ModelDataTranslator::prepareFieldValuesForJson(
96
+					$field_obj,
97
+					$value,
98
+					$request_version
99
+				);
100
+			}
101
+		} else {
102
+			$new_value = ModelDataTranslator::prepareFieldValueForJson(
103
+				$field_obj,
104
+				$original_value_maybe_array,
105
+				$request_version
106
+			);
107
+		}
108
+		return $new_value;
109
+	}
110
+
111
+
112
+	/**
113
+	 * Prepares incoming data from the json or $_REQUEST parameters for the models'
114
+	 * "$query_params".
115
+	 *
116
+	 * @param EE_Model_Field_Base $field_obj
117
+	 * @param mixed               $original_value
118
+	 * @param string              $requested_version
119
+	 * @param string              $timezone_string treat values as being in this timezone
120
+	 * @return mixed
121
+	 * @throws RestException
122
+	 * @throws DomainException
123
+	 * @throws EE_Error
124
+	 */
125
+	public static function prepareFieldValueFromJson(
126
+		$field_obj,
127
+		$original_value,
128
+		$requested_version,
129
+		$timezone_string = 'UTC' // UTC
130
+	) {
131
+		// check if they accidentally submitted an error value. If so throw an exception
132
+		if (is_array($original_value)
133
+			&& isset($original_value['error_code'], $original_value['error_message'])) {
134
+			throw new RestException(
135
+				'rest_submitted_error_value',
136
+				sprintf(
137
+					esc_html__(
138
+						'You tried to submit a JSON error object as a value for %1$s. That\'s not allowed.',
139
+						'event_espresso'
140
+					),
141
+					$field_obj->get_name()
142
+				),
143
+				array(
144
+					'status' => 400,
145
+				)
146
+			);
147
+		}
148
+		// double-check for serialized PHP. We never accept serialized PHP. No way Jose.
149
+		ModelDataTranslator::throwExceptionIfContainsSerializedData($original_value);
150
+		$timezone_string = $timezone_string !== '' ? $timezone_string : get_option('timezone_string', '');
151
+		$new_value = null;
152
+		// walk through the submitted data and double-check for serialized PHP. We never accept serialized PHP. No
153
+		// way Jose.
154
+		ModelDataTranslator::throwExceptionIfContainsSerializedData($original_value);
155
+		if ($field_obj instanceof EE_Infinite_Integer_Field
156
+			&& in_array($original_value, array(null, ''), true)
157
+		) {
158
+			$new_value = EE_INF;
159
+		} elseif ($field_obj instanceof EE_Datetime_Field) {
160
+			$new_value = rest_parse_date(
161
+				self::getTimestampWithTimezoneOffset($original_value, $field_obj, $timezone_string)
162
+			);
163
+			if ($new_value === false) {
164
+				throw new RestException(
165
+					'invalid_format_for_timestamp',
166
+					sprintf(
167
+						esc_html__(
168
+							'Timestamps received on a request as the value for Date and Time fields must be in %1$s/%2$s format.  The timestamp provided (%3$s) is not that format.',
169
+							'event_espresso'
170
+						),
171
+						'RFC3339',
172
+						'ISO8601',
173
+						$original_value
174
+					),
175
+					array(
176
+						'status' => 400,
177
+					)
178
+				);
179
+			}
180
+		} else {
181
+			$new_value = $original_value;
182
+		}
183
+		return $new_value;
184
+	}
185
+
186
+
187
+	/**
188
+	 * This checks if the incoming timestamp has timezone information already on it and if it doesn't then adds timezone
189
+	 * information via details obtained from the host site.
190
+	 *
191
+	 * @param string            $original_timestamp
192
+	 * @param EE_Datetime_Field $datetime_field
193
+	 * @param                   $timezone_string
194
+	 * @return string
195
+	 * @throws DomainException
196
+	 */
197
+	private static function getTimestampWithTimezoneOffset(
198
+		$original_timestamp,
199
+		EE_Datetime_Field $datetime_field,
200
+		$timezone_string
201
+	) {
202
+		// already have timezone information?
203
+		if (preg_match('/Z|(\+|\-)(\d{2}:\d{2})/', $original_timestamp)) {
204
+			// yes, we're ignoring the timezone.
205
+			return $original_timestamp;
206
+		}
207
+		// need to append timezone
208
+		list($offset_sign, $offset_secs) = self::parseTimezoneOffset(
209
+			$datetime_field->get_timezone_offset(
210
+				new \DateTimeZone($timezone_string),
211
+				$original_timestamp
212
+			)
213
+		);
214
+		$offset_string =
215
+			str_pad(
216
+				floor($offset_secs / HOUR_IN_SECONDS),
217
+				2,
218
+				'0',
219
+				STR_PAD_LEFT
220
+			)
221
+			. ':'
222
+			. str_pad(
223
+				($offset_secs % HOUR_IN_SECONDS) / MINUTE_IN_SECONDS,
224
+				2,
225
+				'0',
226
+				STR_PAD_LEFT
227
+			);
228
+		return $original_timestamp . $offset_sign . $offset_string;
229
+	}
230
+
231
+
232
+	/**
233
+	 * Throws an exception if $data is a serialized PHP string (or somehow an actually PHP object, although I don't
234
+	 * think that can happen). If $data is an array, recurses into its keys and values
235
+	 *
236
+	 * @param mixed $data
237
+	 * @throws RestException
238
+	 * @return void
239
+	 */
240
+	public static function throwExceptionIfContainsSerializedData($data)
241
+	{
242
+		if (is_array($data)) {
243
+			foreach ($data as $key => $value) {
244
+				ModelDataTranslator::throwExceptionIfContainsSerializedData($key);
245
+				ModelDataTranslator::throwExceptionIfContainsSerializedData($value);
246
+			}
247
+		} else {
248
+			if (is_serialized($data) || is_object($data)) {
249
+				throw new RestException(
250
+					'serialized_data_submission_prohibited',
251
+					esc_html__(
252
+					// @codingStandardsIgnoreStart
253
+						'You tried to submit a string of serialized text. Serialized PHP is prohibited over the EE4 REST API.',
254
+						// @codingStandardsIgnoreEnd
255
+						'event_espresso'
256
+					)
257
+				);
258
+			}
259
+		}
260
+	}
261
+
262
+
263
+	/**
264
+	 * determines what's going on with them timezone strings
265
+	 *
266
+	 * @param int $timezone_offset
267
+	 * @return array
268
+	 */
269
+	private static function parseTimezoneOffset($timezone_offset)
270
+	{
271
+		$first_char = substr((string) $timezone_offset, 0, 1);
272
+		if ($first_char === '+' || $first_char === '-') {
273
+			$offset_sign = $first_char;
274
+			$offset_secs = substr((string) $timezone_offset, 1);
275
+		} else {
276
+			$offset_sign = '+';
277
+			$offset_secs = $timezone_offset;
278
+		}
279
+		return array($offset_sign, $offset_secs);
280
+	}
281
+
282
+
283
+	/**
284
+	 * Prepares a field's value for display in the API
285
+	 *
286
+	 * @param EE_Model_Field_Base $field_obj
287
+	 * @param mixed               $original_value
288
+	 * @param string              $requested_version
289
+	 * @return mixed
290
+	 */
291
+	public static function prepareFieldValueForJson($field_obj, $original_value, $requested_version)
292
+	{
293
+		if ($original_value === EE_INF) {
294
+			$new_value = ModelDataTranslator::EE_INF_IN_REST;
295
+		} elseif ($field_obj instanceof EE_Datetime_Field) {
296
+			if (is_string($original_value)) {
297
+				// did they submit a string of a unix timestamp?
298
+				if (is_numeric($original_value)) {
299
+					$datetime_obj = new \DateTime();
300
+					$datetime_obj->setTimestamp((int) $original_value);
301
+				} else {
302
+					// first, check if its a MySQL timestamp in GMT
303
+					$datetime_obj = \DateTime::createFromFormat('Y-m-d H:i:s', $original_value);
304
+				}
305
+				if (! $datetime_obj instanceof \DateTime) {
306
+					// so it's not a unix timestamp or a MySQL timestamp. Maybe its in the field's date/time format?
307
+					$datetime_obj = $field_obj->prepare_for_set($original_value);
308
+				}
309
+				$original_value = $datetime_obj;
310
+			}
311
+			if ($original_value instanceof \DateTime) {
312
+				$new_value = $original_value->format('Y-m-d H:i:s');
313
+			} elseif (is_int($original_value) || is_float($original_value)) {
314
+				$new_value = date('Y-m-d H:i:s', $original_value);
315
+			} elseif ($original_value === null || $original_value === '') {
316
+				$new_value = null;
317
+			} else {
318
+				// so it's not a datetime object, unix timestamp (as string or int),
319
+				// MySQL timestamp, or even a string in the field object's format. So no idea what it is
320
+				throw new \EE_Error(
321
+					sprintf(
322
+						esc_html__(
323
+						// @codingStandardsIgnoreStart
324
+							'The value "%1$s" for the field "%2$s" on model "%3$s" could not be understood. It should be a PHP DateTime, unix timestamp, MySQL date, or string in the format "%4$s".',
325
+							// @codingStandardsIgnoreEnd
326
+							'event_espresso'
327
+						),
328
+						$original_value,
329
+						$field_obj->get_name(),
330
+						$field_obj->get_model_name(),
331
+						$field_obj->get_time_format() . ' ' . $field_obj->get_time_format()
332
+					)
333
+				);
334
+			}
335
+			if ($new_value !== null) {
336
+				$new_value = mysql_to_rfc3339($new_value);
337
+			}
338
+		} else {
339
+			$new_value = $original_value;
340
+		}
341
+		// are we about to send an object? just don't. We have no good way to represent it in JSON.
342
+		// can't just check using is_object() because that missed PHP incomplete objects
343
+		if (! ModelDataTranslator::isRepresentableInJson($new_value)) {
344
+			$new_value = array(
345
+				'error_code'    => 'php_object_not_return',
346
+				'error_message' => esc_html__(
347
+					'The value of this field in the database is a PHP object, which can\'t be represented in JSON.',
348
+					'event_espresso'
349
+				),
350
+			);
351
+		}
352
+		return apply_filters(
353
+			'FHEE__EventEspresso\core\libraries\rest_api\Model_Data_Translator__prepare_field_for_rest_api',
354
+			$new_value,
355
+			$field_obj,
356
+			$original_value,
357
+			$requested_version
358
+		);
359
+	}
360
+
361
+
362
+	/**
363
+	 * Prepares condition-query-parameters (like what's in where and having) from
364
+	 * the format expected in the API to use in the models
365
+	 *
366
+	 * @param array    $inputted_query_params_of_this_type
367
+	 * @param EEM_Base $model
368
+	 * @param string   $requested_version
369
+	 * @param boolean  $writing whether this data will be written to the DB, or if we're just building a query.
370
+	 *                          If we're writing to the DB, we don't expect any operators, or any logic query
371
+	 *                          parameters, and we also won't accept serialized data unless the current user has
372
+	 *                          unfiltered_html.
373
+	 * @return array
374
+	 * @throws DomainException
375
+	 * @throws RestException
376
+	 * @throws EE_Error
377
+	 */
378
+	public static function prepareConditionsQueryParamsForModels(
379
+		$inputted_query_params_of_this_type,
380
+		EEM_Base $model,
381
+		$requested_version,
382
+		$writing = false
383
+	) {
384
+		$query_param_for_models = array();
385
+		$valid_operators = $model->valid_operators();
386
+		foreach ($inputted_query_params_of_this_type as $query_param_key => $query_param_value) {
387
+			$is_gmt_datetime_field = false;
388
+			$query_param_sans_stars = ModelDataTranslator::removeStarsAndAnythingAfterFromConditionQueryParamKey(
389
+				$query_param_key
390
+			);
391
+			$field = ModelDataTranslator::deduceFieldFromQueryParam(
392
+				$query_param_sans_stars,
393
+				$model
394
+			);
395
+			// double-check is it a *_gmt field?
396
+			if (! $field instanceof EE_Model_Field_Base
397
+				&& ModelDataTranslator::isGmtDateFieldName($query_param_sans_stars)
398
+			) {
399
+				// yep, take off '_gmt', and find the field
400
+				$query_param_key = ModelDataTranslator::removeGmtFromFieldName($query_param_sans_stars);
401
+				$field = ModelDataTranslator::deduceFieldFromQueryParam(
402
+					$query_param_key,
403
+					$model
404
+				);
405
+				$timezone = 'UTC';
406
+				$is_gmt_datetime_field = true;
407
+			} elseif ($field instanceof EE_Datetime_Field) {
408
+				// so it's not a GMT field. Set the timezone on the model to the default
409
+				$timezone = \EEH_DTT_Helper::get_valid_timezone_string();
410
+			} else {
411
+				// just keep using what's already set for the timezone
412
+				$timezone = $model->get_timezone();
413
+			}
414
+			if ($field instanceof EE_Model_Field_Base) {
415
+				if (! $writing && is_array($query_param_value)) {
416
+					if (! \EEH_Array::is_array_numerically_and_sequentially_indexed($query_param_value)) {
417
+						if (defined('EE_REST_API_DEBUG_MODE') && EE_REST_API_DEBUG_MODE) {
418
+							throw new RestException(
419
+								'numerically_indexed_array_of_values_only',
420
+								sprintf(
421
+									esc_html__(
422
+										'The array provided for the parameter "%1$s" should be numerically indexed.',
423
+										'event_espresso'
424
+									),
425
+									$query_param_key
426
+								),
427
+								array(
428
+									'status' => 400,
429
+								)
430
+							);
431
+						}
432
+					}
433
+					// did they specify an operator?
434
+					if (isset($query_param_value[0])
435
+						&& isset($valid_operators[ $query_param_value[0] ])
436
+					) {
437
+						$op = $query_param_value[0];
438
+						$translated_value = array($op);
439
+						if (array_key_exists($op, $model->valid_in_style_operators())
440
+							&& isset($query_param_value[1])
441
+							&& ! isset($query_param_value[2])
442
+						) {
443
+							$translated_value[] = ModelDataTranslator::prepareFieldValuesFromJson(
444
+								$field,
445
+								$query_param_value[1],
446
+								$requested_version,
447
+								$timezone
448
+							);
449
+						} elseif (array_key_exists($op, $model->valid_between_style_operators())
450
+								  && isset($query_param_value[1])
451
+								  && is_array($query_param_value[1])
452
+								  && isset($query_param_key[1][0], $query_param_value[1][1])
453
+								  && ! isset($query_param_value[1][2])
454
+								  && ! isset($query_param_value[2])
455
+						) {
456
+							$translated_value[] = array(
457
+								ModelDataTranslator::prepareFieldValuesFromJson(
458
+									$field,
459
+									$query_param_value[1][0],
460
+									$requested_version,
461
+									$timezone
462
+								),
463
+								ModelDataTranslator::prepareFieldValuesFromJson(
464
+									$field,
465
+									$query_param_value[1][1],
466
+									$requested_version,
467
+									$timezone
468
+								)
469
+							);
470
+						} elseif (array_key_exists($op, $model->valid_like_style_operators())
471
+								  && isset($query_param_value[1])
472
+								  && ! isset($query_param_value[2])
473
+						) {
474
+							// we want to leave this value mostly-as-is (eg don't force it to be a float
475
+							// or a boolean or an enum value. Leave it as-is with wildcards etc)
476
+							// but do verify it at least doesn't have any serialized data
477
+							ModelDataTranslator::throwExceptionIfContainsSerializedData($query_param_value[1]);
478
+							$translated_value[] = $query_param_value[1];
479
+						} elseif (array_key_exists($op, $model->valid_null_style_operators())
480
+								  && ! isset($query_param_value[1])) {
481
+							// no arguments should have been provided, so don't look for any
482
+						} elseif (isset($query_param_value[1])
483
+								  && ! isset($query_param_value[2])
484
+								  && ! array_key_exists(
485
+									  $op,
486
+									  array_merge(
487
+										  $model->valid_in_style_operators(),
488
+										  $model->valid_null_style_operators(),
489
+										  $model->valid_like_style_operators(),
490
+										  $model->valid_between_style_operators()
491
+									  )
492
+								  )
493
+						) {
494
+							// it's a valid operator, but none of the exceptions. Treat it normally.
495
+							$translated_value[] = ModelDataTranslator::prepareFieldValuesFromJson(
496
+								$field,
497
+								$query_param_value[1],
498
+								$requested_version,
499
+								$timezone
500
+							);
501
+						} else {
502
+							// so they provided a valid operator, but wrong number of arguments
503
+							if (defined('EE_REST_API_DEBUG_MODE') && EE_REST_API_DEBUG_MODE) {
504
+								throw new RestException(
505
+									'wrong_number_of_arguments',
506
+									sprintf(
507
+										esc_html__(
508
+											'The operator you provided, "%1$s" had the wrong number of arguments',
509
+											'event_espresso'
510
+										),
511
+										$op
512
+									),
513
+									array(
514
+										'status' => 400,
515
+									)
516
+								);
517
+							}
518
+							$translated_value = null;
519
+						}
520
+					} else {
521
+						// so they didn't provide a valid operator
522
+						if (defined('EE_REST_API_DEBUG_MODE') && EE_REST_API_DEBUG_MODE) {
523
+							throw new RestException(
524
+								'invalid_operator',
525
+								sprintf(
526
+									esc_html__(
527
+										'You provided an invalid parameter, with key "%1$s" and value "%2$s"',
528
+										'event_espresso'
529
+									),
530
+									$query_param_key,
531
+									$query_param_value
532
+								),
533
+								array(
534
+									'status' => 400,
535
+								)
536
+							);
537
+						}
538
+						// if we aren't in debug mode, then just try our best to fulfill the user's request
539
+						$translated_value = null;
540
+					}
541
+				} else {
542
+					$translated_value = ModelDataTranslator::prepareFieldValueFromJson(
543
+						$field,
544
+						$query_param_value,
545
+						$requested_version,
546
+						$timezone
547
+					);
548
+				}
549
+				if ((isset($query_param_for_models[ $query_param_key ]) && $is_gmt_datetime_field)
550
+					|| $translated_value === null
551
+				) {
552
+					// they have already provided a non-gmt field, ignore the gmt one. That's what WP core
553
+					// currently does (they might change it though). See https://core.trac.wordpress.org/ticket/39954
554
+					// OR we couldn't create a translated value from their input
555
+					continue;
556
+				}
557
+				$query_param_for_models[ $query_param_key ] = $translated_value;
558
+			} else {
559
+				// so this param doesn't correspond to a field eh?
560
+				if ($writing) {
561
+					// always tell API clients about invalid parameters when they're creating data. Otherwise,
562
+					// they are probably going to create invalid data
563
+					throw new RestException(
564
+						'invalid_field',
565
+						sprintf(
566
+							esc_html__('You have provided an invalid parameter: "%1$s"', 'event_espresso'),
567
+							$query_param_key
568
+						)
569
+					);
570
+				} else {
571
+					// so it's not for a field, is it a logic query param key?
572
+					if (in_array(
573
+						$query_param_sans_stars,
574
+						$model->logic_query_param_keys()
575
+					)) {
576
+						$query_param_for_models[ $query_param_key ] = ModelDataTranslator::prepareConditionsQueryParamsForModels(
577
+							$query_param_value,
578
+							$model,
579
+							$requested_version
580
+						);
581
+					} elseif (defined('EE_REST_API_DEBUG_MODE') && EE_REST_API_DEBUG_MODE) {
582
+						// only tell API clients they got it wrong if we're in debug mode
583
+						// otherwise try our best ot fulfill their request by ignoring this invalid data
584
+						throw new RestException(
585
+							'invalid_parameter',
586
+							sprintf(
587
+								esc_html__(
588
+									'You provided an invalid parameter, with key "%1$s"',
589
+									'event_espresso'
590
+								),
591
+								$query_param_sans_stars
592
+							),
593
+							array(
594
+								'status' => 400,
595
+							)
596
+						);
597
+					}
598
+				}
599
+			}
600
+		}
601
+		return $query_param_for_models;
602
+	}
603
+
604
+
605
+	/**
606
+	 * Mostly checks if the last 4 characters are "_gmt", indicating its a
607
+	 * gmt date field name
608
+	 *
609
+	 * @param string $field_name
610
+	 * @return boolean
611
+	 */
612
+	public static function isGmtDateFieldName($field_name)
613
+	{
614
+		return substr(
615
+			ModelDataTranslator::removeStarsAndAnythingAfterFromConditionQueryParamKey($field_name),
616
+			-4,
617
+			4
618
+		) === '_gmt';
619
+	}
620
+
621
+
622
+	/**
623
+	 * Removes the last "_gmt" part of a field name (and if there is no "_gmt" at the end, leave it alone)
624
+	 *
625
+	 * @param string $field_name
626
+	 * @return string
627
+	 */
628
+	public static function removeGmtFromFieldName($field_name)
629
+	{
630
+		if (! ModelDataTranslator::isGmtDateFieldName($field_name)) {
631
+			return $field_name;
632
+		}
633
+		$query_param_sans_stars = ModelDataTranslator::removeStarsAndAnythingAfterFromConditionQueryParamKey(
634
+			$field_name
635
+		);
636
+		$query_param_sans_gmt_and_sans_stars = substr(
637
+			$query_param_sans_stars,
638
+			0,
639
+			strrpos(
640
+				$field_name,
641
+				'_gmt'
642
+			)
643
+		);
644
+		return str_replace($query_param_sans_stars, $query_param_sans_gmt_and_sans_stars, $field_name);
645
+	}
646
+
647
+
648
+	/**
649
+	 * Takes a field name from the REST API and prepares it for the model querying
650
+	 *
651
+	 * @param string $field_name
652
+	 * @return string
653
+	 */
654
+	public static function prepareFieldNameFromJson($field_name)
655
+	{
656
+		if (ModelDataTranslator::isGmtDateFieldName($field_name)) {
657
+			return ModelDataTranslator::removeGmtFromFieldName($field_name);
658
+		}
659
+		return $field_name;
660
+	}
661
+
662
+
663
+	/**
664
+	 * Takes array of field names from REST API and prepares for models
665
+	 *
666
+	 * @param array $field_names
667
+	 * @return array of field names (possibly include model prefixes)
668
+	 */
669
+	public static function prepareFieldNamesFromJson(array $field_names)
670
+	{
671
+		$new_array = array();
672
+		foreach ($field_names as $key => $field_name) {
673
+			$new_array[ $key ] = ModelDataTranslator::prepareFieldNameFromJson($field_name);
674
+		}
675
+		return $new_array;
676
+	}
677
+
678
+
679
+	/**
680
+	 * Takes array where array keys are field names (possibly with model path prefixes)
681
+	 * from the REST API and prepares them for model querying
682
+	 *
683
+	 * @param array $field_names_as_keys
684
+	 * @return array
685
+	 */
686
+	public static function prepareFieldNamesInArrayKeysFromJson(array $field_names_as_keys)
687
+	{
688
+		$new_array = array();
689
+		foreach ($field_names_as_keys as $field_name => $value) {
690
+			$new_array[ ModelDataTranslator::prepareFieldNameFromJson($field_name) ] = $value;
691
+		}
692
+		return $new_array;
693
+	}
694
+
695
+
696
+	/**
697
+	 * Prepares an array of model query params for use in the REST API
698
+	 *
699
+	 * @param array    $model_query_params
700
+	 * @param EEM_Base $model
701
+	 * @param string   $requested_version  eg "4.8.36". If null is provided, defaults to the latest release of the EE4
702
+	 *                                     REST API
703
+	 * @return array which can be passed into the EE4 REST API when querying a model resource
704
+	 * @throws EE_Error
705
+	 */
706
+	public static function prepareQueryParamsForRestApi(
707
+		array $model_query_params,
708
+		EEM_Base $model,
709
+		$requested_version = null
710
+	) {
711
+		if ($requested_version === null) {
712
+			$requested_version = \EED_Core_Rest_Api::latest_rest_api_version();
713
+		}
714
+		$rest_query_params = $model_query_params;
715
+		if (isset($model_query_params[0])) {
716
+			$rest_query_params['where'] = ModelDataTranslator::prepareConditionsQueryParamsForRestApi(
717
+				$model_query_params[0],
718
+				$model,
719
+				$requested_version
720
+			);
721
+			unset($rest_query_params[0]);
722
+		}
723
+		if (isset($model_query_params['having'])) {
724
+			$rest_query_params['having'] = ModelDataTranslator::prepareConditionsQueryParamsForRestApi(
725
+				$model_query_params['having'],
726
+				$model,
727
+				$requested_version
728
+			);
729
+		}
730
+		return apply_filters(
731
+			'FHEE__EventEspresso\core\libraries\rest_api\Model_Data_Translator__prepare_query_params_for_rest_api',
732
+			$rest_query_params,
733
+			$model_query_params,
734
+			$model,
735
+			$requested_version
736
+		);
737
+	}
738
+
739
+
740
+	/**
741
+	 * Prepares all the sub-conditions query parameters (eg having or where conditions) for use in the rest api
742
+	 *
743
+	 * @param array    $inputted_query_params_of_this_type  eg like the "where" or "having" conditions query params
744
+	 *                                                      passed into EEM_Base::get_all()
745
+	 * @param EEM_Base $model
746
+	 * @param string   $requested_version                   eg "4.8.36"
747
+	 * @return array ready for use in the rest api query params
748
+	 * @throws EE_Error
749
+	 * @throws ObjectDetectedException if somehow a PHP object were in the query params' values,
750
+	 *                                                      (which would be really unusual)
751
+	 */
752
+	public static function prepareConditionsQueryParamsForRestApi(
753
+		$inputted_query_params_of_this_type,
754
+		EEM_Base $model,
755
+		$requested_version
756
+	) {
757
+		$query_param_for_models = array();
758
+		foreach ($inputted_query_params_of_this_type as $query_param_key => $query_param_value) {
759
+			$field = ModelDataTranslator::deduceFieldFromQueryParam(
760
+				ModelDataTranslator::removeStarsAndAnythingAfterFromConditionQueryParamKey($query_param_key),
761
+				$model
762
+			);
763
+			if ($field instanceof EE_Model_Field_Base) {
764
+				// did they specify an operator?
765
+				if (is_array($query_param_value)) {
766
+					$op = $query_param_value[0];
767
+					$translated_value = array($op);
768
+					if (isset($query_param_value[1])) {
769
+						$value = $query_param_value[1];
770
+						$translated_value[1] = ModelDataTranslator::prepareFieldValuesForJson(
771
+							$field,
772
+							$value,
773
+							$requested_version
774
+						);
775
+					}
776
+				} else {
777
+					$translated_value = ModelDataTranslator::prepareFieldValueForJson(
778
+						$field,
779
+						$query_param_value,
780
+						$requested_version
781
+					);
782
+				}
783
+				$query_param_for_models[ $query_param_key ] = $translated_value;
784
+			} else {
785
+				// so it's not for a field, assume it's a logic query param key
786
+				$query_param_for_models[ $query_param_key ] = ModelDataTranslator::prepareConditionsQueryParamsForRestApi(
787
+					$query_param_value,
788
+					$model,
789
+					$requested_version
790
+				);
791
+			}
792
+		}
793
+		return $query_param_for_models;
794
+	}
795
+
796
+
797
+	/**
798
+	 * @param $condition_query_param_key
799
+	 * @return string
800
+	 */
801
+	public static function removeStarsAndAnythingAfterFromConditionQueryParamKey($condition_query_param_key)
802
+	{
803
+		$pos_of_star = strpos($condition_query_param_key, '*');
804
+		if ($pos_of_star === false) {
805
+			return $condition_query_param_key;
806
+		} else {
807
+			$condition_query_param_sans_star = substr($condition_query_param_key, 0, $pos_of_star);
808
+			return $condition_query_param_sans_star;
809
+		}
810
+	}
811
+
812
+
813
+	/**
814
+	 * Takes the input parameter and finds the model field that it indicates.
815
+	 *
816
+	 * @param string   $query_param_name like Registration.Transaction.TXN_ID, Event.Datetime.start_time, or REG_ID
817
+	 * @param EEM_Base $model
818
+	 * @return EE_Model_Field_Base
819
+	 * @throws EE_Error
820
+	 */
821
+	public static function deduceFieldFromQueryParam($query_param_name, EEM_Base $model)
822
+	{
823
+		// ok, now proceed with deducing which part is the model's name, and which is the field's name
824
+		// which will help us find the database table and column
825
+		$query_param_parts = explode('.', $query_param_name);
826
+		if (empty($query_param_parts)) {
827
+			throw new EE_Error(
828
+				sprintf(
829
+					__(
830
+						'_extract_column_name is empty when trying to extract column and table name from %s',
831
+						'event_espresso'
832
+					),
833
+					$query_param_name
834
+				)
835
+			);
836
+		}
837
+		$number_of_parts = count($query_param_parts);
838
+		$last_query_param_part = $query_param_parts[ count($query_param_parts) - 1 ];
839
+		if ($number_of_parts === 1) {
840
+			$field_name = $last_query_param_part;
841
+		} else {// $number_of_parts >= 2
842
+			// the last part is the column name, and there are only 2parts. therefore...
843
+			$field_name = $last_query_param_part;
844
+			$model = \EE_Registry::instance()->load_model($query_param_parts[ $number_of_parts - 2 ]);
845
+		}
846
+		try {
847
+			return $model->field_settings_for($field_name, false);
848
+		} catch (EE_Error $e) {
849
+			return null;
850
+		}
851
+	}
852
+
853
+
854
+	/**
855
+	 * Returns true if $data can be easily represented in JSON.
856
+	 * Basically, objects and resources can't be represented in JSON easily.
857
+	 *
858
+	 * @param mixed $data
859
+	 * @return bool
860
+	 */
861
+	protected static function isRepresentableInJson($data)
862
+	{
863
+		return is_scalar($data)
864
+			   || is_array($data)
865
+			   || is_null($data);
866
+	}
867 867
 }
Please login to merge, or discard this patch.
core/libraries/rest_api/ModelVersionInfo.php 1 patch
Indentation   +436 added lines, -436 removed lines patch added patch discarded remove patch
@@ -21,440 +21,440 @@
 block discarded – undo
21 21
 class ModelVersionInfo
22 22
 {
23 23
 
24
-    /**
25
-     * Constant used in the $_model_changes array to indicate that a model
26
-     * was completely new in this version
27
-     */
28
-    const MODEL_ADDED = 'model_added_in_this_version';
29
-
30
-    /**
31
-     * Top-level keys are versions (major and minor version numbers, eg "4.6")
32
-     * next-level keys are model names (eg "Event") that underwent some change in that version
33
-     * and the value is either Model_Version_Info::model_added (indicating the model is completely NEW in this version),
34
-     * or it's an array where the values are model field names,
35
-     * or API resource properties (ie, non-model fields that appear in REST API results)
36
-     * If a version is missing then we don't know anything about what changes it introduced from the previous version
37
-     *
38
-     * @var array
39
-     */
40
-    protected $model_changes = array();
41
-
42
-    /**
43
-     * top-level keys are version numbers,
44
-     * next-level keys are model CLASSNAMES (even parent classnames),
45
-     * and next-level keys are extra resource properties to attach to those models' resources,
46
-     * and next-level key-value pairs, where the keys are:
47
-     * 'raw', 'type', 'nullable', 'table_alias', 'table_column',  'always_available'
48
-     *
49
-     * @var array
50
-     */
51
-    protected $resource_changes = array();
52
-
53
-    /**
54
-     * @var string indicating what version of the API was requested
55
-     * (eg although core might be at version 4.8.11, they may have sent a request
56
-     * for 4.6)
57
-     */
58
-    protected $requested_version = null;
59
-
60
-    /**
61
-     * Keys are model names, values are their classnames.
62
-     * We cache this so we only need to calculate this once per request
63
-     *
64
-     * @var array
65
-     */
66
-    protected $cached_models_for_requested_version = null;
67
-
68
-    /**
69
-     * @var array
70
-     */
71
-    protected $cached_model_changes_between_requested_version_and_current = null;
72
-
73
-    /**
74
-     * @var array
75
-     */
76
-    protected $cached_resource_changes_between_requested_version_and_current = null;
77
-
78
-    /**
79
-     * 2d array where top-level keys are model names, 2nd-level keys are field names
80
-     * and values are the actual field objects
81
-     *
82
-     * @var array
83
-     */
84
-    protected $cached_fields_on_models = array();
85
-
86
-
87
-    /**
88
-     * Model_Version_Info constructor.
89
-     *
90
-     * @param string $requested_version
91
-     */
92
-    public function __construct($requested_version)
93
-    {
94
-        $this->requested_version = (string) $requested_version;
95
-        $this->model_changes = array(
96
-            '4.8.29' => array(
97
-                // first version where the REST API is in EE core, so no need
98
-                // to specify how its different from the previous
99
-            ),
100
-        );
101
-        // setup data for "extra" fields added onto resources which don't actually exist on models
102
-        $this->resource_changes = apply_filters(
103
-            'FHEE__Model_Version_Info___construct__extra_resource_properties_for_models',
104
-            array()
105
-        );
106
-        $defaults = array(
107
-            'raw'              => false,
108
-            'type'             => 'N/A',
109
-            'nullable'         => true,
110
-            'table_alias'      => 'N/A',
111
-            'table_column'     => 'N/A',
112
-            'always_available' => true,
113
-        );
114
-        foreach ($this->resource_changes as $version => $model_classnames) {
115
-            foreach ($model_classnames as $model_classname => $extra_fields) {
116
-                foreach ($extra_fields as $fieldname => $field_data) {
117
-                    $this->resource_changes[ $model_classname ][ $fieldname ]['name'] = $fieldname;
118
-                    foreach ($defaults as $attribute => $default_value) {
119
-                        if (! isset($this->resource_changes[ $model_classname ][ $fieldname ][ $attribute ])) {
120
-                            $this->resource_changes[ $model_classname ][ $fieldname ][ $attribute ] = $default_value;
121
-                        }
122
-                    }
123
-                }
124
-            }
125
-        }
126
-    }
127
-
128
-
129
-    /**
130
-     * Returns a slice of Model_Version_Info::model_changes()'s array
131
-     * indicating exactly what changes happened between the current core version,
132
-     * and the version requested
133
-     *
134
-     * @return array
135
-     */
136
-    public function modelChangesBetweenRequestedVersionAndCurrent()
137
-    {
138
-        if ($this->cached_model_changes_between_requested_version_and_current === null) {
139
-            $model_changes = array();
140
-            foreach ($this->modelChanges() as $version => $models_changed_in_version) {
141
-                if ($version <= EED_Core_Rest_Api::core_version() && $version > $this->requestedVersion()) {
142
-                    $model_changes[ $version ] = $models_changed_in_version;
143
-                }
144
-            }
145
-            $this->cached_model_changes_between_requested_version_and_current = $model_changes;
146
-        }
147
-        return $this->cached_model_changes_between_requested_version_and_current;
148
-    }
149
-
150
-
151
-    /**
152
-     * Returns a slice of Model_Version_Info::model_changes()'s array
153
-     * indicating exactly what changes happened between the current core version,
154
-     * and the version requested
155
-     *
156
-     * @return array
157
-     */
158
-    public function resourceChangesBetweenRequestedVersionAndCurrent()
159
-    {
160
-        if ($this->cached_resource_changes_between_requested_version_and_current === null) {
161
-            $resource_changes = array();
162
-            foreach ($this->resourceChanges() as $version => $model_classnames) {
163
-                if ($version <= EED_Core_Rest_Api::core_version() && $version > $this->requestedVersion()) {
164
-                    $resource_changes[ $version ] = $model_classnames;
165
-                }
166
-            }
167
-            $this->cached_resource_changes_between_requested_version_and_current = $resource_changes;
168
-        }
169
-        return $this->cached_resource_changes_between_requested_version_and_current;
170
-    }
171
-
172
-
173
-    /**
174
-     * If a request was sent to 'wp-json/ee/v4.7/events' this would be '4.7'
175
-     *
176
-     * @return string like '4.6'
177
-     */
178
-    public function requestedVersion()
179
-    {
180
-        return $this->requested_version;
181
-    }
182
-
183
-
184
-    /**
185
-     * Returns an array describing how the models have changed in each version of core
186
-     * that supports the API (starting at 4.6)
187
-     * Top-level keys are versions (major and minor version numbers, eg "4.6")
188
-     * next-level keys are model names (eg "Event") that underwent some change in that version
189
-     * and the value is either NULL (indicating the model is completely NEW in this version),
190
-     * or it's an array where fields are value names.
191
-     * If a version is missing then we don't know anything about what changes it introduced from the previous version
192
-     *
193
-     * @return array
194
-     */
195
-    public function modelChanges()
196
-    {
197
-        return $this->model_changes;
198
-    }
199
-
200
-
201
-    /**
202
-     * Takes into account the requested version, and the current version, and
203
-     * what changed between the two, and tries to return.
204
-     * Analogous to EE_Registry::instance()->non_abstract_db_models
205
-     *
206
-     * @return array keys are model names, values are their classname
207
-     */
208
-    public function modelsForRequestedVersion()
209
-    {
210
-        if ($this->cached_models_for_requested_version === null) {
211
-            $all_models_in_current_version = EE_Registry::instance()->non_abstract_db_models;
212
-            foreach ($this->modelChangesBetweenRequestedVersionAndCurrent() as $version => $models_changed) {
213
-                foreach ($models_changed as $model_name => $new_indicator_or_fields_added) {
214
-                    if ($new_indicator_or_fields_added === ModelVersionInfo::MODEL_ADDED) {
215
-                        unset($all_models_in_current_version[ $model_name ]);
216
-                    }
217
-                }
218
-            }
219
-            $this->cached_models_for_requested_version = apply_filters(
220
-                'FHEE__EventEspresso_core_libraries_rest_api__models_for_requested_version',
221
-                $all_models_in_current_version,
222
-                $this
223
-            );
224
-        }
225
-        return $this->cached_models_for_requested_version;
226
-    }
227
-
228
-
229
-    /**
230
-     * Determines if this is a valid model name in the requested version.
231
-     * Similar to EE_Registry::instance()->is_model_name(), but takes the requested
232
-     * version's models into account
233
-     *
234
-     * @param string $model_name eg 'Event'
235
-     * @return boolean
236
-     */
237
-    public function isModelNameInThisVersion($model_name)
238
-    {
239
-        $model_names = $this->modelsForRequestedVersion();
240
-        if (isset($model_names[ $model_name ])) {
241
-            return true;
242
-        } else {
243
-            return false;
244
-        }
245
-    }
246
-
247
-
248
-    /**
249
-     * Wrapper for EE_Registry::instance()->load_model(), but takes the requested
250
-     * version's models into account
251
-     *
252
-     * @param string $model_name
253
-     * @return \EEM_Base
254
-     * @throws \EE_Error
255
-     */
256
-    public function loadModel($model_name)
257
-    {
258
-        if ($this->isModelNameInThisVersion($model_name)) {
259
-            return EE_Registry::instance()->load_model($model_name);
260
-        } else {
261
-            throw new \EE_Error(
262
-                sprintf(
263
-                    __(
264
-                        'Cannot load model "%1$s" because it does not exist in version %2$s of Event Espresso',
265
-                        'event_espresso'
266
-                    ),
267
-                    $model_name,
268
-                    $this->requestedVersion()
269
-                )
270
-            );
271
-        }
272
-    }
273
-
274
-
275
-    /**
276
-     * Gets all the fields that should exist on this model right now
277
-     *
278
-     * @param \EEM_Base $model
279
-     * @return array|\EE_Model_Field_Base[]
280
-     */
281
-    public function fieldsOnModelInThisVersion($model)
282
-    {
283
-        if (! isset($this->cached_fields_on_models[ $model->get_this_model_name() ])) {
284
-            // get all model changes between the requested version and current core version
285
-            $changes = $this->modelChangesBetweenRequestedVersionAndCurrent();
286
-            // fetch all fields currently on this model
287
-            $current_fields = $model->field_settings();
288
-            // remove all fields that have been added since
289
-            foreach ($changes as $version => $changes_in_version) {
290
-                if (isset($changes_in_version[ $model->get_this_model_name() ])
291
-                    && $changes_in_version[ $model->get_this_model_name() ] !== ModelVersionInfo::MODEL_ADDED
292
-                ) {
293
-                    $current_fields = array_diff_key(
294
-                        $current_fields,
295
-                        array_flip($changes_in_version[ $model->get_this_model_name() ])
296
-                    );
297
-                }
298
-            }
299
-            $this->cached_fields_on_models = $current_fields;
300
-        }
301
-        return $this->cached_fields_on_models;
302
-    }
303
-
304
-
305
-    /**
306
-     * Determines if $object is of one of the classes of $classes. Similar to
307
-     * in_array(), except this checks if $object is a subclass of the classnames provided
308
-     * in $classnames
309
-     *
310
-     * @param object $object
311
-     * @param array  $classnames
312
-     * @return boolean
313
-     */
314
-    public function isSubclassOfOne($object, $classnames)
315
-    {
316
-        foreach ($classnames as $classname) {
317
-            if (is_a($object, $classname)) {
318
-                return true;
319
-            }
320
-        }
321
-        return false;
322
-    }
323
-
324
-
325
-    /**
326
-     * Returns the list of model field classes that that the API basically ignores
327
-     *
328
-     * @return array
329
-     */
330
-    public function fieldsIgnored()
331
-    {
332
-        return apply_filters(
333
-            'FHEE__Controller_Model_Read_fields_ignored',
334
-            array()
335
-        );
336
-    }
337
-
338
-
339
-    /**
340
-     * If this field one that should be ignored by the API?
341
-     *
342
-     * @param EE_Model_Field_Base
343
-     * @return boolean
344
-     */
345
-    public function fieldIsIgnored($field_obj)
346
-    {
347
-        return $this->isSubclassOfOne($field_obj, $this->fieldsIgnored());
348
-    }
349
-
350
-
351
-    /**
352
-     * Returns the list of model field classes that have a "raw" and non-raw formats.
353
-     * Normally the "raw" versions are only accessible to those who can edit them.
354
-     *
355
-     * @return array an array of EE_Model_Field_Base child classnames
356
-     */
357
-    public function fieldsThatHaveRenderedFormat()
358
-    {
359
-        return apply_filters(
360
-            'FHEE__Controller_Model_Read__fields_raw',
361
-            array('EE_Post_Content_Field', 'EE_Full_HTML_Field')
362
-        );
363
-    }
364
-
365
-
366
-    /**
367
-     * If this field one that has a raw format
368
-     *
369
-     * @param EE_Model_Field_Base
370
-     * @return boolean
371
-     */
372
-    public function fieldHasRenderedFormat($field_obj)
373
-    {
374
-        return $this->isSubclassOfOne($field_obj, $this->fieldsThatHaveRenderedFormat());
375
-    }
376
-
377
-
378
-    /**
379
-     * Returns the list of model field classes that have a "_pretty" and non-pretty versions.
380
-     * The pretty version of the field is NOT query-able or editable, but requires no extra permissions
381
-     * to view
382
-     *
383
-     * @return array an array of EE_Model_Field_Base child classnames
384
-     */
385
-    public function fieldsThatHavePrettyFormat()
386
-    {
387
-        return apply_filters(
388
-            'FHEE__Controller_Model_Read__fields_pretty',
389
-            array('EE_Enum_Integer_Field', 'EE_Enum_Text_Field', 'EE_Money_Field')
390
-        );
391
-    }
392
-
393
-
394
-    /**
395
-     * If this field one that has a pretty equivalent
396
-     *
397
-     * @param EE_Model_Field_Base
398
-     * @return boolean
399
-     */
400
-    public function fieldHasPrettyFormat($field_obj)
401
-    {
402
-        return $this->isSubclassOfOne($field_obj, $this->fieldsThatHavePrettyFormat());
403
-    }
404
-
405
-
406
-    /**
407
-     * Returns an array describing what extra API resource properties have been added through the versions
408
-     *
409
-     * @return array @see $this->_extra_resource_properties_for_models
410
-     */
411
-    public function resourceChanges()
412
-    {
413
-        return $this->resource_changes;
414
-    }
415
-
416
-
417
-    /**
418
-     * Returns an array where keys are extra resource properties in this version of the API,
419
-     * and values are key-value pairs describing the new properties. @see Model_Version::_resource_changes
420
-     *
421
-     * @param \EEM_Base $model
422
-     * @return array
423
-     */
424
-    public function extraResourcePropertiesForModel($model)
425
-    {
426
-        $extra_properties = array();
427
-        foreach ($this->resourceChangesBetweenRequestedVersionAndCurrent() as $version => $model_classnames) {
428
-            foreach ($model_classnames as $model_classname => $properties_added_in_this_version) {
429
-                if (is_subclass_of($model, $model_classname)) {
430
-                    $extra_properties = array_merge($extra_properties, $properties_added_in_this_version);
431
-                }
432
-            }
433
-        }
434
-        return $extra_properties;
435
-    }
436
-
437
-
438
-    /**
439
-     * Gets all the related models for the specified model. It's good to use this
440
-     * in case this model didn't exist for this version or something
441
-     *
442
-     * @param \EEM_Base $model
443
-     * @return \EE_Model_Relation_Base[]
444
-     */
445
-    public function relationSettings(\EEM_Base $model)
446
-    {
447
-        $relations = array();
448
-        foreach ($model->relation_settings() as $relation_name => $relation_obj) {
449
-            if ($this->isModelNameInThisVersion($relation_name)) {
450
-                $relations[ $relation_name ] = $relation_obj;
451
-            }
452
-        }
453
-        // filter the results, but use the old filter name
454
-        return apply_filters(
455
-            'FHEE__Read__create_entity_from_wpdb_result__related_models_to_include',
456
-            $relations,
457
-            $model
458
-        );
459
-    }
24
+	/**
25
+	 * Constant used in the $_model_changes array to indicate that a model
26
+	 * was completely new in this version
27
+	 */
28
+	const MODEL_ADDED = 'model_added_in_this_version';
29
+
30
+	/**
31
+	 * Top-level keys are versions (major and minor version numbers, eg "4.6")
32
+	 * next-level keys are model names (eg "Event") that underwent some change in that version
33
+	 * and the value is either Model_Version_Info::model_added (indicating the model is completely NEW in this version),
34
+	 * or it's an array where the values are model field names,
35
+	 * or API resource properties (ie, non-model fields that appear in REST API results)
36
+	 * If a version is missing then we don't know anything about what changes it introduced from the previous version
37
+	 *
38
+	 * @var array
39
+	 */
40
+	protected $model_changes = array();
41
+
42
+	/**
43
+	 * top-level keys are version numbers,
44
+	 * next-level keys are model CLASSNAMES (even parent classnames),
45
+	 * and next-level keys are extra resource properties to attach to those models' resources,
46
+	 * and next-level key-value pairs, where the keys are:
47
+	 * 'raw', 'type', 'nullable', 'table_alias', 'table_column',  'always_available'
48
+	 *
49
+	 * @var array
50
+	 */
51
+	protected $resource_changes = array();
52
+
53
+	/**
54
+	 * @var string indicating what version of the API was requested
55
+	 * (eg although core might be at version 4.8.11, they may have sent a request
56
+	 * for 4.6)
57
+	 */
58
+	protected $requested_version = null;
59
+
60
+	/**
61
+	 * Keys are model names, values are their classnames.
62
+	 * We cache this so we only need to calculate this once per request
63
+	 *
64
+	 * @var array
65
+	 */
66
+	protected $cached_models_for_requested_version = null;
67
+
68
+	/**
69
+	 * @var array
70
+	 */
71
+	protected $cached_model_changes_between_requested_version_and_current = null;
72
+
73
+	/**
74
+	 * @var array
75
+	 */
76
+	protected $cached_resource_changes_between_requested_version_and_current = null;
77
+
78
+	/**
79
+	 * 2d array where top-level keys are model names, 2nd-level keys are field names
80
+	 * and values are the actual field objects
81
+	 *
82
+	 * @var array
83
+	 */
84
+	protected $cached_fields_on_models = array();
85
+
86
+
87
+	/**
88
+	 * Model_Version_Info constructor.
89
+	 *
90
+	 * @param string $requested_version
91
+	 */
92
+	public function __construct($requested_version)
93
+	{
94
+		$this->requested_version = (string) $requested_version;
95
+		$this->model_changes = array(
96
+			'4.8.29' => array(
97
+				// first version where the REST API is in EE core, so no need
98
+				// to specify how its different from the previous
99
+			),
100
+		);
101
+		// setup data for "extra" fields added onto resources which don't actually exist on models
102
+		$this->resource_changes = apply_filters(
103
+			'FHEE__Model_Version_Info___construct__extra_resource_properties_for_models',
104
+			array()
105
+		);
106
+		$defaults = array(
107
+			'raw'              => false,
108
+			'type'             => 'N/A',
109
+			'nullable'         => true,
110
+			'table_alias'      => 'N/A',
111
+			'table_column'     => 'N/A',
112
+			'always_available' => true,
113
+		);
114
+		foreach ($this->resource_changes as $version => $model_classnames) {
115
+			foreach ($model_classnames as $model_classname => $extra_fields) {
116
+				foreach ($extra_fields as $fieldname => $field_data) {
117
+					$this->resource_changes[ $model_classname ][ $fieldname ]['name'] = $fieldname;
118
+					foreach ($defaults as $attribute => $default_value) {
119
+						if (! isset($this->resource_changes[ $model_classname ][ $fieldname ][ $attribute ])) {
120
+							$this->resource_changes[ $model_classname ][ $fieldname ][ $attribute ] = $default_value;
121
+						}
122
+					}
123
+				}
124
+			}
125
+		}
126
+	}
127
+
128
+
129
+	/**
130
+	 * Returns a slice of Model_Version_Info::model_changes()'s array
131
+	 * indicating exactly what changes happened between the current core version,
132
+	 * and the version requested
133
+	 *
134
+	 * @return array
135
+	 */
136
+	public function modelChangesBetweenRequestedVersionAndCurrent()
137
+	{
138
+		if ($this->cached_model_changes_between_requested_version_and_current === null) {
139
+			$model_changes = array();
140
+			foreach ($this->modelChanges() as $version => $models_changed_in_version) {
141
+				if ($version <= EED_Core_Rest_Api::core_version() && $version > $this->requestedVersion()) {
142
+					$model_changes[ $version ] = $models_changed_in_version;
143
+				}
144
+			}
145
+			$this->cached_model_changes_between_requested_version_and_current = $model_changes;
146
+		}
147
+		return $this->cached_model_changes_between_requested_version_and_current;
148
+	}
149
+
150
+
151
+	/**
152
+	 * Returns a slice of Model_Version_Info::model_changes()'s array
153
+	 * indicating exactly what changes happened between the current core version,
154
+	 * and the version requested
155
+	 *
156
+	 * @return array
157
+	 */
158
+	public function resourceChangesBetweenRequestedVersionAndCurrent()
159
+	{
160
+		if ($this->cached_resource_changes_between_requested_version_and_current === null) {
161
+			$resource_changes = array();
162
+			foreach ($this->resourceChanges() as $version => $model_classnames) {
163
+				if ($version <= EED_Core_Rest_Api::core_version() && $version > $this->requestedVersion()) {
164
+					$resource_changes[ $version ] = $model_classnames;
165
+				}
166
+			}
167
+			$this->cached_resource_changes_between_requested_version_and_current = $resource_changes;
168
+		}
169
+		return $this->cached_resource_changes_between_requested_version_and_current;
170
+	}
171
+
172
+
173
+	/**
174
+	 * If a request was sent to 'wp-json/ee/v4.7/events' this would be '4.7'
175
+	 *
176
+	 * @return string like '4.6'
177
+	 */
178
+	public function requestedVersion()
179
+	{
180
+		return $this->requested_version;
181
+	}
182
+
183
+
184
+	/**
185
+	 * Returns an array describing how the models have changed in each version of core
186
+	 * that supports the API (starting at 4.6)
187
+	 * Top-level keys are versions (major and minor version numbers, eg "4.6")
188
+	 * next-level keys are model names (eg "Event") that underwent some change in that version
189
+	 * and the value is either NULL (indicating the model is completely NEW in this version),
190
+	 * or it's an array where fields are value names.
191
+	 * If a version is missing then we don't know anything about what changes it introduced from the previous version
192
+	 *
193
+	 * @return array
194
+	 */
195
+	public function modelChanges()
196
+	{
197
+		return $this->model_changes;
198
+	}
199
+
200
+
201
+	/**
202
+	 * Takes into account the requested version, and the current version, and
203
+	 * what changed between the two, and tries to return.
204
+	 * Analogous to EE_Registry::instance()->non_abstract_db_models
205
+	 *
206
+	 * @return array keys are model names, values are their classname
207
+	 */
208
+	public function modelsForRequestedVersion()
209
+	{
210
+		if ($this->cached_models_for_requested_version === null) {
211
+			$all_models_in_current_version = EE_Registry::instance()->non_abstract_db_models;
212
+			foreach ($this->modelChangesBetweenRequestedVersionAndCurrent() as $version => $models_changed) {
213
+				foreach ($models_changed as $model_name => $new_indicator_or_fields_added) {
214
+					if ($new_indicator_or_fields_added === ModelVersionInfo::MODEL_ADDED) {
215
+						unset($all_models_in_current_version[ $model_name ]);
216
+					}
217
+				}
218
+			}
219
+			$this->cached_models_for_requested_version = apply_filters(
220
+				'FHEE__EventEspresso_core_libraries_rest_api__models_for_requested_version',
221
+				$all_models_in_current_version,
222
+				$this
223
+			);
224
+		}
225
+		return $this->cached_models_for_requested_version;
226
+	}
227
+
228
+
229
+	/**
230
+	 * Determines if this is a valid model name in the requested version.
231
+	 * Similar to EE_Registry::instance()->is_model_name(), but takes the requested
232
+	 * version's models into account
233
+	 *
234
+	 * @param string $model_name eg 'Event'
235
+	 * @return boolean
236
+	 */
237
+	public function isModelNameInThisVersion($model_name)
238
+	{
239
+		$model_names = $this->modelsForRequestedVersion();
240
+		if (isset($model_names[ $model_name ])) {
241
+			return true;
242
+		} else {
243
+			return false;
244
+		}
245
+	}
246
+
247
+
248
+	/**
249
+	 * Wrapper for EE_Registry::instance()->load_model(), but takes the requested
250
+	 * version's models into account
251
+	 *
252
+	 * @param string $model_name
253
+	 * @return \EEM_Base
254
+	 * @throws \EE_Error
255
+	 */
256
+	public function loadModel($model_name)
257
+	{
258
+		if ($this->isModelNameInThisVersion($model_name)) {
259
+			return EE_Registry::instance()->load_model($model_name);
260
+		} else {
261
+			throw new \EE_Error(
262
+				sprintf(
263
+					__(
264
+						'Cannot load model "%1$s" because it does not exist in version %2$s of Event Espresso',
265
+						'event_espresso'
266
+					),
267
+					$model_name,
268
+					$this->requestedVersion()
269
+				)
270
+			);
271
+		}
272
+	}
273
+
274
+
275
+	/**
276
+	 * Gets all the fields that should exist on this model right now
277
+	 *
278
+	 * @param \EEM_Base $model
279
+	 * @return array|\EE_Model_Field_Base[]
280
+	 */
281
+	public function fieldsOnModelInThisVersion($model)
282
+	{
283
+		if (! isset($this->cached_fields_on_models[ $model->get_this_model_name() ])) {
284
+			// get all model changes between the requested version and current core version
285
+			$changes = $this->modelChangesBetweenRequestedVersionAndCurrent();
286
+			// fetch all fields currently on this model
287
+			$current_fields = $model->field_settings();
288
+			// remove all fields that have been added since
289
+			foreach ($changes as $version => $changes_in_version) {
290
+				if (isset($changes_in_version[ $model->get_this_model_name() ])
291
+					&& $changes_in_version[ $model->get_this_model_name() ] !== ModelVersionInfo::MODEL_ADDED
292
+				) {
293
+					$current_fields = array_diff_key(
294
+						$current_fields,
295
+						array_flip($changes_in_version[ $model->get_this_model_name() ])
296
+					);
297
+				}
298
+			}
299
+			$this->cached_fields_on_models = $current_fields;
300
+		}
301
+		return $this->cached_fields_on_models;
302
+	}
303
+
304
+
305
+	/**
306
+	 * Determines if $object is of one of the classes of $classes. Similar to
307
+	 * in_array(), except this checks if $object is a subclass of the classnames provided
308
+	 * in $classnames
309
+	 *
310
+	 * @param object $object
311
+	 * @param array  $classnames
312
+	 * @return boolean
313
+	 */
314
+	public function isSubclassOfOne($object, $classnames)
315
+	{
316
+		foreach ($classnames as $classname) {
317
+			if (is_a($object, $classname)) {
318
+				return true;
319
+			}
320
+		}
321
+		return false;
322
+	}
323
+
324
+
325
+	/**
326
+	 * Returns the list of model field classes that that the API basically ignores
327
+	 *
328
+	 * @return array
329
+	 */
330
+	public function fieldsIgnored()
331
+	{
332
+		return apply_filters(
333
+			'FHEE__Controller_Model_Read_fields_ignored',
334
+			array()
335
+		);
336
+	}
337
+
338
+
339
+	/**
340
+	 * If this field one that should be ignored by the API?
341
+	 *
342
+	 * @param EE_Model_Field_Base
343
+	 * @return boolean
344
+	 */
345
+	public function fieldIsIgnored($field_obj)
346
+	{
347
+		return $this->isSubclassOfOne($field_obj, $this->fieldsIgnored());
348
+	}
349
+
350
+
351
+	/**
352
+	 * Returns the list of model field classes that have a "raw" and non-raw formats.
353
+	 * Normally the "raw" versions are only accessible to those who can edit them.
354
+	 *
355
+	 * @return array an array of EE_Model_Field_Base child classnames
356
+	 */
357
+	public function fieldsThatHaveRenderedFormat()
358
+	{
359
+		return apply_filters(
360
+			'FHEE__Controller_Model_Read__fields_raw',
361
+			array('EE_Post_Content_Field', 'EE_Full_HTML_Field')
362
+		);
363
+	}
364
+
365
+
366
+	/**
367
+	 * If this field one that has a raw format
368
+	 *
369
+	 * @param EE_Model_Field_Base
370
+	 * @return boolean
371
+	 */
372
+	public function fieldHasRenderedFormat($field_obj)
373
+	{
374
+		return $this->isSubclassOfOne($field_obj, $this->fieldsThatHaveRenderedFormat());
375
+	}
376
+
377
+
378
+	/**
379
+	 * Returns the list of model field classes that have a "_pretty" and non-pretty versions.
380
+	 * The pretty version of the field is NOT query-able or editable, but requires no extra permissions
381
+	 * to view
382
+	 *
383
+	 * @return array an array of EE_Model_Field_Base child classnames
384
+	 */
385
+	public function fieldsThatHavePrettyFormat()
386
+	{
387
+		return apply_filters(
388
+			'FHEE__Controller_Model_Read__fields_pretty',
389
+			array('EE_Enum_Integer_Field', 'EE_Enum_Text_Field', 'EE_Money_Field')
390
+		);
391
+	}
392
+
393
+
394
+	/**
395
+	 * If this field one that has a pretty equivalent
396
+	 *
397
+	 * @param EE_Model_Field_Base
398
+	 * @return boolean
399
+	 */
400
+	public function fieldHasPrettyFormat($field_obj)
401
+	{
402
+		return $this->isSubclassOfOne($field_obj, $this->fieldsThatHavePrettyFormat());
403
+	}
404
+
405
+
406
+	/**
407
+	 * Returns an array describing what extra API resource properties have been added through the versions
408
+	 *
409
+	 * @return array @see $this->_extra_resource_properties_for_models
410
+	 */
411
+	public function resourceChanges()
412
+	{
413
+		return $this->resource_changes;
414
+	}
415
+
416
+
417
+	/**
418
+	 * Returns an array where keys are extra resource properties in this version of the API,
419
+	 * and values are key-value pairs describing the new properties. @see Model_Version::_resource_changes
420
+	 *
421
+	 * @param \EEM_Base $model
422
+	 * @return array
423
+	 */
424
+	public function extraResourcePropertiesForModel($model)
425
+	{
426
+		$extra_properties = array();
427
+		foreach ($this->resourceChangesBetweenRequestedVersionAndCurrent() as $version => $model_classnames) {
428
+			foreach ($model_classnames as $model_classname => $properties_added_in_this_version) {
429
+				if (is_subclass_of($model, $model_classname)) {
430
+					$extra_properties = array_merge($extra_properties, $properties_added_in_this_version);
431
+				}
432
+			}
433
+		}
434
+		return $extra_properties;
435
+	}
436
+
437
+
438
+	/**
439
+	 * Gets all the related models for the specified model. It's good to use this
440
+	 * in case this model didn't exist for this version or something
441
+	 *
442
+	 * @param \EEM_Base $model
443
+	 * @return \EE_Model_Relation_Base[]
444
+	 */
445
+	public function relationSettings(\EEM_Base $model)
446
+	{
447
+		$relations = array();
448
+		foreach ($model->relation_settings() as $relation_name => $relation_obj) {
449
+			if ($this->isModelNameInThisVersion($relation_name)) {
450
+				$relations[ $relation_name ] = $relation_obj;
451
+			}
452
+		}
453
+		// filter the results, but use the old filter name
454
+		return apply_filters(
455
+			'FHEE__Read__create_entity_from_wpdb_result__related_models_to_include',
456
+			$relations,
457
+			$model
458
+		);
459
+	}
460 460
 }
Please login to merge, or discard this patch.
caffeinated/admin/extend/events/Extend_Events_Admin_Page.core.php 1 patch
Indentation   +1278 added lines, -1278 removed lines patch added patch discarded remove patch
@@ -16,1282 +16,1282 @@
 block discarded – undo
16 16
 {
17 17
 
18 18
 
19
-    /**
20
-     * Extend_Events_Admin_Page constructor.
21
-     *
22
-     * @param bool $routing
23
-     */
24
-    public function __construct($routing = true)
25
-    {
26
-        parent::__construct($routing);
27
-        if (! defined('EVENTS_CAF_TEMPLATE_PATH')) {
28
-            define('EVENTS_CAF_TEMPLATE_PATH', EE_CORE_CAF_ADMIN_EXTEND . 'events/templates/');
29
-            define('EVENTS_CAF_ASSETS', EE_CORE_CAF_ADMIN_EXTEND . 'events/assets/');
30
-            define('EVENTS_CAF_ASSETS_URL', EE_CORE_CAF_ADMIN_EXTEND_URL . 'events/assets/');
31
-        }
32
-    }
33
-
34
-
35
-    /**
36
-     * Sets routes.
37
-     */
38
-    protected function _extend_page_config()
39
-    {
40
-        $this->_admin_base_path = EE_CORE_CAF_ADMIN_EXTEND . 'events';
41
-        // is there a evt_id in the request?
42
-        $evt_id = ! empty($this->_req_data['EVT_ID']) && ! is_array($this->_req_data['EVT_ID'])
43
-            ? $this->_req_data['EVT_ID']
44
-            : 0;
45
-        $evt_id = ! empty($this->_req_data['post']) ? $this->_req_data['post'] : $evt_id;
46
-        // tkt_id?
47
-        $tkt_id = ! empty($this->_req_data['TKT_ID']) && ! is_array($this->_req_data['TKT_ID'])
48
-            ? $this->_req_data['TKT_ID']
49
-            : 0;
50
-        $new_page_routes = array(
51
-            'duplicate_event'          => array(
52
-                'func'       => '_duplicate_event',
53
-                'capability' => 'ee_edit_event',
54
-                'obj_id'     => $evt_id,
55
-                'noheader'   => true,
56
-            ),
57
-            'ticket_list_table'        => array(
58
-                'func'       => '_tickets_overview_list_table',
59
-                'capability' => 'ee_read_default_tickets',
60
-            ),
61
-            'trash_ticket'             => array(
62
-                'func'       => '_trash_or_restore_ticket',
63
-                'capability' => 'ee_delete_default_ticket',
64
-                'obj_id'     => $tkt_id,
65
-                'noheader'   => true,
66
-                'args'       => array('trash' => true),
67
-            ),
68
-            'trash_tickets'            => array(
69
-                'func'       => '_trash_or_restore_ticket',
70
-                'capability' => 'ee_delete_default_tickets',
71
-                'noheader'   => true,
72
-                'args'       => array('trash' => true),
73
-            ),
74
-            'restore_ticket'           => array(
75
-                'func'       => '_trash_or_restore_ticket',
76
-                'capability' => 'ee_delete_default_ticket',
77
-                'obj_id'     => $tkt_id,
78
-                'noheader'   => true,
79
-            ),
80
-            'restore_tickets'          => array(
81
-                'func'       => '_trash_or_restore_ticket',
82
-                'capability' => 'ee_delete_default_tickets',
83
-                'noheader'   => true,
84
-            ),
85
-            'delete_ticket'            => array(
86
-                'func'       => '_delete_ticket',
87
-                'capability' => 'ee_delete_default_ticket',
88
-                'obj_id'     => $tkt_id,
89
-                'noheader'   => true,
90
-            ),
91
-            'delete_tickets'           => array(
92
-                'func'       => '_delete_ticket',
93
-                'capability' => 'ee_delete_default_tickets',
94
-                'noheader'   => true,
95
-            ),
96
-            'import_page'              => array(
97
-                'func'       => '_import_page',
98
-                'capability' => 'import',
99
-            ),
100
-            'import'                   => array(
101
-                'func'       => '_import_events',
102
-                'capability' => 'import',
103
-                'noheader'   => true,
104
-            ),
105
-            'import_events'            => array(
106
-                'func'       => '_import_events',
107
-                'capability' => 'import',
108
-                'noheader'   => true,
109
-            ),
110
-            'export_events'            => array(
111
-                'func'       => '_events_export',
112
-                'capability' => 'export',
113
-                'noheader'   => true,
114
-            ),
115
-            'export_categories'        => array(
116
-                'func'       => '_categories_export',
117
-                'capability' => 'export',
118
-                'noheader'   => true,
119
-            ),
120
-            'sample_export_file'       => array(
121
-                'func'       => '_sample_export_file',
122
-                'capability' => 'export',
123
-                'noheader'   => true,
124
-            ),
125
-            'update_template_settings' => array(
126
-                'func'       => '_update_template_settings',
127
-                'capability' => 'manage_options',
128
-                'noheader'   => true,
129
-            ),
130
-        );
131
-        $this->_page_routes = array_merge($this->_page_routes, $new_page_routes);
132
-        // partial route/config override
133
-        $this->_page_config['import_events']['metaboxes'] = $this->_default_espresso_metaboxes;
134
-        $this->_page_config['create_new']['metaboxes'][] = '_premium_event_editor_meta_boxes';
135
-        $this->_page_config['create_new']['qtips'][] = 'EE_Event_Editor_Tips';
136
-        $this->_page_config['edit']['qtips'][] = 'EE_Event_Editor_Tips';
137
-        $this->_page_config['edit']['metaboxes'][] = '_premium_event_editor_meta_boxes';
138
-        $this->_page_config['default']['list_table'] = 'Extend_Events_Admin_List_Table';
139
-        // add tickets tab but only if there are more than one default ticket!
140
-        $tkt_count = EEM_Ticket::instance()->count_deleted_and_undeleted(
141
-            array(array('TKT_is_default' => 1)),
142
-            'TKT_ID',
143
-            true
144
-        );
145
-        if ($tkt_count > 1) {
146
-            $new_page_config = array(
147
-                'ticket_list_table' => array(
148
-                    'nav'           => array(
149
-                        'label' => esc_html__('Default Tickets', 'event_espresso'),
150
-                        'order' => 60,
151
-                    ),
152
-                    'list_table'    => 'Tickets_List_Table',
153
-                    'require_nonce' => false,
154
-                ),
155
-            );
156
-        }
157
-        // template settings
158
-        $new_page_config['template_settings'] = array(
159
-            'nav'           => array(
160
-                'label' => esc_html__('Templates', 'event_espresso'),
161
-                'order' => 30,
162
-            ),
163
-            'metaboxes'     => array_merge($this->_default_espresso_metaboxes, array('_publish_post_box')),
164
-            'help_tabs'     => array(
165
-                'general_settings_templates_help_tab' => array(
166
-                    'title'    => esc_html__('Templates', 'event_espresso'),
167
-                    'filename' => 'general_settings_templates',
168
-                ),
169
-            ),
170
-            'help_tour'     => array('Templates_Help_Tour'),
171
-            'require_nonce' => false,
172
-        );
173
-        $this->_page_config = array_merge($this->_page_config, $new_page_config);
174
-        // add filters and actions
175
-        // modifying _views
176
-        add_filter(
177
-            'FHEE_event_datetime_metabox_add_additional_date_time_template',
178
-            array($this, 'add_additional_datetime_button'),
179
-            10,
180
-            2
181
-        );
182
-        add_filter(
183
-            'FHEE_event_datetime_metabox_clone_button_template',
184
-            array($this, 'add_datetime_clone_button'),
185
-            10,
186
-            2
187
-        );
188
-        add_filter(
189
-            'FHEE_event_datetime_metabox_timezones_template',
190
-            array($this, 'datetime_timezones_template'),
191
-            10,
192
-            2
193
-        );
194
-        // filters for event list table
195
-        add_filter('FHEE__Extend_Events_Admin_List_Table__filters', array($this, 'list_table_filters'), 10, 2);
196
-        add_filter(
197
-            'FHEE__Events_Admin_List_Table__column_actions__action_links',
198
-            array($this, 'extra_list_table_actions'),
199
-            10,
200
-            2
201
-        );
202
-        // legend item
203
-        add_filter('FHEE__Events_Admin_Page___event_legend_items__items', array($this, 'additional_legend_items'));
204
-        add_action('admin_init', array($this, 'admin_init'));
205
-        // heartbeat stuff
206
-        add_filter('heartbeat_received', array($this, 'heartbeat_response'), 10, 2);
207
-    }
208
-
209
-
210
-    /**
211
-     * admin_init
212
-     */
213
-    public function admin_init()
214
-    {
215
-        EE_Registry::$i18n_js_strings = array_merge(
216
-            EE_Registry::$i18n_js_strings,
217
-            array(
218
-                'image_confirm'          => esc_html__(
219
-                    'Do you really want to delete this image? Please remember to update your event to complete the removal.',
220
-                    'event_espresso'
221
-                ),
222
-                'event_starts_on'        => esc_html__('Event Starts on', 'event_espresso'),
223
-                'event_ends_on'          => esc_html__('Event Ends on', 'event_espresso'),
224
-                'event_datetime_actions' => esc_html__('Actions', 'event_espresso'),
225
-                'event_clone_dt_msg'     => esc_html__('Clone this Event Date and Time', 'event_espresso'),
226
-                'remove_event_dt_msg'    => esc_html__('Remove this Event Time', 'event_espresso'),
227
-            )
228
-        );
229
-    }
230
-
231
-
232
-    /**
233
-     * This will be used to listen for any heartbeat data packages coming via the WordPress heartbeat API and handle
234
-     * accordingly.
235
-     *
236
-     * @param array $response The existing heartbeat response array.
237
-     * @param array $data     The incoming data package.
238
-     * @return array  possibly appended response.
239
-     */
240
-    public function heartbeat_response($response, $data)
241
-    {
242
-        /**
243
-         * check whether count of tickets is approaching the potential
244
-         * limits for the server.
245
-         */
246
-        if (! empty($data['input_count'])) {
247
-            $response['max_input_vars_check'] = EE_Registry::instance()->CFG->environment->max_input_vars_limit_check(
248
-                $data['input_count']
249
-            );
250
-        }
251
-        return $response;
252
-    }
253
-
254
-
255
-    /**
256
-     * Add per page screen options to the default ticket list table view.
257
-     */
258
-    protected function _add_screen_options_ticket_list_table()
259
-    {
260
-        $this->_per_page_screen_option();
261
-    }
262
-
263
-
264
-    /**
265
-     * @param string $return
266
-     * @param int    $id
267
-     * @param string $new_title
268
-     * @param string $new_slug
269
-     * @return string
270
-     */
271
-    public function extra_permalink_field_buttons($return, $id, $new_title, $new_slug)
272
-    {
273
-        $return = parent::extra_permalink_field_buttons($return, $id, $new_title, $new_slug);
274
-        // make sure this is only when editing
275
-        if (! empty($id)) {
276
-            $href = EE_Admin_Page::add_query_args_and_nonce(
277
-                array('action' => 'duplicate_event', 'EVT_ID' => $id),
278
-                $this->_admin_base_url
279
-            );
280
-            $title = esc_attr__('Duplicate Event', 'event_espresso');
281
-            $return .= '<a href="'
282
-                       . $href
283
-                       . '" title="'
284
-                       . $title
285
-                       . '" id="ee-duplicate-event-button" class="button button-small"  value="duplicate_event">'
286
-                       . $title
287
-                       . '</a>';
288
-        }
289
-        return $return;
290
-    }
291
-
292
-
293
-    /**
294
-     * Set the list table views for the default ticket list table view.
295
-     */
296
-    public function _set_list_table_views_ticket_list_table()
297
-    {
298
-        $this->_views = array(
299
-            'all'     => array(
300
-                'slug'        => 'all',
301
-                'label'       => esc_html__('All', 'event_espresso'),
302
-                'count'       => 0,
303
-                'bulk_action' => array(
304
-                    'trash_tickets' => esc_html__('Move to Trash', 'event_espresso'),
305
-                ),
306
-            ),
307
-            'trashed' => array(
308
-                'slug'        => 'trashed',
309
-                'label'       => esc_html__('Trash', 'event_espresso'),
310
-                'count'       => 0,
311
-                'bulk_action' => array(
312
-                    'restore_tickets' => esc_html__('Restore from Trash', 'event_espresso'),
313
-                    'delete_tickets'  => esc_html__('Delete Permanently', 'event_espresso'),
314
-                ),
315
-            ),
316
-        );
317
-    }
318
-
319
-
320
-    /**
321
-     * Enqueue scripts and styles for the event editor.
322
-     */
323
-    public function load_scripts_styles_edit()
324
-    {
325
-        wp_register_script(
326
-            'ee-event-editor-heartbeat',
327
-            EVENTS_CAF_ASSETS_URL . 'event-editor-heartbeat.js',
328
-            array('ee_admin_js', 'heartbeat'),
329
-            EVENT_ESPRESSO_VERSION,
330
-            true
331
-        );
332
-        wp_enqueue_script('ee-accounting');
333
-        // styles
334
-        wp_enqueue_style('espresso-ui-theme');
335
-        wp_enqueue_script('event_editor_js');
336
-        wp_enqueue_script('ee-event-editor-heartbeat');
337
-    }
338
-
339
-
340
-    /**
341
-     * Returns template for the additional datetime.
342
-     *
343
-     * @param $template
344
-     * @param $template_args
345
-     * @return mixed
346
-     * @throws DomainException
347
-     */
348
-    public function add_additional_datetime_button($template, $template_args)
349
-    {
350
-        return EEH_Template::display_template(
351
-            EVENTS_CAF_TEMPLATE_PATH . 'event_datetime_add_additional_time.template.php',
352
-            $template_args,
353
-            true
354
-        );
355
-    }
356
-
357
-
358
-    /**
359
-     * Returns the template for cloning a datetime.
360
-     *
361
-     * @param $template
362
-     * @param $template_args
363
-     * @return mixed
364
-     * @throws DomainException
365
-     */
366
-    public function add_datetime_clone_button($template, $template_args)
367
-    {
368
-        return EEH_Template::display_template(
369
-            EVENTS_CAF_TEMPLATE_PATH . 'event_datetime_metabox_clone_button.template.php',
370
-            $template_args,
371
-            true
372
-        );
373
-    }
374
-
375
-
376
-    /**
377
-     * Returns the template for datetime timezones.
378
-     *
379
-     * @param $template
380
-     * @param $template_args
381
-     * @return mixed
382
-     * @throws DomainException
383
-     */
384
-    public function datetime_timezones_template($template, $template_args)
385
-    {
386
-        return EEH_Template::display_template(
387
-            EVENTS_CAF_TEMPLATE_PATH . 'event_datetime_timezones.template.php',
388
-            $template_args,
389
-            true
390
-        );
391
-    }
392
-
393
-
394
-    /**
395
-     * Sets the views for the default list table view.
396
-     */
397
-    protected function _set_list_table_views_default()
398
-    {
399
-        parent::_set_list_table_views_default();
400
-        $new_views = array(
401
-            'today' => array(
402
-                'slug'        => 'today',
403
-                'label'       => esc_html__('Today', 'event_espresso'),
404
-                'count'       => $this->total_events_today(),
405
-                'bulk_action' => array(
406
-                    'trash_events' => esc_html__('Move to Trash', 'event_espresso'),
407
-                ),
408
-            ),
409
-            'month' => array(
410
-                'slug'        => 'month',
411
-                'label'       => esc_html__('This Month', 'event_espresso'),
412
-                'count'       => $this->total_events_this_month(),
413
-                'bulk_action' => array(
414
-                    'trash_events' => esc_html__('Move to Trash', 'event_espresso'),
415
-                ),
416
-            ),
417
-        );
418
-        $this->_views = array_merge($this->_views, $new_views);
419
-    }
420
-
421
-
422
-    /**
423
-     * Returns the extra action links for the default list table view.
424
-     *
425
-     * @param array     $action_links
426
-     * @param \EE_Event $event
427
-     * @return array
428
-     * @throws EE_Error
429
-     */
430
-    public function extra_list_table_actions(array $action_links, \EE_Event $event)
431
-    {
432
-        if (EE_Registry::instance()->CAP->current_user_can(
433
-            'ee_read_registrations',
434
-            'espresso_registrations_reports',
435
-            $event->ID()
436
-        )
437
-        ) {
438
-            $reports_query_args = array(
439
-                'action' => 'reports',
440
-                'EVT_ID' => $event->ID(),
441
-            );
442
-            $reports_link = EE_Admin_Page::add_query_args_and_nonce($reports_query_args, REG_ADMIN_URL);
443
-            $action_links[] = '<a href="'
444
-                              . $reports_link
445
-                              . '" title="'
446
-                              . esc_attr__('View Report', 'event_espresso')
447
-                              . '"><div class="dashicons dashicons-chart-bar"></div></a>'
448
-                              . "\n\t";
449
-        }
450
-        if (EE_Registry::instance()->CAP->current_user_can('ee_read_global_messages', 'view_filtered_messages')) {
451
-            EE_Registry::instance()->load_helper('MSG_Template');
452
-            $action_links[] = EEH_MSG_Template::get_message_action_link(
453
-                'see_notifications_for',
454
-                null,
455
-                array('EVT_ID' => $event->ID())
456
-            );
457
-        }
458
-        return $action_links;
459
-    }
460
-
461
-
462
-    /**
463
-     * @param $items
464
-     * @return mixed
465
-     */
466
-    public function additional_legend_items($items)
467
-    {
468
-        if (EE_Registry::instance()->CAP->current_user_can(
469
-            'ee_read_registrations',
470
-            'espresso_registrations_reports'
471
-        )
472
-        ) {
473
-            $items['reports'] = array(
474
-                'class' => 'dashicons dashicons-chart-bar',
475
-                'desc'  => esc_html__('Event Reports', 'event_espresso'),
476
-            );
477
-        }
478
-        if (EE_Registry::instance()->CAP->current_user_can('ee_read_global_messages', 'view_filtered_messages')) {
479
-            $related_for_icon = EEH_MSG_Template::get_message_action_icon('see_notifications_for');
480
-            if (isset($related_for_icon['css_class']) && isset($related_for_icon['label'])) {
481
-                $items['view_related_messages'] = array(
482
-                    'class' => $related_for_icon['css_class'],
483
-                    'desc'  => $related_for_icon['label'],
484
-                );
485
-            }
486
-        }
487
-        return $items;
488
-    }
489
-
490
-
491
-    /**
492
-     * This is the callback method for the duplicate event route
493
-     * Method looks for 'EVT_ID' in the request and retrieves that event and its details and duplicates them
494
-     * into a new event.  We add a hook so that any plugins that add extra event details can hook into this
495
-     * action.  Note that the dupe will have **DUPLICATE** as its title and slug.
496
-     * After duplication the redirect is to the new event edit page.
497
-     *
498
-     * @return void
499
-     * @access protected
500
-     * @throws EE_Error If EE_Event is not available with given ID
501
-     */
502
-    protected function _duplicate_event()
503
-    {
504
-        // first make sure the ID for the event is in the request.
505
-        //  If it isn't then we need to bail and redirect back to overview list table (cause how did we get here?)
506
-        if (! isset($this->_req_data['EVT_ID'])) {
507
-            EE_Error::add_error(
508
-                esc_html__(
509
-                    'In order to duplicate an event an Event ID is required.  None was given.',
510
-                    'event_espresso'
511
-                ),
512
-                __FILE__,
513
-                __FUNCTION__,
514
-                __LINE__
515
-            );
516
-            $this->_redirect_after_action(false, '', '', array(), true);
517
-            return;
518
-        }
519
-        // k we've got EVT_ID so let's use that to get the event we'll duplicate
520
-        $orig_event = EEM_Event::instance()->get_one_by_ID($this->_req_data['EVT_ID']);
521
-        if (! $orig_event instanceof EE_Event) {
522
-            throw new EE_Error(
523
-                sprintf(
524
-                    esc_html__('An EE_Event object could not be retrieved for the given ID (%s)', 'event_espresso'),
525
-                    $this->_req_data['EVT_ID']
526
-                )
527
-            );
528
-        }
529
-        // k now let's clone the $orig_event before getting relations
530
-        $new_event = clone $orig_event;
531
-        // original datetimes
532
-        $orig_datetimes = $orig_event->get_many_related('Datetime');
533
-        // other original relations
534
-        $orig_ven = $orig_event->get_many_related('Venue');
535
-        // reset the ID and modify other details to make it clear this is a dupe
536
-        $new_event->set('EVT_ID', 0);
537
-        $new_name = $new_event->name() . ' ' . esc_html__('**DUPLICATE**', 'event_espresso');
538
-        $new_event->set('EVT_name', $new_name);
539
-        $new_event->set(
540
-            'EVT_slug',
541
-            wp_unique_post_slug(
542
-                sanitize_title($orig_event->name()),
543
-                0,
544
-                'publish',
545
-                'espresso_events',
546
-                0
547
-            )
548
-        );
549
-        $new_event->set('status', 'draft');
550
-        // duplicate discussion settings
551
-        $new_event->set('comment_status', $orig_event->get('comment_status'));
552
-        $new_event->set('ping_status', $orig_event->get('ping_status'));
553
-        // save the new event
554
-        $new_event->save();
555
-        // venues
556
-        foreach ($orig_ven as $ven) {
557
-            $new_event->_add_relation_to($ven, 'Venue');
558
-        }
559
-        $new_event->save();
560
-        // now we need to get the question group relations and handle that
561
-        // first primary question groups
562
-        $orig_primary_qgs = $orig_event->get_many_related(
563
-            'Question_Group',
564
-            array(array('Event_Question_Group.EQG_primary' => 1))
565
-        );
566
-        if (! empty($orig_primary_qgs)) {
567
-            foreach ($orig_primary_qgs as $id => $obj) {
568
-                if ($obj instanceof EE_Question_Group) {
569
-                    $new_event->_add_relation_to($obj, 'Question_Group', array('EQG_primary' => 1));
570
-                }
571
-            }
572
-        }
573
-        // next additional attendee question groups
574
-        $orig_additional_qgs = $orig_event->get_many_related(
575
-            'Question_Group',
576
-            array(array('Event_Question_Group.EQG_primary' => 0))
577
-        );
578
-        if (! empty($orig_additional_qgs)) {
579
-            foreach ($orig_additional_qgs as $id => $obj) {
580
-                if ($obj instanceof EE_Question_Group) {
581
-                    $new_event->_add_relation_to($obj, 'Question_Group', array('EQG_primary' => 0));
582
-                }
583
-            }
584
-        }
585
-
586
-        $new_event->save();
587
-
588
-        // k now that we have the new event saved we can loop through the datetimes and start adding relations.
589
-        $cloned_tickets = array();
590
-        foreach ($orig_datetimes as $orig_dtt) {
591
-            if (! $orig_dtt instanceof EE_Datetime) {
592
-                continue;
593
-            }
594
-            $new_dtt = clone $orig_dtt;
595
-            $orig_tkts = $orig_dtt->tickets();
596
-            // save new dtt then add to event
597
-            $new_dtt->set('DTT_ID', 0);
598
-            $new_dtt->set('DTT_sold', 0);
599
-            $new_dtt->set_reserved(0);
600
-            $new_dtt->save();
601
-            $new_event->_add_relation_to($new_dtt, 'Datetime');
602
-            $new_event->save();
603
-            // now let's get the ticket relations setup.
604
-            foreach ((array) $orig_tkts as $orig_tkt) {
605
-                // it's possible a datetime will have no tickets so let's verify we HAVE a ticket first.
606
-                if (! $orig_tkt instanceof EE_Ticket) {
607
-                    continue;
608
-                }
609
-                // is this ticket archived?  If it is then let's skip
610
-                if ($orig_tkt->get('TKT_deleted')) {
611
-                    continue;
612
-                }
613
-                // does this original ticket already exist in the clone_tickets cache?
614
-                //  If so we'll just use the new ticket from it.
615
-                if (isset($cloned_tickets[ $orig_tkt->ID() ])) {
616
-                    $new_tkt = $cloned_tickets[ $orig_tkt->ID() ];
617
-                } else {
618
-                    $new_tkt = clone $orig_tkt;
619
-                    // get relations on the $orig_tkt that we need to setup.
620
-                    $orig_prices = $orig_tkt->prices();
621
-                    $new_tkt->set('TKT_ID', 0);
622
-                    $new_tkt->set('TKT_sold', 0);
623
-                    $new_tkt->set('TKT_reserved', 0);
624
-                    $new_tkt->save(); // make sure new ticket has ID.
625
-                    // price relations on new ticket need to be setup.
626
-                    foreach ($orig_prices as $orig_price) {
627
-                        $new_price = clone $orig_price;
628
-                        $new_price->set('PRC_ID', 0);
629
-                        $new_price->save();
630
-                        $new_tkt->_add_relation_to($new_price, 'Price');
631
-                        $new_tkt->save();
632
-                    }
633
-
634
-                    do_action(
635
-                        'AHEE__Extend_Events_Admin_Page___duplicate_event__duplicate_ticket__after',
636
-                        $orig_tkt,
637
-                        $new_tkt,
638
-                        $orig_prices,
639
-                        $orig_event,
640
-                        $orig_dtt,
641
-                        $new_dtt
642
-                    );
643
-                }
644
-                // k now we can add the new ticket as a relation to the new datetime
645
-                // and make sure its added to our cached $cloned_tickets array
646
-                // for use with later datetimes that have the same ticket.
647
-                $new_dtt->_add_relation_to($new_tkt, 'Ticket');
648
-                $new_dtt->save();
649
-                $cloned_tickets[ $orig_tkt->ID() ] = $new_tkt;
650
-            }
651
-        }
652
-        // clone taxonomy information
653
-        $taxonomies_to_clone_with = apply_filters(
654
-            'FHEE__Extend_Events_Admin_Page___duplicate_event__taxonomies_to_clone',
655
-            array('espresso_event_categories', 'espresso_event_type', 'post_tag')
656
-        );
657
-        // get terms for original event (notice)
658
-        $orig_terms = wp_get_object_terms($orig_event->ID(), $taxonomies_to_clone_with);
659
-        // loop through terms and add them to new event.
660
-        foreach ($orig_terms as $term) {
661
-            wp_set_object_terms($new_event->ID(), $term->term_id, $term->taxonomy, true);
662
-        }
663
-
664
-        // duplicate other core WP_Post items for this event.
665
-        // post thumbnail (feature image).
666
-        $feature_image_id = get_post_thumbnail_id($orig_event->ID());
667
-        if ($feature_image_id) {
668
-            update_post_meta($new_event->ID(), '_thumbnail_id', $feature_image_id);
669
-        }
670
-
671
-        // duplicate page_template setting
672
-        $page_template = get_post_meta($orig_event->ID(), '_wp_page_template', true);
673
-        if ($page_template) {
674
-            update_post_meta($new_event->ID(), '_wp_page_template', $page_template);
675
-        }
676
-
677
-        do_action('AHEE__Extend_Events_Admin_Page___duplicate_event__after', $new_event, $orig_event);
678
-        // now let's redirect to the edit page for this duplicated event if we have a new event id.
679
-        if ($new_event->ID()) {
680
-            $redirect_args = array(
681
-                'post'   => $new_event->ID(),
682
-                'action' => 'edit',
683
-            );
684
-            EE_Error::add_success(
685
-                esc_html__(
686
-                    'Event successfully duplicated.  Please review the details below and make any necessary edits',
687
-                    'event_espresso'
688
-                )
689
-            );
690
-        } else {
691
-            $redirect_args = array(
692
-                'action' => 'default',
693
-            );
694
-            EE_Error::add_error(
695
-                esc_html__('Not able to duplicate event.  Something went wrong.', 'event_espresso'),
696
-                __FILE__,
697
-                __FUNCTION__,
698
-                __LINE__
699
-            );
700
-        }
701
-        $this->_redirect_after_action(false, '', '', $redirect_args, true);
702
-    }
703
-
704
-
705
-    /**
706
-     * Generates output for the import page.
707
-     *
708
-     * @throws DomainException
709
-     */
710
-    protected function _import_page()
711
-    {
712
-        $title = esc_html__('Import', 'event_espresso');
713
-        $intro = esc_html__(
714
-            'If you have a previously exported Event Espresso 4 information in a Comma Separated Value (CSV) file format, you can upload the file here: ',
715
-            'event_espresso'
716
-        );
717
-        $form_url = EVENTS_ADMIN_URL;
718
-        $action = 'import_events';
719
-        $type = 'csv';
720
-        $this->_template_args['form'] = EE_Import::instance()->upload_form(
721
-            $title,
722
-            $intro,
723
-            $form_url,
724
-            $action,
725
-            $type
726
-        );
727
-        $this->_template_args['sample_file_link'] = EE_Admin_Page::add_query_args_and_nonce(
728
-            array('action' => 'sample_export_file'),
729
-            $this->_admin_base_url
730
-        );
731
-        $content = EEH_Template::display_template(
732
-            EVENTS_CAF_TEMPLATE_PATH . 'import_page.template.php',
733
-            $this->_template_args,
734
-            true
735
-        );
736
-        $this->_template_args['admin_page_content'] = $content;
737
-        $this->display_admin_page_with_sidebar();
738
-    }
739
-
740
-
741
-    /**
742
-     * _import_events
743
-     * This handles displaying the screen and running imports for importing events.
744
-     *
745
-     * @return void
746
-     */
747
-    protected function _import_events()
748
-    {
749
-        require_once(EE_CLASSES . 'EE_Import.class.php');
750
-        $success = EE_Import::instance()->import();
751
-        $this->_redirect_after_action($success, 'Import File', 'ran', array('action' => 'import_page'), true);
752
-    }
753
-
754
-
755
-    /**
756
-     * _events_export
757
-     * Will export all (or just the given event) to a Excel compatible file.
758
-     *
759
-     * @access protected
760
-     * @return void
761
-     */
762
-    protected function _events_export()
763
-    {
764
-        if (isset($this->_req_data['EVT_ID'])) {
765
-            $event_ids = $this->_req_data['EVT_ID'];
766
-        } elseif (isset($this->_req_data['EVT_IDs'])) {
767
-            $event_ids = $this->_req_data['EVT_IDs'];
768
-        } else {
769
-            $event_ids = null;
770
-        }
771
-        // todo: I don't like doing this but it'll do until we modify EE_Export Class.
772
-        $new_request_args = array(
773
-            'export' => 'report',
774
-            'action' => 'all_event_data',
775
-            'EVT_ID' => $event_ids,
776
-        );
777
-        $this->_req_data = array_merge($this->_req_data, $new_request_args);
778
-        if (is_readable(EE_CLASSES . 'EE_Export.class.php')) {
779
-            require_once(EE_CLASSES . 'EE_Export.class.php');
780
-            $EE_Export = EE_Export::instance($this->_req_data);
781
-            $EE_Export->export();
782
-        }
783
-    }
784
-
785
-
786
-    /**
787
-     * handle category exports()
788
-     *
789
-     * @return void
790
-     */
791
-    protected function _categories_export()
792
-    {
793
-        // todo: I don't like doing this but it'll do until we modify EE_Export Class.
794
-        $new_request_args = array(
795
-            'export'       => 'report',
796
-            'action'       => 'categories',
797
-            'category_ids' => $this->_req_data['EVT_CAT_ID'],
798
-        );
799
-        $this->_req_data = array_merge($this->_req_data, $new_request_args);
800
-        if (is_readable(EE_CLASSES . 'EE_Export.class.php')) {
801
-            require_once(EE_CLASSES . 'EE_Export.class.php');
802
-            $EE_Export = EE_Export::instance($this->_req_data);
803
-            $EE_Export->export();
804
-        }
805
-    }
806
-
807
-
808
-    /**
809
-     * Creates a sample CSV file for importing
810
-     */
811
-    protected function _sample_export_file()
812
-    {
813
-        // require_once(EE_CLASSES . 'EE_Export.class.php');
814
-        EE_Export::instance()->export_sample();
815
-    }
816
-
817
-
818
-    /*************        Template Settings        *************/
819
-    /**
820
-     * Generates template settings page output
821
-     *
822
-     * @throws DomainException
823
-     * @throws EE_Error
824
-     */
825
-    protected function _template_settings()
826
-    {
827
-        $this->_template_args['values'] = $this->_yes_no_values;
828
-        /**
829
-         * Note leaving this filter in for backward compatibility this was moved in 4.6.x
830
-         * from General_Settings_Admin_Page to here.
831
-         */
832
-        $this->_template_args = apply_filters(
833
-            'FHEE__General_Settings_Admin_Page__template_settings__template_args',
834
-            $this->_template_args
835
-        );
836
-        $this->_set_add_edit_form_tags('update_template_settings');
837
-        $this->_set_publish_post_box_vars(null, false, false, null, false);
838
-        $this->_template_args['admin_page_content'] = EEH_Template::display_template(
839
-            EVENTS_CAF_TEMPLATE_PATH . 'template_settings.template.php',
840
-            $this->_template_args,
841
-            true
842
-        );
843
-        $this->display_admin_page_with_sidebar();
844
-    }
845
-
846
-
847
-    /**
848
-     * Handler for updating template settings.
849
-     *
850
-     * @throws InvalidInterfaceException
851
-     * @throws InvalidDataTypeException
852
-     * @throws InvalidArgumentException
853
-     */
854
-    protected function _update_template_settings()
855
-    {
856
-        /**
857
-         * Note leaving this filter in for backward compatibility this was moved in 4.6.x
858
-         * from General_Settings_Admin_Page to here.
859
-         */
860
-        EE_Registry::instance()->CFG->template_settings = apply_filters(
861
-            'FHEE__General_Settings_Admin_Page__update_template_settings__data',
862
-            EE_Registry::instance()->CFG->template_settings,
863
-            $this->_req_data
864
-        );
865
-        // update custom post type slugs and detect if we need to flush rewrite rules
866
-        $old_slug = EE_Registry::instance()->CFG->core->event_cpt_slug;
867
-        EE_Registry::instance()->CFG->core->event_cpt_slug = empty($this->_req_data['event_cpt_slug'])
868
-            ? EE_Registry::instance()->CFG->core->event_cpt_slug
869
-            : EEH_URL::slugify($this->_req_data['event_cpt_slug'], 'events');
870
-        $what = 'Template Settings';
871
-        $success = $this->_update_espresso_configuration(
872
-            $what,
873
-            EE_Registry::instance()->CFG->template_settings,
874
-            __FILE__,
875
-            __FUNCTION__,
876
-            __LINE__
877
-        );
878
-        if (EE_Registry::instance()->CFG->core->event_cpt_slug != $old_slug) {
879
-            /** @var EventEspresso\core\domain\services\custom_post_types\RewriteRules $rewrite_rules */
880
-            $rewrite_rules = LoaderFactory::getLoader()->getShared(
881
-                'EventEspresso\core\domain\services\custom_post_types\RewriteRules'
882
-            );
883
-            $rewrite_rules->flush();
884
-        }
885
-        $this->_redirect_after_action($success, $what, 'updated', array('action' => 'template_settings'));
886
-    }
887
-
888
-
889
-    /**
890
-     * _premium_event_editor_meta_boxes
891
-     * add all metaboxes related to the event_editor
892
-     *
893
-     * @access protected
894
-     * @return void
895
-     * @throws EE_Error
896
-     */
897
-    protected function _premium_event_editor_meta_boxes()
898
-    {
899
-        $this->verify_cpt_object();
900
-        add_meta_box(
901
-            'espresso_event_editor_event_options',
902
-            esc_html__('Event Registration Options', 'event_espresso'),
903
-            array($this, 'registration_options_meta_box'),
904
-            $this->page_slug,
905
-            'side',
906
-            'core'
907
-        );
908
-    }
909
-
910
-
911
-    /**
912
-     * override caf metabox
913
-     *
914
-     * @return void
915
-     * @throws DomainException
916
-     */
917
-    public function registration_options_meta_box()
918
-    {
919
-        $yes_no_values = array(
920
-            array('id' => true, 'text' => esc_html__('Yes', 'event_espresso')),
921
-            array('id' => false, 'text' => esc_html__('No', 'event_espresso')),
922
-        );
923
-        $default_reg_status_values = EEM_Registration::reg_status_array(
924
-            array(
925
-                EEM_Registration::status_id_cancelled,
926
-                EEM_Registration::status_id_declined,
927
-                EEM_Registration::status_id_incomplete,
928
-                EEM_Registration::status_id_wait_list,
929
-            ),
930
-            true
931
-        );
932
-        $template_args['active_status'] = $this->_cpt_model_obj->pretty_active_status(false);
933
-        $template_args['_event'] = $this->_cpt_model_obj;
934
-        $template_args['additional_limit'] = $this->_cpt_model_obj->additional_limit();
935
-        $template_args['default_registration_status'] = EEH_Form_Fields::select_input(
936
-            'default_reg_status',
937
-            $default_reg_status_values,
938
-            $this->_cpt_model_obj->default_registration_status()
939
-        );
940
-        $template_args['display_description'] = EEH_Form_Fields::select_input(
941
-            'display_desc',
942
-            $yes_no_values,
943
-            $this->_cpt_model_obj->display_description()
944
-        );
945
-        $template_args['display_ticket_selector'] = EEH_Form_Fields::select_input(
946
-            'display_ticket_selector',
947
-            $yes_no_values,
948
-            $this->_cpt_model_obj->display_ticket_selector(),
949
-            '',
950
-            '',
951
-            false
952
-        );
953
-        $template_args['EVT_default_registration_status'] = EEH_Form_Fields::select_input(
954
-            'EVT_default_registration_status',
955
-            $default_reg_status_values,
956
-            $this->_cpt_model_obj->default_registration_status()
957
-        );
958
-        $template_args['additional_registration_options'] = apply_filters(
959
-            'FHEE__Events_Admin_Page__registration_options_meta_box__additional_registration_options',
960
-            '',
961
-            $template_args,
962
-            $yes_no_values,
963
-            $default_reg_status_values
964
-        );
965
-        EEH_Template::display_template(
966
-            EVENTS_CAF_TEMPLATE_PATH . 'event_registration_options.template.php',
967
-            $template_args
968
-        );
969
-    }
970
-
971
-
972
-
973
-    /**
974
-     * wp_list_table_mods for caf
975
-     * ============================
976
-     */
977
-    /**
978
-     * hook into list table filters and provide filters for caffeinated list table
979
-     *
980
-     * @param  array $old_filters    any existing filters present
981
-     * @param  array $list_table_obj the list table object
982
-     * @return array                  new filters
983
-     */
984
-    public function list_table_filters($old_filters, $list_table_obj)
985
-    {
986
-        $filters = array();
987
-        // first month/year filters
988
-        $filters[] = $this->espresso_event_months_dropdown();
989
-        $status = isset($this->_req_data['status']) ? $this->_req_data['status'] : null;
990
-        // active status dropdown
991
-        if ($status !== 'draft') {
992
-            $filters[] = $this->active_status_dropdown(
993
-                isset($this->_req_data['active_status']) ? $this->_req_data['active_status'] : ''
994
-            );
995
-        }
996
-        // category filter
997
-        $filters[] = $this->category_dropdown();
998
-        return array_merge($old_filters, $filters);
999
-    }
1000
-
1001
-
1002
-    /**
1003
-     * espresso_event_months_dropdown
1004
-     *
1005
-     * @access public
1006
-     * @return string                dropdown listing month/year selections for events.
1007
-     */
1008
-    public function espresso_event_months_dropdown()
1009
-    {
1010
-        // what we need to do is get all PRIMARY datetimes for all events to filter on.
1011
-        // Note we need to include any other filters that are set!
1012
-        $status = isset($this->_req_data['status']) ? $this->_req_data['status'] : null;
1013
-        // categories?
1014
-        $category = isset($this->_req_data['EVT_CAT']) && $this->_req_data['EVT_CAT'] > 0
1015
-            ? $this->_req_data['EVT_CAT']
1016
-            : null;
1017
-        // active status?
1018
-        $active_status = isset($this->_req_data['active_status']) ? $this->_req_data['active_status'] : null;
1019
-        $cur_date = isset($this->_req_data['month_range']) ? $this->_req_data['month_range'] : '';
1020
-        return EEH_Form_Fields::generate_event_months_dropdown($cur_date, $status, $category, $active_status);
1021
-    }
1022
-
1023
-
1024
-    /**
1025
-     * returns a list of "active" statuses on the event
1026
-     *
1027
-     * @param  string $current_value whatever the current active status is
1028
-     * @return string
1029
-     */
1030
-    public function active_status_dropdown($current_value = '')
1031
-    {
1032
-        $select_name = 'active_status';
1033
-        $values = array(
1034
-            'none'     => esc_html__('Show Active/Inactive', 'event_espresso'),
1035
-            'active'   => esc_html__('Active', 'event_espresso'),
1036
-            'upcoming' => esc_html__('Upcoming', 'event_espresso'),
1037
-            'expired'  => esc_html__('Expired', 'event_espresso'),
1038
-            'inactive' => esc_html__('Inactive', 'event_espresso'),
1039
-        );
1040
-        $id = 'id="espresso-active-status-dropdown-filter"';
1041
-        $class = 'wide';
1042
-        return EEH_Form_Fields::select_input($select_name, $values, $current_value, $id, $class);
1043
-    }
1044
-
1045
-
1046
-    /**
1047
-     * output a dropdown of the categories for the category filter on the event admin list table
1048
-     *
1049
-     * @access  public
1050
-     * @return string html
1051
-     */
1052
-    public function category_dropdown()
1053
-    {
1054
-        $cur_cat = isset($this->_req_data['EVT_CAT']) ? $this->_req_data['EVT_CAT'] : -1;
1055
-        return EEH_Form_Fields::generate_event_category_dropdown($cur_cat);
1056
-    }
1057
-
1058
-
1059
-    /**
1060
-     * get total number of events today
1061
-     *
1062
-     * @access public
1063
-     * @return int
1064
-     * @throws EE_Error
1065
-     */
1066
-    public function total_events_today()
1067
-    {
1068
-        $start = EEM_Datetime::instance()->convert_datetime_for_query(
1069
-            'DTT_EVT_start',
1070
-            date('Y-m-d') . ' 00:00:00',
1071
-            'Y-m-d H:i:s',
1072
-            'UTC'
1073
-        );
1074
-        $end = EEM_Datetime::instance()->convert_datetime_for_query(
1075
-            'DTT_EVT_start',
1076
-            date('Y-m-d') . ' 23:59:59',
1077
-            'Y-m-d H:i:s',
1078
-            'UTC'
1079
-        );
1080
-        $where = array(
1081
-            'Datetime.DTT_EVT_start' => array('BETWEEN', array($start, $end)),
1082
-        );
1083
-        $count = EEM_Event::instance()->count(array($where, 'caps' => 'read_admin'), 'EVT_ID', true);
1084
-        return $count;
1085
-    }
1086
-
1087
-
1088
-    /**
1089
-     * get total number of events this month
1090
-     *
1091
-     * @access public
1092
-     * @return int
1093
-     * @throws EE_Error
1094
-     */
1095
-    public function total_events_this_month()
1096
-    {
1097
-        // Dates
1098
-        $this_year_r = date('Y');
1099
-        $this_month_r = date('m');
1100
-        $days_this_month = date('t');
1101
-        $start = EEM_Datetime::instance()->convert_datetime_for_query(
1102
-            'DTT_EVT_start',
1103
-            $this_year_r . '-' . $this_month_r . '-01 00:00:00',
1104
-            'Y-m-d H:i:s',
1105
-            'UTC'
1106
-        );
1107
-        $end = EEM_Datetime::instance()->convert_datetime_for_query(
1108
-            'DTT_EVT_start',
1109
-            $this_year_r . '-' . $this_month_r . '-' . $days_this_month . ' 23:59:59',
1110
-            'Y-m-d H:i:s',
1111
-            'UTC'
1112
-        );
1113
-        $where = array(
1114
-            'Datetime.DTT_EVT_start' => array('BETWEEN', array($start, $end)),
1115
-        );
1116
-        $count = EEM_Event::instance()->count(array($where, 'caps' => 'read_admin'), 'EVT_ID', true);
1117
-        return $count;
1118
-    }
1119
-
1120
-
1121
-    /** DEFAULT TICKETS STUFF **/
1122
-
1123
-    /**
1124
-     * Output default tickets list table view.
1125
-     */
1126
-    public function _tickets_overview_list_table()
1127
-    {
1128
-        $this->_search_btn_label = esc_html__('Tickets', 'event_espresso');
1129
-        $this->display_admin_list_table_page_with_no_sidebar();
1130
-    }
1131
-
1132
-
1133
-    /**
1134
-     * @param int  $per_page
1135
-     * @param bool $count
1136
-     * @param bool $trashed
1137
-     * @return \EE_Soft_Delete_Base_Class[]|int
1138
-     */
1139
-    public function get_default_tickets($per_page = 10, $count = false, $trashed = false)
1140
-    {
1141
-        $orderby = empty($this->_req_data['orderby']) ? 'TKT_name' : $this->_req_data['orderby'];
1142
-        $order = empty($this->_req_data['order']) ? 'ASC' : $this->_req_data['order'];
1143
-        switch ($orderby) {
1144
-            case 'TKT_name':
1145
-                $orderby = array('TKT_name' => $order);
1146
-                break;
1147
-            case 'TKT_price':
1148
-                $orderby = array('TKT_price' => $order);
1149
-                break;
1150
-            case 'TKT_uses':
1151
-                $orderby = array('TKT_uses' => $order);
1152
-                break;
1153
-            case 'TKT_min':
1154
-                $orderby = array('TKT_min' => $order);
1155
-                break;
1156
-            case 'TKT_max':
1157
-                $orderby = array('TKT_max' => $order);
1158
-                break;
1159
-            case 'TKT_qty':
1160
-                $orderby = array('TKT_qty' => $order);
1161
-                break;
1162
-        }
1163
-        $current_page = isset($this->_req_data['paged']) && ! empty($this->_req_data['paged'])
1164
-            ? $this->_req_data['paged']
1165
-            : 1;
1166
-        $per_page = isset($this->_req_data['perpage']) && ! empty($this->_req_data['perpage'])
1167
-            ? $this->_req_data['perpage']
1168
-            : $per_page;
1169
-        $_where = array(
1170
-            'TKT_is_default' => 1,
1171
-            'TKT_deleted'    => $trashed,
1172
-        );
1173
-        $offset = ($current_page - 1) * $per_page;
1174
-        $limit = array($offset, $per_page);
1175
-        if (isset($this->_req_data['s'])) {
1176
-            $sstr = '%' . $this->_req_data['s'] . '%';
1177
-            $_where['OR'] = array(
1178
-                'TKT_name'        => array('LIKE', $sstr),
1179
-                'TKT_description' => array('LIKE', $sstr),
1180
-            );
1181
-        }
1182
-        $query_params = array(
1183
-            $_where,
1184
-            'order_by' => $orderby,
1185
-            'limit'    => $limit,
1186
-            'group_by' => 'TKT_ID',
1187
-        );
1188
-        if ($count) {
1189
-            return EEM_Ticket::instance()->count_deleted_and_undeleted(array($_where));
1190
-        } else {
1191
-            return EEM_Ticket::instance()->get_all_deleted_and_undeleted($query_params);
1192
-        }
1193
-    }
1194
-
1195
-
1196
-    /**
1197
-     * @param bool $trash
1198
-     * @throws EE_Error
1199
-     */
1200
-    protected function _trash_or_restore_ticket($trash = false)
1201
-    {
1202
-        $success = 1;
1203
-        $TKT = EEM_Ticket::instance();
1204
-        // checkboxes?
1205
-        if (! empty($this->_req_data['checkbox']) && is_array($this->_req_data['checkbox'])) {
1206
-            // if array has more than one element then success message should be plural
1207
-            $success = count($this->_req_data['checkbox']) > 1 ? 2 : 1;
1208
-            // cycle thru the boxes
1209
-            while (list($TKT_ID, $value) = each($this->_req_data['checkbox'])) {
1210
-                if ($trash) {
1211
-                    if (! $TKT->delete_by_ID($TKT_ID)) {
1212
-                        $success = 0;
1213
-                    }
1214
-                } else {
1215
-                    if (! $TKT->restore_by_ID($TKT_ID)) {
1216
-                        $success = 0;
1217
-                    }
1218
-                }
1219
-            }
1220
-        } else {
1221
-            // grab single id and trash
1222
-            $TKT_ID = absint($this->_req_data['TKT_ID']);
1223
-            if ($trash) {
1224
-                if (! $TKT->delete_by_ID($TKT_ID)) {
1225
-                    $success = 0;
1226
-                }
1227
-            } else {
1228
-                if (! $TKT->restore_by_ID($TKT_ID)) {
1229
-                    $success = 0;
1230
-                }
1231
-            }
1232
-        }
1233
-        $action_desc = $trash ? 'moved to the trash' : 'restored';
1234
-        $query_args = array(
1235
-            'action' => 'ticket_list_table',
1236
-            'status' => $trash ? '' : 'trashed',
1237
-        );
1238
-        $this->_redirect_after_action($success, 'Tickets', $action_desc, $query_args);
1239
-    }
1240
-
1241
-
1242
-    /**
1243
-     * Handles trashing default ticket.
1244
-     */
1245
-    protected function _delete_ticket()
1246
-    {
1247
-        $success = 1;
1248
-        // checkboxes?
1249
-        if (! empty($this->_req_data['checkbox']) && is_array($this->_req_data['checkbox'])) {
1250
-            // if array has more than one element then success message should be plural
1251
-            $success = count($this->_req_data['checkbox']) > 1 ? 2 : 1;
1252
-            // cycle thru the boxes
1253
-            while (list($TKT_ID, $value) = each($this->_req_data['checkbox'])) {
1254
-                // delete
1255
-                if (! $this->_delete_the_ticket($TKT_ID)) {
1256
-                    $success = 0;
1257
-                }
1258
-            }
1259
-        } else {
1260
-            // grab single id and trash
1261
-            $TKT_ID = absint($this->_req_data['TKT_ID']);
1262
-            if (! $this->_delete_the_ticket($TKT_ID)) {
1263
-                $success = 0;
1264
-            }
1265
-        }
1266
-        $action_desc = 'deleted';
1267
-        $query_args = array(
1268
-            'action' => 'ticket_list_table',
1269
-            'status' => 'trashed',
1270
-        );
1271
-        // fail safe.  If the default ticket count === 1 then we need to redirect to event overview.
1272
-        if (EEM_Ticket::instance()->count_deleted_and_undeleted(
1273
-            array(array('TKT_is_default' => 1)),
1274
-            'TKT_ID',
1275
-            true
1276
-        )
1277
-        ) {
1278
-            $query_args = array();
1279
-        }
1280
-        $this->_redirect_after_action($success, 'Tickets', $action_desc, $query_args);
1281
-    }
1282
-
1283
-
1284
-    /**
1285
-     * @param int $TKT_ID
1286
-     * @return bool|int
1287
-     * @throws EE_Error
1288
-     */
1289
-    protected function _delete_the_ticket($TKT_ID)
1290
-    {
1291
-        $tkt = EEM_Ticket::instance()->get_one_by_ID($TKT_ID);
1292
-        $tkt->_remove_relations('Datetime');
1293
-        // delete all related prices first
1294
-        $tkt->delete_related_permanently('Price');
1295
-        return $tkt->delete_permanently();
1296
-    }
19
+	/**
20
+	 * Extend_Events_Admin_Page constructor.
21
+	 *
22
+	 * @param bool $routing
23
+	 */
24
+	public function __construct($routing = true)
25
+	{
26
+		parent::__construct($routing);
27
+		if (! defined('EVENTS_CAF_TEMPLATE_PATH')) {
28
+			define('EVENTS_CAF_TEMPLATE_PATH', EE_CORE_CAF_ADMIN_EXTEND . 'events/templates/');
29
+			define('EVENTS_CAF_ASSETS', EE_CORE_CAF_ADMIN_EXTEND . 'events/assets/');
30
+			define('EVENTS_CAF_ASSETS_URL', EE_CORE_CAF_ADMIN_EXTEND_URL . 'events/assets/');
31
+		}
32
+	}
33
+
34
+
35
+	/**
36
+	 * Sets routes.
37
+	 */
38
+	protected function _extend_page_config()
39
+	{
40
+		$this->_admin_base_path = EE_CORE_CAF_ADMIN_EXTEND . 'events';
41
+		// is there a evt_id in the request?
42
+		$evt_id = ! empty($this->_req_data['EVT_ID']) && ! is_array($this->_req_data['EVT_ID'])
43
+			? $this->_req_data['EVT_ID']
44
+			: 0;
45
+		$evt_id = ! empty($this->_req_data['post']) ? $this->_req_data['post'] : $evt_id;
46
+		// tkt_id?
47
+		$tkt_id = ! empty($this->_req_data['TKT_ID']) && ! is_array($this->_req_data['TKT_ID'])
48
+			? $this->_req_data['TKT_ID']
49
+			: 0;
50
+		$new_page_routes = array(
51
+			'duplicate_event'          => array(
52
+				'func'       => '_duplicate_event',
53
+				'capability' => 'ee_edit_event',
54
+				'obj_id'     => $evt_id,
55
+				'noheader'   => true,
56
+			),
57
+			'ticket_list_table'        => array(
58
+				'func'       => '_tickets_overview_list_table',
59
+				'capability' => 'ee_read_default_tickets',
60
+			),
61
+			'trash_ticket'             => array(
62
+				'func'       => '_trash_or_restore_ticket',
63
+				'capability' => 'ee_delete_default_ticket',
64
+				'obj_id'     => $tkt_id,
65
+				'noheader'   => true,
66
+				'args'       => array('trash' => true),
67
+			),
68
+			'trash_tickets'            => array(
69
+				'func'       => '_trash_or_restore_ticket',
70
+				'capability' => 'ee_delete_default_tickets',
71
+				'noheader'   => true,
72
+				'args'       => array('trash' => true),
73
+			),
74
+			'restore_ticket'           => array(
75
+				'func'       => '_trash_or_restore_ticket',
76
+				'capability' => 'ee_delete_default_ticket',
77
+				'obj_id'     => $tkt_id,
78
+				'noheader'   => true,
79
+			),
80
+			'restore_tickets'          => array(
81
+				'func'       => '_trash_or_restore_ticket',
82
+				'capability' => 'ee_delete_default_tickets',
83
+				'noheader'   => true,
84
+			),
85
+			'delete_ticket'            => array(
86
+				'func'       => '_delete_ticket',
87
+				'capability' => 'ee_delete_default_ticket',
88
+				'obj_id'     => $tkt_id,
89
+				'noheader'   => true,
90
+			),
91
+			'delete_tickets'           => array(
92
+				'func'       => '_delete_ticket',
93
+				'capability' => 'ee_delete_default_tickets',
94
+				'noheader'   => true,
95
+			),
96
+			'import_page'              => array(
97
+				'func'       => '_import_page',
98
+				'capability' => 'import',
99
+			),
100
+			'import'                   => array(
101
+				'func'       => '_import_events',
102
+				'capability' => 'import',
103
+				'noheader'   => true,
104
+			),
105
+			'import_events'            => array(
106
+				'func'       => '_import_events',
107
+				'capability' => 'import',
108
+				'noheader'   => true,
109
+			),
110
+			'export_events'            => array(
111
+				'func'       => '_events_export',
112
+				'capability' => 'export',
113
+				'noheader'   => true,
114
+			),
115
+			'export_categories'        => array(
116
+				'func'       => '_categories_export',
117
+				'capability' => 'export',
118
+				'noheader'   => true,
119
+			),
120
+			'sample_export_file'       => array(
121
+				'func'       => '_sample_export_file',
122
+				'capability' => 'export',
123
+				'noheader'   => true,
124
+			),
125
+			'update_template_settings' => array(
126
+				'func'       => '_update_template_settings',
127
+				'capability' => 'manage_options',
128
+				'noheader'   => true,
129
+			),
130
+		);
131
+		$this->_page_routes = array_merge($this->_page_routes, $new_page_routes);
132
+		// partial route/config override
133
+		$this->_page_config['import_events']['metaboxes'] = $this->_default_espresso_metaboxes;
134
+		$this->_page_config['create_new']['metaboxes'][] = '_premium_event_editor_meta_boxes';
135
+		$this->_page_config['create_new']['qtips'][] = 'EE_Event_Editor_Tips';
136
+		$this->_page_config['edit']['qtips'][] = 'EE_Event_Editor_Tips';
137
+		$this->_page_config['edit']['metaboxes'][] = '_premium_event_editor_meta_boxes';
138
+		$this->_page_config['default']['list_table'] = 'Extend_Events_Admin_List_Table';
139
+		// add tickets tab but only if there are more than one default ticket!
140
+		$tkt_count = EEM_Ticket::instance()->count_deleted_and_undeleted(
141
+			array(array('TKT_is_default' => 1)),
142
+			'TKT_ID',
143
+			true
144
+		);
145
+		if ($tkt_count > 1) {
146
+			$new_page_config = array(
147
+				'ticket_list_table' => array(
148
+					'nav'           => array(
149
+						'label' => esc_html__('Default Tickets', 'event_espresso'),
150
+						'order' => 60,
151
+					),
152
+					'list_table'    => 'Tickets_List_Table',
153
+					'require_nonce' => false,
154
+				),
155
+			);
156
+		}
157
+		// template settings
158
+		$new_page_config['template_settings'] = array(
159
+			'nav'           => array(
160
+				'label' => esc_html__('Templates', 'event_espresso'),
161
+				'order' => 30,
162
+			),
163
+			'metaboxes'     => array_merge($this->_default_espresso_metaboxes, array('_publish_post_box')),
164
+			'help_tabs'     => array(
165
+				'general_settings_templates_help_tab' => array(
166
+					'title'    => esc_html__('Templates', 'event_espresso'),
167
+					'filename' => 'general_settings_templates',
168
+				),
169
+			),
170
+			'help_tour'     => array('Templates_Help_Tour'),
171
+			'require_nonce' => false,
172
+		);
173
+		$this->_page_config = array_merge($this->_page_config, $new_page_config);
174
+		// add filters and actions
175
+		// modifying _views
176
+		add_filter(
177
+			'FHEE_event_datetime_metabox_add_additional_date_time_template',
178
+			array($this, 'add_additional_datetime_button'),
179
+			10,
180
+			2
181
+		);
182
+		add_filter(
183
+			'FHEE_event_datetime_metabox_clone_button_template',
184
+			array($this, 'add_datetime_clone_button'),
185
+			10,
186
+			2
187
+		);
188
+		add_filter(
189
+			'FHEE_event_datetime_metabox_timezones_template',
190
+			array($this, 'datetime_timezones_template'),
191
+			10,
192
+			2
193
+		);
194
+		// filters for event list table
195
+		add_filter('FHEE__Extend_Events_Admin_List_Table__filters', array($this, 'list_table_filters'), 10, 2);
196
+		add_filter(
197
+			'FHEE__Events_Admin_List_Table__column_actions__action_links',
198
+			array($this, 'extra_list_table_actions'),
199
+			10,
200
+			2
201
+		);
202
+		// legend item
203
+		add_filter('FHEE__Events_Admin_Page___event_legend_items__items', array($this, 'additional_legend_items'));
204
+		add_action('admin_init', array($this, 'admin_init'));
205
+		// heartbeat stuff
206
+		add_filter('heartbeat_received', array($this, 'heartbeat_response'), 10, 2);
207
+	}
208
+
209
+
210
+	/**
211
+	 * admin_init
212
+	 */
213
+	public function admin_init()
214
+	{
215
+		EE_Registry::$i18n_js_strings = array_merge(
216
+			EE_Registry::$i18n_js_strings,
217
+			array(
218
+				'image_confirm'          => esc_html__(
219
+					'Do you really want to delete this image? Please remember to update your event to complete the removal.',
220
+					'event_espresso'
221
+				),
222
+				'event_starts_on'        => esc_html__('Event Starts on', 'event_espresso'),
223
+				'event_ends_on'          => esc_html__('Event Ends on', 'event_espresso'),
224
+				'event_datetime_actions' => esc_html__('Actions', 'event_espresso'),
225
+				'event_clone_dt_msg'     => esc_html__('Clone this Event Date and Time', 'event_espresso'),
226
+				'remove_event_dt_msg'    => esc_html__('Remove this Event Time', 'event_espresso'),
227
+			)
228
+		);
229
+	}
230
+
231
+
232
+	/**
233
+	 * This will be used to listen for any heartbeat data packages coming via the WordPress heartbeat API and handle
234
+	 * accordingly.
235
+	 *
236
+	 * @param array $response The existing heartbeat response array.
237
+	 * @param array $data     The incoming data package.
238
+	 * @return array  possibly appended response.
239
+	 */
240
+	public function heartbeat_response($response, $data)
241
+	{
242
+		/**
243
+		 * check whether count of tickets is approaching the potential
244
+		 * limits for the server.
245
+		 */
246
+		if (! empty($data['input_count'])) {
247
+			$response['max_input_vars_check'] = EE_Registry::instance()->CFG->environment->max_input_vars_limit_check(
248
+				$data['input_count']
249
+			);
250
+		}
251
+		return $response;
252
+	}
253
+
254
+
255
+	/**
256
+	 * Add per page screen options to the default ticket list table view.
257
+	 */
258
+	protected function _add_screen_options_ticket_list_table()
259
+	{
260
+		$this->_per_page_screen_option();
261
+	}
262
+
263
+
264
+	/**
265
+	 * @param string $return
266
+	 * @param int    $id
267
+	 * @param string $new_title
268
+	 * @param string $new_slug
269
+	 * @return string
270
+	 */
271
+	public function extra_permalink_field_buttons($return, $id, $new_title, $new_slug)
272
+	{
273
+		$return = parent::extra_permalink_field_buttons($return, $id, $new_title, $new_slug);
274
+		// make sure this is only when editing
275
+		if (! empty($id)) {
276
+			$href = EE_Admin_Page::add_query_args_and_nonce(
277
+				array('action' => 'duplicate_event', 'EVT_ID' => $id),
278
+				$this->_admin_base_url
279
+			);
280
+			$title = esc_attr__('Duplicate Event', 'event_espresso');
281
+			$return .= '<a href="'
282
+					   . $href
283
+					   . '" title="'
284
+					   . $title
285
+					   . '" id="ee-duplicate-event-button" class="button button-small"  value="duplicate_event">'
286
+					   . $title
287
+					   . '</a>';
288
+		}
289
+		return $return;
290
+	}
291
+
292
+
293
+	/**
294
+	 * Set the list table views for the default ticket list table view.
295
+	 */
296
+	public function _set_list_table_views_ticket_list_table()
297
+	{
298
+		$this->_views = array(
299
+			'all'     => array(
300
+				'slug'        => 'all',
301
+				'label'       => esc_html__('All', 'event_espresso'),
302
+				'count'       => 0,
303
+				'bulk_action' => array(
304
+					'trash_tickets' => esc_html__('Move to Trash', 'event_espresso'),
305
+				),
306
+			),
307
+			'trashed' => array(
308
+				'slug'        => 'trashed',
309
+				'label'       => esc_html__('Trash', 'event_espresso'),
310
+				'count'       => 0,
311
+				'bulk_action' => array(
312
+					'restore_tickets' => esc_html__('Restore from Trash', 'event_espresso'),
313
+					'delete_tickets'  => esc_html__('Delete Permanently', 'event_espresso'),
314
+				),
315
+			),
316
+		);
317
+	}
318
+
319
+
320
+	/**
321
+	 * Enqueue scripts and styles for the event editor.
322
+	 */
323
+	public function load_scripts_styles_edit()
324
+	{
325
+		wp_register_script(
326
+			'ee-event-editor-heartbeat',
327
+			EVENTS_CAF_ASSETS_URL . 'event-editor-heartbeat.js',
328
+			array('ee_admin_js', 'heartbeat'),
329
+			EVENT_ESPRESSO_VERSION,
330
+			true
331
+		);
332
+		wp_enqueue_script('ee-accounting');
333
+		// styles
334
+		wp_enqueue_style('espresso-ui-theme');
335
+		wp_enqueue_script('event_editor_js');
336
+		wp_enqueue_script('ee-event-editor-heartbeat');
337
+	}
338
+
339
+
340
+	/**
341
+	 * Returns template for the additional datetime.
342
+	 *
343
+	 * @param $template
344
+	 * @param $template_args
345
+	 * @return mixed
346
+	 * @throws DomainException
347
+	 */
348
+	public function add_additional_datetime_button($template, $template_args)
349
+	{
350
+		return EEH_Template::display_template(
351
+			EVENTS_CAF_TEMPLATE_PATH . 'event_datetime_add_additional_time.template.php',
352
+			$template_args,
353
+			true
354
+		);
355
+	}
356
+
357
+
358
+	/**
359
+	 * Returns the template for cloning a datetime.
360
+	 *
361
+	 * @param $template
362
+	 * @param $template_args
363
+	 * @return mixed
364
+	 * @throws DomainException
365
+	 */
366
+	public function add_datetime_clone_button($template, $template_args)
367
+	{
368
+		return EEH_Template::display_template(
369
+			EVENTS_CAF_TEMPLATE_PATH . 'event_datetime_metabox_clone_button.template.php',
370
+			$template_args,
371
+			true
372
+		);
373
+	}
374
+
375
+
376
+	/**
377
+	 * Returns the template for datetime timezones.
378
+	 *
379
+	 * @param $template
380
+	 * @param $template_args
381
+	 * @return mixed
382
+	 * @throws DomainException
383
+	 */
384
+	public function datetime_timezones_template($template, $template_args)
385
+	{
386
+		return EEH_Template::display_template(
387
+			EVENTS_CAF_TEMPLATE_PATH . 'event_datetime_timezones.template.php',
388
+			$template_args,
389
+			true
390
+		);
391
+	}
392
+
393
+
394
+	/**
395
+	 * Sets the views for the default list table view.
396
+	 */
397
+	protected function _set_list_table_views_default()
398
+	{
399
+		parent::_set_list_table_views_default();
400
+		$new_views = array(
401
+			'today' => array(
402
+				'slug'        => 'today',
403
+				'label'       => esc_html__('Today', 'event_espresso'),
404
+				'count'       => $this->total_events_today(),
405
+				'bulk_action' => array(
406
+					'trash_events' => esc_html__('Move to Trash', 'event_espresso'),
407
+				),
408
+			),
409
+			'month' => array(
410
+				'slug'        => 'month',
411
+				'label'       => esc_html__('This Month', 'event_espresso'),
412
+				'count'       => $this->total_events_this_month(),
413
+				'bulk_action' => array(
414
+					'trash_events' => esc_html__('Move to Trash', 'event_espresso'),
415
+				),
416
+			),
417
+		);
418
+		$this->_views = array_merge($this->_views, $new_views);
419
+	}
420
+
421
+
422
+	/**
423
+	 * Returns the extra action links for the default list table view.
424
+	 *
425
+	 * @param array     $action_links
426
+	 * @param \EE_Event $event
427
+	 * @return array
428
+	 * @throws EE_Error
429
+	 */
430
+	public function extra_list_table_actions(array $action_links, \EE_Event $event)
431
+	{
432
+		if (EE_Registry::instance()->CAP->current_user_can(
433
+			'ee_read_registrations',
434
+			'espresso_registrations_reports',
435
+			$event->ID()
436
+		)
437
+		) {
438
+			$reports_query_args = array(
439
+				'action' => 'reports',
440
+				'EVT_ID' => $event->ID(),
441
+			);
442
+			$reports_link = EE_Admin_Page::add_query_args_and_nonce($reports_query_args, REG_ADMIN_URL);
443
+			$action_links[] = '<a href="'
444
+							  . $reports_link
445
+							  . '" title="'
446
+							  . esc_attr__('View Report', 'event_espresso')
447
+							  . '"><div class="dashicons dashicons-chart-bar"></div></a>'
448
+							  . "\n\t";
449
+		}
450
+		if (EE_Registry::instance()->CAP->current_user_can('ee_read_global_messages', 'view_filtered_messages')) {
451
+			EE_Registry::instance()->load_helper('MSG_Template');
452
+			$action_links[] = EEH_MSG_Template::get_message_action_link(
453
+				'see_notifications_for',
454
+				null,
455
+				array('EVT_ID' => $event->ID())
456
+			);
457
+		}
458
+		return $action_links;
459
+	}
460
+
461
+
462
+	/**
463
+	 * @param $items
464
+	 * @return mixed
465
+	 */
466
+	public function additional_legend_items($items)
467
+	{
468
+		if (EE_Registry::instance()->CAP->current_user_can(
469
+			'ee_read_registrations',
470
+			'espresso_registrations_reports'
471
+		)
472
+		) {
473
+			$items['reports'] = array(
474
+				'class' => 'dashicons dashicons-chart-bar',
475
+				'desc'  => esc_html__('Event Reports', 'event_espresso'),
476
+			);
477
+		}
478
+		if (EE_Registry::instance()->CAP->current_user_can('ee_read_global_messages', 'view_filtered_messages')) {
479
+			$related_for_icon = EEH_MSG_Template::get_message_action_icon('see_notifications_for');
480
+			if (isset($related_for_icon['css_class']) && isset($related_for_icon['label'])) {
481
+				$items['view_related_messages'] = array(
482
+					'class' => $related_for_icon['css_class'],
483
+					'desc'  => $related_for_icon['label'],
484
+				);
485
+			}
486
+		}
487
+		return $items;
488
+	}
489
+
490
+
491
+	/**
492
+	 * This is the callback method for the duplicate event route
493
+	 * Method looks for 'EVT_ID' in the request and retrieves that event and its details and duplicates them
494
+	 * into a new event.  We add a hook so that any plugins that add extra event details can hook into this
495
+	 * action.  Note that the dupe will have **DUPLICATE** as its title and slug.
496
+	 * After duplication the redirect is to the new event edit page.
497
+	 *
498
+	 * @return void
499
+	 * @access protected
500
+	 * @throws EE_Error If EE_Event is not available with given ID
501
+	 */
502
+	protected function _duplicate_event()
503
+	{
504
+		// first make sure the ID for the event is in the request.
505
+		//  If it isn't then we need to bail and redirect back to overview list table (cause how did we get here?)
506
+		if (! isset($this->_req_data['EVT_ID'])) {
507
+			EE_Error::add_error(
508
+				esc_html__(
509
+					'In order to duplicate an event an Event ID is required.  None was given.',
510
+					'event_espresso'
511
+				),
512
+				__FILE__,
513
+				__FUNCTION__,
514
+				__LINE__
515
+			);
516
+			$this->_redirect_after_action(false, '', '', array(), true);
517
+			return;
518
+		}
519
+		// k we've got EVT_ID so let's use that to get the event we'll duplicate
520
+		$orig_event = EEM_Event::instance()->get_one_by_ID($this->_req_data['EVT_ID']);
521
+		if (! $orig_event instanceof EE_Event) {
522
+			throw new EE_Error(
523
+				sprintf(
524
+					esc_html__('An EE_Event object could not be retrieved for the given ID (%s)', 'event_espresso'),
525
+					$this->_req_data['EVT_ID']
526
+				)
527
+			);
528
+		}
529
+		// k now let's clone the $orig_event before getting relations
530
+		$new_event = clone $orig_event;
531
+		// original datetimes
532
+		$orig_datetimes = $orig_event->get_many_related('Datetime');
533
+		// other original relations
534
+		$orig_ven = $orig_event->get_many_related('Venue');
535
+		// reset the ID and modify other details to make it clear this is a dupe
536
+		$new_event->set('EVT_ID', 0);
537
+		$new_name = $new_event->name() . ' ' . esc_html__('**DUPLICATE**', 'event_espresso');
538
+		$new_event->set('EVT_name', $new_name);
539
+		$new_event->set(
540
+			'EVT_slug',
541
+			wp_unique_post_slug(
542
+				sanitize_title($orig_event->name()),
543
+				0,
544
+				'publish',
545
+				'espresso_events',
546
+				0
547
+			)
548
+		);
549
+		$new_event->set('status', 'draft');
550
+		// duplicate discussion settings
551
+		$new_event->set('comment_status', $orig_event->get('comment_status'));
552
+		$new_event->set('ping_status', $orig_event->get('ping_status'));
553
+		// save the new event
554
+		$new_event->save();
555
+		// venues
556
+		foreach ($orig_ven as $ven) {
557
+			$new_event->_add_relation_to($ven, 'Venue');
558
+		}
559
+		$new_event->save();
560
+		// now we need to get the question group relations and handle that
561
+		// first primary question groups
562
+		$orig_primary_qgs = $orig_event->get_many_related(
563
+			'Question_Group',
564
+			array(array('Event_Question_Group.EQG_primary' => 1))
565
+		);
566
+		if (! empty($orig_primary_qgs)) {
567
+			foreach ($orig_primary_qgs as $id => $obj) {
568
+				if ($obj instanceof EE_Question_Group) {
569
+					$new_event->_add_relation_to($obj, 'Question_Group', array('EQG_primary' => 1));
570
+				}
571
+			}
572
+		}
573
+		// next additional attendee question groups
574
+		$orig_additional_qgs = $orig_event->get_many_related(
575
+			'Question_Group',
576
+			array(array('Event_Question_Group.EQG_primary' => 0))
577
+		);
578
+		if (! empty($orig_additional_qgs)) {
579
+			foreach ($orig_additional_qgs as $id => $obj) {
580
+				if ($obj instanceof EE_Question_Group) {
581
+					$new_event->_add_relation_to($obj, 'Question_Group', array('EQG_primary' => 0));
582
+				}
583
+			}
584
+		}
585
+
586
+		$new_event->save();
587
+
588
+		// k now that we have the new event saved we can loop through the datetimes and start adding relations.
589
+		$cloned_tickets = array();
590
+		foreach ($orig_datetimes as $orig_dtt) {
591
+			if (! $orig_dtt instanceof EE_Datetime) {
592
+				continue;
593
+			}
594
+			$new_dtt = clone $orig_dtt;
595
+			$orig_tkts = $orig_dtt->tickets();
596
+			// save new dtt then add to event
597
+			$new_dtt->set('DTT_ID', 0);
598
+			$new_dtt->set('DTT_sold', 0);
599
+			$new_dtt->set_reserved(0);
600
+			$new_dtt->save();
601
+			$new_event->_add_relation_to($new_dtt, 'Datetime');
602
+			$new_event->save();
603
+			// now let's get the ticket relations setup.
604
+			foreach ((array) $orig_tkts as $orig_tkt) {
605
+				// it's possible a datetime will have no tickets so let's verify we HAVE a ticket first.
606
+				if (! $orig_tkt instanceof EE_Ticket) {
607
+					continue;
608
+				}
609
+				// is this ticket archived?  If it is then let's skip
610
+				if ($orig_tkt->get('TKT_deleted')) {
611
+					continue;
612
+				}
613
+				// does this original ticket already exist in the clone_tickets cache?
614
+				//  If so we'll just use the new ticket from it.
615
+				if (isset($cloned_tickets[ $orig_tkt->ID() ])) {
616
+					$new_tkt = $cloned_tickets[ $orig_tkt->ID() ];
617
+				} else {
618
+					$new_tkt = clone $orig_tkt;
619
+					// get relations on the $orig_tkt that we need to setup.
620
+					$orig_prices = $orig_tkt->prices();
621
+					$new_tkt->set('TKT_ID', 0);
622
+					$new_tkt->set('TKT_sold', 0);
623
+					$new_tkt->set('TKT_reserved', 0);
624
+					$new_tkt->save(); // make sure new ticket has ID.
625
+					// price relations on new ticket need to be setup.
626
+					foreach ($orig_prices as $orig_price) {
627
+						$new_price = clone $orig_price;
628
+						$new_price->set('PRC_ID', 0);
629
+						$new_price->save();
630
+						$new_tkt->_add_relation_to($new_price, 'Price');
631
+						$new_tkt->save();
632
+					}
633
+
634
+					do_action(
635
+						'AHEE__Extend_Events_Admin_Page___duplicate_event__duplicate_ticket__after',
636
+						$orig_tkt,
637
+						$new_tkt,
638
+						$orig_prices,
639
+						$orig_event,
640
+						$orig_dtt,
641
+						$new_dtt
642
+					);
643
+				}
644
+				// k now we can add the new ticket as a relation to the new datetime
645
+				// and make sure its added to our cached $cloned_tickets array
646
+				// for use with later datetimes that have the same ticket.
647
+				$new_dtt->_add_relation_to($new_tkt, 'Ticket');
648
+				$new_dtt->save();
649
+				$cloned_tickets[ $orig_tkt->ID() ] = $new_tkt;
650
+			}
651
+		}
652
+		// clone taxonomy information
653
+		$taxonomies_to_clone_with = apply_filters(
654
+			'FHEE__Extend_Events_Admin_Page___duplicate_event__taxonomies_to_clone',
655
+			array('espresso_event_categories', 'espresso_event_type', 'post_tag')
656
+		);
657
+		// get terms for original event (notice)
658
+		$orig_terms = wp_get_object_terms($orig_event->ID(), $taxonomies_to_clone_with);
659
+		// loop through terms and add them to new event.
660
+		foreach ($orig_terms as $term) {
661
+			wp_set_object_terms($new_event->ID(), $term->term_id, $term->taxonomy, true);
662
+		}
663
+
664
+		// duplicate other core WP_Post items for this event.
665
+		// post thumbnail (feature image).
666
+		$feature_image_id = get_post_thumbnail_id($orig_event->ID());
667
+		if ($feature_image_id) {
668
+			update_post_meta($new_event->ID(), '_thumbnail_id', $feature_image_id);
669
+		}
670
+
671
+		// duplicate page_template setting
672
+		$page_template = get_post_meta($orig_event->ID(), '_wp_page_template', true);
673
+		if ($page_template) {
674
+			update_post_meta($new_event->ID(), '_wp_page_template', $page_template);
675
+		}
676
+
677
+		do_action('AHEE__Extend_Events_Admin_Page___duplicate_event__after', $new_event, $orig_event);
678
+		// now let's redirect to the edit page for this duplicated event if we have a new event id.
679
+		if ($new_event->ID()) {
680
+			$redirect_args = array(
681
+				'post'   => $new_event->ID(),
682
+				'action' => 'edit',
683
+			);
684
+			EE_Error::add_success(
685
+				esc_html__(
686
+					'Event successfully duplicated.  Please review the details below and make any necessary edits',
687
+					'event_espresso'
688
+				)
689
+			);
690
+		} else {
691
+			$redirect_args = array(
692
+				'action' => 'default',
693
+			);
694
+			EE_Error::add_error(
695
+				esc_html__('Not able to duplicate event.  Something went wrong.', 'event_espresso'),
696
+				__FILE__,
697
+				__FUNCTION__,
698
+				__LINE__
699
+			);
700
+		}
701
+		$this->_redirect_after_action(false, '', '', $redirect_args, true);
702
+	}
703
+
704
+
705
+	/**
706
+	 * Generates output for the import page.
707
+	 *
708
+	 * @throws DomainException
709
+	 */
710
+	protected function _import_page()
711
+	{
712
+		$title = esc_html__('Import', 'event_espresso');
713
+		$intro = esc_html__(
714
+			'If you have a previously exported Event Espresso 4 information in a Comma Separated Value (CSV) file format, you can upload the file here: ',
715
+			'event_espresso'
716
+		);
717
+		$form_url = EVENTS_ADMIN_URL;
718
+		$action = 'import_events';
719
+		$type = 'csv';
720
+		$this->_template_args['form'] = EE_Import::instance()->upload_form(
721
+			$title,
722
+			$intro,
723
+			$form_url,
724
+			$action,
725
+			$type
726
+		);
727
+		$this->_template_args['sample_file_link'] = EE_Admin_Page::add_query_args_and_nonce(
728
+			array('action' => 'sample_export_file'),
729
+			$this->_admin_base_url
730
+		);
731
+		$content = EEH_Template::display_template(
732
+			EVENTS_CAF_TEMPLATE_PATH . 'import_page.template.php',
733
+			$this->_template_args,
734
+			true
735
+		);
736
+		$this->_template_args['admin_page_content'] = $content;
737
+		$this->display_admin_page_with_sidebar();
738
+	}
739
+
740
+
741
+	/**
742
+	 * _import_events
743
+	 * This handles displaying the screen and running imports for importing events.
744
+	 *
745
+	 * @return void
746
+	 */
747
+	protected function _import_events()
748
+	{
749
+		require_once(EE_CLASSES . 'EE_Import.class.php');
750
+		$success = EE_Import::instance()->import();
751
+		$this->_redirect_after_action($success, 'Import File', 'ran', array('action' => 'import_page'), true);
752
+	}
753
+
754
+
755
+	/**
756
+	 * _events_export
757
+	 * Will export all (or just the given event) to a Excel compatible file.
758
+	 *
759
+	 * @access protected
760
+	 * @return void
761
+	 */
762
+	protected function _events_export()
763
+	{
764
+		if (isset($this->_req_data['EVT_ID'])) {
765
+			$event_ids = $this->_req_data['EVT_ID'];
766
+		} elseif (isset($this->_req_data['EVT_IDs'])) {
767
+			$event_ids = $this->_req_data['EVT_IDs'];
768
+		} else {
769
+			$event_ids = null;
770
+		}
771
+		// todo: I don't like doing this but it'll do until we modify EE_Export Class.
772
+		$new_request_args = array(
773
+			'export' => 'report',
774
+			'action' => 'all_event_data',
775
+			'EVT_ID' => $event_ids,
776
+		);
777
+		$this->_req_data = array_merge($this->_req_data, $new_request_args);
778
+		if (is_readable(EE_CLASSES . 'EE_Export.class.php')) {
779
+			require_once(EE_CLASSES . 'EE_Export.class.php');
780
+			$EE_Export = EE_Export::instance($this->_req_data);
781
+			$EE_Export->export();
782
+		}
783
+	}
784
+
785
+
786
+	/**
787
+	 * handle category exports()
788
+	 *
789
+	 * @return void
790
+	 */
791
+	protected function _categories_export()
792
+	{
793
+		// todo: I don't like doing this but it'll do until we modify EE_Export Class.
794
+		$new_request_args = array(
795
+			'export'       => 'report',
796
+			'action'       => 'categories',
797
+			'category_ids' => $this->_req_data['EVT_CAT_ID'],
798
+		);
799
+		$this->_req_data = array_merge($this->_req_data, $new_request_args);
800
+		if (is_readable(EE_CLASSES . 'EE_Export.class.php')) {
801
+			require_once(EE_CLASSES . 'EE_Export.class.php');
802
+			$EE_Export = EE_Export::instance($this->_req_data);
803
+			$EE_Export->export();
804
+		}
805
+	}
806
+
807
+
808
+	/**
809
+	 * Creates a sample CSV file for importing
810
+	 */
811
+	protected function _sample_export_file()
812
+	{
813
+		// require_once(EE_CLASSES . 'EE_Export.class.php');
814
+		EE_Export::instance()->export_sample();
815
+	}
816
+
817
+
818
+	/*************        Template Settings        *************/
819
+	/**
820
+	 * Generates template settings page output
821
+	 *
822
+	 * @throws DomainException
823
+	 * @throws EE_Error
824
+	 */
825
+	protected function _template_settings()
826
+	{
827
+		$this->_template_args['values'] = $this->_yes_no_values;
828
+		/**
829
+		 * Note leaving this filter in for backward compatibility this was moved in 4.6.x
830
+		 * from General_Settings_Admin_Page to here.
831
+		 */
832
+		$this->_template_args = apply_filters(
833
+			'FHEE__General_Settings_Admin_Page__template_settings__template_args',
834
+			$this->_template_args
835
+		);
836
+		$this->_set_add_edit_form_tags('update_template_settings');
837
+		$this->_set_publish_post_box_vars(null, false, false, null, false);
838
+		$this->_template_args['admin_page_content'] = EEH_Template::display_template(
839
+			EVENTS_CAF_TEMPLATE_PATH . 'template_settings.template.php',
840
+			$this->_template_args,
841
+			true
842
+		);
843
+		$this->display_admin_page_with_sidebar();
844
+	}
845
+
846
+
847
+	/**
848
+	 * Handler for updating template settings.
849
+	 *
850
+	 * @throws InvalidInterfaceException
851
+	 * @throws InvalidDataTypeException
852
+	 * @throws InvalidArgumentException
853
+	 */
854
+	protected function _update_template_settings()
855
+	{
856
+		/**
857
+		 * Note leaving this filter in for backward compatibility this was moved in 4.6.x
858
+		 * from General_Settings_Admin_Page to here.
859
+		 */
860
+		EE_Registry::instance()->CFG->template_settings = apply_filters(
861
+			'FHEE__General_Settings_Admin_Page__update_template_settings__data',
862
+			EE_Registry::instance()->CFG->template_settings,
863
+			$this->_req_data
864
+		);
865
+		// update custom post type slugs and detect if we need to flush rewrite rules
866
+		$old_slug = EE_Registry::instance()->CFG->core->event_cpt_slug;
867
+		EE_Registry::instance()->CFG->core->event_cpt_slug = empty($this->_req_data['event_cpt_slug'])
868
+			? EE_Registry::instance()->CFG->core->event_cpt_slug
869
+			: EEH_URL::slugify($this->_req_data['event_cpt_slug'], 'events');
870
+		$what = 'Template Settings';
871
+		$success = $this->_update_espresso_configuration(
872
+			$what,
873
+			EE_Registry::instance()->CFG->template_settings,
874
+			__FILE__,
875
+			__FUNCTION__,
876
+			__LINE__
877
+		);
878
+		if (EE_Registry::instance()->CFG->core->event_cpt_slug != $old_slug) {
879
+			/** @var EventEspresso\core\domain\services\custom_post_types\RewriteRules $rewrite_rules */
880
+			$rewrite_rules = LoaderFactory::getLoader()->getShared(
881
+				'EventEspresso\core\domain\services\custom_post_types\RewriteRules'
882
+			);
883
+			$rewrite_rules->flush();
884
+		}
885
+		$this->_redirect_after_action($success, $what, 'updated', array('action' => 'template_settings'));
886
+	}
887
+
888
+
889
+	/**
890
+	 * _premium_event_editor_meta_boxes
891
+	 * add all metaboxes related to the event_editor
892
+	 *
893
+	 * @access protected
894
+	 * @return void
895
+	 * @throws EE_Error
896
+	 */
897
+	protected function _premium_event_editor_meta_boxes()
898
+	{
899
+		$this->verify_cpt_object();
900
+		add_meta_box(
901
+			'espresso_event_editor_event_options',
902
+			esc_html__('Event Registration Options', 'event_espresso'),
903
+			array($this, 'registration_options_meta_box'),
904
+			$this->page_slug,
905
+			'side',
906
+			'core'
907
+		);
908
+	}
909
+
910
+
911
+	/**
912
+	 * override caf metabox
913
+	 *
914
+	 * @return void
915
+	 * @throws DomainException
916
+	 */
917
+	public function registration_options_meta_box()
918
+	{
919
+		$yes_no_values = array(
920
+			array('id' => true, 'text' => esc_html__('Yes', 'event_espresso')),
921
+			array('id' => false, 'text' => esc_html__('No', 'event_espresso')),
922
+		);
923
+		$default_reg_status_values = EEM_Registration::reg_status_array(
924
+			array(
925
+				EEM_Registration::status_id_cancelled,
926
+				EEM_Registration::status_id_declined,
927
+				EEM_Registration::status_id_incomplete,
928
+				EEM_Registration::status_id_wait_list,
929
+			),
930
+			true
931
+		);
932
+		$template_args['active_status'] = $this->_cpt_model_obj->pretty_active_status(false);
933
+		$template_args['_event'] = $this->_cpt_model_obj;
934
+		$template_args['additional_limit'] = $this->_cpt_model_obj->additional_limit();
935
+		$template_args['default_registration_status'] = EEH_Form_Fields::select_input(
936
+			'default_reg_status',
937
+			$default_reg_status_values,
938
+			$this->_cpt_model_obj->default_registration_status()
939
+		);
940
+		$template_args['display_description'] = EEH_Form_Fields::select_input(
941
+			'display_desc',
942
+			$yes_no_values,
943
+			$this->_cpt_model_obj->display_description()
944
+		);
945
+		$template_args['display_ticket_selector'] = EEH_Form_Fields::select_input(
946
+			'display_ticket_selector',
947
+			$yes_no_values,
948
+			$this->_cpt_model_obj->display_ticket_selector(),
949
+			'',
950
+			'',
951
+			false
952
+		);
953
+		$template_args['EVT_default_registration_status'] = EEH_Form_Fields::select_input(
954
+			'EVT_default_registration_status',
955
+			$default_reg_status_values,
956
+			$this->_cpt_model_obj->default_registration_status()
957
+		);
958
+		$template_args['additional_registration_options'] = apply_filters(
959
+			'FHEE__Events_Admin_Page__registration_options_meta_box__additional_registration_options',
960
+			'',
961
+			$template_args,
962
+			$yes_no_values,
963
+			$default_reg_status_values
964
+		);
965
+		EEH_Template::display_template(
966
+			EVENTS_CAF_TEMPLATE_PATH . 'event_registration_options.template.php',
967
+			$template_args
968
+		);
969
+	}
970
+
971
+
972
+
973
+	/**
974
+	 * wp_list_table_mods for caf
975
+	 * ============================
976
+	 */
977
+	/**
978
+	 * hook into list table filters and provide filters for caffeinated list table
979
+	 *
980
+	 * @param  array $old_filters    any existing filters present
981
+	 * @param  array $list_table_obj the list table object
982
+	 * @return array                  new filters
983
+	 */
984
+	public function list_table_filters($old_filters, $list_table_obj)
985
+	{
986
+		$filters = array();
987
+		// first month/year filters
988
+		$filters[] = $this->espresso_event_months_dropdown();
989
+		$status = isset($this->_req_data['status']) ? $this->_req_data['status'] : null;
990
+		// active status dropdown
991
+		if ($status !== 'draft') {
992
+			$filters[] = $this->active_status_dropdown(
993
+				isset($this->_req_data['active_status']) ? $this->_req_data['active_status'] : ''
994
+			);
995
+		}
996
+		// category filter
997
+		$filters[] = $this->category_dropdown();
998
+		return array_merge($old_filters, $filters);
999
+	}
1000
+
1001
+
1002
+	/**
1003
+	 * espresso_event_months_dropdown
1004
+	 *
1005
+	 * @access public
1006
+	 * @return string                dropdown listing month/year selections for events.
1007
+	 */
1008
+	public function espresso_event_months_dropdown()
1009
+	{
1010
+		// what we need to do is get all PRIMARY datetimes for all events to filter on.
1011
+		// Note we need to include any other filters that are set!
1012
+		$status = isset($this->_req_data['status']) ? $this->_req_data['status'] : null;
1013
+		// categories?
1014
+		$category = isset($this->_req_data['EVT_CAT']) && $this->_req_data['EVT_CAT'] > 0
1015
+			? $this->_req_data['EVT_CAT']
1016
+			: null;
1017
+		// active status?
1018
+		$active_status = isset($this->_req_data['active_status']) ? $this->_req_data['active_status'] : null;
1019
+		$cur_date = isset($this->_req_data['month_range']) ? $this->_req_data['month_range'] : '';
1020
+		return EEH_Form_Fields::generate_event_months_dropdown($cur_date, $status, $category, $active_status);
1021
+	}
1022
+
1023
+
1024
+	/**
1025
+	 * returns a list of "active" statuses on the event
1026
+	 *
1027
+	 * @param  string $current_value whatever the current active status is
1028
+	 * @return string
1029
+	 */
1030
+	public function active_status_dropdown($current_value = '')
1031
+	{
1032
+		$select_name = 'active_status';
1033
+		$values = array(
1034
+			'none'     => esc_html__('Show Active/Inactive', 'event_espresso'),
1035
+			'active'   => esc_html__('Active', 'event_espresso'),
1036
+			'upcoming' => esc_html__('Upcoming', 'event_espresso'),
1037
+			'expired'  => esc_html__('Expired', 'event_espresso'),
1038
+			'inactive' => esc_html__('Inactive', 'event_espresso'),
1039
+		);
1040
+		$id = 'id="espresso-active-status-dropdown-filter"';
1041
+		$class = 'wide';
1042
+		return EEH_Form_Fields::select_input($select_name, $values, $current_value, $id, $class);
1043
+	}
1044
+
1045
+
1046
+	/**
1047
+	 * output a dropdown of the categories for the category filter on the event admin list table
1048
+	 *
1049
+	 * @access  public
1050
+	 * @return string html
1051
+	 */
1052
+	public function category_dropdown()
1053
+	{
1054
+		$cur_cat = isset($this->_req_data['EVT_CAT']) ? $this->_req_data['EVT_CAT'] : -1;
1055
+		return EEH_Form_Fields::generate_event_category_dropdown($cur_cat);
1056
+	}
1057
+
1058
+
1059
+	/**
1060
+	 * get total number of events today
1061
+	 *
1062
+	 * @access public
1063
+	 * @return int
1064
+	 * @throws EE_Error
1065
+	 */
1066
+	public function total_events_today()
1067
+	{
1068
+		$start = EEM_Datetime::instance()->convert_datetime_for_query(
1069
+			'DTT_EVT_start',
1070
+			date('Y-m-d') . ' 00:00:00',
1071
+			'Y-m-d H:i:s',
1072
+			'UTC'
1073
+		);
1074
+		$end = EEM_Datetime::instance()->convert_datetime_for_query(
1075
+			'DTT_EVT_start',
1076
+			date('Y-m-d') . ' 23:59:59',
1077
+			'Y-m-d H:i:s',
1078
+			'UTC'
1079
+		);
1080
+		$where = array(
1081
+			'Datetime.DTT_EVT_start' => array('BETWEEN', array($start, $end)),
1082
+		);
1083
+		$count = EEM_Event::instance()->count(array($where, 'caps' => 'read_admin'), 'EVT_ID', true);
1084
+		return $count;
1085
+	}
1086
+
1087
+
1088
+	/**
1089
+	 * get total number of events this month
1090
+	 *
1091
+	 * @access public
1092
+	 * @return int
1093
+	 * @throws EE_Error
1094
+	 */
1095
+	public function total_events_this_month()
1096
+	{
1097
+		// Dates
1098
+		$this_year_r = date('Y');
1099
+		$this_month_r = date('m');
1100
+		$days_this_month = date('t');
1101
+		$start = EEM_Datetime::instance()->convert_datetime_for_query(
1102
+			'DTT_EVT_start',
1103
+			$this_year_r . '-' . $this_month_r . '-01 00:00:00',
1104
+			'Y-m-d H:i:s',
1105
+			'UTC'
1106
+		);
1107
+		$end = EEM_Datetime::instance()->convert_datetime_for_query(
1108
+			'DTT_EVT_start',
1109
+			$this_year_r . '-' . $this_month_r . '-' . $days_this_month . ' 23:59:59',
1110
+			'Y-m-d H:i:s',
1111
+			'UTC'
1112
+		);
1113
+		$where = array(
1114
+			'Datetime.DTT_EVT_start' => array('BETWEEN', array($start, $end)),
1115
+		);
1116
+		$count = EEM_Event::instance()->count(array($where, 'caps' => 'read_admin'), 'EVT_ID', true);
1117
+		return $count;
1118
+	}
1119
+
1120
+
1121
+	/** DEFAULT TICKETS STUFF **/
1122
+
1123
+	/**
1124
+	 * Output default tickets list table view.
1125
+	 */
1126
+	public function _tickets_overview_list_table()
1127
+	{
1128
+		$this->_search_btn_label = esc_html__('Tickets', 'event_espresso');
1129
+		$this->display_admin_list_table_page_with_no_sidebar();
1130
+	}
1131
+
1132
+
1133
+	/**
1134
+	 * @param int  $per_page
1135
+	 * @param bool $count
1136
+	 * @param bool $trashed
1137
+	 * @return \EE_Soft_Delete_Base_Class[]|int
1138
+	 */
1139
+	public function get_default_tickets($per_page = 10, $count = false, $trashed = false)
1140
+	{
1141
+		$orderby = empty($this->_req_data['orderby']) ? 'TKT_name' : $this->_req_data['orderby'];
1142
+		$order = empty($this->_req_data['order']) ? 'ASC' : $this->_req_data['order'];
1143
+		switch ($orderby) {
1144
+			case 'TKT_name':
1145
+				$orderby = array('TKT_name' => $order);
1146
+				break;
1147
+			case 'TKT_price':
1148
+				$orderby = array('TKT_price' => $order);
1149
+				break;
1150
+			case 'TKT_uses':
1151
+				$orderby = array('TKT_uses' => $order);
1152
+				break;
1153
+			case 'TKT_min':
1154
+				$orderby = array('TKT_min' => $order);
1155
+				break;
1156
+			case 'TKT_max':
1157
+				$orderby = array('TKT_max' => $order);
1158
+				break;
1159
+			case 'TKT_qty':
1160
+				$orderby = array('TKT_qty' => $order);
1161
+				break;
1162
+		}
1163
+		$current_page = isset($this->_req_data['paged']) && ! empty($this->_req_data['paged'])
1164
+			? $this->_req_data['paged']
1165
+			: 1;
1166
+		$per_page = isset($this->_req_data['perpage']) && ! empty($this->_req_data['perpage'])
1167
+			? $this->_req_data['perpage']
1168
+			: $per_page;
1169
+		$_where = array(
1170
+			'TKT_is_default' => 1,
1171
+			'TKT_deleted'    => $trashed,
1172
+		);
1173
+		$offset = ($current_page - 1) * $per_page;
1174
+		$limit = array($offset, $per_page);
1175
+		if (isset($this->_req_data['s'])) {
1176
+			$sstr = '%' . $this->_req_data['s'] . '%';
1177
+			$_where['OR'] = array(
1178
+				'TKT_name'        => array('LIKE', $sstr),
1179
+				'TKT_description' => array('LIKE', $sstr),
1180
+			);
1181
+		}
1182
+		$query_params = array(
1183
+			$_where,
1184
+			'order_by' => $orderby,
1185
+			'limit'    => $limit,
1186
+			'group_by' => 'TKT_ID',
1187
+		);
1188
+		if ($count) {
1189
+			return EEM_Ticket::instance()->count_deleted_and_undeleted(array($_where));
1190
+		} else {
1191
+			return EEM_Ticket::instance()->get_all_deleted_and_undeleted($query_params);
1192
+		}
1193
+	}
1194
+
1195
+
1196
+	/**
1197
+	 * @param bool $trash
1198
+	 * @throws EE_Error
1199
+	 */
1200
+	protected function _trash_or_restore_ticket($trash = false)
1201
+	{
1202
+		$success = 1;
1203
+		$TKT = EEM_Ticket::instance();
1204
+		// checkboxes?
1205
+		if (! empty($this->_req_data['checkbox']) && is_array($this->_req_data['checkbox'])) {
1206
+			// if array has more than one element then success message should be plural
1207
+			$success = count($this->_req_data['checkbox']) > 1 ? 2 : 1;
1208
+			// cycle thru the boxes
1209
+			while (list($TKT_ID, $value) = each($this->_req_data['checkbox'])) {
1210
+				if ($trash) {
1211
+					if (! $TKT->delete_by_ID($TKT_ID)) {
1212
+						$success = 0;
1213
+					}
1214
+				} else {
1215
+					if (! $TKT->restore_by_ID($TKT_ID)) {
1216
+						$success = 0;
1217
+					}
1218
+				}
1219
+			}
1220
+		} else {
1221
+			// grab single id and trash
1222
+			$TKT_ID = absint($this->_req_data['TKT_ID']);
1223
+			if ($trash) {
1224
+				if (! $TKT->delete_by_ID($TKT_ID)) {
1225
+					$success = 0;
1226
+				}
1227
+			} else {
1228
+				if (! $TKT->restore_by_ID($TKT_ID)) {
1229
+					$success = 0;
1230
+				}
1231
+			}
1232
+		}
1233
+		$action_desc = $trash ? 'moved to the trash' : 'restored';
1234
+		$query_args = array(
1235
+			'action' => 'ticket_list_table',
1236
+			'status' => $trash ? '' : 'trashed',
1237
+		);
1238
+		$this->_redirect_after_action($success, 'Tickets', $action_desc, $query_args);
1239
+	}
1240
+
1241
+
1242
+	/**
1243
+	 * Handles trashing default ticket.
1244
+	 */
1245
+	protected function _delete_ticket()
1246
+	{
1247
+		$success = 1;
1248
+		// checkboxes?
1249
+		if (! empty($this->_req_data['checkbox']) && is_array($this->_req_data['checkbox'])) {
1250
+			// if array has more than one element then success message should be plural
1251
+			$success = count($this->_req_data['checkbox']) > 1 ? 2 : 1;
1252
+			// cycle thru the boxes
1253
+			while (list($TKT_ID, $value) = each($this->_req_data['checkbox'])) {
1254
+				// delete
1255
+				if (! $this->_delete_the_ticket($TKT_ID)) {
1256
+					$success = 0;
1257
+				}
1258
+			}
1259
+		} else {
1260
+			// grab single id and trash
1261
+			$TKT_ID = absint($this->_req_data['TKT_ID']);
1262
+			if (! $this->_delete_the_ticket($TKT_ID)) {
1263
+				$success = 0;
1264
+			}
1265
+		}
1266
+		$action_desc = 'deleted';
1267
+		$query_args = array(
1268
+			'action' => 'ticket_list_table',
1269
+			'status' => 'trashed',
1270
+		);
1271
+		// fail safe.  If the default ticket count === 1 then we need to redirect to event overview.
1272
+		if (EEM_Ticket::instance()->count_deleted_and_undeleted(
1273
+			array(array('TKT_is_default' => 1)),
1274
+			'TKT_ID',
1275
+			true
1276
+		)
1277
+		) {
1278
+			$query_args = array();
1279
+		}
1280
+		$this->_redirect_after_action($success, 'Tickets', $action_desc, $query_args);
1281
+	}
1282
+
1283
+
1284
+	/**
1285
+	 * @param int $TKT_ID
1286
+	 * @return bool|int
1287
+	 * @throws EE_Error
1288
+	 */
1289
+	protected function _delete_the_ticket($TKT_ID)
1290
+	{
1291
+		$tkt = EEM_Ticket::instance()->get_one_by_ID($TKT_ID);
1292
+		$tkt->_remove_relations('Datetime');
1293
+		// delete all related prices first
1294
+		$tkt->delete_related_permanently('Price');
1295
+		return $tkt->delete_permanently();
1296
+	}
1297 1297
 }
Please login to merge, or discard this patch.
core/domain/entities/custom_post_types/CustomTaxonomyDefinitions.php 1 patch
Indentation   +131 added lines, -131 removed lines patch added patch discarded remove patch
@@ -15,145 +15,145 @@
 block discarded – undo
15 15
 class CustomTaxonomyDefinitions
16 16
 {
17 17
 
18
-    /**
19
-     * @var array $taxonomies
20
-     */
21
-    private $taxonomies;
18
+	/**
19
+	 * @var array $taxonomies
20
+	 */
21
+	private $taxonomies;
22 22
 
23 23
 
24
-    /**
25
-     * EspressoCustomPostTypeDefinitions constructor.
26
-     */
27
-    public function __construct()
28
-    {
29
-        $this->setTaxonomies();
30
-        add_filter('pre_term_description', array($this, 'filterCustomTermDescription'), 1, 2);
31
-    }
24
+	/**
25
+	 * EspressoCustomPostTypeDefinitions constructor.
26
+	 */
27
+	public function __construct()
28
+	{
29
+		$this->setTaxonomies();
30
+		add_filter('pre_term_description', array($this, 'filterCustomTermDescription'), 1, 2);
31
+	}
32 32
 
33 33
 
34
-    private function setTaxonomies()
35
-    {
36
-        $this->taxonomies = array(
37
-            'espresso_event_categories' => array(
38
-                'singular_name' => esc_html__('Event Category', 'event_espresso'),
39
-                'plural_name'   => esc_html__('Event Categories', 'event_espresso'),
40
-                'args'          => array(
41
-                    'public'            => true,
42
-                    'show_in_nav_menus' => true,
43
-                    'show_in_rest'      => true,
44
-                    'capabilities'      => array(
45
-                        'manage_terms' => 'ee_manage_event_categories',
46
-                        'edit_terms'   => 'ee_edit_event_category',
47
-                        'delete_terms' => 'ee_delete_event_category',
48
-                        'assign_terms' => 'ee_assign_event_category',
49
-                    ),
50
-                    'rewrite'           => array(
51
-                        'slug' => EEH_URL::slugify(
52
-                            __('event-category', 'event_espresso'),
53
-                            'event-category'
54
-                        )
55
-                    ),
56
-                ),
57
-            ),
58
-            'espresso_venue_categories' => array(
59
-                'singular_name' => esc_html__('Venue Category', 'event_espresso'),
60
-                'plural_name'   => esc_html__('Venue Categories', 'event_espresso'),
61
-                'args'          => array(
62
-                    'public'            => true,
63
-                    'show_in_nav_menus' => false, // by default this doesn't show for decaf
64
-                    'show_in_rest'      => true,
65
-                    'capabilities'      => array(
66
-                        'manage_terms' => 'ee_manage_venue_categories',
67
-                        'edit_terms'   => 'ee_edit_venue_category',
68
-                        'delete_terms' => 'ee_delete_venue_category',
69
-                        'assign_terms' => 'ee_assign_venue_category',
70
-                    ),
71
-                    'rewrite'           => array(
72
-                        'slug' => EEH_URL::slugify(
73
-                            __('venue-category', 'event_espresso'),
74
-                            'venue-category'
75
-                        )
76
-                    ),
77
-                ),
78
-            ),
79
-            'espresso_event_type'       => array(
80
-                'singular_name' => esc_html__('Event Type', 'event_espresso'),
81
-                'plural_name'   => esc_html__('Event Types', 'event_espresso'),
82
-                'args'          => array(
83
-                    'public'       => true,
84
-                    'show_ui'      => false,
85
-                    'show_in_rest' => true,
86
-                    'capabilities' => array(
87
-                        'manage_terms' => 'ee_read_event_type',
88
-                        'edit_terms'   => 'ee_edit_event_type',
89
-                        'delete_terms' => 'ee_delete_event_type',
90
-                        'assign_terms' => 'ee_assign_event_type',
91
-                    ),
92
-                    'rewrite'      => array(
93
-                        'slug' => EEH_URL::slugify(
94
-                            __('event-type', 'event_espresso'),
95
-                            'event-type'
96
-                        )
97
-                    ),
98
-                    'hierarchical' => true,
99
-                ),
100
-            ),
101
-        );
102
-    }
34
+	private function setTaxonomies()
35
+	{
36
+		$this->taxonomies = array(
37
+			'espresso_event_categories' => array(
38
+				'singular_name' => esc_html__('Event Category', 'event_espresso'),
39
+				'plural_name'   => esc_html__('Event Categories', 'event_espresso'),
40
+				'args'          => array(
41
+					'public'            => true,
42
+					'show_in_nav_menus' => true,
43
+					'show_in_rest'      => true,
44
+					'capabilities'      => array(
45
+						'manage_terms' => 'ee_manage_event_categories',
46
+						'edit_terms'   => 'ee_edit_event_category',
47
+						'delete_terms' => 'ee_delete_event_category',
48
+						'assign_terms' => 'ee_assign_event_category',
49
+					),
50
+					'rewrite'           => array(
51
+						'slug' => EEH_URL::slugify(
52
+							__('event-category', 'event_espresso'),
53
+							'event-category'
54
+						)
55
+					),
56
+				),
57
+			),
58
+			'espresso_venue_categories' => array(
59
+				'singular_name' => esc_html__('Venue Category', 'event_espresso'),
60
+				'plural_name'   => esc_html__('Venue Categories', 'event_espresso'),
61
+				'args'          => array(
62
+					'public'            => true,
63
+					'show_in_nav_menus' => false, // by default this doesn't show for decaf
64
+					'show_in_rest'      => true,
65
+					'capabilities'      => array(
66
+						'manage_terms' => 'ee_manage_venue_categories',
67
+						'edit_terms'   => 'ee_edit_venue_category',
68
+						'delete_terms' => 'ee_delete_venue_category',
69
+						'assign_terms' => 'ee_assign_venue_category',
70
+					),
71
+					'rewrite'           => array(
72
+						'slug' => EEH_URL::slugify(
73
+							__('venue-category', 'event_espresso'),
74
+							'venue-category'
75
+						)
76
+					),
77
+				),
78
+			),
79
+			'espresso_event_type'       => array(
80
+				'singular_name' => esc_html__('Event Type', 'event_espresso'),
81
+				'plural_name'   => esc_html__('Event Types', 'event_espresso'),
82
+				'args'          => array(
83
+					'public'       => true,
84
+					'show_ui'      => false,
85
+					'show_in_rest' => true,
86
+					'capabilities' => array(
87
+						'manage_terms' => 'ee_read_event_type',
88
+						'edit_terms'   => 'ee_edit_event_type',
89
+						'delete_terms' => 'ee_delete_event_type',
90
+						'assign_terms' => 'ee_assign_event_type',
91
+					),
92
+					'rewrite'      => array(
93
+						'slug' => EEH_URL::slugify(
94
+							__('event-type', 'event_espresso'),
95
+							'event-type'
96
+						)
97
+					),
98
+					'hierarchical' => true,
99
+				),
100
+			),
101
+		);
102
+	}
103 103
 
104 104
 
105
-    /**
106
-     * @return array
107
-     */
108
-    public function getCustomTaxonomyDefinitions()
109
-    {
110
-        return (array) apply_filters(
111
-            'FHEE__EventEspresso_core_domain_entities_custom_post_types_TaxonomyDefinitions__getTaxonomies',
112
-            // legacy filter applied for now,
113
-            // later on we'll run a has_filter($tag) check and throw a doing_it_wrong() notice
114
-            apply_filters(
115
-                'FHEE__EE_Register_CPTs__get_taxonomies__taxonomies',
116
-                $this->taxonomies
117
-            )
118
-        );
119
-    }
105
+	/**
106
+	 * @return array
107
+	 */
108
+	public function getCustomTaxonomyDefinitions()
109
+	{
110
+		return (array) apply_filters(
111
+			'FHEE__EventEspresso_core_domain_entities_custom_post_types_TaxonomyDefinitions__getTaxonomies',
112
+			// legacy filter applied for now,
113
+			// later on we'll run a has_filter($tag) check and throw a doing_it_wrong() notice
114
+			apply_filters(
115
+				'FHEE__EE_Register_CPTs__get_taxonomies__taxonomies',
116
+				$this->taxonomies
117
+			)
118
+		);
119
+	}
120 120
 
121 121
 
122
-    /**
123
-     * @return array
124
-     */
125
-    public function getCustomTaxonomySlugs()
126
-    {
127
-        return array_keys($this->getCustomTaxonomyDefinitions());
128
-    }
122
+	/**
123
+	 * @return array
124
+	 */
125
+	public function getCustomTaxonomySlugs()
126
+	{
127
+		return array_keys($this->getCustomTaxonomyDefinitions());
128
+	}
129 129
 
130 130
 
131
-    /**
132
-     * By default, WordPress strips all html from term taxonomy description content.
133
-     * The purpose of this method is to remove that restriction
134
-     * and ensure that we still run ee term taxonomy descriptions
135
-     * through some full html sanitization equivalent to the post content field.
136
-     * So first we remove default filter for term description
137
-     * but we have to do this earlier before wp sets their own filter
138
-     * because they just set a global filter on all term descriptions
139
-     * before the custom term description filter.
140
-     * Really sux.
141
-     *
142
-     * @param string $description The description content.
143
-     * @param string $taxonomy    The taxonomy name for the taxonomy being filtered.
144
-     * @return string
145
-     */
146
-    public function filterCustomTermDescription($description, $taxonomy)
147
-    {
148
-        // get a list of EE taxonomies
149
-        $custom_taxonomies = $this->getCustomTaxonomySlugs();
150
-        // only do our own thing if the taxonomy listed is an ee taxonomy.
151
-        if (in_array($taxonomy, $custom_taxonomies, true)) {
152
-            // remove default wp filter
153
-            remove_filter('pre_term_description', 'wp_filter_kses');
154
-            // sanitize THIS content.
155
-            $description = wp_kses($description, wp_kses_allowed_html('post'));
156
-        }
157
-        return $description;
158
-    }
131
+	/**
132
+	 * By default, WordPress strips all html from term taxonomy description content.
133
+	 * The purpose of this method is to remove that restriction
134
+	 * and ensure that we still run ee term taxonomy descriptions
135
+	 * through some full html sanitization equivalent to the post content field.
136
+	 * So first we remove default filter for term description
137
+	 * but we have to do this earlier before wp sets their own filter
138
+	 * because they just set a global filter on all term descriptions
139
+	 * before the custom term description filter.
140
+	 * Really sux.
141
+	 *
142
+	 * @param string $description The description content.
143
+	 * @param string $taxonomy    The taxonomy name for the taxonomy being filtered.
144
+	 * @return string
145
+	 */
146
+	public function filterCustomTermDescription($description, $taxonomy)
147
+	{
148
+		// get a list of EE taxonomies
149
+		$custom_taxonomies = $this->getCustomTaxonomySlugs();
150
+		// only do our own thing if the taxonomy listed is an ee taxonomy.
151
+		if (in_array($taxonomy, $custom_taxonomies, true)) {
152
+			// remove default wp filter
153
+			remove_filter('pre_term_description', 'wp_filter_kses');
154
+			// sanitize THIS content.
155
+			$description = wp_kses($description, wp_kses_allowed_html('post'));
156
+		}
157
+		return $description;
158
+	}
159 159
 }
Please login to merge, or discard this patch.
core/db_models/fields/EE_Money_Field.php 1 patch
Indentation   +78 added lines, -78 removed lines patch added patch discarded remove patch
@@ -7,92 +7,92 @@
 block discarded – undo
7 7
 class EE_Money_Field extends EE_Float_Field
8 8
 {
9 9
 
10
-    /**
11
-     * @param string $table_column
12
-     * @param string $nicename
13
-     * @param bool   $nullable
14
-     * @param null   $default_value
15
-     */
16
-    public function __construct($table_column, $nicename, $nullable, $default_value = null)
17
-    {
18
-        parent::__construct($table_column, $nicename, $nullable, $default_value);
19
-        $this->setSchemaType('object');
20
-    }
10
+	/**
11
+	 * @param string $table_column
12
+	 * @param string $nicename
13
+	 * @param bool   $nullable
14
+	 * @param null   $default_value
15
+	 */
16
+	public function __construct($table_column, $nicename, $nullable, $default_value = null)
17
+	{
18
+		parent::__construct($table_column, $nicename, $nullable, $default_value);
19
+		$this->setSchemaType('object');
20
+	}
21 21
 
22 22
 
23
-    /**
24
-     * Schemas:
25
-     *    'localized_float': "3,023.00"
26
-     *    'no_currency_code': "$3,023.00"
27
-     *    null: "$3,023.00<span>USD</span>"
28
-     *
29
-     * @param string $value_on_field_to_be_outputted
30
-     * @param string $schema
31
-     * @return string
32
-     */
33
-    public function prepare_for_pretty_echoing($value_on_field_to_be_outputted, $schema = null)
34
-    {
35
-        $pretty_float = parent::prepare_for_pretty_echoing($value_on_field_to_be_outputted);
23
+	/**
24
+	 * Schemas:
25
+	 *    'localized_float': "3,023.00"
26
+	 *    'no_currency_code': "$3,023.00"
27
+	 *    null: "$3,023.00<span>USD</span>"
28
+	 *
29
+	 * @param string $value_on_field_to_be_outputted
30
+	 * @param string $schema
31
+	 * @return string
32
+	 */
33
+	public function prepare_for_pretty_echoing($value_on_field_to_be_outputted, $schema = null)
34
+	{
35
+		$pretty_float = parent::prepare_for_pretty_echoing($value_on_field_to_be_outputted);
36 36
 
37
-        if ($schema == 'localized_float') {
38
-            return $pretty_float;
39
-        }
40
-        if ($schema == 'no_currency_code') {
37
+		if ($schema == 'localized_float') {
38
+			return $pretty_float;
39
+		}
40
+		if ($schema == 'no_currency_code') {
41 41
 //          echo "schema no currency!";
42
-            $display_code = false;
43
-        } else {
44
-            $display_code = true;
45
-        }
46
-        // we don't use the $pretty_float because format_currency will take care of it.
47
-        return EEH_Template::format_currency($value_on_field_to_be_outputted, false, $display_code);
48
-    }
42
+			$display_code = false;
43
+		} else {
44
+			$display_code = true;
45
+		}
46
+		// we don't use the $pretty_float because format_currency will take care of it.
47
+		return EEH_Template::format_currency($value_on_field_to_be_outputted, false, $display_code);
48
+	}
49 49
 
50
-    /**
51
-     * If provided with a string, strips out money-related formatting to turn it into a proper float.
52
-     * Rounds the float to the correct number of decimal places for this country's currency.
53
-     * Also, interprets periods and commas according to the country's currency settings.
54
-     * So if you want to pass in a string that NEEDS to interpret periods as decimal marks, call floatval() on it first.
55
-     *
56
-     * @param string $value_inputted_for_field_on_model_object
57
-     * @return float
58
-     */
59
-    public function prepare_for_set($value_inputted_for_field_on_model_object)
60
-    {
61
-        // remove any currencies etc.
50
+	/**
51
+	 * If provided with a string, strips out money-related formatting to turn it into a proper float.
52
+	 * Rounds the float to the correct number of decimal places for this country's currency.
53
+	 * Also, interprets periods and commas according to the country's currency settings.
54
+	 * So if you want to pass in a string that NEEDS to interpret periods as decimal marks, call floatval() on it first.
55
+	 *
56
+	 * @param string $value_inputted_for_field_on_model_object
57
+	 * @return float
58
+	 */
59
+	public function prepare_for_set($value_inputted_for_field_on_model_object)
60
+	{
61
+		// remove any currencies etc.
62 62
 //      if(is_string($value_inputted_for_field_on_model_object)){
63 63
 //          $value_inputted_for_field_on_model_object = preg_replace("/[^0-9,.]/", "", $value_inputted_for_field_on_model_object);
64 64
 //      }
65
-        // now it's a float-style string or number
66
-        $float_val = parent::prepare_for_set($value_inputted_for_field_on_model_object);
67
-        // round to the correctly number of decimal places for this  currency
68
-        $rounded_value = round($float_val, EE_Registry::instance()->CFG->currency->dec_plc);
69
-        return $rounded_value;
70
-    }
65
+		// now it's a float-style string or number
66
+		$float_val = parent::prepare_for_set($value_inputted_for_field_on_model_object);
67
+		// round to the correctly number of decimal places for this  currency
68
+		$rounded_value = round($float_val, EE_Registry::instance()->CFG->currency->dec_plc);
69
+		return $rounded_value;
70
+	}
71 71
 
72
-    public function prepare_for_get($value_of_field_on_model_object)
73
-    {
74
-        $c = EE_Registry::instance()->CFG->currency;
75
-        return round(parent::prepare_for_get($value_of_field_on_model_object), $c->dec_plc);
76
-    }
72
+	public function prepare_for_get($value_of_field_on_model_object)
73
+	{
74
+		$c = EE_Registry::instance()->CFG->currency;
75
+		return round(parent::prepare_for_get($value_of_field_on_model_object), $c->dec_plc);
76
+	}
77 77
 
78
-    public function getSchemaProperties()
79
-    {
80
-        return array(
81
-            'raw' => array(
82
-                'description' =>  sprintf(
83
-                    __('%s - the raw value as it exists in the database as a simple float.', 'event_espresso'),
84
-                    $this->get_nicename()
85
-                ),
86
-                'type' => 'number',
87
-            ),
88
-            'pretty' => array(
89
-                'description' =>  sprintf(
90
-                    __('%s - formatted for display in the set currency and decimal places.', 'event_espresso'),
91
-                    $this->get_nicename()
92
-                ),
93
-                'type' => 'string',
94
-                'format' => 'money'
95
-            )
96
-        );
97
-    }
78
+	public function getSchemaProperties()
79
+	{
80
+		return array(
81
+			'raw' => array(
82
+				'description' =>  sprintf(
83
+					__('%s - the raw value as it exists in the database as a simple float.', 'event_espresso'),
84
+					$this->get_nicename()
85
+				),
86
+				'type' => 'number',
87
+			),
88
+			'pretty' => array(
89
+				'description' =>  sprintf(
90
+					__('%s - formatted for display in the set currency and decimal places.', 'event_espresso'),
91
+					$this->get_nicename()
92
+				),
93
+				'type' => 'string',
94
+				'format' => 'money'
95
+			)
96
+		);
97
+	}
98 98
 }
Please login to merge, or discard this patch.
core/db_models/fields/EE_Datetime_Field.php 2 patches
Doc Comments   +3 added lines, -3 removed lines patch added patch discarded remove patch
@@ -560,7 +560,7 @@  discard block
 block discarded – undo
560 560
      * allowed)
561 561
      *
562 562
      * @param string $datetime_string mysql timestamp in UTC
563
-     * @return  mixed null | DateTime
563
+     * @return  null|DbSafeDateTime null | DateTime
564 564
      * @throws \EE_Error
565 565
      */
566 566
     public function prepare_for_set_from_db($datetime_string)
@@ -712,7 +712,7 @@  discard block
 block discarded – undo
712 712
      *
713 713
      * @param \DateTimeZone $DateTimeZone
714 714
      * @param int           $time
715
-     * @return mixed
715
+     * @return integer
716 716
      * @throws \DomainException
717 717
      */
718 718
     public function get_timezone_offset(DateTimeZone $DateTimeZone, $time = null)
@@ -753,7 +753,7 @@  discard block
 block discarded – undo
753 753
     /**
754 754
      * Gets the default datetime object from the field's default time
755 755
      * @since 4.9.66.p
756
-     * @return DbSafeDateTime|null
756
+     * @return DateTime|null
757 757
      * @throws InvalidArgumentException
758 758
      * @throws InvalidDataTypeException
759 759
      * @throws InvalidInterfaceException
Please login to merge, or discard this patch.
Indentation   +764 added lines, -764 removed lines patch added patch discarded remove patch
@@ -15,769 +15,769 @@
 block discarded – undo
15 15
 class EE_Datetime_Field extends EE_Model_Field_Base
16 16
 {
17 17
 
18
-    /**
19
-     * The pattern we're looking for is if only the characters 0-9 are found and there are only
20
-     * 10 or more numbers (because 9 numbers even with all 9's would be sometime in 2001 )
21
-     *
22
-     * @type string unix_timestamp_regex
23
-     */
24
-    const unix_timestamp_regex = '/[0-9]{10,}/';
25
-
26
-    /**
27
-     * @type string mysql_timestamp_format
28
-     */
29
-    const mysql_timestamp_format = 'Y-m-d H:i:s';
30
-
31
-    /**
32
-     * @type string mysql_date_format
33
-     */
34
-    const mysql_date_format = 'Y-m-d';
35
-
36
-    /**
37
-     * @type string mysql_time_format
38
-     */
39
-    const mysql_time_format = 'H:i:s';
40
-
41
-    /**
42
-     * Const for using in the default value. If the field's default is set to this,
43
-     * then we will return the time of calling `get_default_value()`, not
44
-     * just the current time at construction
45
-     */
46
-    const now = 'now';
47
-
48
-    /**
49
-     * The following properties hold the default formats for date and time.
50
-     * Defaults are set via the constructor and can be overridden on class instantiation.
51
-     * However they can also be overridden later by the set_format() method
52
-     * (and corresponding set_date_format, set_time_format methods);
53
-     */
54
-    /**
55
-     * @type string $_date_format
56
-     */
57
-    protected $_date_format = '';
58
-
59
-    /**
60
-     * @type string $_time_format
61
-     */
62
-    protected $_time_format = '';
63
-
64
-    /**
65
-     * @type string $_pretty_date_format
66
-     */
67
-    protected $_pretty_date_format = '';
68
-
69
-    /**
70
-     * @type string $_pretty_time_format
71
-     */
72
-    protected $_pretty_time_format = '';
73
-
74
-    /**
75
-     * @type DateTimeZone $_DateTimeZone
76
-     */
77
-    protected $_DateTimeZone;
78
-
79
-    /**
80
-     * @type DateTimeZone $_UTC_DateTimeZone
81
-     */
82
-    protected $_UTC_DateTimeZone;
83
-
84
-    /**
85
-     * @type DateTimeZone $_blog_DateTimeZone
86
-     */
87
-    protected $_blog_DateTimeZone;
88
-
89
-
90
-    /**
91
-     * This property holds how we want the output returned when getting a datetime string.  It is set for the
92
-     * set_date_time_output() method.  By default this is empty.  When empty, we are assuming that we want both date
93
-     * and time returned via getters.
94
-     *
95
-     * @var mixed (null|string)
96
-     */
97
-    protected $_date_time_output;
98
-
99
-
100
-    /**
101
-     * timezone string
102
-     * This gets set by the constructor and can be changed by the "set_timezone()" method so that we know what timezone
103
-     * incoming strings|timestamps are in.  This can also be used before a get to set what timezone you want strings
104
-     * coming out of the object to be in.  Default timezone is the current WP timezone option setting
105
-     *
106
-     * @var string
107
-     */
108
-    protected $_timezone_string;
109
-
110
-
111
-    /**
112
-     * This holds whatever UTC offset for the blog (we automatically convert timezone strings into their related
113
-     * offsets for comparison purposes).
114
-     *
115
-     * @var int
116
-     */
117
-    protected $_blog_offset;
118
-
119
-
120
-
121
-    /**
122
-     * @param string $table_column
123
-     * @param string $nice_name
124
-     * @param bool   $nullable
125
-     * @param string $default_value
126
-     * @param string $timezone_string
127
-     * @param string $date_format
128
-     * @param string $time_format
129
-     * @param string $pretty_date_format
130
-     * @param string $pretty_time_format
131
-     * @throws EE_Error
132
-     * @throws InvalidArgumentException
133
-     */
134
-    public function __construct(
135
-        $table_column,
136
-        $nice_name,
137
-        $nullable,
138
-        $default_value,
139
-        $timezone_string = '',
140
-        $date_format = '',
141
-        $time_format = '',
142
-        $pretty_date_format = '',
143
-        $pretty_time_format = ''
144
-    ) {
145
-
146
-        $this->_date_format        = ! empty($date_format) ? $date_format : get_option('date_format');
147
-        $this->_time_format        = ! empty($time_format) ? $time_format : get_option('time_format');
148
-        $this->_pretty_date_format = ! empty($pretty_date_format) ? $pretty_date_format : get_option('date_format');
149
-        $this->_pretty_time_format = ! empty($pretty_time_format) ? $pretty_time_format : get_option('time_format');
150
-
151
-        parent::__construct($table_column, $nice_name, $nullable, $default_value);
152
-        $this->set_timezone($timezone_string);
153
-        $this->setSchemaFormat('date-time');
154
-    }
155
-
156
-
157
-    /**
158
-     * @return DateTimeZone
159
-     * @throws \EE_Error
160
-     */
161
-    public function get_UTC_DateTimeZone()
162
-    {
163
-        return $this->_UTC_DateTimeZone instanceof DateTimeZone
164
-            ? $this->_UTC_DateTimeZone
165
-            : $this->_create_timezone_object_from_timezone_string('UTC');
166
-    }
167
-
168
-
169
-    /**
170
-     * @return DateTimeZone
171
-     * @throws \EE_Error
172
-     */
173
-    public function get_blog_DateTimeZone()
174
-    {
175
-        return $this->_blog_DateTimeZone instanceof DateTimeZone
176
-            ? $this->_blog_DateTimeZone
177
-            : $this->_create_timezone_object_from_timezone_string('');
178
-    }
179
-
180
-
181
-    /**
182
-     * this prepares any incoming date data and make sure its converted to a utc unix timestamp
183
-     *
184
-     * @param  string|int $value_inputted_for_field_on_model_object could be a string formatted date time or int unix
185
-     *                                                              timestamp
186
-     * @return DateTime
187
-     */
188
-    public function prepare_for_set($value_inputted_for_field_on_model_object)
189
-    {
190
-        return $this->_get_date_object($value_inputted_for_field_on_model_object);
191
-    }
192
-
193
-
194
-    /**
195
-     * This returns the format string to be used by getters depending on what the $_date_time_output property is set at.
196
-     * getters need to know whether we're just returning the date or the time or both.  By default we return both.
197
-     *
198
-     * @param bool $pretty If we're returning the pretty formats or standard format string.
199
-     * @return string    The final assembled format string.
200
-     */
201
-    protected function _get_date_time_output($pretty = false)
202
-    {
203
-
204
-        switch ($this->_date_time_output) {
205
-            case 'time':
206
-                return $pretty ? $this->_pretty_time_format : $this->_time_format;
207
-                break;
208
-
209
-            case 'date':
210
-                return $pretty ? $this->_pretty_date_format : $this->_date_format;
211
-                break;
212
-
213
-            default:
214
-                return $pretty
215
-                    ? $this->_pretty_date_format . ' ' . $this->_pretty_time_format
216
-                    : $this->_date_format . ' ' . $this->_time_format;
217
-        }
218
-    }
219
-
220
-
221
-    /**
222
-     * This just sets the $_date_time_output property so we can flag how date and times are formatted before being
223
-     * returned (using the format properties)
224
-     *
225
-     * @param string $what acceptable values are 'time' or 'date'.
226
-     *                     Any other value will be set but will always result
227
-     *                     in both 'date' and 'time' being returned.
228
-     * @return void
229
-     */
230
-    public function set_date_time_output($what = null)
231
-    {
232
-        $this->_date_time_output = $what;
233
-    }
234
-
235
-
236
-    /**
237
-     * See $_timezone property for description of what the timezone property is for.  This SETS the timezone internally
238
-     * for being able to reference what timezone we are running conversions on when converting TO the internal timezone
239
-     * (UTC Unix Timestamp) for the object OR when converting FROM the internal timezone (UTC Unix Timestamp).
240
-     * We also set some other properties in this method.
241
-     *
242
-     * @param string $timezone_string A valid timezone string as described by @link
243
-     *                                http://www.php.net/manual/en/timezones.php
244
-     * @return void
245
-     * @throws InvalidArgumentException
246
-     * @throws InvalidDataTypeException
247
-     * @throws InvalidInterfaceException
248
-     */
249
-    public function set_timezone($timezone_string)
250
-    {
251
-        if (empty($timezone_string) && $this->_timezone_string !== null) {
252
-            // leave the timezone AS-IS if we already have one and
253
-            // the function arg didn't provide one
254
-            return;
255
-        }
256
-        $timezone_string        = EEH_DTT_Helper::get_valid_timezone_string($timezone_string);
257
-        $this->_timezone_string = ! empty($timezone_string) ? $timezone_string : 'UTC';
258
-        $this->_DateTimeZone    = $this->_create_timezone_object_from_timezone_string($this->_timezone_string);
259
-    }
260
-
261
-
262
-    /**
263
-     * _create_timezone_object_from_timezone_name
264
-     *
265
-     * @access protected
266
-     * @param string $timezone_string
267
-     * @return \DateTimeZone
268
-     * @throws InvalidArgumentException
269
-     * @throws InvalidDataTypeException
270
-     * @throws InvalidInterfaceException
271
-     */
272
-    protected function _create_timezone_object_from_timezone_string($timezone_string = '')
273
-    {
274
-        return new DateTimeZone(EEH_DTT_Helper::get_valid_timezone_string($timezone_string));
275
-    }
276
-
277
-
278
-    /**
279
-     * This just returns whatever is set for the current timezone.
280
-     *
281
-     * @access public
282
-     * @return string timezone string
283
-     */
284
-    public function get_timezone()
285
-    {
286
-        return $this->_timezone_string;
287
-    }
288
-
289
-
290
-    /**
291
-     * set the $_date_format property
292
-     *
293
-     * @access public
294
-     * @param string $format a new date format (corresponding to formats accepted by PHP date() function)
295
-     * @param bool   $pretty Whether to set pretty format or not.
296
-     * @return void
297
-     */
298
-    public function set_date_format($format, $pretty = false)
299
-    {
300
-        if ($pretty) {
301
-            $this->_pretty_date_format = $format;
302
-        } else {
303
-            $this->_date_format = $format;
304
-        }
305
-    }
306
-
307
-
308
-    /**
309
-     * return the $_date_format property value.
310
-     *
311
-     * @param bool $pretty Whether to get pretty format or not.
312
-     * @return string
313
-     */
314
-    public function get_date_format($pretty = false)
315
-    {
316
-        return $pretty ? $this->_pretty_date_format : $this->_date_format;
317
-    }
318
-
319
-
320
-    /**
321
-     * set the $_time_format property
322
-     *
323
-     * @access public
324
-     * @param string $format a new time format (corresponding to formats accepted by PHP date() function)
325
-     * @param bool   $pretty Whether to set pretty format or not.
326
-     * @return void
327
-     */
328
-    public function set_time_format($format, $pretty = false)
329
-    {
330
-        if ($pretty) {
331
-            $this->_pretty_time_format = $format;
332
-        } else {
333
-            $this->_time_format = $format;
334
-        }
335
-    }
336
-
337
-
338
-    /**
339
-     * return the $_time_format property value.
340
-     *
341
-     * @param bool $pretty Whether to get pretty format or not.
342
-     * @return string
343
-     */
344
-    public function get_time_format($pretty = false)
345
-    {
346
-        return $pretty ? $this->_pretty_time_format : $this->_time_format;
347
-    }
348
-
349
-
350
-    /**
351
-     * set the $_pretty_date_format property
352
-     *
353
-     * @access public
354
-     * @param string $format a new pretty date format (corresponding to formats accepted by PHP date() function)
355
-     * @return void
356
-     */
357
-    public function set_pretty_date_format($format)
358
-    {
359
-        $this->_pretty_date_format = $format;
360
-    }
361
-
362
-
363
-    /**
364
-     * set the $_pretty_time_format property
365
-     *
366
-     * @access public
367
-     * @param string $format a new pretty time format (corresponding to formats accepted by PHP date() function)
368
-     * @return void
369
-     */
370
-    public function set_pretty_time_format($format)
371
-    {
372
-        $this->_pretty_time_format = $format;
373
-    }
374
-
375
-
376
-    /**
377
-     * Only sets the time portion of the datetime.
378
-     *
379
-     * @param string|DateTime $time_to_set_string like 8am OR a DateTime object.
380
-     * @param DateTime        $current            current DateTime object for the datetime field
381
-     * @return DateTime
382
-     */
383
-    public function prepare_for_set_with_new_time($time_to_set_string, DateTime $current)
384
-    {
385
-        // if $time_to_set_string is datetime object, then let's use it to set the parse array.
386
-        // Otherwise parse the string.
387
-        if ($time_to_set_string instanceof DateTime) {
388
-            $parsed = array(
389
-                'hour'   => $time_to_set_string->format('H'),
390
-                'minute' => $time_to_set_string->format('i'),
391
-                'second' => $time_to_set_string->format('s'),
392
-            );
393
-        } else {
394
-            // parse incoming string
395
-            $parsed = date_parse_from_format($this->_time_format, $time_to_set_string);
396
-        }
397
-        EEH_DTT_Helper::setTimezone($current, $this->_DateTimeZone);
398
-        return $current->setTime($parsed['hour'], $parsed['minute'], $parsed['second']);
399
-    }
400
-
401
-
402
-    /**
403
-     * Only sets the date portion of the datetime.
404
-     *
405
-     * @param string|DateTime $date_to_set_string like Friday, January 8th or a DateTime object.
406
-     * @param DateTime        $current            current DateTime object for the datetime field
407
-     * @return DateTime
408
-     */
409
-    public function prepare_for_set_with_new_date($date_to_set_string, DateTime $current)
410
-    {
411
-        // if $time_to_set_string is datetime object, then let's use it to set the parse array.
412
-        // Otherwise parse the string.
413
-        if ($date_to_set_string instanceof DateTime) {
414
-            $parsed = array(
415
-                'year'  => $date_to_set_string->format('Y'),
416
-                'month' => $date_to_set_string->format('m'),
417
-                'day'   => $date_to_set_string->format('d'),
418
-            );
419
-        } else {
420
-            // parse incoming string
421
-            $parsed = date_parse_from_format($this->_date_format, $date_to_set_string);
422
-        }
423
-        EEH_DTT_Helper::setTimezone($current, $this->_DateTimeZone);
424
-        return $current->setDate($parsed['year'], $parsed['month'], $parsed['day']);
425
-    }
426
-
427
-
428
-    /**
429
-     * This prepares the EE_DateTime value to be saved to the db as mysql timestamp (UTC +0 timezone).  When the
430
-     * datetime gets to this stage it should ALREADY be in UTC time
431
-     *
432
-     * @param  DateTime $DateTime
433
-     * @return string formatted date time for given timezone
434
-     * @throws \EE_Error
435
-     */
436
-    public function prepare_for_get($DateTime)
437
-    {
438
-        return $this->_prepare_for_display($DateTime);
439
-    }
440
-
441
-
442
-    /**
443
-     * This differs from prepare_for_get in that it considers whether the internal $_timezone differs
444
-     * from the set wp timezone.  If so, then it returns the datetime string formatted via
445
-     * _pretty_date_format, and _pretty_time_format.  However, it also appends a timezone
446
-     * abbreviation to the date_string.
447
-     *
448
-     * @param mixed $DateTime
449
-     * @param null  $schema
450
-     * @return string
451
-     * @throws \EE_Error
452
-     */
453
-    public function prepare_for_pretty_echoing($DateTime, $schema = null)
454
-    {
455
-        return $this->_prepare_for_display($DateTime, $schema ? $schema : true);
456
-    }
457
-
458
-
459
-    /**
460
-     * This prepares the EE_DateTime value to be saved to the db as mysql timestamp (UTC +0
461
-     * timezone).
462
-     *
463
-     * @param DateTime    $DateTime
464
-     * @param bool|string $schema
465
-     * @return string
466
-     * @throws \EE_Error
467
-     */
468
-    protected function _prepare_for_display($DateTime, $schema = false)
469
-    {
470
-        if (! $DateTime instanceof DateTime) {
471
-            if ($this->_nullable) {
472
-                return '';
473
-            } else {
474
-                if (WP_DEBUG) {
475
-                    throw new EE_Error(
476
-                        sprintf(
477
-                            __(
478
-                                'EE_Datetime_Field::_prepare_for_display requires a DateTime class to be the value for the $DateTime argument because the %s field is not nullable.',
479
-                                'event_espresso'
480
-                            ),
481
-                            $this->_nicename
482
-                        )
483
-                    );
484
-                } else {
485
-                    $DateTime = new DbSafeDateTime(\EE_Datetime_Field::now);
486
-                    EE_Error::add_error(
487
-                        sprintf(
488
-                            __(
489
-                                'EE_Datetime_Field::_prepare_for_display requires a DateTime class to be the value for the $DateTime argument because the %s field is not nullable.  When WP_DEBUG is false, the value is set to "now" instead of throwing an exception.',
490
-                                'event_espresso'
491
-                            ),
492
-                            $this->_nicename
493
-                        )
494
-                    );
495
-                }
496
-            }
497
-        }
498
-        $format_string = $this->_get_date_time_output($schema);
499
-        EEH_DTT_Helper::setTimezone($DateTime, $this->_DateTimeZone);
500
-        if ($schema) {
501
-            if ($this->_display_timezone()) {
502
-                // must be explicit because schema could equal true.
503
-                if ($schema === 'no_html') {
504
-                    $timezone_string = ' (' . $DateTime->format('T') . ')';
505
-                } else {
506
-                    $timezone_string = ' <span class="ee_dtt_timezone_string">(' . $DateTime->format('T') . ')</span>';
507
-                }
508
-            } else {
509
-                $timezone_string = '';
510
-            }
511
-
512
-            return $DateTime->format($format_string) . $timezone_string;
513
-        }
514
-        return $DateTime->format($format_string);
515
-    }
516
-
517
-
518
-    /**
519
-     * This prepares the EE_DateTime value to be saved to the db as mysql timestamp (UTC +0
520
-     * timezone).
521
-     *
522
-     * @param  mixed $datetime_value u
523
-     * @return string mysql timestamp in UTC
524
-     * @throws \EE_Error
525
-     */
526
-    public function prepare_for_use_in_db($datetime_value)
527
-    {
528
-        // we allow an empty value or DateTime object, but nothing else.
529
-        if (! empty($datetime_value) && ! $datetime_value instanceof DateTime) {
530
-            throw new EE_Error(
531
-                sprintf(
532
-                    __(
533
-                        'The incoming value being prepared for setting in the database must either be empty or a php 
18
+	/**
19
+	 * The pattern we're looking for is if only the characters 0-9 are found and there are only
20
+	 * 10 or more numbers (because 9 numbers even with all 9's would be sometime in 2001 )
21
+	 *
22
+	 * @type string unix_timestamp_regex
23
+	 */
24
+	const unix_timestamp_regex = '/[0-9]{10,}/';
25
+
26
+	/**
27
+	 * @type string mysql_timestamp_format
28
+	 */
29
+	const mysql_timestamp_format = 'Y-m-d H:i:s';
30
+
31
+	/**
32
+	 * @type string mysql_date_format
33
+	 */
34
+	const mysql_date_format = 'Y-m-d';
35
+
36
+	/**
37
+	 * @type string mysql_time_format
38
+	 */
39
+	const mysql_time_format = 'H:i:s';
40
+
41
+	/**
42
+	 * Const for using in the default value. If the field's default is set to this,
43
+	 * then we will return the time of calling `get_default_value()`, not
44
+	 * just the current time at construction
45
+	 */
46
+	const now = 'now';
47
+
48
+	/**
49
+	 * The following properties hold the default formats for date and time.
50
+	 * Defaults are set via the constructor and can be overridden on class instantiation.
51
+	 * However they can also be overridden later by the set_format() method
52
+	 * (and corresponding set_date_format, set_time_format methods);
53
+	 */
54
+	/**
55
+	 * @type string $_date_format
56
+	 */
57
+	protected $_date_format = '';
58
+
59
+	/**
60
+	 * @type string $_time_format
61
+	 */
62
+	protected $_time_format = '';
63
+
64
+	/**
65
+	 * @type string $_pretty_date_format
66
+	 */
67
+	protected $_pretty_date_format = '';
68
+
69
+	/**
70
+	 * @type string $_pretty_time_format
71
+	 */
72
+	protected $_pretty_time_format = '';
73
+
74
+	/**
75
+	 * @type DateTimeZone $_DateTimeZone
76
+	 */
77
+	protected $_DateTimeZone;
78
+
79
+	/**
80
+	 * @type DateTimeZone $_UTC_DateTimeZone
81
+	 */
82
+	protected $_UTC_DateTimeZone;
83
+
84
+	/**
85
+	 * @type DateTimeZone $_blog_DateTimeZone
86
+	 */
87
+	protected $_blog_DateTimeZone;
88
+
89
+
90
+	/**
91
+	 * This property holds how we want the output returned when getting a datetime string.  It is set for the
92
+	 * set_date_time_output() method.  By default this is empty.  When empty, we are assuming that we want both date
93
+	 * and time returned via getters.
94
+	 *
95
+	 * @var mixed (null|string)
96
+	 */
97
+	protected $_date_time_output;
98
+
99
+
100
+	/**
101
+	 * timezone string
102
+	 * This gets set by the constructor and can be changed by the "set_timezone()" method so that we know what timezone
103
+	 * incoming strings|timestamps are in.  This can also be used before a get to set what timezone you want strings
104
+	 * coming out of the object to be in.  Default timezone is the current WP timezone option setting
105
+	 *
106
+	 * @var string
107
+	 */
108
+	protected $_timezone_string;
109
+
110
+
111
+	/**
112
+	 * This holds whatever UTC offset for the blog (we automatically convert timezone strings into their related
113
+	 * offsets for comparison purposes).
114
+	 *
115
+	 * @var int
116
+	 */
117
+	protected $_blog_offset;
118
+
119
+
120
+
121
+	/**
122
+	 * @param string $table_column
123
+	 * @param string $nice_name
124
+	 * @param bool   $nullable
125
+	 * @param string $default_value
126
+	 * @param string $timezone_string
127
+	 * @param string $date_format
128
+	 * @param string $time_format
129
+	 * @param string $pretty_date_format
130
+	 * @param string $pretty_time_format
131
+	 * @throws EE_Error
132
+	 * @throws InvalidArgumentException
133
+	 */
134
+	public function __construct(
135
+		$table_column,
136
+		$nice_name,
137
+		$nullable,
138
+		$default_value,
139
+		$timezone_string = '',
140
+		$date_format = '',
141
+		$time_format = '',
142
+		$pretty_date_format = '',
143
+		$pretty_time_format = ''
144
+	) {
145
+
146
+		$this->_date_format        = ! empty($date_format) ? $date_format : get_option('date_format');
147
+		$this->_time_format        = ! empty($time_format) ? $time_format : get_option('time_format');
148
+		$this->_pretty_date_format = ! empty($pretty_date_format) ? $pretty_date_format : get_option('date_format');
149
+		$this->_pretty_time_format = ! empty($pretty_time_format) ? $pretty_time_format : get_option('time_format');
150
+
151
+		parent::__construct($table_column, $nice_name, $nullable, $default_value);
152
+		$this->set_timezone($timezone_string);
153
+		$this->setSchemaFormat('date-time');
154
+	}
155
+
156
+
157
+	/**
158
+	 * @return DateTimeZone
159
+	 * @throws \EE_Error
160
+	 */
161
+	public function get_UTC_DateTimeZone()
162
+	{
163
+		return $this->_UTC_DateTimeZone instanceof DateTimeZone
164
+			? $this->_UTC_DateTimeZone
165
+			: $this->_create_timezone_object_from_timezone_string('UTC');
166
+	}
167
+
168
+
169
+	/**
170
+	 * @return DateTimeZone
171
+	 * @throws \EE_Error
172
+	 */
173
+	public function get_blog_DateTimeZone()
174
+	{
175
+		return $this->_blog_DateTimeZone instanceof DateTimeZone
176
+			? $this->_blog_DateTimeZone
177
+			: $this->_create_timezone_object_from_timezone_string('');
178
+	}
179
+
180
+
181
+	/**
182
+	 * this prepares any incoming date data and make sure its converted to a utc unix timestamp
183
+	 *
184
+	 * @param  string|int $value_inputted_for_field_on_model_object could be a string formatted date time or int unix
185
+	 *                                                              timestamp
186
+	 * @return DateTime
187
+	 */
188
+	public function prepare_for_set($value_inputted_for_field_on_model_object)
189
+	{
190
+		return $this->_get_date_object($value_inputted_for_field_on_model_object);
191
+	}
192
+
193
+
194
+	/**
195
+	 * This returns the format string to be used by getters depending on what the $_date_time_output property is set at.
196
+	 * getters need to know whether we're just returning the date or the time or both.  By default we return both.
197
+	 *
198
+	 * @param bool $pretty If we're returning the pretty formats or standard format string.
199
+	 * @return string    The final assembled format string.
200
+	 */
201
+	protected function _get_date_time_output($pretty = false)
202
+	{
203
+
204
+		switch ($this->_date_time_output) {
205
+			case 'time':
206
+				return $pretty ? $this->_pretty_time_format : $this->_time_format;
207
+				break;
208
+
209
+			case 'date':
210
+				return $pretty ? $this->_pretty_date_format : $this->_date_format;
211
+				break;
212
+
213
+			default:
214
+				return $pretty
215
+					? $this->_pretty_date_format . ' ' . $this->_pretty_time_format
216
+					: $this->_date_format . ' ' . $this->_time_format;
217
+		}
218
+	}
219
+
220
+
221
+	/**
222
+	 * This just sets the $_date_time_output property so we can flag how date and times are formatted before being
223
+	 * returned (using the format properties)
224
+	 *
225
+	 * @param string $what acceptable values are 'time' or 'date'.
226
+	 *                     Any other value will be set but will always result
227
+	 *                     in both 'date' and 'time' being returned.
228
+	 * @return void
229
+	 */
230
+	public function set_date_time_output($what = null)
231
+	{
232
+		$this->_date_time_output = $what;
233
+	}
234
+
235
+
236
+	/**
237
+	 * See $_timezone property for description of what the timezone property is for.  This SETS the timezone internally
238
+	 * for being able to reference what timezone we are running conversions on when converting TO the internal timezone
239
+	 * (UTC Unix Timestamp) for the object OR when converting FROM the internal timezone (UTC Unix Timestamp).
240
+	 * We also set some other properties in this method.
241
+	 *
242
+	 * @param string $timezone_string A valid timezone string as described by @link
243
+	 *                                http://www.php.net/manual/en/timezones.php
244
+	 * @return void
245
+	 * @throws InvalidArgumentException
246
+	 * @throws InvalidDataTypeException
247
+	 * @throws InvalidInterfaceException
248
+	 */
249
+	public function set_timezone($timezone_string)
250
+	{
251
+		if (empty($timezone_string) && $this->_timezone_string !== null) {
252
+			// leave the timezone AS-IS if we already have one and
253
+			// the function arg didn't provide one
254
+			return;
255
+		}
256
+		$timezone_string        = EEH_DTT_Helper::get_valid_timezone_string($timezone_string);
257
+		$this->_timezone_string = ! empty($timezone_string) ? $timezone_string : 'UTC';
258
+		$this->_DateTimeZone    = $this->_create_timezone_object_from_timezone_string($this->_timezone_string);
259
+	}
260
+
261
+
262
+	/**
263
+	 * _create_timezone_object_from_timezone_name
264
+	 *
265
+	 * @access protected
266
+	 * @param string $timezone_string
267
+	 * @return \DateTimeZone
268
+	 * @throws InvalidArgumentException
269
+	 * @throws InvalidDataTypeException
270
+	 * @throws InvalidInterfaceException
271
+	 */
272
+	protected function _create_timezone_object_from_timezone_string($timezone_string = '')
273
+	{
274
+		return new DateTimeZone(EEH_DTT_Helper::get_valid_timezone_string($timezone_string));
275
+	}
276
+
277
+
278
+	/**
279
+	 * This just returns whatever is set for the current timezone.
280
+	 *
281
+	 * @access public
282
+	 * @return string timezone string
283
+	 */
284
+	public function get_timezone()
285
+	{
286
+		return $this->_timezone_string;
287
+	}
288
+
289
+
290
+	/**
291
+	 * set the $_date_format property
292
+	 *
293
+	 * @access public
294
+	 * @param string $format a new date format (corresponding to formats accepted by PHP date() function)
295
+	 * @param bool   $pretty Whether to set pretty format or not.
296
+	 * @return void
297
+	 */
298
+	public function set_date_format($format, $pretty = false)
299
+	{
300
+		if ($pretty) {
301
+			$this->_pretty_date_format = $format;
302
+		} else {
303
+			$this->_date_format = $format;
304
+		}
305
+	}
306
+
307
+
308
+	/**
309
+	 * return the $_date_format property value.
310
+	 *
311
+	 * @param bool $pretty Whether to get pretty format or not.
312
+	 * @return string
313
+	 */
314
+	public function get_date_format($pretty = false)
315
+	{
316
+		return $pretty ? $this->_pretty_date_format : $this->_date_format;
317
+	}
318
+
319
+
320
+	/**
321
+	 * set the $_time_format property
322
+	 *
323
+	 * @access public
324
+	 * @param string $format a new time format (corresponding to formats accepted by PHP date() function)
325
+	 * @param bool   $pretty Whether to set pretty format or not.
326
+	 * @return void
327
+	 */
328
+	public function set_time_format($format, $pretty = false)
329
+	{
330
+		if ($pretty) {
331
+			$this->_pretty_time_format = $format;
332
+		} else {
333
+			$this->_time_format = $format;
334
+		}
335
+	}
336
+
337
+
338
+	/**
339
+	 * return the $_time_format property value.
340
+	 *
341
+	 * @param bool $pretty Whether to get pretty format or not.
342
+	 * @return string
343
+	 */
344
+	public function get_time_format($pretty = false)
345
+	{
346
+		return $pretty ? $this->_pretty_time_format : $this->_time_format;
347
+	}
348
+
349
+
350
+	/**
351
+	 * set the $_pretty_date_format property
352
+	 *
353
+	 * @access public
354
+	 * @param string $format a new pretty date format (corresponding to formats accepted by PHP date() function)
355
+	 * @return void
356
+	 */
357
+	public function set_pretty_date_format($format)
358
+	{
359
+		$this->_pretty_date_format = $format;
360
+	}
361
+
362
+
363
+	/**
364
+	 * set the $_pretty_time_format property
365
+	 *
366
+	 * @access public
367
+	 * @param string $format a new pretty time format (corresponding to formats accepted by PHP date() function)
368
+	 * @return void
369
+	 */
370
+	public function set_pretty_time_format($format)
371
+	{
372
+		$this->_pretty_time_format = $format;
373
+	}
374
+
375
+
376
+	/**
377
+	 * Only sets the time portion of the datetime.
378
+	 *
379
+	 * @param string|DateTime $time_to_set_string like 8am OR a DateTime object.
380
+	 * @param DateTime        $current            current DateTime object for the datetime field
381
+	 * @return DateTime
382
+	 */
383
+	public function prepare_for_set_with_new_time($time_to_set_string, DateTime $current)
384
+	{
385
+		// if $time_to_set_string is datetime object, then let's use it to set the parse array.
386
+		// Otherwise parse the string.
387
+		if ($time_to_set_string instanceof DateTime) {
388
+			$parsed = array(
389
+				'hour'   => $time_to_set_string->format('H'),
390
+				'minute' => $time_to_set_string->format('i'),
391
+				'second' => $time_to_set_string->format('s'),
392
+			);
393
+		} else {
394
+			// parse incoming string
395
+			$parsed = date_parse_from_format($this->_time_format, $time_to_set_string);
396
+		}
397
+		EEH_DTT_Helper::setTimezone($current, $this->_DateTimeZone);
398
+		return $current->setTime($parsed['hour'], $parsed['minute'], $parsed['second']);
399
+	}
400
+
401
+
402
+	/**
403
+	 * Only sets the date portion of the datetime.
404
+	 *
405
+	 * @param string|DateTime $date_to_set_string like Friday, January 8th or a DateTime object.
406
+	 * @param DateTime        $current            current DateTime object for the datetime field
407
+	 * @return DateTime
408
+	 */
409
+	public function prepare_for_set_with_new_date($date_to_set_string, DateTime $current)
410
+	{
411
+		// if $time_to_set_string is datetime object, then let's use it to set the parse array.
412
+		// Otherwise parse the string.
413
+		if ($date_to_set_string instanceof DateTime) {
414
+			$parsed = array(
415
+				'year'  => $date_to_set_string->format('Y'),
416
+				'month' => $date_to_set_string->format('m'),
417
+				'day'   => $date_to_set_string->format('d'),
418
+			);
419
+		} else {
420
+			// parse incoming string
421
+			$parsed = date_parse_from_format($this->_date_format, $date_to_set_string);
422
+		}
423
+		EEH_DTT_Helper::setTimezone($current, $this->_DateTimeZone);
424
+		return $current->setDate($parsed['year'], $parsed['month'], $parsed['day']);
425
+	}
426
+
427
+
428
+	/**
429
+	 * This prepares the EE_DateTime value to be saved to the db as mysql timestamp (UTC +0 timezone).  When the
430
+	 * datetime gets to this stage it should ALREADY be in UTC time
431
+	 *
432
+	 * @param  DateTime $DateTime
433
+	 * @return string formatted date time for given timezone
434
+	 * @throws \EE_Error
435
+	 */
436
+	public function prepare_for_get($DateTime)
437
+	{
438
+		return $this->_prepare_for_display($DateTime);
439
+	}
440
+
441
+
442
+	/**
443
+	 * This differs from prepare_for_get in that it considers whether the internal $_timezone differs
444
+	 * from the set wp timezone.  If so, then it returns the datetime string formatted via
445
+	 * _pretty_date_format, and _pretty_time_format.  However, it also appends a timezone
446
+	 * abbreviation to the date_string.
447
+	 *
448
+	 * @param mixed $DateTime
449
+	 * @param null  $schema
450
+	 * @return string
451
+	 * @throws \EE_Error
452
+	 */
453
+	public function prepare_for_pretty_echoing($DateTime, $schema = null)
454
+	{
455
+		return $this->_prepare_for_display($DateTime, $schema ? $schema : true);
456
+	}
457
+
458
+
459
+	/**
460
+	 * This prepares the EE_DateTime value to be saved to the db as mysql timestamp (UTC +0
461
+	 * timezone).
462
+	 *
463
+	 * @param DateTime    $DateTime
464
+	 * @param bool|string $schema
465
+	 * @return string
466
+	 * @throws \EE_Error
467
+	 */
468
+	protected function _prepare_for_display($DateTime, $schema = false)
469
+	{
470
+		if (! $DateTime instanceof DateTime) {
471
+			if ($this->_nullable) {
472
+				return '';
473
+			} else {
474
+				if (WP_DEBUG) {
475
+					throw new EE_Error(
476
+						sprintf(
477
+							__(
478
+								'EE_Datetime_Field::_prepare_for_display requires a DateTime class to be the value for the $DateTime argument because the %s field is not nullable.',
479
+								'event_espresso'
480
+							),
481
+							$this->_nicename
482
+						)
483
+					);
484
+				} else {
485
+					$DateTime = new DbSafeDateTime(\EE_Datetime_Field::now);
486
+					EE_Error::add_error(
487
+						sprintf(
488
+							__(
489
+								'EE_Datetime_Field::_prepare_for_display requires a DateTime class to be the value for the $DateTime argument because the %s field is not nullable.  When WP_DEBUG is false, the value is set to "now" instead of throwing an exception.',
490
+								'event_espresso'
491
+							),
492
+							$this->_nicename
493
+						)
494
+					);
495
+				}
496
+			}
497
+		}
498
+		$format_string = $this->_get_date_time_output($schema);
499
+		EEH_DTT_Helper::setTimezone($DateTime, $this->_DateTimeZone);
500
+		if ($schema) {
501
+			if ($this->_display_timezone()) {
502
+				// must be explicit because schema could equal true.
503
+				if ($schema === 'no_html') {
504
+					$timezone_string = ' (' . $DateTime->format('T') . ')';
505
+				} else {
506
+					$timezone_string = ' <span class="ee_dtt_timezone_string">(' . $DateTime->format('T') . ')</span>';
507
+				}
508
+			} else {
509
+				$timezone_string = '';
510
+			}
511
+
512
+			return $DateTime->format($format_string) . $timezone_string;
513
+		}
514
+		return $DateTime->format($format_string);
515
+	}
516
+
517
+
518
+	/**
519
+	 * This prepares the EE_DateTime value to be saved to the db as mysql timestamp (UTC +0
520
+	 * timezone).
521
+	 *
522
+	 * @param  mixed $datetime_value u
523
+	 * @return string mysql timestamp in UTC
524
+	 * @throws \EE_Error
525
+	 */
526
+	public function prepare_for_use_in_db($datetime_value)
527
+	{
528
+		// we allow an empty value or DateTime object, but nothing else.
529
+		if (! empty($datetime_value) && ! $datetime_value instanceof DateTime) {
530
+			throw new EE_Error(
531
+				sprintf(
532
+					__(
533
+						'The incoming value being prepared for setting in the database must either be empty or a php 
534 534
             		    DateTime object, instead of: %1$s %2$s',
535
-                        'event_espresso'
536
-                    ),
537
-                    '<br />',
538
-                    print_r($datetime_value, true)
539
-                )
540
-            );
541
-        }
542
-
543
-        if ($datetime_value instanceof DateTime) {
544
-            if (! $datetime_value instanceof DbSafeDateTime) {
545
-                $datetime_value = DbSafeDateTime::createFromDateTime($datetime_value);
546
-            }
547
-            EEH_DTT_Helper::setTimezone($datetime_value, $this->get_UTC_DateTimeZone());
548
-            return $datetime_value->format(
549
-                EE_Datetime_Field::mysql_timestamp_format
550
-            );
551
-        }
552
-
553
-        // if $datetime_value is empty, and ! $this->_nullable, use current_time() but set the GMT flag to true
554
-        return ! $this->_nullable && empty($datetime_value) ? current_time('mysql', true) : null;
555
-    }
556
-
557
-
558
-    /**
559
-     * This prepares the datetime for internal usage as a PHP DateTime object OR null (if nullable is
560
-     * allowed)
561
-     *
562
-     * @param string $datetime_string mysql timestamp in UTC
563
-     * @return  mixed null | DateTime
564
-     * @throws \EE_Error
565
-     */
566
-    public function prepare_for_set_from_db($datetime_string)
567
-    {
568
-        // if $datetime_value is empty, and ! $this->_nullable, just use time()
569
-        if (empty($datetime_string) && $this->_nullable) {
570
-            return null;
571
-        }
572
-        // datetime strings from the db should ALWAYS be in UTC+0, so use UTC_DateTimeZone when creating
573
-        if (empty($datetime_string)) {
574
-            $DateTime = new DbSafeDateTime(\EE_Datetime_Field::now, $this->get_UTC_DateTimeZone());
575
-        } else {
576
-            $DateTime = DateTime::createFromFormat(
577
-                EE_Datetime_Field::mysql_timestamp_format,
578
-                $datetime_string,
579
-                $this->get_UTC_DateTimeZone()
580
-            );
581
-            if ($DateTime instanceof \DateTime) {
582
-                $DateTime = new DbSafeDateTime(
583
-                    $DateTime->format(\EE_Datetime_Field::mysql_timestamp_format),
584
-                    $this->get_UTC_DateTimeZone()
585
-                );
586
-            }
587
-        }
588
-
589
-        if (! $DateTime instanceof DbSafeDateTime) {
590
-            // if still no datetime object, then let's just use now
591
-            $DateTime = new DbSafeDateTime(\EE_Datetime_Field::now, $this->get_UTC_DateTimeZone());
592
-        }
593
-        // THEN apply the field's set DateTimeZone
594
-        EEH_DTT_Helper::setTimezone($DateTime, $this->_DateTimeZone);
595
-        return $DateTime;
596
-    }
597
-
598
-
599
-    /**
600
-     * All this method does is determine if we're going to display the timezone string or not on any output.
601
-     * To determine this we check if the set timezone offset is different than the blog's set timezone offset.
602
-     * If so, then true.
603
-     *
604
-     * @return bool true for yes false for no
605
-     * @throws \EE_Error
606
-     */
607
-    protected function _display_timezone()
608
-    {
609
-
610
-        // first let's do a comparison of timezone strings.
611
-        // If they match then we can get out without any further calculations
612
-        $blog_string = get_option('timezone_string');
613
-        if ($blog_string === $this->_timezone_string) {
614
-            return false;
615
-        }
616
-        // now we need to calc the offset for the timezone string so we can compare with the blog offset.
617
-        $this_offset = $this->get_timezone_offset($this->_DateTimeZone);
618
-        $blog_offset = $this->get_timezone_offset($this->get_blog_DateTimeZone());
619
-        // now compare
620
-        return $blog_offset !== $this_offset;
621
-    }
622
-
623
-
624
-    /**
625
-     * This method returns a php DateTime object for setting on the EE_Base_Class model.
626
-     * EE passes around DateTime objects because they are MUCH easier to manipulate and deal
627
-     * with.
628
-     *
629
-     * @param int|string|DateTime $date_string            This should be the incoming date string.  It's assumed to be
630
-     *                                                    in the format that is set on the date_field (or DateTime
631
-     *                                                    object)!
632
-     * @return DateTime
633
-     */
634
-    protected function _get_date_object($date_string)
635
-    {
636
-        // first if this is an empty date_string and nullable is allowed, just return null.
637
-        if ($this->_nullable && empty($date_string)) {
638
-            return null;
639
-        }
640
-
641
-        // if incoming date
642
-        if ($date_string instanceof DateTime) {
643
-            EEH_DTT_Helper::setTimezone($date_string, $this->_DateTimeZone);
644
-            return $date_string;
645
-        }
646
-        // if empty date_string and made it here.
647
-        // Return a datetime object for now in the given timezone.
648
-        if (empty($date_string)) {
649
-            return new DbSafeDateTime(\EE_Datetime_Field::now, $this->_DateTimeZone);
650
-        }
651
-        // if $date_string is matches something that looks like a Unix timestamp let's just use it.
652
-        if (preg_match(EE_Datetime_Field::unix_timestamp_regex, $date_string)) {
653
-            try {
654
-                // This is operating under the assumption that the incoming Unix timestamp
655
-                // is an ACTUAL Unix timestamp and not the calculated one output by current_time('timestamp');
656
-                $DateTime = new DbSafeDateTime(\EE_Datetime_Field::now, $this->_DateTimeZone);
657
-                $DateTime->setTimestamp($date_string);
658
-
659
-                return $DateTime;
660
-            } catch (Exception $e) {
661
-                // should be rare, but if things got fooled then let's just continue
662
-            }
663
-        }
664
-        // not a unix timestamp.  So we will use the set format on this object and set timezone to
665
-        // create the DateTime object.
666
-        $format = $this->_date_format . ' ' . $this->_time_format;
667
-        try {
668
-            $DateTime = DateTime::createFromFormat($format, $date_string, $this->_DateTimeZone);
669
-            if ($DateTime instanceof DateTime) {
670
-                $DateTime = new DbSafeDateTime(
671
-                    $DateTime->format(\EE_Datetime_Field::mysql_timestamp_format),
672
-                    $this->_DateTimeZone
673
-                );
674
-            }
675
-            if (! $DateTime instanceof DbSafeDateTime) {
676
-                throw new EE_Error(
677
-                    sprintf(
678
-                        __('"%1$s" does not represent a valid Date Time in the format "%2$s".', 'event_espresso'),
679
-                        $date_string,
680
-                        $format
681
-                    )
682
-                );
683
-            }
684
-        } catch (Exception $e) {
685
-            // if we made it here then likely then something went really wrong.
686
-            // Instead of throwing an exception, let's just return a DateTime object for now, in the set timezone.
687
-            $DateTime = new DbSafeDateTime(\EE_Datetime_Field::now, $this->_DateTimeZone);
688
-        }
689
-
690
-        return $DateTime;
691
-    }
692
-
693
-
694
-
695
-    /**
696
-     * get_timezone_transitions
697
-     *
698
-     * @param \DateTimeZone $DateTimeZone
699
-     * @param int           $time
700
-     * @param bool          $first_only
701
-     * @return mixed
702
-     */
703
-    public function get_timezone_transitions(DateTimeZone $DateTimeZone, $time = null, $first_only = true)
704
-    {
705
-        return EEH_DTT_Helper::get_timezone_transitions($DateTimeZone, $time, $first_only);
706
-    }
707
-
708
-
709
-
710
-    /**
711
-     * get_timezone_offset
712
-     *
713
-     * @param \DateTimeZone $DateTimeZone
714
-     * @param int           $time
715
-     * @return mixed
716
-     * @throws \DomainException
717
-     */
718
-    public function get_timezone_offset(DateTimeZone $DateTimeZone, $time = null)
719
-    {
720
-        return EEH_DTT_Helper::get_timezone_offset($DateTimeZone, $time);
721
-    }
722
-
723
-
724
-    /**
725
-     * This will take an incoming timezone string and return the abbreviation for that timezone
726
-     *
727
-     * @param  string $timezone_string
728
-     * @return string           abbreviation
729
-     * @throws \EE_Error
730
-     */
731
-    public function get_timezone_abbrev($timezone_string)
732
-    {
733
-        $timezone_string = EEH_DTT_Helper::get_valid_timezone_string($timezone_string);
734
-        $dateTime        = new DateTime(\EE_Datetime_Field::now, new DateTimeZone($timezone_string));
735
-
736
-        return $dateTime->format('T');
737
-    }
738
-
739
-    /**
740
-     * Overrides the parent to allow for having a dynamic "now" value
741
-     *
742
-     * @return mixed
743
-     */
744
-    public function get_default_value()
745
-    {
746
-        if ($this->_default_value === EE_Datetime_Field::now) {
747
-            return time();
748
-        } else {
749
-            return parent::get_default_value();
750
-        }
751
-    }
752
-
753
-    /**
754
-     * Gets the default datetime object from the field's default time
755
-     * @since 4.9.66.p
756
-     * @return DbSafeDateTime|null
757
-     * @throws InvalidArgumentException
758
-     * @throws InvalidDataTypeException
759
-     * @throws InvalidInterfaceException
760
-     */
761
-    public function getDefaultDateTimeObj()
762
-    {
763
-        $default_raw = $this->get_default_value();
764
-        if ($default_raw instanceof DateTime) {
765
-            return $default_raw;
766
-        } elseif (is_null($default_raw)) {
767
-            return $default_raw;
768
-        } else {
769
-            return new DbSafeDateTime(
770
-                $this->get_default_value(),
771
-                EEH_DTT_Helper::get_valid_timezone_string($this->get_timezone())
772
-            );
773
-        }
774
-    }
775
-
776
-    public function getSchemaDescription()
777
-    {
778
-        return sprintf(
779
-            esc_html__('%s - the value for this field is in the timezone of the site.', 'event_espresso'),
780
-            $this->get_nicename()
781
-        );
782
-    }
535
+						'event_espresso'
536
+					),
537
+					'<br />',
538
+					print_r($datetime_value, true)
539
+				)
540
+			);
541
+		}
542
+
543
+		if ($datetime_value instanceof DateTime) {
544
+			if (! $datetime_value instanceof DbSafeDateTime) {
545
+				$datetime_value = DbSafeDateTime::createFromDateTime($datetime_value);
546
+			}
547
+			EEH_DTT_Helper::setTimezone($datetime_value, $this->get_UTC_DateTimeZone());
548
+			return $datetime_value->format(
549
+				EE_Datetime_Field::mysql_timestamp_format
550
+			);
551
+		}
552
+
553
+		// if $datetime_value is empty, and ! $this->_nullable, use current_time() but set the GMT flag to true
554
+		return ! $this->_nullable && empty($datetime_value) ? current_time('mysql', true) : null;
555
+	}
556
+
557
+
558
+	/**
559
+	 * This prepares the datetime for internal usage as a PHP DateTime object OR null (if nullable is
560
+	 * allowed)
561
+	 *
562
+	 * @param string $datetime_string mysql timestamp in UTC
563
+	 * @return  mixed null | DateTime
564
+	 * @throws \EE_Error
565
+	 */
566
+	public function prepare_for_set_from_db($datetime_string)
567
+	{
568
+		// if $datetime_value is empty, and ! $this->_nullable, just use time()
569
+		if (empty($datetime_string) && $this->_nullable) {
570
+			return null;
571
+		}
572
+		// datetime strings from the db should ALWAYS be in UTC+0, so use UTC_DateTimeZone when creating
573
+		if (empty($datetime_string)) {
574
+			$DateTime = new DbSafeDateTime(\EE_Datetime_Field::now, $this->get_UTC_DateTimeZone());
575
+		} else {
576
+			$DateTime = DateTime::createFromFormat(
577
+				EE_Datetime_Field::mysql_timestamp_format,
578
+				$datetime_string,
579
+				$this->get_UTC_DateTimeZone()
580
+			);
581
+			if ($DateTime instanceof \DateTime) {
582
+				$DateTime = new DbSafeDateTime(
583
+					$DateTime->format(\EE_Datetime_Field::mysql_timestamp_format),
584
+					$this->get_UTC_DateTimeZone()
585
+				);
586
+			}
587
+		}
588
+
589
+		if (! $DateTime instanceof DbSafeDateTime) {
590
+			// if still no datetime object, then let's just use now
591
+			$DateTime = new DbSafeDateTime(\EE_Datetime_Field::now, $this->get_UTC_DateTimeZone());
592
+		}
593
+		// THEN apply the field's set DateTimeZone
594
+		EEH_DTT_Helper::setTimezone($DateTime, $this->_DateTimeZone);
595
+		return $DateTime;
596
+	}
597
+
598
+
599
+	/**
600
+	 * All this method does is determine if we're going to display the timezone string or not on any output.
601
+	 * To determine this we check if the set timezone offset is different than the blog's set timezone offset.
602
+	 * If so, then true.
603
+	 *
604
+	 * @return bool true for yes false for no
605
+	 * @throws \EE_Error
606
+	 */
607
+	protected function _display_timezone()
608
+	{
609
+
610
+		// first let's do a comparison of timezone strings.
611
+		// If they match then we can get out without any further calculations
612
+		$blog_string = get_option('timezone_string');
613
+		if ($blog_string === $this->_timezone_string) {
614
+			return false;
615
+		}
616
+		// now we need to calc the offset for the timezone string so we can compare with the blog offset.
617
+		$this_offset = $this->get_timezone_offset($this->_DateTimeZone);
618
+		$blog_offset = $this->get_timezone_offset($this->get_blog_DateTimeZone());
619
+		// now compare
620
+		return $blog_offset !== $this_offset;
621
+	}
622
+
623
+
624
+	/**
625
+	 * This method returns a php DateTime object for setting on the EE_Base_Class model.
626
+	 * EE passes around DateTime objects because they are MUCH easier to manipulate and deal
627
+	 * with.
628
+	 *
629
+	 * @param int|string|DateTime $date_string            This should be the incoming date string.  It's assumed to be
630
+	 *                                                    in the format that is set on the date_field (or DateTime
631
+	 *                                                    object)!
632
+	 * @return DateTime
633
+	 */
634
+	protected function _get_date_object($date_string)
635
+	{
636
+		// first if this is an empty date_string and nullable is allowed, just return null.
637
+		if ($this->_nullable && empty($date_string)) {
638
+			return null;
639
+		}
640
+
641
+		// if incoming date
642
+		if ($date_string instanceof DateTime) {
643
+			EEH_DTT_Helper::setTimezone($date_string, $this->_DateTimeZone);
644
+			return $date_string;
645
+		}
646
+		// if empty date_string and made it here.
647
+		// Return a datetime object for now in the given timezone.
648
+		if (empty($date_string)) {
649
+			return new DbSafeDateTime(\EE_Datetime_Field::now, $this->_DateTimeZone);
650
+		}
651
+		// if $date_string is matches something that looks like a Unix timestamp let's just use it.
652
+		if (preg_match(EE_Datetime_Field::unix_timestamp_regex, $date_string)) {
653
+			try {
654
+				// This is operating under the assumption that the incoming Unix timestamp
655
+				// is an ACTUAL Unix timestamp and not the calculated one output by current_time('timestamp');
656
+				$DateTime = new DbSafeDateTime(\EE_Datetime_Field::now, $this->_DateTimeZone);
657
+				$DateTime->setTimestamp($date_string);
658
+
659
+				return $DateTime;
660
+			} catch (Exception $e) {
661
+				// should be rare, but if things got fooled then let's just continue
662
+			}
663
+		}
664
+		// not a unix timestamp.  So we will use the set format on this object and set timezone to
665
+		// create the DateTime object.
666
+		$format = $this->_date_format . ' ' . $this->_time_format;
667
+		try {
668
+			$DateTime = DateTime::createFromFormat($format, $date_string, $this->_DateTimeZone);
669
+			if ($DateTime instanceof DateTime) {
670
+				$DateTime = new DbSafeDateTime(
671
+					$DateTime->format(\EE_Datetime_Field::mysql_timestamp_format),
672
+					$this->_DateTimeZone
673
+				);
674
+			}
675
+			if (! $DateTime instanceof DbSafeDateTime) {
676
+				throw new EE_Error(
677
+					sprintf(
678
+						__('"%1$s" does not represent a valid Date Time in the format "%2$s".', 'event_espresso'),
679
+						$date_string,
680
+						$format
681
+					)
682
+				);
683
+			}
684
+		} catch (Exception $e) {
685
+			// if we made it here then likely then something went really wrong.
686
+			// Instead of throwing an exception, let's just return a DateTime object for now, in the set timezone.
687
+			$DateTime = new DbSafeDateTime(\EE_Datetime_Field::now, $this->_DateTimeZone);
688
+		}
689
+
690
+		return $DateTime;
691
+	}
692
+
693
+
694
+
695
+	/**
696
+	 * get_timezone_transitions
697
+	 *
698
+	 * @param \DateTimeZone $DateTimeZone
699
+	 * @param int           $time
700
+	 * @param bool          $first_only
701
+	 * @return mixed
702
+	 */
703
+	public function get_timezone_transitions(DateTimeZone $DateTimeZone, $time = null, $first_only = true)
704
+	{
705
+		return EEH_DTT_Helper::get_timezone_transitions($DateTimeZone, $time, $first_only);
706
+	}
707
+
708
+
709
+
710
+	/**
711
+	 * get_timezone_offset
712
+	 *
713
+	 * @param \DateTimeZone $DateTimeZone
714
+	 * @param int           $time
715
+	 * @return mixed
716
+	 * @throws \DomainException
717
+	 */
718
+	public function get_timezone_offset(DateTimeZone $DateTimeZone, $time = null)
719
+	{
720
+		return EEH_DTT_Helper::get_timezone_offset($DateTimeZone, $time);
721
+	}
722
+
723
+
724
+	/**
725
+	 * This will take an incoming timezone string and return the abbreviation for that timezone
726
+	 *
727
+	 * @param  string $timezone_string
728
+	 * @return string           abbreviation
729
+	 * @throws \EE_Error
730
+	 */
731
+	public function get_timezone_abbrev($timezone_string)
732
+	{
733
+		$timezone_string = EEH_DTT_Helper::get_valid_timezone_string($timezone_string);
734
+		$dateTime        = new DateTime(\EE_Datetime_Field::now, new DateTimeZone($timezone_string));
735
+
736
+		return $dateTime->format('T');
737
+	}
738
+
739
+	/**
740
+	 * Overrides the parent to allow for having a dynamic "now" value
741
+	 *
742
+	 * @return mixed
743
+	 */
744
+	public function get_default_value()
745
+	{
746
+		if ($this->_default_value === EE_Datetime_Field::now) {
747
+			return time();
748
+		} else {
749
+			return parent::get_default_value();
750
+		}
751
+	}
752
+
753
+	/**
754
+	 * Gets the default datetime object from the field's default time
755
+	 * @since 4.9.66.p
756
+	 * @return DbSafeDateTime|null
757
+	 * @throws InvalidArgumentException
758
+	 * @throws InvalidDataTypeException
759
+	 * @throws InvalidInterfaceException
760
+	 */
761
+	public function getDefaultDateTimeObj()
762
+	{
763
+		$default_raw = $this->get_default_value();
764
+		if ($default_raw instanceof DateTime) {
765
+			return $default_raw;
766
+		} elseif (is_null($default_raw)) {
767
+			return $default_raw;
768
+		} else {
769
+			return new DbSafeDateTime(
770
+				$this->get_default_value(),
771
+				EEH_DTT_Helper::get_valid_timezone_string($this->get_timezone())
772
+			);
773
+		}
774
+	}
775
+
776
+	public function getSchemaDescription()
777
+	{
778
+		return sprintf(
779
+			esc_html__('%s - the value for this field is in the timezone of the site.', 'event_espresso'),
780
+			$this->get_nicename()
781
+		);
782
+	}
783 783
 }
Please login to merge, or discard this patch.
core/helpers/EEH_URL.helper.php 1 patch
Indentation   +260 added lines, -260 removed lines patch added patch discarded remove patch
@@ -12,285 +12,285 @@
 block discarded – undo
12 12
 class EEH_URL
13 13
 {
14 14
 
15
-    /**
16
-     * _add_query_arg
17
-     * adds nonce to array of arguments then calls WP add_query_arg function
18
-     *
19
-     * @access public
20
-     * @param array  $args
21
-     * @param string $url
22
-     * @param bool   $exclude_nonce If true then the nonce will be excluded from the generated url.
23
-     * @return string
24
-     */
25
-    public static function add_query_args_and_nonce($args = array(), $url = '', $exclude_nonce = false)
26
-    {
27
-        if (empty($url)) {
28
-            $user_msg = esc_html__(
29
-                'An error occurred. A URL is a required parameter for the add_query_args_and_nonce method.',
30
-                'event_espresso'
31
-            );
32
-            $dev_msg  = $user_msg . "\n"
33
-                . sprintf(
34
-                    esc_html__(
35
-                        'In order to dynamically generate nonces for your actions, you need to supply a valid URL as a second parameter for the %s method.',
36
-                        'event_espresso'
37
-                    ),
38
-                    __CLASS__ . '::add_query_args_and_nonce'
39
-                );
40
-            EE_Error::add_error($user_msg . '||' . $dev_msg, __FILE__, __FUNCTION__, __LINE__);
41
-        }
42
-        // check that an action exists and add nonce
43
-        if (! $exclude_nonce) {
44
-            if (isset($args['action']) && ! empty($args['action'])) {
45
-                $args = array_merge(
46
-                    $args,
47
-                    array(
48
-                        $args['action'] . '_nonce' => wp_create_nonce($args['action'] . '_nonce')
49
-                    )
50
-                );
51
-            } else {
52
-                $args = array_merge(
53
-                    $args,
54
-                    array(
55
-                        'action' => 'default', 'default_nonce' => wp_create_nonce('default_nonce')
56
-                    )
57
-                );
58
-            }
59
-        }
15
+	/**
16
+	 * _add_query_arg
17
+	 * adds nonce to array of arguments then calls WP add_query_arg function
18
+	 *
19
+	 * @access public
20
+	 * @param array  $args
21
+	 * @param string $url
22
+	 * @param bool   $exclude_nonce If true then the nonce will be excluded from the generated url.
23
+	 * @return string
24
+	 */
25
+	public static function add_query_args_and_nonce($args = array(), $url = '', $exclude_nonce = false)
26
+	{
27
+		if (empty($url)) {
28
+			$user_msg = esc_html__(
29
+				'An error occurred. A URL is a required parameter for the add_query_args_and_nonce method.',
30
+				'event_espresso'
31
+			);
32
+			$dev_msg  = $user_msg . "\n"
33
+				. sprintf(
34
+					esc_html__(
35
+						'In order to dynamically generate nonces for your actions, you need to supply a valid URL as a second parameter for the %s method.',
36
+						'event_espresso'
37
+					),
38
+					__CLASS__ . '::add_query_args_and_nonce'
39
+				);
40
+			EE_Error::add_error($user_msg . '||' . $dev_msg, __FILE__, __FUNCTION__, __LINE__);
41
+		}
42
+		// check that an action exists and add nonce
43
+		if (! $exclude_nonce) {
44
+			if (isset($args['action']) && ! empty($args['action'])) {
45
+				$args = array_merge(
46
+					$args,
47
+					array(
48
+						$args['action'] . '_nonce' => wp_create_nonce($args['action'] . '_nonce')
49
+					)
50
+				);
51
+			} else {
52
+				$args = array_merge(
53
+					$args,
54
+					array(
55
+						'action' => 'default', 'default_nonce' => wp_create_nonce('default_nonce')
56
+					)
57
+				);
58
+			}
59
+		}
60 60
 
61
-        // finally, let's always add a return address (if present) :)
62
-        $args = ! empty($_REQUEST['action']) && ! isset($_REQUEST['return'])
63
-            ? array_merge($args, array('return' => $_REQUEST['action']))
64
-            : $args;
61
+		// finally, let's always add a return address (if present) :)
62
+		$args = ! empty($_REQUEST['action']) && ! isset($_REQUEST['return'])
63
+			? array_merge($args, array('return' => $_REQUEST['action']))
64
+			: $args;
65 65
 
66
-        return add_query_arg($args, $url);
67
-    }
66
+		return add_query_arg($args, $url);
67
+	}
68 68
 
69 69
 
70
-    /**
71
-     * Returns whether not the remote file exists.
72
-     * Checking via GET because HEAD requests are blocked on some server configurations.
73
-     *
74
-     * @param string  $url
75
-     * @param array $args  the arguments that should be passed through to the wp_remote_request call.
76
-     * @return boolean
77
-     */
78
-    public static function remote_file_exists($url, $args = array())
79
-    {
80
-        $results = wp_remote_request(
81
-            $url,
82
-            array_merge(
83
-                array(
84
-                    'method'      => 'GET',
85
-                    'redirection' => 1,
86
-                ),
87
-                $args
88
-            )
89
-        );
90
-        if (! $results instanceof WP_Error &&
91
-            isset($results['response']) &&
92
-            isset($results['response']['code']) &&
93
-            $results['response']['code'] == '200') {
94
-            return true;
95
-        } else {
96
-            return false;
97
-        }
98
-    }
70
+	/**
71
+	 * Returns whether not the remote file exists.
72
+	 * Checking via GET because HEAD requests are blocked on some server configurations.
73
+	 *
74
+	 * @param string  $url
75
+	 * @param array $args  the arguments that should be passed through to the wp_remote_request call.
76
+	 * @return boolean
77
+	 */
78
+	public static function remote_file_exists($url, $args = array())
79
+	{
80
+		$results = wp_remote_request(
81
+			$url,
82
+			array_merge(
83
+				array(
84
+					'method'      => 'GET',
85
+					'redirection' => 1,
86
+				),
87
+				$args
88
+			)
89
+		);
90
+		if (! $results instanceof WP_Error &&
91
+			isset($results['response']) &&
92
+			isset($results['response']['code']) &&
93
+			$results['response']['code'] == '200') {
94
+			return true;
95
+		} else {
96
+			return false;
97
+		}
98
+	}
99 99
 
100 100
 
101
-    /**
102
-     * refactor_url
103
-     * primarily used for removing the query string from a URL
104
-     *
105
-     * @param string $url
106
-     * @param bool   $remove_query  - TRUE (default) will strip off any URL params, ie: ?this=1&that=2
107
-     * @param bool   $base_url_only - TRUE will only return the scheme and host with no other parameters
108
-     * @return string
109
-     */
110
-    public static function refactor_url($url = '', $remove_query = true, $base_url_only = false)
111
-    {
112
-        // break apart incoming URL
113
-        $url_bits = parse_url($url);
114
-        // HTTP or HTTPS ?
115
-        $scheme = isset($url_bits['scheme']) ? $url_bits['scheme'] . '://' : 'http://';
116
-        // domain
117
-        $host = isset($url_bits['host']) ? $url_bits['host'] : '';
118
-        // if only the base URL is requested, then return that now
119
-        if ($base_url_only) {
120
-            return $scheme . $host;
121
-        }
122
-        $port = isset($url_bits['port']) ? ':' . $url_bits['port'] : '';
123
-        $user = isset($url_bits['user']) ? $url_bits['user'] : '';
124
-        $pass = isset($url_bits['pass']) ? ':' . $url_bits['pass'] : '';
125
-        $pass = ($user || $pass) ? $pass . '@' : '';
126
-        $path = isset($url_bits['path']) ? $url_bits['path'] : '';
127
-        // if the query string is not required, then return what we have so far
128
-        if ($remove_query) {
129
-            return $scheme . $user . $pass . $host . $port . $path;
130
-        }
131
-        $query    = isset($url_bits['query']) ? '?' . $url_bits['query'] : '';
132
-        $fragment = isset($url_bits['fragment']) ? '#' . $url_bits['fragment'] : '';
133
-        return $scheme . $user . $pass . $host . $port . $path . $query . $fragment;
134
-    }
101
+	/**
102
+	 * refactor_url
103
+	 * primarily used for removing the query string from a URL
104
+	 *
105
+	 * @param string $url
106
+	 * @param bool   $remove_query  - TRUE (default) will strip off any URL params, ie: ?this=1&that=2
107
+	 * @param bool   $base_url_only - TRUE will only return the scheme and host with no other parameters
108
+	 * @return string
109
+	 */
110
+	public static function refactor_url($url = '', $remove_query = true, $base_url_only = false)
111
+	{
112
+		// break apart incoming URL
113
+		$url_bits = parse_url($url);
114
+		// HTTP or HTTPS ?
115
+		$scheme = isset($url_bits['scheme']) ? $url_bits['scheme'] . '://' : 'http://';
116
+		// domain
117
+		$host = isset($url_bits['host']) ? $url_bits['host'] : '';
118
+		// if only the base URL is requested, then return that now
119
+		if ($base_url_only) {
120
+			return $scheme . $host;
121
+		}
122
+		$port = isset($url_bits['port']) ? ':' . $url_bits['port'] : '';
123
+		$user = isset($url_bits['user']) ? $url_bits['user'] : '';
124
+		$pass = isset($url_bits['pass']) ? ':' . $url_bits['pass'] : '';
125
+		$pass = ($user || $pass) ? $pass . '@' : '';
126
+		$path = isset($url_bits['path']) ? $url_bits['path'] : '';
127
+		// if the query string is not required, then return what we have so far
128
+		if ($remove_query) {
129
+			return $scheme . $user . $pass . $host . $port . $path;
130
+		}
131
+		$query    = isset($url_bits['query']) ? '?' . $url_bits['query'] : '';
132
+		$fragment = isset($url_bits['fragment']) ? '#' . $url_bits['fragment'] : '';
133
+		return $scheme . $user . $pass . $host . $port . $path . $query . $fragment;
134
+	}
135 135
 
136 136
 
137
-    /**
138
-     * get_query_string
139
-     * returns just the query string from a URL, formatted by default into an array of key value pairs
140
-     *
141
-     * @param string $url
142
-     * @param bool   $as_array TRUE (default) will return query params as an array of key value pairs, FALSE will
143
-     *                         simply return the query string
144
-     * @return string|array
145
-     */
146
-    public static function get_query_string($url = '', $as_array = true)
147
-    {
148
-        // decode, then break apart incoming URL
149
-        $url_bits = parse_url(html_entity_decode($url));
150
-        // grab query string from URL
151
-        $query = isset($url_bits['query']) ? $url_bits['query'] : '';
152
-        // if we don't want the query string formatted into an array of key => value pairs, then just return it as is
153
-        if (! $as_array) {
154
-            return $query;
155
-        }
156
-        // if no query string exists then just return an empty array now
157
-        if (empty($query)) {
158
-            return array();
159
-        }
160
-        // empty array to hold results
161
-        $query_params = array();
162
-        // now break apart the query string into separate params
163
-        $query = explode('&', $query);
164
-        // loop thru our query params
165
-        foreach ($query as $query_args) {
166
-            // break apart the key value pairs
167
-            $query_args = explode('=', $query_args);
168
-            // and add to our results array
169
-            $query_params[ $query_args[0] ] = $query_args[1];
170
-        }
171
-        return $query_params;
172
-    }
137
+	/**
138
+	 * get_query_string
139
+	 * returns just the query string from a URL, formatted by default into an array of key value pairs
140
+	 *
141
+	 * @param string $url
142
+	 * @param bool   $as_array TRUE (default) will return query params as an array of key value pairs, FALSE will
143
+	 *                         simply return the query string
144
+	 * @return string|array
145
+	 */
146
+	public static function get_query_string($url = '', $as_array = true)
147
+	{
148
+		// decode, then break apart incoming URL
149
+		$url_bits = parse_url(html_entity_decode($url));
150
+		// grab query string from URL
151
+		$query = isset($url_bits['query']) ? $url_bits['query'] : '';
152
+		// if we don't want the query string formatted into an array of key => value pairs, then just return it as is
153
+		if (! $as_array) {
154
+			return $query;
155
+		}
156
+		// if no query string exists then just return an empty array now
157
+		if (empty($query)) {
158
+			return array();
159
+		}
160
+		// empty array to hold results
161
+		$query_params = array();
162
+		// now break apart the query string into separate params
163
+		$query = explode('&', $query);
164
+		// loop thru our query params
165
+		foreach ($query as $query_args) {
166
+			// break apart the key value pairs
167
+			$query_args = explode('=', $query_args);
168
+			// and add to our results array
169
+			$query_params[ $query_args[0] ] = $query_args[1];
170
+		}
171
+		return $query_params;
172
+	}
173 173
 
174 174
 
175
-    /**
176
-     * prevent_prefetching
177
-     *
178
-     * @return void
179
-     */
180
-    public static function prevent_prefetching()
181
-    {
182
-        // prevent browsers from prefetching of the rel='next' link, because it may contain content that interferes
183
-        // with the registration process
184
-        remove_action('wp_head', 'adjacent_posts_rel_link_wp_head');
185
-    }
175
+	/**
176
+	 * prevent_prefetching
177
+	 *
178
+	 * @return void
179
+	 */
180
+	public static function prevent_prefetching()
181
+	{
182
+		// prevent browsers from prefetching of the rel='next' link, because it may contain content that interferes
183
+		// with the registration process
184
+		remove_action('wp_head', 'adjacent_posts_rel_link_wp_head');
185
+	}
186 186
 
187 187
 
188
-    /**
189
-     * This generates a unique site-specific string.
190
-     * An example usage for this string would be to save as a unique identifier for a record in the db for usage in
191
-     * urls.
192
-     *
193
-     * @param   string $prefix Use this to prefix the string with something.
194
-     * @return string
195
-     */
196
-    public static function generate_unique_token($prefix = '')
197
-    {
198
-        $token = md5(uniqid() . mt_rand());
199
-        return $prefix ? $prefix . '_' . $token : $token;
200
-    }
188
+	/**
189
+	 * This generates a unique site-specific string.
190
+	 * An example usage for this string would be to save as a unique identifier for a record in the db for usage in
191
+	 * urls.
192
+	 *
193
+	 * @param   string $prefix Use this to prefix the string with something.
194
+	 * @return string
195
+	 */
196
+	public static function generate_unique_token($prefix = '')
197
+	{
198
+		$token = md5(uniqid() . mt_rand());
199
+		return $prefix ? $prefix . '_' . $token : $token;
200
+	}
201 201
 
202 202
 
203
-    /**
204
-     * filter_input_server_url
205
-     * uses filter_input() to sanitize one of the INPUT_SERVER URL values
206
-     * but adds a backup in case filter_input() returns nothing, which can erringly happen on some servers
207
-     *
208
-     * @param string $server_variable
209
-     * @return string
210
-     */
211
-    public static function filter_input_server_url($server_variable = 'REQUEST_URI')
212
-    {
213
-        $URL              = '';
214
-        $server_variables = array(
215
-            'REQUEST_URI' => 1,
216
-            'HTTP_HOST'   => 1,
217
-            'PHP_SELF'    => 1,
218
-        );
219
-        $server_variable  = strtoupper($server_variable);
220
-        // whitelist INPUT_SERVER var
221
-        if (isset($server_variables[ $server_variable ])) {
222
-            $URL = filter_input(INPUT_SERVER, $server_variable, FILTER_SANITIZE_URL, FILTER_NULL_ON_FAILURE);
223
-            if (empty($URL)) {
224
-                // fallback sanitization if the above fails
225
-                $URL = wp_sanitize_redirect($_SERVER[ $server_variable ]);
226
-            }
227
-        }
228
-        return $URL;
229
-    }
203
+	/**
204
+	 * filter_input_server_url
205
+	 * uses filter_input() to sanitize one of the INPUT_SERVER URL values
206
+	 * but adds a backup in case filter_input() returns nothing, which can erringly happen on some servers
207
+	 *
208
+	 * @param string $server_variable
209
+	 * @return string
210
+	 */
211
+	public static function filter_input_server_url($server_variable = 'REQUEST_URI')
212
+	{
213
+		$URL              = '';
214
+		$server_variables = array(
215
+			'REQUEST_URI' => 1,
216
+			'HTTP_HOST'   => 1,
217
+			'PHP_SELF'    => 1,
218
+		);
219
+		$server_variable  = strtoupper($server_variable);
220
+		// whitelist INPUT_SERVER var
221
+		if (isset($server_variables[ $server_variable ])) {
222
+			$URL = filter_input(INPUT_SERVER, $server_variable, FILTER_SANITIZE_URL, FILTER_NULL_ON_FAILURE);
223
+			if (empty($URL)) {
224
+				// fallback sanitization if the above fails
225
+				$URL = wp_sanitize_redirect($_SERVER[ $server_variable ]);
226
+			}
227
+		}
228
+		return $URL;
229
+	}
230 230
 
231 231
 
232
-    /**
233
-     * Gets the current page's full URL.
234
-     *
235
-     * @return string
236
-     */
237
-    public static function current_url()
238
-    {
239
-        $url = '';
240
-        if (isset($_SERVER['HTTP_HOST'], $_SERVER['REQUEST_URI'])) {
241
-            $url = is_ssl() ? 'https://' : 'http://';
242
-            $url .= \EEH_URL::filter_input_server_url('HTTP_HOST');
243
-            $url .= \EEH_URL::filter_input_server_url('REQUEST_URI');
244
-        }
245
-        return $url;
246
-    }
232
+	/**
233
+	 * Gets the current page's full URL.
234
+	 *
235
+	 * @return string
236
+	 */
237
+	public static function current_url()
238
+	{
239
+		$url = '';
240
+		if (isset($_SERVER['HTTP_HOST'], $_SERVER['REQUEST_URI'])) {
241
+			$url = is_ssl() ? 'https://' : 'http://';
242
+			$url .= \EEH_URL::filter_input_server_url('HTTP_HOST');
243
+			$url .= \EEH_URL::filter_input_server_url('REQUEST_URI');
244
+		}
245
+		return $url;
246
+	}
247 247
 
248 248
 
249
-    /**
250
-     * Identical in functionality to EEH_current_url except it removes any provided query_parameters from it.
251
-     *
252
-     * @param array $query_parameters An array of query_parameters to remove from the current url.
253
-     * @since 4.9.46.rc.029
254
-     * @return string
255
-     */
256
-    public static function current_url_without_query_paramaters(array $query_parameters)
257
-    {
258
-        return remove_query_arg($query_parameters, EEH_URL::current_url());
259
-    }
249
+	/**
250
+	 * Identical in functionality to EEH_current_url except it removes any provided query_parameters from it.
251
+	 *
252
+	 * @param array $query_parameters An array of query_parameters to remove from the current url.
253
+	 * @since 4.9.46.rc.029
254
+	 * @return string
255
+	 */
256
+	public static function current_url_without_query_paramaters(array $query_parameters)
257
+	{
258
+		return remove_query_arg($query_parameters, EEH_URL::current_url());
259
+	}
260 260
 
261 261
 
262
-    /**
263
-     * @param string $location
264
-     * @param int    $status
265
-     * @param string $exit_notice
266
-     */
267
-    public static function safeRedirectAndExit($location, $status = 302, $exit_notice = '')
268
-    {
269
-        EE_Error::get_notices(false, true);
270
-        wp_safe_redirect($location, $status);
271
-        exit($exit_notice);
272
-    }
262
+	/**
263
+	 * @param string $location
264
+	 * @param int    $status
265
+	 * @param string $exit_notice
266
+	 */
267
+	public static function safeRedirectAndExit($location, $status = 302, $exit_notice = '')
268
+	{
269
+		EE_Error::get_notices(false, true);
270
+		wp_safe_redirect($location, $status);
271
+		exit($exit_notice);
272
+	}
273 273
 
274
-    /**
275
-     * Slugifies text for usage in a URL.
276
-     *
277
-     * Currently, this isn't just calling `sanitize_title()` on it, because that percent-encodes unicode characters,
278
-     * and WordPress chokes on them when used as CPT and custom taxonomy slugs.
279
-     *
280
-     * @since 4.9.66.p
281
-     * @param string $text
282
-     * @param string $fallback
283
-     * @return string which can be used in a URL
284
-     */
285
-    public static function slugify($text, $fallback)
286
-    {
287
-        // url decode after sanitizing title to restore unicode characters,
288
-        // see https://github.com/eventespresso/event-espresso-core/issues/575
289
-        return urldecode(
290
-            sanitize_title(
291
-                $text,
292
-                $fallback
293
-            )
294
-        );
295
-    }
274
+	/**
275
+	 * Slugifies text for usage in a URL.
276
+	 *
277
+	 * Currently, this isn't just calling `sanitize_title()` on it, because that percent-encodes unicode characters,
278
+	 * and WordPress chokes on them when used as CPT and custom taxonomy slugs.
279
+	 *
280
+	 * @since 4.9.66.p
281
+	 * @param string $text
282
+	 * @param string $fallback
283
+	 * @return string which can be used in a URL
284
+	 */
285
+	public static function slugify($text, $fallback)
286
+	{
287
+		// url decode after sanitizing title to restore unicode characters,
288
+		// see https://github.com/eventespresso/event-espresso-core/issues/575
289
+		return urldecode(
290
+			sanitize_title(
291
+				$text,
292
+				$fallback
293
+			)
294
+		);
295
+	}
296 296
 }
Please login to merge, or discard this patch.