Completed
Branch fix/escaping-2 (5dcb9a)
by
unknown
13:02 queued 10:26
created
core/services/address/CountrySubRegionDao.php 2 patches
Indentation   +227 added lines, -227 removed lines patch added patch discarded remove patch
@@ -26,252 +26,252 @@
 block discarded – undo
26 26
 class CountrySubRegionDao
27 27
 {
28 28
 
29
-    const REPO_URL = 'https://raw.githubusercontent.com/eventespresso/countries-and-subregions/master/';
29
+	const REPO_URL = 'https://raw.githubusercontent.com/eventespresso/countries-and-subregions/master/';
30 30
 
31
-    const OPTION_NAME_COUNTRY_DATA_VERSION = 'espresso-country-sub-region-data-version';
31
+	const OPTION_NAME_COUNTRY_DATA_VERSION = 'espresso-country-sub-region-data-version';
32 32
 
33
-    /**
34
-     * @var EEM_State $state_model
35
-     */
36
-    private $state_model;
33
+	/**
34
+	 * @var EEM_State $state_model
35
+	 */
36
+	private $state_model;
37 37
 
38
-    /**
39
-     * @var JsonValidator $json_validator
40
-     */
41
-    private $json_validator;
38
+	/**
39
+	 * @var JsonValidator $json_validator
40
+	 */
41
+	private $json_validator;
42 42
 
43
-    /**
44
-     * @var string $data_version
45
-     */
46
-    private $data_version;
43
+	/**
44
+	 * @var string $data_version
45
+	 */
46
+	private $data_version;
47 47
 
48
-    /**
49
-     * @var array $countries
50
-     */
51
-    private $countries = array();
48
+	/**
49
+	 * @var array $countries
50
+	 */
51
+	private $countries = array();
52 52
 
53 53
 
54
-    /**
55
-     * CountrySubRegionDao constructor.
56
-     *
57
-     * @param EEM_State     $state_model
58
-     * @param JsonValidator $json_validator
59
-     */
60
-    public function __construct(EEM_State $state_model, JsonValidator $json_validator)
61
-    {
62
-        $this->state_model = $state_model;
63
-        $this->json_validator = $json_validator;
64
-    }
54
+	/**
55
+	 * CountrySubRegionDao constructor.
56
+	 *
57
+	 * @param EEM_State     $state_model
58
+	 * @param JsonValidator $json_validator
59
+	 */
60
+	public function __construct(EEM_State $state_model, JsonValidator $json_validator)
61
+	{
62
+		$this->state_model = $state_model;
63
+		$this->json_validator = $json_validator;
64
+	}
65 65
 
66 66
 
67
-    /**
68
-     * @param EE_Country $country_object
69
-     * @return bool
70
-     * @throws EE_Error
71
-     * @throws InvalidArgumentException
72
-     * @throws InvalidDataTypeException
73
-     * @throws InvalidInterfaceException
74
-     * @throws ReflectionException
75
-     */
76
-    public function saveCountrySubRegions(EE_Country $country_object)
77
-    {
78
-        $CNT_ISO = $country_object->ID();
79
-        $has_sub_regions = $this->state_model->count(array(array('Country.CNT_ISO' => $CNT_ISO)));
80
-        $data = [];
81
-        if (empty($this->countries)) {
82
-            $this->data_version = $this->getCountrySubRegionDataVersion();
83
-            $data = $this->retrieveJsonData(self::REPO_URL . 'countries.json');
84
-        }
85
-        if (empty($data)) {
86
-            EE_Error::add_error(
87
-                'Country Subregion Data could not be retrieved',
88
-                __FILE__,
89
-                __METHOD__,
90
-                __LINE__
91
-            );
92
-        }
93
-        if (
94
-            ! $has_sub_regions
95
-            || (isset($data->version) && version_compare($data->version, $this->data_version))
96
-        ) {
97
-            if (
98
-                isset($data->countries)
99
-                && $this->processCountryData($CNT_ISO, $data->countries) > 0
100
-            ) {
101
-                $this->countries = $data->countries;
102
-                $this->updateCountrySubRegionDataVersion($data->version);
103
-                return true;
104
-            }
105
-        }
106
-        return false;
107
-    }
67
+	/**
68
+	 * @param EE_Country $country_object
69
+	 * @return bool
70
+	 * @throws EE_Error
71
+	 * @throws InvalidArgumentException
72
+	 * @throws InvalidDataTypeException
73
+	 * @throws InvalidInterfaceException
74
+	 * @throws ReflectionException
75
+	 */
76
+	public function saveCountrySubRegions(EE_Country $country_object)
77
+	{
78
+		$CNT_ISO = $country_object->ID();
79
+		$has_sub_regions = $this->state_model->count(array(array('Country.CNT_ISO' => $CNT_ISO)));
80
+		$data = [];
81
+		if (empty($this->countries)) {
82
+			$this->data_version = $this->getCountrySubRegionDataVersion();
83
+			$data = $this->retrieveJsonData(self::REPO_URL . 'countries.json');
84
+		}
85
+		if (empty($data)) {
86
+			EE_Error::add_error(
87
+				'Country Subregion Data could not be retrieved',
88
+				__FILE__,
89
+				__METHOD__,
90
+				__LINE__
91
+			);
92
+		}
93
+		if (
94
+			! $has_sub_regions
95
+			|| (isset($data->version) && version_compare($data->version, $this->data_version))
96
+		) {
97
+			if (
98
+				isset($data->countries)
99
+				&& $this->processCountryData($CNT_ISO, $data->countries) > 0
100
+			) {
101
+				$this->countries = $data->countries;
102
+				$this->updateCountrySubRegionDataVersion($data->version);
103
+				return true;
104
+			}
105
+		}
106
+		return false;
107
+	}
108 108
 
109 109
 
110
-    /**
111
-     * @since 4.9.70.p
112
-     * @return string
113
-     */
114
-    private function getCountrySubRegionDataVersion()
115
-    {
116
-        return get_option(self::OPTION_NAME_COUNTRY_DATA_VERSION, null);
117
-    }
110
+	/**
111
+	 * @since 4.9.70.p
112
+	 * @return string
113
+	 */
114
+	private function getCountrySubRegionDataVersion()
115
+	{
116
+		return get_option(self::OPTION_NAME_COUNTRY_DATA_VERSION, null);
117
+	}
118 118
 
119 119
 
120
-    /**
121
-     * @param string $version
122
-     */
123
-    private function updateCountrySubRegionDataVersion($version = '')
124
-    {
125
-        // add version option if it has never been added before, or update existing
126
-        if ($this->data_version === null) {
127
-            add_option(self::OPTION_NAME_COUNTRY_DATA_VERSION, $version, '', false);
128
-        } else {
129
-            update_option(self::OPTION_NAME_COUNTRY_DATA_VERSION, $version);
130
-        }
131
-    }
120
+	/**
121
+	 * @param string $version
122
+	 */
123
+	private function updateCountrySubRegionDataVersion($version = '')
124
+	{
125
+		// add version option if it has never been added before, or update existing
126
+		if ($this->data_version === null) {
127
+			add_option(self::OPTION_NAME_COUNTRY_DATA_VERSION, $version, '', false);
128
+		} else {
129
+			update_option(self::OPTION_NAME_COUNTRY_DATA_VERSION, $version);
130
+		}
131
+	}
132 132
 
133 133
 
134
-    /**
135
-     * @param string $CNT_ISO
136
-     * @param array  $countries
137
-     * @return int
138
-     * @throws EE_Error
139
-     * @throws InvalidArgumentException
140
-     * @throws InvalidDataTypeException
141
-     * @throws InvalidInterfaceException
142
-     * @throws ReflectionException
143
-     * @since 4.9.70.p
144
-     */
145
-    private function processCountryData($CNT_ISO, $countries = array())
146
-    {
147
-        if (! empty($countries)) {
148
-            foreach ($countries as $key => $country) {
149
-                if (
150
-                    $country instanceof stdClass
151
-                    && $country->code === $CNT_ISO
152
-                    && empty($country->sub_regions)
153
-                    && ! empty($country->filename)
154
-                ) {
155
-                    $country->sub_regions = $this->retrieveJsonData(
156
-                        self::REPO_URL . 'countries/' . $country->filename . '.json'
157
-                    );
158
-                    return $this->saveSubRegionData($country, $country->sub_regions);
159
-                }
160
-            }
161
-        }
162
-        return 0;
163
-    }
134
+	/**
135
+	 * @param string $CNT_ISO
136
+	 * @param array  $countries
137
+	 * @return int
138
+	 * @throws EE_Error
139
+	 * @throws InvalidArgumentException
140
+	 * @throws InvalidDataTypeException
141
+	 * @throws InvalidInterfaceException
142
+	 * @throws ReflectionException
143
+	 * @since 4.9.70.p
144
+	 */
145
+	private function processCountryData($CNT_ISO, $countries = array())
146
+	{
147
+		if (! empty($countries)) {
148
+			foreach ($countries as $key => $country) {
149
+				if (
150
+					$country instanceof stdClass
151
+					&& $country->code === $CNT_ISO
152
+					&& empty($country->sub_regions)
153
+					&& ! empty($country->filename)
154
+				) {
155
+					$country->sub_regions = $this->retrieveJsonData(
156
+						self::REPO_URL . 'countries/' . $country->filename . '.json'
157
+					);
158
+					return $this->saveSubRegionData($country, $country->sub_regions);
159
+				}
160
+			}
161
+		}
162
+		return 0;
163
+	}
164 164
 
165 165
 
166
-    /**
167
-     * @param string $url
168
-     * @return array
169
-     */
170
-    private function retrieveJsonData($url)
171
-    {
172
-        if (empty($url)) {
173
-            EE_Error::add_error(
174
-                'No URL was provided!',
175
-                __FILE__,
176
-                __METHOD__,
177
-                __LINE__
178
-            );
179
-            return array();
180
-        }
181
-        $request = wp_safe_remote_get($url);
182
-        if ($request instanceof WP_Error) {
183
-            EE_Error::add_error(
184
-                $request->get_error_message(),
185
-                __FILE__,
186
-                __METHOD__,
187
-                __LINE__
188
-            );
189
-            return array();
190
-        }
191
-        $body = wp_remote_retrieve_body($request);
192
-        $json = json_decode($body);
193
-        if ($this->json_validator->isValid(__FILE__, __METHOD__, __LINE__)) {
194
-            return $json;
195
-        }
196
-        return array();
197
-    }
166
+	/**
167
+	 * @param string $url
168
+	 * @return array
169
+	 */
170
+	private function retrieveJsonData($url)
171
+	{
172
+		if (empty($url)) {
173
+			EE_Error::add_error(
174
+				'No URL was provided!',
175
+				__FILE__,
176
+				__METHOD__,
177
+				__LINE__
178
+			);
179
+			return array();
180
+		}
181
+		$request = wp_safe_remote_get($url);
182
+		if ($request instanceof WP_Error) {
183
+			EE_Error::add_error(
184
+				$request->get_error_message(),
185
+				__FILE__,
186
+				__METHOD__,
187
+				__LINE__
188
+			);
189
+			return array();
190
+		}
191
+		$body = wp_remote_retrieve_body($request);
192
+		$json = json_decode($body);
193
+		if ($this->json_validator->isValid(__FILE__, __METHOD__, __LINE__)) {
194
+			return $json;
195
+		}
196
+		return array();
197
+	}
198 198
 
199 199
 
200
-    /**
201
-     * @param stdClass $country
202
-     * @param array    $sub_regions
203
-     * @return int
204
-     * @throws EE_Error
205
-     * @throws InvalidArgumentException
206
-     * @throws InvalidDataTypeException
207
-     * @throws InvalidInterfaceException
208
-     * @throws ReflectionException
209
-     */
210
-    private function saveSubRegionData(stdClass $country, $sub_regions = array())
211
-    {
212
-        $results = 0;
213
-        if (is_array($sub_regions)) {
214
-            $existing_sub_regions = $this->getExistingStateAbbreviations($country->code);
215
-            foreach ($sub_regions as $sub_region) {
216
-                // remove country code from sub region code
217
-                $abbrev = str_replace(
218
-                    $country->code . '-',
219
-                    '',
220
-                    sanitize_text_field($sub_region->code)
221
-                );
222
-                // but NOT if sub region code results in only a number
223
-                if (absint($abbrev) !== 0) {
224
-                    $abbrev = sanitize_text_field($sub_region->code);
225
-                }
226
-                if (
227
-                    ! in_array($abbrev, $existing_sub_regions, true)
228
-                    && $this->state_model->insert(
229
-                        [
230
-                            // STA_ID CNT_ISO STA_abbrev STA_name STA_active
231
-                            'CNT_ISO'    => $country->code,
232
-                            'STA_abbrev' => $abbrev,
233
-                            'STA_name'   => sanitize_text_field($sub_region->name),
234
-                            'STA_active' => 1,
235
-                        ]
236
-                    )
237
-                ) {
238
-                    $results++;
239
-                }
240
-            }
241
-        }
242
-        return $results;
243
-    }
200
+	/**
201
+	 * @param stdClass $country
202
+	 * @param array    $sub_regions
203
+	 * @return int
204
+	 * @throws EE_Error
205
+	 * @throws InvalidArgumentException
206
+	 * @throws InvalidDataTypeException
207
+	 * @throws InvalidInterfaceException
208
+	 * @throws ReflectionException
209
+	 */
210
+	private function saveSubRegionData(stdClass $country, $sub_regions = array())
211
+	{
212
+		$results = 0;
213
+		if (is_array($sub_regions)) {
214
+			$existing_sub_regions = $this->getExistingStateAbbreviations($country->code);
215
+			foreach ($sub_regions as $sub_region) {
216
+				// remove country code from sub region code
217
+				$abbrev = str_replace(
218
+					$country->code . '-',
219
+					'',
220
+					sanitize_text_field($sub_region->code)
221
+				);
222
+				// but NOT if sub region code results in only a number
223
+				if (absint($abbrev) !== 0) {
224
+					$abbrev = sanitize_text_field($sub_region->code);
225
+				}
226
+				if (
227
+					! in_array($abbrev, $existing_sub_regions, true)
228
+					&& $this->state_model->insert(
229
+						[
230
+							// STA_ID CNT_ISO STA_abbrev STA_name STA_active
231
+							'CNT_ISO'    => $country->code,
232
+							'STA_abbrev' => $abbrev,
233
+							'STA_name'   => sanitize_text_field($sub_region->name),
234
+							'STA_active' => 1,
235
+						]
236
+					)
237
+				) {
238
+					$results++;
239
+				}
240
+			}
241
+		}
242
+		return $results;
243
+	}
244 244
 
245 245
 
246
-    /**
247
-     * @param string $CNT_ISO
248
-     * @since 4.9.76.p
249
-     * @return array
250
-     * @throws EE_Error
251
-     * @throws InvalidArgumentException
252
-     * @throws InvalidDataTypeException
253
-     * @throws InvalidInterfaceException
254
-     * @throws ReflectionException
255
-     */
256
-    private function getExistingStateAbbreviations($CNT_ISO)
257
-    {
258
-        $existing_sub_region_IDs = [];
259
-        $existing_sub_regions = $this->state_model->get_all(array(
260
-            array(
261
-                'Country.CNT_ISO' => array(
262
-                    'IN',
263
-                    [$CNT_ISO]
264
-                )
265
-            ),
266
-            'order_by' => array('Country.CNT_name' => 'ASC', 'STA_name' => 'ASC')
267
-        ));
268
-        if (is_array($existing_sub_regions)) {
269
-            foreach ($existing_sub_regions as $existing_sub_region) {
270
-                if ($existing_sub_region instanceof EE_State) {
271
-                    $existing_sub_region_IDs[] = $existing_sub_region->abbrev();
272
-                }
273
-            }
274
-        }
275
-        return $existing_sub_region_IDs;
276
-    }
246
+	/**
247
+	 * @param string $CNT_ISO
248
+	 * @since 4.9.76.p
249
+	 * @return array
250
+	 * @throws EE_Error
251
+	 * @throws InvalidArgumentException
252
+	 * @throws InvalidDataTypeException
253
+	 * @throws InvalidInterfaceException
254
+	 * @throws ReflectionException
255
+	 */
256
+	private function getExistingStateAbbreviations($CNT_ISO)
257
+	{
258
+		$existing_sub_region_IDs = [];
259
+		$existing_sub_regions = $this->state_model->get_all(array(
260
+			array(
261
+				'Country.CNT_ISO' => array(
262
+					'IN',
263
+					[$CNT_ISO]
264
+				)
265
+			),
266
+			'order_by' => array('Country.CNT_name' => 'ASC', 'STA_name' => 'ASC')
267
+		));
268
+		if (is_array($existing_sub_regions)) {
269
+			foreach ($existing_sub_regions as $existing_sub_region) {
270
+				if ($existing_sub_region instanceof EE_State) {
271
+					$existing_sub_region_IDs[] = $existing_sub_region->abbrev();
272
+				}
273
+			}
274
+		}
275
+		return $existing_sub_region_IDs;
276
+	}
277 277
 }
Please login to merge, or discard this patch.
Spacing   +4 added lines, -4 removed lines patch added patch discarded remove patch
@@ -80,7 +80,7 @@  discard block
 block discarded – undo
80 80
         $data = [];
81 81
         if (empty($this->countries)) {
82 82
             $this->data_version = $this->getCountrySubRegionDataVersion();
83
-            $data = $this->retrieveJsonData(self::REPO_URL . 'countries.json');
83
+            $data = $this->retrieveJsonData(self::REPO_URL.'countries.json');
84 84
         }
85 85
         if (empty($data)) {
86 86
             EE_Error::add_error(
@@ -144,7 +144,7 @@  discard block
 block discarded – undo
144 144
      */
145 145
     private function processCountryData($CNT_ISO, $countries = array())
146 146
     {
147
-        if (! empty($countries)) {
147
+        if ( ! empty($countries)) {
148 148
             foreach ($countries as $key => $country) {
149 149
                 if (
150 150
                     $country instanceof stdClass
@@ -153,7 +153,7 @@  discard block
 block discarded – undo
153 153
                     && ! empty($country->filename)
154 154
                 ) {
155 155
                     $country->sub_regions = $this->retrieveJsonData(
156
-                        self::REPO_URL . 'countries/' . $country->filename . '.json'
156
+                        self::REPO_URL.'countries/'.$country->filename.'.json'
157 157
                     );
158 158
                     return $this->saveSubRegionData($country, $country->sub_regions);
159 159
                 }
@@ -215,7 +215,7 @@  discard block
 block discarded – undo
215 215
             foreach ($sub_regions as $sub_region) {
216 216
                 // remove country code from sub region code
217 217
                 $abbrev = str_replace(
218
-                    $country->code . '-',
218
+                    $country->code.'-',
219 219
                     '',
220 220
                     sanitize_text_field($sub_region->code)
221 221
                 );
Please login to merge, or discard this patch.
core/services/payment_methods/forms/PayPalSettingsForm.php 1 patch
Indentation   +191 added lines, -191 removed lines patch added patch discarded remove patch
@@ -20,202 +20,202 @@
 block discarded – undo
20 20
  */
21 21
 class PayPalSettingsForm extends EE_Payment_Method_Form
22 22
 {
23
-    /**
24
-     * @var string of HTML being the help tab link
25
-     */
26
-    protected $helpTabLink;
23
+	/**
24
+	 * @var string of HTML being the help tab link
25
+	 */
26
+	protected $helpTabLink;
27 27
 
28
-    public function __construct(array $options_array = array(), $help_tab_link = '')
29
-    {
30
-        $this->helpTabLink = $help_tab_link;
31
-        $options_array = array_replace_recursive(
32
-            array(
33
-                'extra_meta_inputs' => array(
34
-                    'api_username' => new EE_Text_Input(
35
-                        array(
36
-                            'html_label_text' => sprintf(
37
-                                // translators: %s link to help doc
38
-                                esc_html__('API Username %s', 'event_espresso'),
39
-                                $help_tab_link
40
-                            ),
41
-                            'required'        => true,
42
-                        )
43
-                    ),
44
-                    'api_password' => new EE_Text_Input(
45
-                        array(
46
-                            'html_label_text' => sprintf(
47
-                                // translators: %s link to help doc
48
-                                esc_html__('API Password %s', 'event_espresso'),
49
-                                $help_tab_link
50
-                            ),
51
-                            'required'        => true,
52
-                        )
53
-                    ),
54
-                    'api_signature' => new EE_Text_Input(
55
-                        array(
56
-                            'html_label_text' => sprintf(
57
-                                // translators: %s link to help doc
58
-                                esc_html__('API Signature %s', 'event_espresso'),
59
-                                $help_tab_link
60
-                            ),
61
-                            'required'        => true,
62
-                        )
63
-                    ),
64
-                )
65
-            ),
66
-            $options_array
67
-        );
68
-        parent::__construct($options_array);
69
-    }
28
+	public function __construct(array $options_array = array(), $help_tab_link = '')
29
+	{
30
+		$this->helpTabLink = $help_tab_link;
31
+		$options_array = array_replace_recursive(
32
+			array(
33
+				'extra_meta_inputs' => array(
34
+					'api_username' => new EE_Text_Input(
35
+						array(
36
+							'html_label_text' => sprintf(
37
+								// translators: %s link to help doc
38
+								esc_html__('API Username %s', 'event_espresso'),
39
+								$help_tab_link
40
+							),
41
+							'required'        => true,
42
+						)
43
+					),
44
+					'api_password' => new EE_Text_Input(
45
+						array(
46
+							'html_label_text' => sprintf(
47
+								// translators: %s link to help doc
48
+								esc_html__('API Password %s', 'event_espresso'),
49
+								$help_tab_link
50
+							),
51
+							'required'        => true,
52
+						)
53
+					),
54
+					'api_signature' => new EE_Text_Input(
55
+						array(
56
+							'html_label_text' => sprintf(
57
+								// translators: %s link to help doc
58
+								esc_html__('API Signature %s', 'event_espresso'),
59
+								$help_tab_link
60
+							),
61
+							'required'        => true,
62
+						)
63
+					),
64
+				)
65
+			),
66
+			$options_array
67
+		);
68
+		parent::__construct($options_array);
69
+	}
70 70
 
71
-    /**
72
-     * Tests the the PayPal API credentials work ok
73
-     * @return string of an error using the credentials, otherwise, if the credentials work, returns a blank string
74
-     * @throws EE_Error
75
-     */
76
-    protected function checkForCredentialsErrors()
77
-    {
78
-        $request_params = array(
79
-            'METHOD'    => 'GetBalance',
80
-            'VERSION'   => '204.0',
81
-            'USER'      => $this->get_input_value('api_username'),
82
-            'PWD'       => $this->get_input_value('api_password'),
83
-            'SIGNATURE' => $this->get_input_value('api_signature'),
84
-        );
85
-        $gateway_url = $this->get_input_value('PMD_debug_mode')
86
-            ? 'https://api-3t.sandbox.paypal.com/nvp'
87
-            : 'https://api-3t.paypal.com/nvp';
88
-        // Request Customer Details.
89
-        $response = wp_remote_post(
90
-            $gateway_url,
91
-            array(
92
-                'method'      => 'POST',
93
-                'timeout'     => 45,
94
-                'httpversion' => '1.1',
95
-                'cookies'     => array(),
96
-                'headers'     => array(),
97
-                'body'        => http_build_query($request_params, '', '&'),
98
-            )
99
-        );
100
-        if (is_wp_error($response) || empty($response['body'])) {
101
-            // If we got here then there was an error in this request.
102
-            // maybe is turned off. We don't know the credentials are invalid
103
-            EE_Error::add_error(
104
-                sprintf(
105
-                    // translators: %1$s Error message received from PayPal
106
-                    esc_html__(
107
-                        // @codingStandardsIgnoreStart
108
-                        'Your PayPal credentials could not be verified. The following error occurred while communicating with PayPal: %1$s',
109
-                        // @codingStandardsIgnoreEnd
110
-                        'event_espresso'
111
-                    ),
112
-                    $response->get_error_message()
113
-                ),
114
-                __FILE__,
115
-                __FUNCTION__,
116
-                __LINE__
117
-            );
118
-        }
119
-        $response_args = array();
120
-        parse_str(urldecode($response['body']), $response_args);
71
+	/**
72
+	 * Tests the the PayPal API credentials work ok
73
+	 * @return string of an error using the credentials, otherwise, if the credentials work, returns a blank string
74
+	 * @throws EE_Error
75
+	 */
76
+	protected function checkForCredentialsErrors()
77
+	{
78
+		$request_params = array(
79
+			'METHOD'    => 'GetBalance',
80
+			'VERSION'   => '204.0',
81
+			'USER'      => $this->get_input_value('api_username'),
82
+			'PWD'       => $this->get_input_value('api_password'),
83
+			'SIGNATURE' => $this->get_input_value('api_signature'),
84
+		);
85
+		$gateway_url = $this->get_input_value('PMD_debug_mode')
86
+			? 'https://api-3t.sandbox.paypal.com/nvp'
87
+			: 'https://api-3t.paypal.com/nvp';
88
+		// Request Customer Details.
89
+		$response = wp_remote_post(
90
+			$gateway_url,
91
+			array(
92
+				'method'      => 'POST',
93
+				'timeout'     => 45,
94
+				'httpversion' => '1.1',
95
+				'cookies'     => array(),
96
+				'headers'     => array(),
97
+				'body'        => http_build_query($request_params, '', '&'),
98
+			)
99
+		);
100
+		if (is_wp_error($response) || empty($response['body'])) {
101
+			// If we got here then there was an error in this request.
102
+			// maybe is turned off. We don't know the credentials are invalid
103
+			EE_Error::add_error(
104
+				sprintf(
105
+					// translators: %1$s Error message received from PayPal
106
+					esc_html__(
107
+						// @codingStandardsIgnoreStart
108
+						'Your PayPal credentials could not be verified. The following error occurred while communicating with PayPal: %1$s',
109
+						// @codingStandardsIgnoreEnd
110
+						'event_espresso'
111
+					),
112
+					$response->get_error_message()
113
+				),
114
+				__FILE__,
115
+				__FUNCTION__,
116
+				__LINE__
117
+			);
118
+		}
119
+		$response_args = array();
120
+		parse_str(urldecode($response['body']), $response_args);
121 121
 
122
-        if (empty($response_args['ACK'])) {
123
-            EE_Error::add_error(
124
-                esc_html__(
125
-                    'Your PayPal credentials could not be verified. Part of their response was missing.',
126
-                    'event_espresso'
127
-                ),
128
-                __FILE__,
129
-                __FUNCTION__,
130
-                __LINE__
131
-            );
132
-        }
133
-        if (
134
-            in_array(
135
-                $response_args['ACK'],
136
-                array(
137
-                'Success',
138
-                'SuccessWithWarning'
139
-                ),
140
-                true
141
-            )
142
-        ) {
143
-            return '';
144
-        } else {
145
-            return sprintf(
146
-                // translators: %1$s: PayPal response message, %2$s: PayPal response code
147
-                esc_html__(
148
-                    // @codingStandardsIgnoreStart
149
-                    'Your PayPal API credentials appear to be invalid. PayPal said "%1$s (%2$s)". Please see tips below.',
150
-                    // @codingStandardsIgnoreEnd
151
-                    'event_espresso'
152
-                ),
153
-                isset($response_args['L_LONGMESSAGE0'])
154
-                    ? $response_args['L_LONGMESSAGE0']
155
-                    : esc_html__('No error message received from PayPal', 'event_espresso'),
156
-                isset($response_args['L_ERRORCODE0']) ? $response_args['L_ERRORCODE0'] : 0
157
-            );
158
-        }
159
-    }
122
+		if (empty($response_args['ACK'])) {
123
+			EE_Error::add_error(
124
+				esc_html__(
125
+					'Your PayPal credentials could not be verified. Part of their response was missing.',
126
+					'event_espresso'
127
+				),
128
+				__FILE__,
129
+				__FUNCTION__,
130
+				__LINE__
131
+			);
132
+		}
133
+		if (
134
+			in_array(
135
+				$response_args['ACK'],
136
+				array(
137
+				'Success',
138
+				'SuccessWithWarning'
139
+				),
140
+				true
141
+			)
142
+		) {
143
+			return '';
144
+		} else {
145
+			return sprintf(
146
+				// translators: %1$s: PayPal response message, %2$s: PayPal response code
147
+				esc_html__(
148
+					// @codingStandardsIgnoreStart
149
+					'Your PayPal API credentials appear to be invalid. PayPal said "%1$s (%2$s)". Please see tips below.',
150
+					// @codingStandardsIgnoreEnd
151
+					'event_espresso'
152
+				),
153
+				isset($response_args['L_LONGMESSAGE0'])
154
+					? $response_args['L_LONGMESSAGE0']
155
+					: esc_html__('No error message received from PayPal', 'event_espresso'),
156
+				isset($response_args['L_ERRORCODE0']) ? $response_args['L_ERRORCODE0'] : 0
157
+			);
158
+		}
159
+	}
160 160
 
161
-    /**
162
-     * Gets the HTML to show the link to the help tab
163
-     * @return string
164
-     */
165
-    protected function helpTabLink()
166
-    {
167
-        return $this->helpTabLink;
168
-    }
161
+	/**
162
+	 * Gets the HTML to show the link to the help tab
163
+	 * @return string
164
+	 */
165
+	protected function helpTabLink()
166
+	{
167
+		return $this->helpTabLink;
168
+	}
169 169
 
170
-    /**
171
-     * Does the normal validation, but also verifies the PayPal API credentials work.
172
-     * If they don't, sets a validation error on the entire form, and adds validation errors (which are really more
173
-     * tips) on each of the inputs that could be the cause of the problem.
174
-     * @throws EE_Error
175
-     */
176
-    public function _validate()
177
-    {
178
-        parent::_validate();
179
-        $credentials_message = $this->checkForCredentialsErrors();
180
-        if ($credentials_message !== '') {
181
-            $this->add_validation_error($credentials_message);
182
-            $this->get_input('PMD_debug_mode')->add_validation_error(
183
-                esc_html__(
184
-                    // @codingStandardsIgnoreStart
185
-                    'If you are using PayPal Sandbox (test) credentials, Debug mode should be set to "Yes". Otherwise, if you are using live PayPal credentials, set this to "No".',
186
-                    // @codingStandardsIgnoreEnd
187
-                    'event_espresso'
188
-                )
189
-            );
190
-            $this->get_input('api_username')->add_validation_error(
191
-                sprintf(
192
-                    // translators: $1$s HTML for a link to the help tab
193
-                    esc_html__(
194
-                        'Are you sure this is your API username, not your login username? %1$s',
195
-                        'event_espresso'
196
-                    ),
197
-                    $this->helpTabLink()
198
-                )
199
-            );
200
-            $this->get_input('api_password')->add_validation_error(
201
-                sprintf(
202
-                    // translators: $1$s HTML for a link to the help tab
203
-                    esc_html__(
204
-                        'Are you sure this is your API password, not your login password? %1$s',
205
-                        'event_espresso'
206
-                    ),
207
-                    $this->helpTabLink()
208
-                )
209
-            );
210
-            $this->get_input('api_signature')->add_validation_error(
211
-                sprintf(
212
-                    // translators: $1$s HTML for a link to the help tab
213
-                    esc_html__('Please verify your API signature is correct. %1$s', 'event_espresso'),
214
-                    $this->helpTabLink()
215
-                )
216
-            );
217
-        }
218
-    }
170
+	/**
171
+	 * Does the normal validation, but also verifies the PayPal API credentials work.
172
+	 * If they don't, sets a validation error on the entire form, and adds validation errors (which are really more
173
+	 * tips) on each of the inputs that could be the cause of the problem.
174
+	 * @throws EE_Error
175
+	 */
176
+	public function _validate()
177
+	{
178
+		parent::_validate();
179
+		$credentials_message = $this->checkForCredentialsErrors();
180
+		if ($credentials_message !== '') {
181
+			$this->add_validation_error($credentials_message);
182
+			$this->get_input('PMD_debug_mode')->add_validation_error(
183
+				esc_html__(
184
+					// @codingStandardsIgnoreStart
185
+					'If you are using PayPal Sandbox (test) credentials, Debug mode should be set to "Yes". Otherwise, if you are using live PayPal credentials, set this to "No".',
186
+					// @codingStandardsIgnoreEnd
187
+					'event_espresso'
188
+				)
189
+			);
190
+			$this->get_input('api_username')->add_validation_error(
191
+				sprintf(
192
+					// translators: $1$s HTML for a link to the help tab
193
+					esc_html__(
194
+						'Are you sure this is your API username, not your login username? %1$s',
195
+						'event_espresso'
196
+					),
197
+					$this->helpTabLink()
198
+				)
199
+			);
200
+			$this->get_input('api_password')->add_validation_error(
201
+				sprintf(
202
+					// translators: $1$s HTML for a link to the help tab
203
+					esc_html__(
204
+						'Are you sure this is your API password, not your login password? %1$s',
205
+						'event_espresso'
206
+					),
207
+					$this->helpTabLink()
208
+				)
209
+			);
210
+			$this->get_input('api_signature')->add_validation_error(
211
+				sprintf(
212
+					// translators: $1$s HTML for a link to the help tab
213
+					esc_html__('Please verify your API signature is correct. %1$s', 'event_espresso'),
214
+					$this->helpTabLink()
215
+				)
216
+			);
217
+		}
218
+	}
219 219
 }
220 220
 // End of file PayPalSettingsForm.php
221 221
 // Location: ${NAMESPACE}/PayPalSettingsForm.php
Please login to merge, or discard this patch.
core/services/collections/CollectionDetails.php 2 patches
Indentation   +349 added lines, -349 removed lines patch added patch discarded remove patch
@@ -43,353 +43,353 @@
 block discarded – undo
43 43
 class CollectionDetails implements CollectionDetailsInterface
44 44
 {
45 45
 
46
-    /**
47
-     * if $identifier_type is set to this,
48
-     * then the collection will use each object's spl_object_hash() as it's identifier
49
-     */
50
-    const ID_OBJECT_HASH = 'identifier-uses-spl-object-hash';
51
-
52
-    /**
53
-     * if $identifier_type is set to this,
54
-     * then the collection will use each object's class name as it's identifier
55
-     */
56
-    const ID_CLASS_NAME = 'identifier-uses-object-class-name';
57
-
58
-    /**
59
-     * if $identifier_type is set to this,
60
-     * then the collection will use the return value from a specified callback method on each object
61
-     */
62
-    const ID_CALLBACK_METHOD = 'identifier-uses-callback-method';
63
-
64
-    /**
65
-     * The interface used for controlling what gets added to the collection
66
-     *
67
-     * @var string $collection_interface
68
-     */
69
-    protected $collection_interface = '';
70
-
71
-    /**
72
-     * a unique name used to identify the collection in filter names
73
-     * supplied value is run through sanitize_title_with_dashes(),
74
-     * but then also converts dashes to underscores
75
-     *
76
-     * @var string $collection_name
77
-     */
78
-    protected $collection_name = '';
79
-
80
-    /**
81
-     * what the collection uses for the object identifier.
82
-     * corresponds to one of the class constants above.
83
-     * CollectionDetails::ID_OBJECT_HASH will use spl_object_hash( object ) for the identifier
84
-     * CollectionDetails::ID_CLASS_NAME will use get_class( object ) for the identifier
85
-     * CollectionDetails::ID_CALLBACK_METHOD will use a callback for the identifier
86
-     * defaults to using spl_object_hash() so that multiple objects of the same class can be added
87
-     *
88
-     * @var string $identifier_type
89
-     */
90
-    protected $identifier_type = CollectionDetails::ID_OBJECT_HASH;
91
-
92
-    /**
93
-     * the pattern applied to paths when searching for class files to add to the collection
94
-     * ie: "My_Awesome_*.class.php"
95
-     * defaults to "*.php"
96
-     *
97
-     * @var string $file_mask
98
-     */
99
-    protected $file_mask = '';
100
-
101
-    /**
102
-     * if the $identifier_type above is set to CollectionDetails::ID_CALLBACK_METHOD,
103
-     * then this specifies the method to use on each entity.
104
-     * If the callback method does not exist, then an exception will be thrown
105
-     *
106
-     * @var string $identifier_callback
107
-     */
108
-    protected $identifier_callback = '';
109
-
110
-    /**
111
-     * an array of Fully Qualified Class Names
112
-     *  for example:
113
-     *  $FQCNs = array(
114
-     *      '/Fully/Qualified/ClassNameA'
115
-     *      '/Fully/Qualified/Other/ClassNameB'
116
-     *  );
117
-     *
118
-     * @var array $collection_FQCNs
119
-     */
120
-    protected $collection_FQCNs = array();
121
-
122
-    /**
123
-     * an array of full server paths to folders containing files to be loaded into collection
124
-     *  for example:
125
-     *  $paths = array(
126
-     *      '/full/server/path/to/ClassNameA.ext.php' // for class ClassNameA
127
-     *      '/full/server/path/to/other/ClassNameB.php' // for class ClassNameB
128
-     *  );
129
-     *
130
-     * @var array $collection_paths
131
-     */
132
-    protected $collection_paths = array();
133
-
134
-    /**
135
-     * @var LocatorInterface $file_locator
136
-     */
137
-    protected $file_locator;
138
-
139
-
140
-    /**
141
-     * CollectionDetails constructor.
142
-     *
143
-     * @access public
144
-     * @param string           $collection_name
145
-     * @param string           $collection_interface
146
-     * @param array            $collection_FQCNs
147
-     * @param array            $collection_paths
148
-     * @param string           $file_mask
149
-     * @param string           $identifier_type
150
-     * @param string           $identifier_callback
151
-     * @param LocatorInterface $file_locator
152
-     * @throws CollectionDetailsException
153
-     */
154
-    public function __construct(
155
-        $collection_name,
156
-        $collection_interface,
157
-        array $collection_FQCNs = array(),
158
-        array $collection_paths = array(),
159
-        $file_mask = '',
160
-        $identifier_type = CollectionDetails::ID_OBJECT_HASH,
161
-        $identifier_callback = '',
162
-        LocatorInterface $file_locator = null
163
-    ) {
164
-        try {
165
-            $this->setCollectionName($collection_name);
166
-            $this->setCollectionInterface($collection_interface);
167
-            $this->setCollectionFQCNs($collection_FQCNs);
168
-            $this->setCollectionPaths($collection_paths);
169
-            $this->setFileMasks($file_mask);
170
-            $this->setIdentifierType($identifier_type);
171
-            $this->setIdentifierCallback($identifier_callback);
172
-            $this->file_locator = $file_locator;
173
-        } catch (Exception $exception) {
174
-            throw new CollectionDetailsException($exception);
175
-        }
176
-    }
177
-
178
-
179
-    /**
180
-     * @access public
181
-     * @return mixed
182
-     */
183
-    public function getCollectionInterface()
184
-    {
185
-        return $this->collection_interface;
186
-    }
187
-
188
-
189
-    /**
190
-     * @access protected
191
-     * @param string $collection_interface
192
-     * @throws \EventEspresso\core\exceptions\InvalidInterfaceException
193
-     */
194
-    protected function setCollectionInterface($collection_interface)
195
-    {
196
-        if (! (interface_exists($collection_interface) || class_exists($collection_interface))) {
197
-            throw new InvalidInterfaceException($collection_interface);
198
-        }
199
-        $this->collection_interface = $collection_interface;
200
-    }
201
-
202
-
203
-    /**
204
-     * the collection name will be used for creating dynamic filters
205
-     *
206
-     * @access public
207
-     * @return string
208
-     */
209
-    public function collectionName()
210
-    {
211
-        return $this->collection_name;
212
-    }
213
-
214
-
215
-    /**
216
-     * sanitizes collection name and converts spaces and dashes to underscores
217
-     *
218
-     * @access protected
219
-     * @param string $collection_name
220
-     * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
221
-     */
222
-    protected function setCollectionName($collection_name)
223
-    {
224
-        if (! is_string($collection_name)) {
225
-            throw new InvalidDataTypeException('$collection_name', $collection_name, 'string');
226
-        }
227
-        $this->collection_name = str_replace(
228
-            '-',
229
-            '_',
230
-            sanitize_title_with_dashes($collection_name, '', 'save')
231
-        );
232
-    }
233
-
234
-
235
-    /**
236
-     * @access public
237
-     * @return string
238
-     */
239
-    public function identifierType()
240
-    {
241
-        return $this->identifier_type;
242
-    }
243
-
244
-
245
-    /**
246
-     * @access protected
247
-     * @param string $identifier_type
248
-     * @throws InvalidIdentifierException
249
-     */
250
-    protected function setIdentifierType($identifier_type)
251
-    {
252
-        if (
253
-            ! ($identifier_type === CollectionDetails::ID_CLASS_NAME
254
-               || $identifier_type === CollectionDetails::ID_OBJECT_HASH
255
-               || $identifier_type === CollectionDetails::ID_CALLBACK_METHOD
256
-            )
257
-        ) {
258
-            throw new InvalidIdentifierException(
259
-                $identifier_type,
260
-                'CollectionDetails::ID_CLASS_NAME or CollectionDetails::ID_OBJECT_HASH or CollectionDetails::ID_CALLBACK_METHOD'
261
-            );
262
-        }
263
-        $this->identifier_type = $identifier_type;
264
-    }
265
-
266
-
267
-    /**
268
-     * @access public
269
-     * @return string
270
-     */
271
-    public function identifierCallback()
272
-    {
273
-        return $this->identifier_callback;
274
-    }
275
-
276
-
277
-    /**
278
-     * @access protected
279
-     * @param string $identifier_callback
280
-     * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
281
-     */
282
-    protected function setIdentifierCallback($identifier_callback = 'identifier')
283
-    {
284
-        if (! is_string($identifier_callback)) {
285
-            throw new InvalidDataTypeException('$identifier_callback', $identifier_callback, 'string');
286
-        }
287
-        $this->identifier_callback = $identifier_callback;
288
-    }
289
-
290
-
291
-    /**
292
-     * @access public
293
-     * @return string
294
-     */
295
-    public function getFileMask()
296
-    {
297
-        return $this->file_mask;
298
-    }
299
-
300
-
301
-    /**
302
-     * sets the file mask which is then used to filter what files get loaded
303
-     * when searching for classes to add to the collection. Defaults to '*.php'
304
-     *
305
-     * @access protected
306
-     * @param string $file_mask
307
-     * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
308
-     */
309
-    protected function setFileMasks($file_mask)
310
-    {
311
-        $this->file_mask = ! empty($file_mask) ? $file_mask : '*.php';
312
-        // we know our default is a string, so if it's not a string now,
313
-        // then that means the incoming parameter was something else
314
-        if (! is_string($this->file_mask)) {
315
-            throw new InvalidDataTypeException('$file_mask', $this->file_mask, 'string');
316
-        }
317
-    }
318
-
319
-
320
-    /**
321
-     * @access public
322
-     * @return array
323
-     */
324
-    public function getCollectionFQCNs()
325
-    {
326
-        return $this->collection_FQCNs;
327
-    }
328
-
329
-
330
-    /**
331
-     * @access public
332
-     * @param string|array $collection_FQCNs
333
-     * @throws \EventEspresso\core\exceptions\InvalidClassException
334
-     * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
335
-     */
336
-    public function setCollectionFQCNs($collection_FQCNs)
337
-    {
338
-        foreach ((array) $collection_FQCNs as $collection_FQCN) {
339
-            if (! empty($collection_FQCN)) {
340
-                if (class_exists($collection_FQCN)) {
341
-                    $this->collection_FQCNs[] = $collection_FQCN;
342
-                } else {
343
-                    foreach ($this->getFQCNsFromPartialNamespace($collection_FQCN) as $FQCN) {
344
-                        $this->collection_FQCNs[] = $FQCN;
345
-                    }
346
-                }
347
-            }
348
-        }
349
-    }
350
-
351
-
352
-    /**
353
-     * @access protected
354
-     * @param  string $partial_FQCN
355
-     * @return array
356
-     * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
357
-     * @throws \EventEspresso\core\exceptions\InvalidClassException
358
-     */
359
-    protected function getFQCNsFromPartialNamespace($partial_FQCN)
360
-    {
361
-        if (! $this->file_locator instanceof FqcnLocator) {
362
-            $this->file_locator = new FqcnLocator();
363
-        }
364
-        $this->file_locator->locate($partial_FQCN);
365
-        return $this->file_locator->getFQCNs();
366
-    }
367
-
368
-
369
-    /**
370
-     * @access public
371
-     * @return array
372
-     */
373
-    public function getCollectionPaths()
374
-    {
375
-        return $this->collection_paths;
376
-    }
377
-
378
-
379
-    /**
380
-     * @access public
381
-     * @param string|array $collection_paths
382
-     * @throws \EventEspresso\core\exceptions\InvalidFilePathException
383
-     */
384
-    public function setCollectionPaths($collection_paths)
385
-    {
386
-        foreach ((array) $collection_paths as $collection_path) {
387
-            if (! empty($collection_path)) {
388
-                if (! is_readable($collection_path)) {
389
-                    throw new InvalidFilePathException($collection_path);
390
-                }
391
-                $this->collection_paths[] = $collection_path;
392
-            }
393
-        }
394
-    }
46
+	/**
47
+	 * if $identifier_type is set to this,
48
+	 * then the collection will use each object's spl_object_hash() as it's identifier
49
+	 */
50
+	const ID_OBJECT_HASH = 'identifier-uses-spl-object-hash';
51
+
52
+	/**
53
+	 * if $identifier_type is set to this,
54
+	 * then the collection will use each object's class name as it's identifier
55
+	 */
56
+	const ID_CLASS_NAME = 'identifier-uses-object-class-name';
57
+
58
+	/**
59
+	 * if $identifier_type is set to this,
60
+	 * then the collection will use the return value from a specified callback method on each object
61
+	 */
62
+	const ID_CALLBACK_METHOD = 'identifier-uses-callback-method';
63
+
64
+	/**
65
+	 * The interface used for controlling what gets added to the collection
66
+	 *
67
+	 * @var string $collection_interface
68
+	 */
69
+	protected $collection_interface = '';
70
+
71
+	/**
72
+	 * a unique name used to identify the collection in filter names
73
+	 * supplied value is run through sanitize_title_with_dashes(),
74
+	 * but then also converts dashes to underscores
75
+	 *
76
+	 * @var string $collection_name
77
+	 */
78
+	protected $collection_name = '';
79
+
80
+	/**
81
+	 * what the collection uses for the object identifier.
82
+	 * corresponds to one of the class constants above.
83
+	 * CollectionDetails::ID_OBJECT_HASH will use spl_object_hash( object ) for the identifier
84
+	 * CollectionDetails::ID_CLASS_NAME will use get_class( object ) for the identifier
85
+	 * CollectionDetails::ID_CALLBACK_METHOD will use a callback for the identifier
86
+	 * defaults to using spl_object_hash() so that multiple objects of the same class can be added
87
+	 *
88
+	 * @var string $identifier_type
89
+	 */
90
+	protected $identifier_type = CollectionDetails::ID_OBJECT_HASH;
91
+
92
+	/**
93
+	 * the pattern applied to paths when searching for class files to add to the collection
94
+	 * ie: "My_Awesome_*.class.php"
95
+	 * defaults to "*.php"
96
+	 *
97
+	 * @var string $file_mask
98
+	 */
99
+	protected $file_mask = '';
100
+
101
+	/**
102
+	 * if the $identifier_type above is set to CollectionDetails::ID_CALLBACK_METHOD,
103
+	 * then this specifies the method to use on each entity.
104
+	 * If the callback method does not exist, then an exception will be thrown
105
+	 *
106
+	 * @var string $identifier_callback
107
+	 */
108
+	protected $identifier_callback = '';
109
+
110
+	/**
111
+	 * an array of Fully Qualified Class Names
112
+	 *  for example:
113
+	 *  $FQCNs = array(
114
+	 *      '/Fully/Qualified/ClassNameA'
115
+	 *      '/Fully/Qualified/Other/ClassNameB'
116
+	 *  );
117
+	 *
118
+	 * @var array $collection_FQCNs
119
+	 */
120
+	protected $collection_FQCNs = array();
121
+
122
+	/**
123
+	 * an array of full server paths to folders containing files to be loaded into collection
124
+	 *  for example:
125
+	 *  $paths = array(
126
+	 *      '/full/server/path/to/ClassNameA.ext.php' // for class ClassNameA
127
+	 *      '/full/server/path/to/other/ClassNameB.php' // for class ClassNameB
128
+	 *  );
129
+	 *
130
+	 * @var array $collection_paths
131
+	 */
132
+	protected $collection_paths = array();
133
+
134
+	/**
135
+	 * @var LocatorInterface $file_locator
136
+	 */
137
+	protected $file_locator;
138
+
139
+
140
+	/**
141
+	 * CollectionDetails constructor.
142
+	 *
143
+	 * @access public
144
+	 * @param string           $collection_name
145
+	 * @param string           $collection_interface
146
+	 * @param array            $collection_FQCNs
147
+	 * @param array            $collection_paths
148
+	 * @param string           $file_mask
149
+	 * @param string           $identifier_type
150
+	 * @param string           $identifier_callback
151
+	 * @param LocatorInterface $file_locator
152
+	 * @throws CollectionDetailsException
153
+	 */
154
+	public function __construct(
155
+		$collection_name,
156
+		$collection_interface,
157
+		array $collection_FQCNs = array(),
158
+		array $collection_paths = array(),
159
+		$file_mask = '',
160
+		$identifier_type = CollectionDetails::ID_OBJECT_HASH,
161
+		$identifier_callback = '',
162
+		LocatorInterface $file_locator = null
163
+	) {
164
+		try {
165
+			$this->setCollectionName($collection_name);
166
+			$this->setCollectionInterface($collection_interface);
167
+			$this->setCollectionFQCNs($collection_FQCNs);
168
+			$this->setCollectionPaths($collection_paths);
169
+			$this->setFileMasks($file_mask);
170
+			$this->setIdentifierType($identifier_type);
171
+			$this->setIdentifierCallback($identifier_callback);
172
+			$this->file_locator = $file_locator;
173
+		} catch (Exception $exception) {
174
+			throw new CollectionDetailsException($exception);
175
+		}
176
+	}
177
+
178
+
179
+	/**
180
+	 * @access public
181
+	 * @return mixed
182
+	 */
183
+	public function getCollectionInterface()
184
+	{
185
+		return $this->collection_interface;
186
+	}
187
+
188
+
189
+	/**
190
+	 * @access protected
191
+	 * @param string $collection_interface
192
+	 * @throws \EventEspresso\core\exceptions\InvalidInterfaceException
193
+	 */
194
+	protected function setCollectionInterface($collection_interface)
195
+	{
196
+		if (! (interface_exists($collection_interface) || class_exists($collection_interface))) {
197
+			throw new InvalidInterfaceException($collection_interface);
198
+		}
199
+		$this->collection_interface = $collection_interface;
200
+	}
201
+
202
+
203
+	/**
204
+	 * the collection name will be used for creating dynamic filters
205
+	 *
206
+	 * @access public
207
+	 * @return string
208
+	 */
209
+	public function collectionName()
210
+	{
211
+		return $this->collection_name;
212
+	}
213
+
214
+
215
+	/**
216
+	 * sanitizes collection name and converts spaces and dashes to underscores
217
+	 *
218
+	 * @access protected
219
+	 * @param string $collection_name
220
+	 * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
221
+	 */
222
+	protected function setCollectionName($collection_name)
223
+	{
224
+		if (! is_string($collection_name)) {
225
+			throw new InvalidDataTypeException('$collection_name', $collection_name, 'string');
226
+		}
227
+		$this->collection_name = str_replace(
228
+			'-',
229
+			'_',
230
+			sanitize_title_with_dashes($collection_name, '', 'save')
231
+		);
232
+	}
233
+
234
+
235
+	/**
236
+	 * @access public
237
+	 * @return string
238
+	 */
239
+	public function identifierType()
240
+	{
241
+		return $this->identifier_type;
242
+	}
243
+
244
+
245
+	/**
246
+	 * @access protected
247
+	 * @param string $identifier_type
248
+	 * @throws InvalidIdentifierException
249
+	 */
250
+	protected function setIdentifierType($identifier_type)
251
+	{
252
+		if (
253
+			! ($identifier_type === CollectionDetails::ID_CLASS_NAME
254
+			   || $identifier_type === CollectionDetails::ID_OBJECT_HASH
255
+			   || $identifier_type === CollectionDetails::ID_CALLBACK_METHOD
256
+			)
257
+		) {
258
+			throw new InvalidIdentifierException(
259
+				$identifier_type,
260
+				'CollectionDetails::ID_CLASS_NAME or CollectionDetails::ID_OBJECT_HASH or CollectionDetails::ID_CALLBACK_METHOD'
261
+			);
262
+		}
263
+		$this->identifier_type = $identifier_type;
264
+	}
265
+
266
+
267
+	/**
268
+	 * @access public
269
+	 * @return string
270
+	 */
271
+	public function identifierCallback()
272
+	{
273
+		return $this->identifier_callback;
274
+	}
275
+
276
+
277
+	/**
278
+	 * @access protected
279
+	 * @param string $identifier_callback
280
+	 * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
281
+	 */
282
+	protected function setIdentifierCallback($identifier_callback = 'identifier')
283
+	{
284
+		if (! is_string($identifier_callback)) {
285
+			throw new InvalidDataTypeException('$identifier_callback', $identifier_callback, 'string');
286
+		}
287
+		$this->identifier_callback = $identifier_callback;
288
+	}
289
+
290
+
291
+	/**
292
+	 * @access public
293
+	 * @return string
294
+	 */
295
+	public function getFileMask()
296
+	{
297
+		return $this->file_mask;
298
+	}
299
+
300
+
301
+	/**
302
+	 * sets the file mask which is then used to filter what files get loaded
303
+	 * when searching for classes to add to the collection. Defaults to '*.php'
304
+	 *
305
+	 * @access protected
306
+	 * @param string $file_mask
307
+	 * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
308
+	 */
309
+	protected function setFileMasks($file_mask)
310
+	{
311
+		$this->file_mask = ! empty($file_mask) ? $file_mask : '*.php';
312
+		// we know our default is a string, so if it's not a string now,
313
+		// then that means the incoming parameter was something else
314
+		if (! is_string($this->file_mask)) {
315
+			throw new InvalidDataTypeException('$file_mask', $this->file_mask, 'string');
316
+		}
317
+	}
318
+
319
+
320
+	/**
321
+	 * @access public
322
+	 * @return array
323
+	 */
324
+	public function getCollectionFQCNs()
325
+	{
326
+		return $this->collection_FQCNs;
327
+	}
328
+
329
+
330
+	/**
331
+	 * @access public
332
+	 * @param string|array $collection_FQCNs
333
+	 * @throws \EventEspresso\core\exceptions\InvalidClassException
334
+	 * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
335
+	 */
336
+	public function setCollectionFQCNs($collection_FQCNs)
337
+	{
338
+		foreach ((array) $collection_FQCNs as $collection_FQCN) {
339
+			if (! empty($collection_FQCN)) {
340
+				if (class_exists($collection_FQCN)) {
341
+					$this->collection_FQCNs[] = $collection_FQCN;
342
+				} else {
343
+					foreach ($this->getFQCNsFromPartialNamespace($collection_FQCN) as $FQCN) {
344
+						$this->collection_FQCNs[] = $FQCN;
345
+					}
346
+				}
347
+			}
348
+		}
349
+	}
350
+
351
+
352
+	/**
353
+	 * @access protected
354
+	 * @param  string $partial_FQCN
355
+	 * @return array
356
+	 * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
357
+	 * @throws \EventEspresso\core\exceptions\InvalidClassException
358
+	 */
359
+	protected function getFQCNsFromPartialNamespace($partial_FQCN)
360
+	{
361
+		if (! $this->file_locator instanceof FqcnLocator) {
362
+			$this->file_locator = new FqcnLocator();
363
+		}
364
+		$this->file_locator->locate($partial_FQCN);
365
+		return $this->file_locator->getFQCNs();
366
+	}
367
+
368
+
369
+	/**
370
+	 * @access public
371
+	 * @return array
372
+	 */
373
+	public function getCollectionPaths()
374
+	{
375
+		return $this->collection_paths;
376
+	}
377
+
378
+
379
+	/**
380
+	 * @access public
381
+	 * @param string|array $collection_paths
382
+	 * @throws \EventEspresso\core\exceptions\InvalidFilePathException
383
+	 */
384
+	public function setCollectionPaths($collection_paths)
385
+	{
386
+		foreach ((array) $collection_paths as $collection_path) {
387
+			if (! empty($collection_path)) {
388
+				if (! is_readable($collection_path)) {
389
+					throw new InvalidFilePathException($collection_path);
390
+				}
391
+				$this->collection_paths[] = $collection_path;
392
+			}
393
+		}
394
+	}
395 395
 }
Please login to merge, or discard this patch.
Spacing   +8 added lines, -8 removed lines patch added patch discarded remove patch
@@ -193,7 +193,7 @@  discard block
 block discarded – undo
193 193
      */
194 194
     protected function setCollectionInterface($collection_interface)
195 195
     {
196
-        if (! (interface_exists($collection_interface) || class_exists($collection_interface))) {
196
+        if ( ! (interface_exists($collection_interface) || class_exists($collection_interface))) {
197 197
             throw new InvalidInterfaceException($collection_interface);
198 198
         }
199 199
         $this->collection_interface = $collection_interface;
@@ -221,7 +221,7 @@  discard block
 block discarded – undo
221 221
      */
222 222
     protected function setCollectionName($collection_name)
223 223
     {
224
-        if (! is_string($collection_name)) {
224
+        if ( ! is_string($collection_name)) {
225 225
             throw new InvalidDataTypeException('$collection_name', $collection_name, 'string');
226 226
         }
227 227
         $this->collection_name = str_replace(
@@ -281,7 +281,7 @@  discard block
 block discarded – undo
281 281
      */
282 282
     protected function setIdentifierCallback($identifier_callback = 'identifier')
283 283
     {
284
-        if (! is_string($identifier_callback)) {
284
+        if ( ! is_string($identifier_callback)) {
285 285
             throw new InvalidDataTypeException('$identifier_callback', $identifier_callback, 'string');
286 286
         }
287 287
         $this->identifier_callback = $identifier_callback;
@@ -311,7 +311,7 @@  discard block
 block discarded – undo
311 311
         $this->file_mask = ! empty($file_mask) ? $file_mask : '*.php';
312 312
         // we know our default is a string, so if it's not a string now,
313 313
         // then that means the incoming parameter was something else
314
-        if (! is_string($this->file_mask)) {
314
+        if ( ! is_string($this->file_mask)) {
315 315
             throw new InvalidDataTypeException('$file_mask', $this->file_mask, 'string');
316 316
         }
317 317
     }
@@ -336,7 +336,7 @@  discard block
 block discarded – undo
336 336
     public function setCollectionFQCNs($collection_FQCNs)
337 337
     {
338 338
         foreach ((array) $collection_FQCNs as $collection_FQCN) {
339
-            if (! empty($collection_FQCN)) {
339
+            if ( ! empty($collection_FQCN)) {
340 340
                 if (class_exists($collection_FQCN)) {
341 341
                     $this->collection_FQCNs[] = $collection_FQCN;
342 342
                 } else {
@@ -358,7 +358,7 @@  discard block
 block discarded – undo
358 358
      */
359 359
     protected function getFQCNsFromPartialNamespace($partial_FQCN)
360 360
     {
361
-        if (! $this->file_locator instanceof FqcnLocator) {
361
+        if ( ! $this->file_locator instanceof FqcnLocator) {
362 362
             $this->file_locator = new FqcnLocator();
363 363
         }
364 364
         $this->file_locator->locate($partial_FQCN);
@@ -384,8 +384,8 @@  discard block
 block discarded – undo
384 384
     public function setCollectionPaths($collection_paths)
385 385
     {
386 386
         foreach ((array) $collection_paths as $collection_path) {
387
-            if (! empty($collection_path)) {
388
-                if (! is_readable($collection_path)) {
387
+            if ( ! empty($collection_path)) {
388
+                if ( ! is_readable($collection_path)) {
389 389
                     throw new InvalidFilePathException($collection_path);
390 390
                 }
391 391
                 $this->collection_paths[] = $collection_path;
Please login to merge, or discard this patch.
core/services/notifications/PersistentAdminNoticeManager.php 2 patches
Spacing   +9 added lines, -9 removed lines patch added patch discarded remove patch
@@ -85,7 +85,7 @@  discard block
 block discarded – undo
85 85
      */
86 86
     public function setReturnUrl($return_url)
87 87
     {
88
-        if (! is_string($return_url)) {
88
+        if ( ! is_string($return_url)) {
89 89
             throw new InvalidDataTypeException('$return_url', $return_url, 'string');
90 90
         }
91 91
         $this->return_url = $return_url;
@@ -102,7 +102,7 @@  discard block
 block discarded – undo
102 102
      */
103 103
     protected function getPersistentAdminNoticeCollection()
104 104
     {
105
-        if (! $this->notice_collection instanceof Collection) {
105
+        if ( ! $this->notice_collection instanceof Collection) {
106 106
             $this->notice_collection = new Collection(
107 107
                 'EventEspresso\core\domain\entities\notifications\PersistentAdminNotice'
108 108
             );
@@ -125,7 +125,7 @@  discard block
 block discarded – undo
125 125
     protected function retrieveStoredNotices()
126 126
     {
127 127
         $persistent_admin_notices = get_option(PersistentAdminNoticeManager::WP_OPTION_KEY, array());
128
-        if (! empty($persistent_admin_notices)) {
128
+        if ( ! empty($persistent_admin_notices)) {
129 129
             foreach ($persistent_admin_notices as $name => $details) {
130 130
                 if (is_array($details)) {
131 131
                     if (
@@ -247,14 +247,14 @@  discard block
 block discarded – undo
247 247
     {
248 248
         wp_register_script(
249 249
             'espresso_core',
250
-            EE_GLOBAL_ASSETS_URL . 'scripts/espresso_core.js',
250
+            EE_GLOBAL_ASSETS_URL.'scripts/espresso_core.js',
251 251
             array('jquery'),
252 252
             EVENT_ESPRESSO_VERSION,
253 253
             true
254 254
         );
255 255
         wp_register_script(
256 256
             'ee_error_js',
257
-            EE_GLOBAL_ASSETS_URL . 'scripts/EE_Error.js',
257
+            EE_GLOBAL_ASSETS_URL.'scripts/EE_Error.js',
258 258
             array('espresso_core'),
259 259
             EVENT_ESPRESSO_VERSION,
260 260
             true
@@ -285,7 +285,7 @@  discard block
 block discarded – undo
285 285
         // used in template
286 286
         $persistent_admin_notice_name = $persistent_admin_notice->getName();
287 287
         $persistent_admin_notice_message = $persistent_admin_notice->getMessage();
288
-        require EE_TEMPLATES . '/notifications/persistent_admin_notice.template.php';
288
+        require EE_TEMPLATES.'/notifications/persistent_admin_notice.template.php';
289 289
     }
290 290
 
291 291
 
@@ -310,7 +310,7 @@  discard block
 block discarded – undo
310 310
     {
311 311
         $pan_name = $this->request->getRequestParam('ee_nag_notice', $pan_name);
312 312
         $this->notice_collection = $this->getPersistentAdminNoticeCollection();
313
-        if (! empty($pan_name) && $this->notice_collection->has($pan_name)) {
313
+        if ( ! empty($pan_name) && $this->notice_collection->has($pan_name)) {
314 314
             /** @var PersistentAdminNotice $persistent_admin_notice */
315 315
             $persistent_admin_notice = $this->notice_collection->get($pan_name);
316 316
             $persistent_admin_notice->setDismissed(true);
@@ -360,10 +360,10 @@  discard block
 block discarded – undo
360 360
             foreach ($this->notice_collection as $persistent_admin_notice) {
361 361
                 // are we deleting this notice ?
362 362
                 if ($persistent_admin_notice->getPurge()) {
363
-                    unset($persistent_admin_notices[ $persistent_admin_notice->getName() ]);
363
+                    unset($persistent_admin_notices[$persistent_admin_notice->getName()]);
364 364
                 } else {
365 365
                     /** @var PersistentAdminNotice $persistent_admin_notice */
366
-                    $persistent_admin_notices[ $persistent_admin_notice->getName() ] = array(
366
+                    $persistent_admin_notices[$persistent_admin_notice->getName()] = array(
367 367
                         'message'     => $persistent_admin_notice->getMessage(),
368 368
                         'capability'  => $persistent_admin_notice->getCapability(),
369 369
                         'cap_context' => $persistent_admin_notice->getCapContext(),
Please login to merge, or discard this patch.
Indentation   +385 added lines, -385 removed lines patch added patch discarded remove patch
@@ -31,389 +31,389 @@
 block discarded – undo
31 31
 class PersistentAdminNoticeManager
32 32
 {
33 33
 
34
-    const WP_OPTION_KEY = 'ee_pers_admin_notices';
35
-
36
-    /**
37
-     * @var Collection|PersistentAdminNotice[] $notice_collection
38
-     */
39
-    private $notice_collection;
40
-
41
-    /**
42
-     * if AJAX is not enabled, then the return URL will be used for redirecting back to the admin page where the
43
-     * persistent admin notice was displayed, and ultimately dismissed from.
44
-     *
45
-     * @var string $return_url
46
-     */
47
-    private $return_url;
48
-
49
-    /**
50
-     * @var CapabilitiesChecker $capabilities_checker
51
-     */
52
-    private $capabilities_checker;
53
-
54
-    /**
55
-     * @var RequestInterface $request
56
-     */
57
-    private $request;
58
-
59
-
60
-    /**
61
-     * PersistentAdminNoticeManager constructor
62
-     *
63
-     * @param string              $return_url where to  redirect to after dismissing notices
64
-     * @param CapabilitiesChecker $capabilities_checker
65
-     * @param RequestInterface          $request
66
-     * @throws InvalidDataTypeException
67
-     */
68
-    public function __construct($return_url = '', CapabilitiesChecker $capabilities_checker, RequestInterface $request)
69
-    {
70
-        $this->setReturnUrl($return_url);
71
-        $this->capabilities_checker = $capabilities_checker;
72
-        $this->request = $request;
73
-        // setup up notices at priority 9 because `EE_Admin::display_admin_notices()` runs at priority 10,
74
-        // and we want to retrieve and generate any nag notices at the last possible moment
75
-        add_action('admin_notices', array($this, 'displayNotices'), 9);
76
-        add_action('network_admin_notices', array($this, 'displayNotices'), 9);
77
-        add_action('wp_ajax_dismiss_ee_nag_notice', array($this, 'dismissNotice'));
78
-        add_action('shutdown', array($this, 'registerAndSaveNotices'), 998);
79
-    }
80
-
81
-
82
-    /**
83
-     * @param string $return_url
84
-     * @throws InvalidDataTypeException
85
-     */
86
-    public function setReturnUrl($return_url)
87
-    {
88
-        if (! is_string($return_url)) {
89
-            throw new InvalidDataTypeException('$return_url', $return_url, 'string');
90
-        }
91
-        $this->return_url = $return_url;
92
-    }
93
-
94
-
95
-    /**
96
-     * @return Collection
97
-     * @throws InvalidEntityException
98
-     * @throws InvalidInterfaceException
99
-     * @throws InvalidDataTypeException
100
-     * @throws DomainException
101
-     * @throws DuplicateCollectionIdentifierException
102
-     */
103
-    protected function getPersistentAdminNoticeCollection()
104
-    {
105
-        if (! $this->notice_collection instanceof Collection) {
106
-            $this->notice_collection = new Collection(
107
-                'EventEspresso\core\domain\entities\notifications\PersistentAdminNotice'
108
-            );
109
-            $this->retrieveStoredNotices();
110
-            $this->registerNotices();
111
-        }
112
-        return $this->notice_collection;
113
-    }
114
-
115
-
116
-    /**
117
-     * generates PersistentAdminNotice objects for all non-dismissed notices saved to the db
118
-     *
119
-     * @return void
120
-     * @throws InvalidEntityException
121
-     * @throws DomainException
122
-     * @throws InvalidDataTypeException
123
-     * @throws DuplicateCollectionIdentifierException
124
-     */
125
-    protected function retrieveStoredNotices()
126
-    {
127
-        $persistent_admin_notices = get_option(PersistentAdminNoticeManager::WP_OPTION_KEY, array());
128
-        if (! empty($persistent_admin_notices)) {
129
-            foreach ($persistent_admin_notices as $name => $details) {
130
-                if (is_array($details)) {
131
-                    if (
132
-                        ! isset(
133
-                            $details['message'],
134
-                            $details['capability'],
135
-                            $details['cap_context'],
136
-                            $details['dismissed']
137
-                        )
138
-                    ) {
139
-                        throw new DomainException(
140
-                            sprintf(
141
-                                esc_html__(
142
-                                    'The "%1$s" PersistentAdminNotice could not be retrieved from the database.',
143
-                                    'event_espresso'
144
-                                ),
145
-                                $name
146
-                            )
147
-                        );
148
-                    }
149
-                    // new format for nag notices
150
-                    $this->notice_collection->add(
151
-                        new PersistentAdminNotice(
152
-                            $name,
153
-                            $details['message'],
154
-                            false,
155
-                            $details['capability'],
156
-                            $details['cap_context'],
157
-                            $details['dismissed']
158
-                        ),
159
-                        sanitize_key($name)
160
-                    );
161
-                } else {
162
-                    try {
163
-                        // old nag notices, that we want to convert to the new format
164
-                        $this->notice_collection->add(
165
-                            new PersistentAdminNotice(
166
-                                $name,
167
-                                (string) $details,
168
-                                false,
169
-                                '',
170
-                                '',
171
-                                empty($details)
172
-                            ),
173
-                            sanitize_key($name)
174
-                        );
175
-                    } catch (Exception $e) {
176
-                        EE_Error::add_error($e->getMessage(), __FILE__, __FUNCTION__, __LINE__);
177
-                    }
178
-                }
179
-                // each notice will self register when the action hook in registerNotices is triggered
180
-            }
181
-        }
182
-    }
183
-
184
-
185
-    /**
186
-     * exposes the Persistent Admin Notice Collection via an action
187
-     * so that PersistentAdminNotice objects can be added and/or removed
188
-     * without compromising the actual collection like a filter would
189
-     */
190
-    protected function registerNotices()
191
-    {
192
-        do_action(
193
-            'AHEE__EventEspresso_core_services_notifications_PersistentAdminNoticeManager__registerNotices',
194
-            $this->notice_collection
195
-        );
196
-    }
197
-
198
-
199
-    /**
200
-     * @throws DomainException
201
-     * @throws InvalidClassException
202
-     * @throws InvalidDataTypeException
203
-     * @throws InvalidInterfaceException
204
-     * @throws InvalidEntityException
205
-     * @throws DuplicateCollectionIdentifierException
206
-     */
207
-    public function displayNotices()
208
-    {
209
-        $this->notice_collection = $this->getPersistentAdminNoticeCollection();
210
-        if ($this->notice_collection->hasObjects()) {
211
-            $enqueue_assets = false;
212
-            // and display notices
213
-            foreach ($this->notice_collection as $persistent_admin_notice) {
214
-                /** @var PersistentAdminNotice $persistent_admin_notice */
215
-                // don't display notices that have already been dismissed
216
-                if ($persistent_admin_notice->getDismissed()) {
217
-                    continue;
218
-                }
219
-                try {
220
-                    $this->capabilities_checker->processCapCheck(
221
-                        $persistent_admin_notice->getCapCheck()
222
-                    );
223
-                } catch (InsufficientPermissionsException $e) {
224
-                    // user does not have required cap, so skip to next notice
225
-                    // and just eat the exception - nom nom nom nom
226
-                    continue;
227
-                }
228
-                if ($persistent_admin_notice->getMessage() === '') {
229
-                    continue;
230
-                }
231
-                $this->displayPersistentAdminNotice($persistent_admin_notice);
232
-                $enqueue_assets = true;
233
-            }
234
-            if ($enqueue_assets) {
235
-                $this->enqueueAssets();
236
-            }
237
-        }
238
-    }
239
-
240
-
241
-    /**
242
-     * does what it's named
243
-     *
244
-     * @return void
245
-     */
246
-    public function enqueueAssets()
247
-    {
248
-        wp_register_script(
249
-            'espresso_core',
250
-            EE_GLOBAL_ASSETS_URL . 'scripts/espresso_core.js',
251
-            array('jquery'),
252
-            EVENT_ESPRESSO_VERSION,
253
-            true
254
-        );
255
-        wp_register_script(
256
-            'ee_error_js',
257
-            EE_GLOBAL_ASSETS_URL . 'scripts/EE_Error.js',
258
-            array('espresso_core'),
259
-            EVENT_ESPRESSO_VERSION,
260
-            true
261
-        );
262
-        wp_localize_script(
263
-            'ee_error_js',
264
-            'ee_dismiss',
265
-            array(
266
-                'return_url'    => urlencode($this->return_url),
267
-                'ajax_url'      => WP_AJAX_URL,
268
-                'unknown_error' => wp_strip_all_tags(
269
-                    __(
270
-                        'An unknown error has occurred on the server while attempting to dismiss this notice.',
271
-                        'event_espresso'
272
-                    )
273
-                ),
274
-            )
275
-        );
276
-        wp_enqueue_script('ee_error_js');
277
-    }
278
-
279
-
280
-    /**
281
-     * displayPersistentAdminNoticeHtml
282
-     *
283
-     * @param  PersistentAdminNotice $persistent_admin_notice
284
-     */
285
-    protected function displayPersistentAdminNotice(PersistentAdminNotice $persistent_admin_notice)
286
-    {
287
-        // used in template
288
-        $persistent_admin_notice_name = $persistent_admin_notice->getName();
289
-        $persistent_admin_notice_message = $persistent_admin_notice->getMessage();
290
-        require EE_TEMPLATES . '/notifications/persistent_admin_notice.template.php';
291
-    }
292
-
293
-
294
-    /**
295
-     * dismissNotice
296
-     *
297
-     * @param string $pan_name the name, or key of the Persistent Admin Notice to be dismissed
298
-     * @param bool   $purge    if true, then delete it from the db
299
-     * @param bool   $return   forget all of this AJAX or redirect nonsense, and just return
300
-     * @return void
301
-     * @throws InvalidEntityException
302
-     * @throws InvalidInterfaceException
303
-     * @throws InvalidDataTypeException
304
-     * @throws DomainException
305
-     * @throws InvalidArgumentException
306
-     * @throws InvalidArgumentException
307
-     * @throws InvalidArgumentException
308
-     * @throws InvalidArgumentException
309
-     * @throws DuplicateCollectionIdentifierException
310
-     */
311
-    public function dismissNotice($pan_name = '', $purge = false, $return = false)
312
-    {
313
-        $pan_name = $this->request->getRequestParam('ee_nag_notice', $pan_name);
314
-        $this->notice_collection = $this->getPersistentAdminNoticeCollection();
315
-        if (! empty($pan_name) && $this->notice_collection->has($pan_name)) {
316
-            /** @var PersistentAdminNotice $persistent_admin_notice */
317
-            $persistent_admin_notice = $this->notice_collection->get($pan_name);
318
-            $persistent_admin_notice->setDismissed(true);
319
-            $persistent_admin_notice->setPurge($purge);
320
-            $this->saveNotices();
321
-        }
322
-        if ($return) {
323
-            return;
324
-        }
325
-        if ($this->request->isAjax()) {
326
-            // grab any notices and concatenate into string
327
-            echo wp_json_encode(
328
-                array(
329
-                    'errors' => implode('<br />', EE_Error::get_notices(false)),
330
-                )
331
-            );
332
-            exit();
333
-        }
334
-        // save errors to a transient to be displayed on next request (after redirect)
335
-        EE_Error::get_notices(false, true);
336
-        wp_safe_redirect(
337
-            urldecode(
338
-                $this->request->getRequestParam('return_url', '')
339
-            )
340
-        );
341
-    }
342
-
343
-
344
-    /**
345
-     * saveNotices
346
-     *
347
-     * @throws DomainException
348
-     * @throws InvalidDataTypeException
349
-     * @throws InvalidInterfaceException
350
-     * @throws InvalidEntityException
351
-     * @throws DuplicateCollectionIdentifierException
352
-     */
353
-    public function saveNotices()
354
-    {
355
-        $this->notice_collection = $this->getPersistentAdminNoticeCollection();
356
-        if ($this->notice_collection->hasObjects()) {
357
-            $persistent_admin_notices = get_option(PersistentAdminNoticeManager::WP_OPTION_KEY, array());
358
-            // maybe initialize persistent_admin_notices
359
-            if (empty($persistent_admin_notices)) {
360
-                add_option(PersistentAdminNoticeManager::WP_OPTION_KEY, array(), '', 'no');
361
-            }
362
-            foreach ($this->notice_collection as $persistent_admin_notice) {
363
-                // are we deleting this notice ?
364
-                if ($persistent_admin_notice->getPurge()) {
365
-                    unset($persistent_admin_notices[ $persistent_admin_notice->getName() ]);
366
-                } else {
367
-                    /** @var PersistentAdminNotice $persistent_admin_notice */
368
-                    $persistent_admin_notices[ $persistent_admin_notice->getName() ] = array(
369
-                        'message'     => $persistent_admin_notice->getMessage(),
370
-                        'capability'  => $persistent_admin_notice->getCapability(),
371
-                        'cap_context' => $persistent_admin_notice->getCapContext(),
372
-                        'dismissed'   => $persistent_admin_notice->getDismissed(),
373
-                    );
374
-                }
375
-            }
376
-            update_option(PersistentAdminNoticeManager::WP_OPTION_KEY, $persistent_admin_notices);
377
-        }
378
-    }
379
-
380
-
381
-    /**
382
-     * @throws DomainException
383
-     * @throws InvalidDataTypeException
384
-     * @throws InvalidEntityException
385
-     * @throws InvalidInterfaceException
386
-     * @throws DuplicateCollectionIdentifierException
387
-     */
388
-    public function registerAndSaveNotices()
389
-    {
390
-        $this->getPersistentAdminNoticeCollection();
391
-        $this->registerNotices();
392
-        $this->saveNotices();
393
-        add_filter(
394
-            'PersistentAdminNoticeManager__registerAndSaveNotices__complete',
395
-            '__return_true'
396
-        );
397
-    }
398
-
399
-
400
-    /**
401
-     * @throws DomainException
402
-     * @throws InvalidDataTypeException
403
-     * @throws InvalidEntityException
404
-     * @throws InvalidInterfaceException
405
-     * @throws InvalidArgumentException
406
-     * @throws DuplicateCollectionIdentifierException
407
-     */
408
-    public static function loadRegisterAndSaveNotices()
409
-    {
410
-        /** @var PersistentAdminNoticeManager $persistent_admin_notice_manager */
411
-        $persistent_admin_notice_manager = LoaderFactory::getLoader()->getShared(
412
-            'EventEspresso\core\services\notifications\PersistentAdminNoticeManager'
413
-        );
414
-        // if shutdown has already run, then call registerAndSaveNotices() manually
415
-        if (did_action('shutdown')) {
416
-            $persistent_admin_notice_manager->registerAndSaveNotices();
417
-        }
418
-    }
34
+	const WP_OPTION_KEY = 'ee_pers_admin_notices';
35
+
36
+	/**
37
+	 * @var Collection|PersistentAdminNotice[] $notice_collection
38
+	 */
39
+	private $notice_collection;
40
+
41
+	/**
42
+	 * if AJAX is not enabled, then the return URL will be used for redirecting back to the admin page where the
43
+	 * persistent admin notice was displayed, and ultimately dismissed from.
44
+	 *
45
+	 * @var string $return_url
46
+	 */
47
+	private $return_url;
48
+
49
+	/**
50
+	 * @var CapabilitiesChecker $capabilities_checker
51
+	 */
52
+	private $capabilities_checker;
53
+
54
+	/**
55
+	 * @var RequestInterface $request
56
+	 */
57
+	private $request;
58
+
59
+
60
+	/**
61
+	 * PersistentAdminNoticeManager constructor
62
+	 *
63
+	 * @param string              $return_url where to  redirect to after dismissing notices
64
+	 * @param CapabilitiesChecker $capabilities_checker
65
+	 * @param RequestInterface          $request
66
+	 * @throws InvalidDataTypeException
67
+	 */
68
+	public function __construct($return_url = '', CapabilitiesChecker $capabilities_checker, RequestInterface $request)
69
+	{
70
+		$this->setReturnUrl($return_url);
71
+		$this->capabilities_checker = $capabilities_checker;
72
+		$this->request = $request;
73
+		// setup up notices at priority 9 because `EE_Admin::display_admin_notices()` runs at priority 10,
74
+		// and we want to retrieve and generate any nag notices at the last possible moment
75
+		add_action('admin_notices', array($this, 'displayNotices'), 9);
76
+		add_action('network_admin_notices', array($this, 'displayNotices'), 9);
77
+		add_action('wp_ajax_dismiss_ee_nag_notice', array($this, 'dismissNotice'));
78
+		add_action('shutdown', array($this, 'registerAndSaveNotices'), 998);
79
+	}
80
+
81
+
82
+	/**
83
+	 * @param string $return_url
84
+	 * @throws InvalidDataTypeException
85
+	 */
86
+	public function setReturnUrl($return_url)
87
+	{
88
+		if (! is_string($return_url)) {
89
+			throw new InvalidDataTypeException('$return_url', $return_url, 'string');
90
+		}
91
+		$this->return_url = $return_url;
92
+	}
93
+
94
+
95
+	/**
96
+	 * @return Collection
97
+	 * @throws InvalidEntityException
98
+	 * @throws InvalidInterfaceException
99
+	 * @throws InvalidDataTypeException
100
+	 * @throws DomainException
101
+	 * @throws DuplicateCollectionIdentifierException
102
+	 */
103
+	protected function getPersistentAdminNoticeCollection()
104
+	{
105
+		if (! $this->notice_collection instanceof Collection) {
106
+			$this->notice_collection = new Collection(
107
+				'EventEspresso\core\domain\entities\notifications\PersistentAdminNotice'
108
+			);
109
+			$this->retrieveStoredNotices();
110
+			$this->registerNotices();
111
+		}
112
+		return $this->notice_collection;
113
+	}
114
+
115
+
116
+	/**
117
+	 * generates PersistentAdminNotice objects for all non-dismissed notices saved to the db
118
+	 *
119
+	 * @return void
120
+	 * @throws InvalidEntityException
121
+	 * @throws DomainException
122
+	 * @throws InvalidDataTypeException
123
+	 * @throws DuplicateCollectionIdentifierException
124
+	 */
125
+	protected function retrieveStoredNotices()
126
+	{
127
+		$persistent_admin_notices = get_option(PersistentAdminNoticeManager::WP_OPTION_KEY, array());
128
+		if (! empty($persistent_admin_notices)) {
129
+			foreach ($persistent_admin_notices as $name => $details) {
130
+				if (is_array($details)) {
131
+					if (
132
+						! isset(
133
+							$details['message'],
134
+							$details['capability'],
135
+							$details['cap_context'],
136
+							$details['dismissed']
137
+						)
138
+					) {
139
+						throw new DomainException(
140
+							sprintf(
141
+								esc_html__(
142
+									'The "%1$s" PersistentAdminNotice could not be retrieved from the database.',
143
+									'event_espresso'
144
+								),
145
+								$name
146
+							)
147
+						);
148
+					}
149
+					// new format for nag notices
150
+					$this->notice_collection->add(
151
+						new PersistentAdminNotice(
152
+							$name,
153
+							$details['message'],
154
+							false,
155
+							$details['capability'],
156
+							$details['cap_context'],
157
+							$details['dismissed']
158
+						),
159
+						sanitize_key($name)
160
+					);
161
+				} else {
162
+					try {
163
+						// old nag notices, that we want to convert to the new format
164
+						$this->notice_collection->add(
165
+							new PersistentAdminNotice(
166
+								$name,
167
+								(string) $details,
168
+								false,
169
+								'',
170
+								'',
171
+								empty($details)
172
+							),
173
+							sanitize_key($name)
174
+						);
175
+					} catch (Exception $e) {
176
+						EE_Error::add_error($e->getMessage(), __FILE__, __FUNCTION__, __LINE__);
177
+					}
178
+				}
179
+				// each notice will self register when the action hook in registerNotices is triggered
180
+			}
181
+		}
182
+	}
183
+
184
+
185
+	/**
186
+	 * exposes the Persistent Admin Notice Collection via an action
187
+	 * so that PersistentAdminNotice objects can be added and/or removed
188
+	 * without compromising the actual collection like a filter would
189
+	 */
190
+	protected function registerNotices()
191
+	{
192
+		do_action(
193
+			'AHEE__EventEspresso_core_services_notifications_PersistentAdminNoticeManager__registerNotices',
194
+			$this->notice_collection
195
+		);
196
+	}
197
+
198
+
199
+	/**
200
+	 * @throws DomainException
201
+	 * @throws InvalidClassException
202
+	 * @throws InvalidDataTypeException
203
+	 * @throws InvalidInterfaceException
204
+	 * @throws InvalidEntityException
205
+	 * @throws DuplicateCollectionIdentifierException
206
+	 */
207
+	public function displayNotices()
208
+	{
209
+		$this->notice_collection = $this->getPersistentAdminNoticeCollection();
210
+		if ($this->notice_collection->hasObjects()) {
211
+			$enqueue_assets = false;
212
+			// and display notices
213
+			foreach ($this->notice_collection as $persistent_admin_notice) {
214
+				/** @var PersistentAdminNotice $persistent_admin_notice */
215
+				// don't display notices that have already been dismissed
216
+				if ($persistent_admin_notice->getDismissed()) {
217
+					continue;
218
+				}
219
+				try {
220
+					$this->capabilities_checker->processCapCheck(
221
+						$persistent_admin_notice->getCapCheck()
222
+					);
223
+				} catch (InsufficientPermissionsException $e) {
224
+					// user does not have required cap, so skip to next notice
225
+					// and just eat the exception - nom nom nom nom
226
+					continue;
227
+				}
228
+				if ($persistent_admin_notice->getMessage() === '') {
229
+					continue;
230
+				}
231
+				$this->displayPersistentAdminNotice($persistent_admin_notice);
232
+				$enqueue_assets = true;
233
+			}
234
+			if ($enqueue_assets) {
235
+				$this->enqueueAssets();
236
+			}
237
+		}
238
+	}
239
+
240
+
241
+	/**
242
+	 * does what it's named
243
+	 *
244
+	 * @return void
245
+	 */
246
+	public function enqueueAssets()
247
+	{
248
+		wp_register_script(
249
+			'espresso_core',
250
+			EE_GLOBAL_ASSETS_URL . 'scripts/espresso_core.js',
251
+			array('jquery'),
252
+			EVENT_ESPRESSO_VERSION,
253
+			true
254
+		);
255
+		wp_register_script(
256
+			'ee_error_js',
257
+			EE_GLOBAL_ASSETS_URL . 'scripts/EE_Error.js',
258
+			array('espresso_core'),
259
+			EVENT_ESPRESSO_VERSION,
260
+			true
261
+		);
262
+		wp_localize_script(
263
+			'ee_error_js',
264
+			'ee_dismiss',
265
+			array(
266
+				'return_url'    => urlencode($this->return_url),
267
+				'ajax_url'      => WP_AJAX_URL,
268
+				'unknown_error' => wp_strip_all_tags(
269
+					__(
270
+						'An unknown error has occurred on the server while attempting to dismiss this notice.',
271
+						'event_espresso'
272
+					)
273
+				),
274
+			)
275
+		);
276
+		wp_enqueue_script('ee_error_js');
277
+	}
278
+
279
+
280
+	/**
281
+	 * displayPersistentAdminNoticeHtml
282
+	 *
283
+	 * @param  PersistentAdminNotice $persistent_admin_notice
284
+	 */
285
+	protected function displayPersistentAdminNotice(PersistentAdminNotice $persistent_admin_notice)
286
+	{
287
+		// used in template
288
+		$persistent_admin_notice_name = $persistent_admin_notice->getName();
289
+		$persistent_admin_notice_message = $persistent_admin_notice->getMessage();
290
+		require EE_TEMPLATES . '/notifications/persistent_admin_notice.template.php';
291
+	}
292
+
293
+
294
+	/**
295
+	 * dismissNotice
296
+	 *
297
+	 * @param string $pan_name the name, or key of the Persistent Admin Notice to be dismissed
298
+	 * @param bool   $purge    if true, then delete it from the db
299
+	 * @param bool   $return   forget all of this AJAX or redirect nonsense, and just return
300
+	 * @return void
301
+	 * @throws InvalidEntityException
302
+	 * @throws InvalidInterfaceException
303
+	 * @throws InvalidDataTypeException
304
+	 * @throws DomainException
305
+	 * @throws InvalidArgumentException
306
+	 * @throws InvalidArgumentException
307
+	 * @throws InvalidArgumentException
308
+	 * @throws InvalidArgumentException
309
+	 * @throws DuplicateCollectionIdentifierException
310
+	 */
311
+	public function dismissNotice($pan_name = '', $purge = false, $return = false)
312
+	{
313
+		$pan_name = $this->request->getRequestParam('ee_nag_notice', $pan_name);
314
+		$this->notice_collection = $this->getPersistentAdminNoticeCollection();
315
+		if (! empty($pan_name) && $this->notice_collection->has($pan_name)) {
316
+			/** @var PersistentAdminNotice $persistent_admin_notice */
317
+			$persistent_admin_notice = $this->notice_collection->get($pan_name);
318
+			$persistent_admin_notice->setDismissed(true);
319
+			$persistent_admin_notice->setPurge($purge);
320
+			$this->saveNotices();
321
+		}
322
+		if ($return) {
323
+			return;
324
+		}
325
+		if ($this->request->isAjax()) {
326
+			// grab any notices and concatenate into string
327
+			echo wp_json_encode(
328
+				array(
329
+					'errors' => implode('<br />', EE_Error::get_notices(false)),
330
+				)
331
+			);
332
+			exit();
333
+		}
334
+		// save errors to a transient to be displayed on next request (after redirect)
335
+		EE_Error::get_notices(false, true);
336
+		wp_safe_redirect(
337
+			urldecode(
338
+				$this->request->getRequestParam('return_url', '')
339
+			)
340
+		);
341
+	}
342
+
343
+
344
+	/**
345
+	 * saveNotices
346
+	 *
347
+	 * @throws DomainException
348
+	 * @throws InvalidDataTypeException
349
+	 * @throws InvalidInterfaceException
350
+	 * @throws InvalidEntityException
351
+	 * @throws DuplicateCollectionIdentifierException
352
+	 */
353
+	public function saveNotices()
354
+	{
355
+		$this->notice_collection = $this->getPersistentAdminNoticeCollection();
356
+		if ($this->notice_collection->hasObjects()) {
357
+			$persistent_admin_notices = get_option(PersistentAdminNoticeManager::WP_OPTION_KEY, array());
358
+			// maybe initialize persistent_admin_notices
359
+			if (empty($persistent_admin_notices)) {
360
+				add_option(PersistentAdminNoticeManager::WP_OPTION_KEY, array(), '', 'no');
361
+			}
362
+			foreach ($this->notice_collection as $persistent_admin_notice) {
363
+				// are we deleting this notice ?
364
+				if ($persistent_admin_notice->getPurge()) {
365
+					unset($persistent_admin_notices[ $persistent_admin_notice->getName() ]);
366
+				} else {
367
+					/** @var PersistentAdminNotice $persistent_admin_notice */
368
+					$persistent_admin_notices[ $persistent_admin_notice->getName() ] = array(
369
+						'message'     => $persistent_admin_notice->getMessage(),
370
+						'capability'  => $persistent_admin_notice->getCapability(),
371
+						'cap_context' => $persistent_admin_notice->getCapContext(),
372
+						'dismissed'   => $persistent_admin_notice->getDismissed(),
373
+					);
374
+				}
375
+			}
376
+			update_option(PersistentAdminNoticeManager::WP_OPTION_KEY, $persistent_admin_notices);
377
+		}
378
+	}
379
+
380
+
381
+	/**
382
+	 * @throws DomainException
383
+	 * @throws InvalidDataTypeException
384
+	 * @throws InvalidEntityException
385
+	 * @throws InvalidInterfaceException
386
+	 * @throws DuplicateCollectionIdentifierException
387
+	 */
388
+	public function registerAndSaveNotices()
389
+	{
390
+		$this->getPersistentAdminNoticeCollection();
391
+		$this->registerNotices();
392
+		$this->saveNotices();
393
+		add_filter(
394
+			'PersistentAdminNoticeManager__registerAndSaveNotices__complete',
395
+			'__return_true'
396
+		);
397
+	}
398
+
399
+
400
+	/**
401
+	 * @throws DomainException
402
+	 * @throws InvalidDataTypeException
403
+	 * @throws InvalidEntityException
404
+	 * @throws InvalidInterfaceException
405
+	 * @throws InvalidArgumentException
406
+	 * @throws DuplicateCollectionIdentifierException
407
+	 */
408
+	public static function loadRegisterAndSaveNotices()
409
+	{
410
+		/** @var PersistentAdminNoticeManager $persistent_admin_notice_manager */
411
+		$persistent_admin_notice_manager = LoaderFactory::getLoader()->getShared(
412
+			'EventEspresso\core\services\notifications\PersistentAdminNoticeManager'
413
+		);
414
+		// if shutdown has already run, then call registerAndSaveNotices() manually
415
+		if (did_action('shutdown')) {
416
+			$persistent_admin_notice_manager->registerAndSaveNotices();
417
+		}
418
+	}
419 419
 }
Please login to merge, or discard this patch.
core/services/database/TableAnalysis.php 2 patches
Spacing   +2 added lines, -2 removed lines patch added patch discarded remove patch
@@ -32,7 +32,7 @@  discard block
 block discarded – undo
32 32
     public function ensureTableNameHasPrefix($table_name)
33 33
     {
34 34
         global $wpdb;
35
-        return strpos($table_name, $wpdb->base_prefix) === 0 ? $table_name : $wpdb->prefix . $table_name;
35
+        return strpos($table_name, $wpdb->base_prefix) === 0 ? $table_name : $wpdb->prefix.$table_name;
36 36
     }
37 37
 
38 38
 
@@ -81,7 +81,7 @@  discard block
 block discarded – undo
81 81
         $wpdb->last_error = $old_error;
82 82
         $EZSQL_ERROR = $ezsql_error_cache;
83 83
         // if there was a table doesn't exist error
84
-        if (! empty($new_error)) {
84
+        if ( ! empty($new_error)) {
85 85
             if (
86 86
                 in_array(
87 87
                     \EEH_Activation::last_wpdb_error_code(),
Please login to merge, or discard this patch.
Indentation   +121 added lines, -121 removed lines patch added patch discarded remove patch
@@ -14,132 +14,132 @@
 block discarded – undo
14 14
 class TableAnalysis extends \EE_Base
15 15
 {
16 16
 
17
-    /**
18
-     * The maximum number of characters that can be indexed on a column using utf8mb4 collation,
19
-     * see https://events.codebasehq.com/redirect?https://make.wordpress.org/core/2015/04/02/the-utf8mb4-upgrade/
20
-     */
21
-    const INDEX_COLUMN_SIZE = 191;
17
+	/**
18
+	 * The maximum number of characters that can be indexed on a column using utf8mb4 collation,
19
+	 * see https://events.codebasehq.com/redirect?https://make.wordpress.org/core/2015/04/02/the-utf8mb4-upgrade/
20
+	 */
21
+	const INDEX_COLUMN_SIZE = 191;
22 22
 
23
-    /**
24
-     * Returns the table name which will definitely have the wpdb prefix on the front,
25
-     * except if it currently has the wpdb->base_prefix on the front, in which case
26
-     * it will have the wpdb->base_prefix on it
27
-     *
28
-     * @global \wpdb $wpdb
29
-     * @param string $table_name
30
-     * @return string $tableName, having ensured it has the wpdb prefix on the front
31
-     */
32
-    public function ensureTableNameHasPrefix($table_name)
33
-    {
34
-        global $wpdb;
35
-        return strpos($table_name, $wpdb->base_prefix) === 0 ? $table_name : $wpdb->prefix . $table_name;
36
-    }
23
+	/**
24
+	 * Returns the table name which will definitely have the wpdb prefix on the front,
25
+	 * except if it currently has the wpdb->base_prefix on the front, in which case
26
+	 * it will have the wpdb->base_prefix on it
27
+	 *
28
+	 * @global \wpdb $wpdb
29
+	 * @param string $table_name
30
+	 * @return string $tableName, having ensured it has the wpdb prefix on the front
31
+	 */
32
+	public function ensureTableNameHasPrefix($table_name)
33
+	{
34
+		global $wpdb;
35
+		return strpos($table_name, $wpdb->base_prefix) === 0 ? $table_name : $wpdb->prefix . $table_name;
36
+	}
37 37
 
38 38
 
39
-    /**
40
-     * Indicates whether or not the table has any entries. $table_name can
41
-     * optionally start with $wpdb->prefix or not
42
-     *
43
-     * @global \wpdb $wpdb
44
-     * @param string $table_name
45
-     * @return bool
46
-     */
47
-    public function tableIsEmpty($table_name)
48
-    {
49
-        global $wpdb;
50
-        $table_name = $this->ensureTableNameHasPrefix($table_name);
51
-        if ($this->tableExists($table_name)) {
52
-            $count = $wpdb->get_var("SELECT COUNT(*) FROM $table_name");
53
-            return absint($count) === 0 ? true : false;
54
-        }
55
-        return false;
56
-    }
39
+	/**
40
+	 * Indicates whether or not the table has any entries. $table_name can
41
+	 * optionally start with $wpdb->prefix or not
42
+	 *
43
+	 * @global \wpdb $wpdb
44
+	 * @param string $table_name
45
+	 * @return bool
46
+	 */
47
+	public function tableIsEmpty($table_name)
48
+	{
49
+		global $wpdb;
50
+		$table_name = $this->ensureTableNameHasPrefix($table_name);
51
+		if ($this->tableExists($table_name)) {
52
+			$count = $wpdb->get_var("SELECT COUNT(*) FROM $table_name");
53
+			return absint($count) === 0 ? true : false;
54
+		}
55
+		return false;
56
+	}
57 57
 
58 58
 
59
-    /**
60
-     * Indicates whether or not the table exists. $table_name can optionally
61
-     * have the $wpdb->prefix on the beginning, or not.
62
-     *
63
-     * @global \wpdb $wpdb
64
-     * @global array EZSQL_Error
65
-     * @param        $table_name
66
-     * @return bool
67
-     */
68
-    public function tableExists($table_name)
69
-    {
70
-        global $wpdb, $EZSQL_ERROR;
71
-        $table_name = $this->ensureTableNameHasPrefix($table_name);
72
-        // ignore if this causes an sql error
73
-        $old_error = $wpdb->last_error;
74
-        $old_suppress_errors = $wpdb->suppress_errors();
75
-        $old_show_errors_value = $wpdb->show_errors(false);
76
-        $ezsql_error_cache = $EZSQL_ERROR;
77
-        $wpdb->get_results("SELECT * from $table_name LIMIT 1");
78
-        $wpdb->show_errors($old_show_errors_value);
79
-        $wpdb->suppress_errors($old_suppress_errors);
80
-        $new_error = $wpdb->last_error;
81
-        $wpdb->last_error = $old_error;
82
-        $EZSQL_ERROR = $ezsql_error_cache;
83
-        // if there was a table doesn't exist error
84
-        if (! empty($new_error)) {
85
-            if (
86
-                in_array(
87
-                    \EEH_Activation::last_wpdb_error_code(),
88
-                    array(
89
-                    1051, // bad table
90
-                    1109, // unknown table
91
-                    117, // no such table
92
-                    )
93
-                )
94
-                ||
95
-                preg_match(
96
-                    '~^Table .* doesn\'t exist~',
97
-                    $new_error
98
-                ) // in case not using mysql and error codes aren't reliable, just check for this error string
99
-            ) {
100
-                return false;
101
-            } else {
102
-                // log this because that's weird. Just use the normal PHP error log
103
-                error_log(
104
-                    sprintf(
105
-                        esc_html__(
106
-                            'Event Espresso error detected when checking if table existed: %1$s (it wasn\'t just that the table didn\'t exist either)',
107
-                            'event_espresso'
108
-                        ),
109
-                        $new_error
110
-                    )
111
-                );
112
-            }
113
-        }
114
-        return true;
115
-    }
59
+	/**
60
+	 * Indicates whether or not the table exists. $table_name can optionally
61
+	 * have the $wpdb->prefix on the beginning, or not.
62
+	 *
63
+	 * @global \wpdb $wpdb
64
+	 * @global array EZSQL_Error
65
+	 * @param        $table_name
66
+	 * @return bool
67
+	 */
68
+	public function tableExists($table_name)
69
+	{
70
+		global $wpdb, $EZSQL_ERROR;
71
+		$table_name = $this->ensureTableNameHasPrefix($table_name);
72
+		// ignore if this causes an sql error
73
+		$old_error = $wpdb->last_error;
74
+		$old_suppress_errors = $wpdb->suppress_errors();
75
+		$old_show_errors_value = $wpdb->show_errors(false);
76
+		$ezsql_error_cache = $EZSQL_ERROR;
77
+		$wpdb->get_results("SELECT * from $table_name LIMIT 1");
78
+		$wpdb->show_errors($old_show_errors_value);
79
+		$wpdb->suppress_errors($old_suppress_errors);
80
+		$new_error = $wpdb->last_error;
81
+		$wpdb->last_error = $old_error;
82
+		$EZSQL_ERROR = $ezsql_error_cache;
83
+		// if there was a table doesn't exist error
84
+		if (! empty($new_error)) {
85
+			if (
86
+				in_array(
87
+					\EEH_Activation::last_wpdb_error_code(),
88
+					array(
89
+					1051, // bad table
90
+					1109, // unknown table
91
+					117, // no such table
92
+					)
93
+				)
94
+				||
95
+				preg_match(
96
+					'~^Table .* doesn\'t exist~',
97
+					$new_error
98
+				) // in case not using mysql and error codes aren't reliable, just check for this error string
99
+			) {
100
+				return false;
101
+			} else {
102
+				// log this because that's weird. Just use the normal PHP error log
103
+				error_log(
104
+					sprintf(
105
+						esc_html__(
106
+							'Event Espresso error detected when checking if table existed: %1$s (it wasn\'t just that the table didn\'t exist either)',
107
+							'event_espresso'
108
+						),
109
+						$new_error
110
+					)
111
+				);
112
+			}
113
+		}
114
+		return true;
115
+	}
116 116
 
117 117
 
118
-    /**
119
-     * @param $table_name
120
-     * @param $index_name
121
-     * @return array of columns used on that index, Each entry is an object with the following properties {
122
-     * @type string Table
123
-     * @type string Non_unique "0" or "1"
124
-     * @type string Key_name
125
-     * @type string Seq_in_index
126
-     * @type string Column_name
127
-     * @type string Collation
128
-     * @type string Cardinality
129
-     * @type string Sub_part on a column, usually this is just the number of characters from this column to use in
130
-     *       indexing
131
-     * @type string|null Packed
132
-     * @type string Null
133
-     * @type string Index_type
134
-     * @type string Comment
135
-     * @type string Index_comment
136
-     * }
137
-     */
138
-    public function showIndexes($table_name, $index_name)
139
-    {
140
-        global $wpdb;
141
-        $table_name = $this->ensureTableNameHasPrefix($table_name);
142
-        $index_exists_query = "SHOW INDEX FROM {$table_name} WHERE Key_name = '{$index_name}'";
143
-        return $wpdb->get_results($index_exists_query);
144
-    }
118
+	/**
119
+	 * @param $table_name
120
+	 * @param $index_name
121
+	 * @return array of columns used on that index, Each entry is an object with the following properties {
122
+	 * @type string Table
123
+	 * @type string Non_unique "0" or "1"
124
+	 * @type string Key_name
125
+	 * @type string Seq_in_index
126
+	 * @type string Column_name
127
+	 * @type string Collation
128
+	 * @type string Cardinality
129
+	 * @type string Sub_part on a column, usually this is just the number of characters from this column to use in
130
+	 *       indexing
131
+	 * @type string|null Packed
132
+	 * @type string Null
133
+	 * @type string Index_type
134
+	 * @type string Comment
135
+	 * @type string Index_comment
136
+	 * }
137
+	 */
138
+	public function showIndexes($table_name, $index_name)
139
+	{
140
+		global $wpdb;
141
+		$table_name = $this->ensureTableNameHasPrefix($table_name);
142
+		$index_exists_query = "SHOW INDEX FROM {$table_name} WHERE Key_name = '{$index_name}'";
143
+		return $wpdb->get_results($index_exists_query);
144
+	}
145 145
 }
Please login to merge, or discard this patch.
core/services/cache/TransientCacheStorage.php 2 patches
Indentation   +363 added lines, -363 removed lines patch added patch discarded remove patch
@@ -16,367 +16,367 @@
 block discarded – undo
16 16
 class TransientCacheStorage implements CacheStorageInterface
17 17
 {
18 18
 
19
-    /**
20
-     * wp-option option_name for tracking transients
21
-     *
22
-     * @type string
23
-     */
24
-    const TRANSIENT_SCHEDULE_OPTIONS_KEY = 'ee_transient_schedule';
25
-
26
-    /**
27
-     * @var int $current_time
28
-     */
29
-    private $current_time;
30
-
31
-    /**
32
-     * how often to perform transient cleanup
33
-     *
34
-     * @var string $transient_cleanup_frequency
35
-     */
36
-    private $transient_cleanup_frequency;
37
-
38
-    /**
39
-     * options for how often to perform transient cleanup
40
-     *
41
-     * @var array $transient_cleanup_frequency_options
42
-     */
43
-    private $transient_cleanup_frequency_options = array();
44
-
45
-    /**
46
-     * @var array $transients
47
-     */
48
-    private $transients;
49
-
50
-
51
-    /**
52
-     * TransientCacheStorage constructor.
53
-     */
54
-    public function __construct()
55
-    {
56
-        $this->transient_cleanup_frequency = $this->setTransientCleanupFrequency();
57
-        // round current time down to closest 5 minutes to simplify scheduling
58
-        $this->current_time = $this->roundTimestamp(time(), '5-minutes', false);
59
-        $this->transients = (array) get_option(TransientCacheStorage::TRANSIENT_SCHEDULE_OPTIONS_KEY, array());
60
-        if (! (defined('DOING_AJAX') && DOING_AJAX) && $this->transient_cleanup_frequency !== 'off') {
61
-            add_action('shutdown', array($this, 'checkTransientCleanupSchedule'), 999);
62
-        }
63
-    }
64
-
65
-
66
-    /**
67
-     * Sets how often transient cleanup occurs
68
-     *
69
-     * @return string
70
-     */
71
-    private function setTransientCleanupFrequency()
72
-    {
73
-        // sets how often transients are cleaned up
74
-        $this->transient_cleanup_frequency_options = apply_filters(
75
-            'FHEE__TransientCacheStorage__transient_cleanup_schedule_options',
76
-            array(
77
-                'off',
78
-                '15-minutes',
79
-                'hour',
80
-                '12-hours',
81
-                'day',
82
-            )
83
-        );
84
-        $transient_cleanup_frequency = apply_filters(
85
-            'FHEE__TransientCacheStorage__transient_cleanup_schedule',
86
-            'hour'
87
-        );
88
-        return in_array(
89
-            $transient_cleanup_frequency,
90
-            $this->transient_cleanup_frequency_options,
91
-            true
92
-        )
93
-            ? $transient_cleanup_frequency
94
-            : 'hour';
95
-    }
96
-
97
-
98
-    /**
99
-     * we need to be able to round timestamps off to match the set transient cleanup frequency
100
-     * so if a transient is set to expire at 1:17 pm for example, and our cleanup schedule is every hour,
101
-     * then that timestamp needs to be rounded up to 2:00 pm so that it is removed
102
-     * during the next scheduled cleanup after its expiration.
103
-     * We also round off the current time timestamp to the closest 5 minutes
104
-     * just to make the timestamps a little easier to round which helps with debugging.
105
-     *
106
-     * @param int    $timestamp [required]
107
-     * @param string $cleanup_frequency
108
-     * @param bool   $round_up
109
-     * @return int
110
-     */
111
-    private function roundTimestamp($timestamp, $cleanup_frequency = 'hour', $round_up = true)
112
-    {
113
-        $cleanup_frequency = $cleanup_frequency ? $cleanup_frequency : $this->transient_cleanup_frequency;
114
-        // in order to round the time to the closest xx minutes (or hours),
115
-        // we take the minutes (or hours) portion of the timestamp and divide it by xx,
116
-        // round down to a whole number, then multiply by xx to bring us almost back up to where we were
117
-        // why round down ? so the minutes (or hours) don't go over 60 (or 24)
118
-        // and bump the hour, which could bump the day, which could bump the month, etc,
119
-        // which would be bad because we don't always want to round up,
120
-        // but when we do we can easily achieve that by simply adding the desired offset,
121
-        $minutes = '00';
122
-        $hours = 'H';
123
-        switch ($cleanup_frequency) {
124
-            case '5-minutes':
125
-                $minutes = floor((int) date('i', $timestamp) / 5) * 5;
126
-                $minutes = str_pad($minutes, 2, '0', STR_PAD_LEFT);
127
-                $offset = MINUTE_IN_SECONDS * 5;
128
-                break;
129
-            case '15-minutes':
130
-                $minutes = floor((int) date('i', $timestamp) / 15) * 15;
131
-                $minutes = str_pad($minutes, 2, '0', STR_PAD_LEFT);
132
-                $offset = MINUTE_IN_SECONDS * 15;
133
-                break;
134
-            case '12-hours':
135
-                $hours = floor((int) date('H', $timestamp) / 12) * 12;
136
-                $hours = str_pad($hours, 2, '0', STR_PAD_LEFT);
137
-                $offset = HOUR_IN_SECONDS * 12;
138
-                break;
139
-            case 'day':
140
-                $hours = '03'; // run cleanup at 3:00 am (or first site hit after that)
141
-                $offset = DAY_IN_SECONDS;
142
-                break;
143
-            case 'hour':
144
-            default:
145
-                $offset = HOUR_IN_SECONDS;
146
-                break;
147
-        }
148
-        $rounded_timestamp = (int) strtotime(date("Y-m-d {$hours}:{$minutes}:00", $timestamp));
149
-        $rounded_timestamp += $round_up ? $offset : 0;
150
-        return apply_filters(
151
-            'FHEE__TransientCacheStorage__roundTimestamp__timestamp',
152
-            $rounded_timestamp,
153
-            $timestamp,
154
-            $cleanup_frequency,
155
-            $round_up
156
-        );
157
-    }
158
-
159
-
160
-    /**
161
-     * Saves supplied data to a transient
162
-     * if an expiration is set, then it automatically schedules the transient for cleanup
163
-     *
164
-     * @param string $transient_key [required]
165
-     * @param string $data          [required]
166
-     * @param int    $expiration    number of seconds until the cache expires
167
-     * @return bool
168
-     */
169
-    public function add($transient_key, $data, $expiration = 0)
170
-    {
171
-        $expiration = (int) abs($expiration);
172
-        $saved = set_transient($transient_key, $data, $expiration);
173
-        if ($saved && $expiration) {
174
-            $this->scheduleTransientCleanup($transient_key, $expiration);
175
-        }
176
-        return $saved;
177
-    }
178
-
179
-
180
-    /**
181
-     * retrieves transient data
182
-     * automatically triggers early cache refresh for standard cache items
183
-     * in order to avoid cache stampedes on busy sites.
184
-     * For non-standard cache items like PHP Session data where early refreshing is not wanted,
185
-     * the $standard_cache parameter should be set to false when retrieving data
186
-     *
187
-     * @param string $transient_key [required]
188
-     * @param bool   $standard_cache
189
-     * @return mixed|null
190
-     */
191
-    public function get($transient_key, $standard_cache = true)
192
-    {
193
-        if (isset($this->transients[ $transient_key ])) {
194
-            // to avoid cache stampedes (AKA:dogpiles) for standard cache items,
195
-            // check if known cache expires within the next minute,
196
-            // and if so, remove it from our tracking and and return nothing.
197
-            // this should trigger the cache content to be regenerated during this request,
198
-            // while allowing any following requests to still access the existing cache
199
-            // until it gets replaced with the refreshed content
200
-            if (
201
-                $standard_cache
202
-                && $this->transients[ $transient_key ] - time() <= MINUTE_IN_SECONDS
203
-            ) {
204
-                unset($this->transients[ $transient_key ]);
205
-                $this->updateTransients();
206
-                return null;
207
-            }
208
-
209
-            // for non standard cache items, remove the key from our tracking,
210
-            // but proceed to retrieve the transient so that it also gets removed from the db
211
-            if ($this->transients[ $transient_key ] <= time()) {
212
-                unset($this->transients[ $transient_key ]);
213
-                $this->updateTransients();
214
-            }
215
-        }
216
-
217
-        $content = get_transient($transient_key);
218
-        return $content !== false ? $content : null;
219
-    }
220
-
221
-
222
-    /**
223
-     * delete a single transient and remove tracking
224
-     *
225
-     * @param string $transient_key [required] full or partial transient key to be deleted
226
-     */
227
-    public function delete($transient_key)
228
-    {
229
-        $this->deleteMany(array($transient_key));
230
-    }
231
-
232
-
233
-    /**
234
-     * delete multiple transients and remove tracking
235
-     *
236
-     * @param array $transient_keys [required] array of full or partial transient keys to be deleted
237
-     * @param bool  $force_delete   [optional] if true, then will not check incoming keys against those being tracked
238
-     *                              and proceed directly to deleting those entries from the cache storage
239
-     */
240
-    public function deleteMany(array $transient_keys, $force_delete = false)
241
-    {
242
-        $full_transient_keys = $force_delete ? $transient_keys : array();
243
-        if (empty($full_transient_keys)) {
244
-            foreach ($this->transients as $transient_key => $expiration) {
245
-                foreach ($transient_keys as $transient_key_to_delete) {
246
-                    if (strpos($transient_key, $transient_key_to_delete) !== false) {
247
-                        $full_transient_keys[] = $transient_key;
248
-                    }
249
-                }
250
-            }
251
-        }
252
-        if ($this->deleteTransientKeys($full_transient_keys)) {
253
-            $this->updateTransients();
254
-        }
255
-    }
256
-
257
-
258
-    /**
259
-     * sorts transients numerically by timestamp
260
-     * then saves the transient schedule to a WP option
261
-     */
262
-    private function updateTransients()
263
-    {
264
-        asort($this->transients, SORT_NUMERIC);
265
-        update_option(
266
-            TransientCacheStorage::TRANSIENT_SCHEDULE_OPTIONS_KEY,
267
-            $this->transients
268
-        );
269
-    }
270
-
271
-
272
-    /**
273
-     * schedules a transient for cleanup by adding it to the transient tracking
274
-     *
275
-     * @param string $transient_key [required]
276
-     * @param int    $expiration    [required]
277
-     */
278
-    private function scheduleTransientCleanup($transient_key, $expiration)
279
-    {
280
-        // make sure a valid future timestamp is set
281
-        $expiration += $expiration < time() ? time() : 0;
282
-        // and round to the closest 15 minutes
283
-        $expiration = $this->roundTimestamp($expiration);
284
-        // save transients to clear using their ID as the key to avoid duplicates
285
-        $this->transients[ $transient_key ] = $expiration;
286
-        $this->updateTransients();
287
-    }
288
-
289
-
290
-    /**
291
-     * Since our tracked transients are sorted by their timestamps
292
-     * we can grab the first transient and see when it is scheduled for cleanup.
293
-     * If that timestamp is less than or equal to the current time,
294
-     * then cleanup is triggered
295
-     */
296
-    public function checkTransientCleanupSchedule()
297
-    {
298
-        if (empty($this->transients)) {
299
-            return;
300
-        }
301
-        // when do we run the next cleanup job?
302
-        reset($this->transients);
303
-        $next_scheduled_cleanup = current($this->transients);
304
-        // if the next cleanup job is scheduled for the current hour
305
-        if ($next_scheduled_cleanup <= $this->current_time) {
306
-            if ($this->cleanupExpiredTransients()) {
307
-                $this->updateTransients();
308
-            }
309
-        }
310
-    }
311
-
312
-
313
-    /**
314
-     * loops through the array of tracked transients,
315
-     * compiles a list of those that have expired, and sends that list off for deletion.
316
-     * Also removes any bad records from the transients array
317
-     *
318
-     * @return bool
319
-     */
320
-    private function cleanupExpiredTransients()
321
-    {
322
-        $update = false;
323
-        // filter the query limit. Set to 0 to turn off garbage collection
324
-        $limit = (int) abs(
325
-            apply_filters(
326
-                'FHEE__TransientCacheStorage__clearExpiredTransients__limit',
327
-                50
328
-            )
329
-        );
330
-        // non-zero LIMIT means take out the trash
331
-        if ($limit) {
332
-            $transient_keys = array();
333
-            foreach ($this->transients as $transient_key => $expiration) {
334
-                if ($expiration > $this->current_time) {
335
-                    continue;
336
-                }
337
-                if (! $expiration || ! $transient_key) {
338
-                    unset($this->transients[ $transient_key ]);
339
-                    $update = true;
340
-                    continue;
341
-                }
342
-                $transient_keys[] = $transient_key;
343
-            }
344
-            // delete expired keys, but maintain value of $update if nothing is deleted
345
-            $update = $this->deleteTransientKeys($transient_keys, $limit) ? true : $update;
346
-            do_action('FHEE__TransientCacheStorage__clearExpiredTransients__end', $this);
347
-        }
348
-        return $update;
349
-    }
350
-
351
-
352
-    /**
353
-     * calls delete_transient() on each transient key provided, up to the specified limit
354
-     *
355
-     * @param array $transient_keys [required]
356
-     * @param int   $limit
357
-     * @return bool
358
-     */
359
-    private function deleteTransientKeys(array $transient_keys, $limit = 50)
360
-    {
361
-        if (empty($transient_keys)) {
362
-            return false;
363
-        }
364
-        $counter = 0;
365
-        foreach ($transient_keys as $transient_key) {
366
-            if ($counter === $limit) {
367
-                break;
368
-            }
369
-            // remove any transient prefixes
370
-            $transient_key = strpos($transient_key, '_transient_timeout_') === 0
371
-                ? str_replace('_transient_timeout_', '', $transient_key)
372
-                : $transient_key;
373
-            $transient_key = strpos($transient_key, '_transient_') === 0
374
-                ? str_replace('_transient_', '', $transient_key)
375
-                : $transient_key;
376
-            delete_transient($transient_key);
377
-            unset($this->transients[ $transient_key ]);
378
-            $counter++;
379
-        }
380
-        return $counter > 0;
381
-    }
19
+	/**
20
+	 * wp-option option_name for tracking transients
21
+	 *
22
+	 * @type string
23
+	 */
24
+	const TRANSIENT_SCHEDULE_OPTIONS_KEY = 'ee_transient_schedule';
25
+
26
+	/**
27
+	 * @var int $current_time
28
+	 */
29
+	private $current_time;
30
+
31
+	/**
32
+	 * how often to perform transient cleanup
33
+	 *
34
+	 * @var string $transient_cleanup_frequency
35
+	 */
36
+	private $transient_cleanup_frequency;
37
+
38
+	/**
39
+	 * options for how often to perform transient cleanup
40
+	 *
41
+	 * @var array $transient_cleanup_frequency_options
42
+	 */
43
+	private $transient_cleanup_frequency_options = array();
44
+
45
+	/**
46
+	 * @var array $transients
47
+	 */
48
+	private $transients;
49
+
50
+
51
+	/**
52
+	 * TransientCacheStorage constructor.
53
+	 */
54
+	public function __construct()
55
+	{
56
+		$this->transient_cleanup_frequency = $this->setTransientCleanupFrequency();
57
+		// round current time down to closest 5 minutes to simplify scheduling
58
+		$this->current_time = $this->roundTimestamp(time(), '5-minutes', false);
59
+		$this->transients = (array) get_option(TransientCacheStorage::TRANSIENT_SCHEDULE_OPTIONS_KEY, array());
60
+		if (! (defined('DOING_AJAX') && DOING_AJAX) && $this->transient_cleanup_frequency !== 'off') {
61
+			add_action('shutdown', array($this, 'checkTransientCleanupSchedule'), 999);
62
+		}
63
+	}
64
+
65
+
66
+	/**
67
+	 * Sets how often transient cleanup occurs
68
+	 *
69
+	 * @return string
70
+	 */
71
+	private function setTransientCleanupFrequency()
72
+	{
73
+		// sets how often transients are cleaned up
74
+		$this->transient_cleanup_frequency_options = apply_filters(
75
+			'FHEE__TransientCacheStorage__transient_cleanup_schedule_options',
76
+			array(
77
+				'off',
78
+				'15-minutes',
79
+				'hour',
80
+				'12-hours',
81
+				'day',
82
+			)
83
+		);
84
+		$transient_cleanup_frequency = apply_filters(
85
+			'FHEE__TransientCacheStorage__transient_cleanup_schedule',
86
+			'hour'
87
+		);
88
+		return in_array(
89
+			$transient_cleanup_frequency,
90
+			$this->transient_cleanup_frequency_options,
91
+			true
92
+		)
93
+			? $transient_cleanup_frequency
94
+			: 'hour';
95
+	}
96
+
97
+
98
+	/**
99
+	 * we need to be able to round timestamps off to match the set transient cleanup frequency
100
+	 * so if a transient is set to expire at 1:17 pm for example, and our cleanup schedule is every hour,
101
+	 * then that timestamp needs to be rounded up to 2:00 pm so that it is removed
102
+	 * during the next scheduled cleanup after its expiration.
103
+	 * We also round off the current time timestamp to the closest 5 minutes
104
+	 * just to make the timestamps a little easier to round which helps with debugging.
105
+	 *
106
+	 * @param int    $timestamp [required]
107
+	 * @param string $cleanup_frequency
108
+	 * @param bool   $round_up
109
+	 * @return int
110
+	 */
111
+	private function roundTimestamp($timestamp, $cleanup_frequency = 'hour', $round_up = true)
112
+	{
113
+		$cleanup_frequency = $cleanup_frequency ? $cleanup_frequency : $this->transient_cleanup_frequency;
114
+		// in order to round the time to the closest xx minutes (or hours),
115
+		// we take the minutes (or hours) portion of the timestamp and divide it by xx,
116
+		// round down to a whole number, then multiply by xx to bring us almost back up to where we were
117
+		// why round down ? so the minutes (or hours) don't go over 60 (or 24)
118
+		// and bump the hour, which could bump the day, which could bump the month, etc,
119
+		// which would be bad because we don't always want to round up,
120
+		// but when we do we can easily achieve that by simply adding the desired offset,
121
+		$minutes = '00';
122
+		$hours = 'H';
123
+		switch ($cleanup_frequency) {
124
+			case '5-minutes':
125
+				$minutes = floor((int) date('i', $timestamp) / 5) * 5;
126
+				$minutes = str_pad($minutes, 2, '0', STR_PAD_LEFT);
127
+				$offset = MINUTE_IN_SECONDS * 5;
128
+				break;
129
+			case '15-minutes':
130
+				$minutes = floor((int) date('i', $timestamp) / 15) * 15;
131
+				$minutes = str_pad($minutes, 2, '0', STR_PAD_LEFT);
132
+				$offset = MINUTE_IN_SECONDS * 15;
133
+				break;
134
+			case '12-hours':
135
+				$hours = floor((int) date('H', $timestamp) / 12) * 12;
136
+				$hours = str_pad($hours, 2, '0', STR_PAD_LEFT);
137
+				$offset = HOUR_IN_SECONDS * 12;
138
+				break;
139
+			case 'day':
140
+				$hours = '03'; // run cleanup at 3:00 am (or first site hit after that)
141
+				$offset = DAY_IN_SECONDS;
142
+				break;
143
+			case 'hour':
144
+			default:
145
+				$offset = HOUR_IN_SECONDS;
146
+				break;
147
+		}
148
+		$rounded_timestamp = (int) strtotime(date("Y-m-d {$hours}:{$minutes}:00", $timestamp));
149
+		$rounded_timestamp += $round_up ? $offset : 0;
150
+		return apply_filters(
151
+			'FHEE__TransientCacheStorage__roundTimestamp__timestamp',
152
+			$rounded_timestamp,
153
+			$timestamp,
154
+			$cleanup_frequency,
155
+			$round_up
156
+		);
157
+	}
158
+
159
+
160
+	/**
161
+	 * Saves supplied data to a transient
162
+	 * if an expiration is set, then it automatically schedules the transient for cleanup
163
+	 *
164
+	 * @param string $transient_key [required]
165
+	 * @param string $data          [required]
166
+	 * @param int    $expiration    number of seconds until the cache expires
167
+	 * @return bool
168
+	 */
169
+	public function add($transient_key, $data, $expiration = 0)
170
+	{
171
+		$expiration = (int) abs($expiration);
172
+		$saved = set_transient($transient_key, $data, $expiration);
173
+		if ($saved && $expiration) {
174
+			$this->scheduleTransientCleanup($transient_key, $expiration);
175
+		}
176
+		return $saved;
177
+	}
178
+
179
+
180
+	/**
181
+	 * retrieves transient data
182
+	 * automatically triggers early cache refresh for standard cache items
183
+	 * in order to avoid cache stampedes on busy sites.
184
+	 * For non-standard cache items like PHP Session data where early refreshing is not wanted,
185
+	 * the $standard_cache parameter should be set to false when retrieving data
186
+	 *
187
+	 * @param string $transient_key [required]
188
+	 * @param bool   $standard_cache
189
+	 * @return mixed|null
190
+	 */
191
+	public function get($transient_key, $standard_cache = true)
192
+	{
193
+		if (isset($this->transients[ $transient_key ])) {
194
+			// to avoid cache stampedes (AKA:dogpiles) for standard cache items,
195
+			// check if known cache expires within the next minute,
196
+			// and if so, remove it from our tracking and and return nothing.
197
+			// this should trigger the cache content to be regenerated during this request,
198
+			// while allowing any following requests to still access the existing cache
199
+			// until it gets replaced with the refreshed content
200
+			if (
201
+				$standard_cache
202
+				&& $this->transients[ $transient_key ] - time() <= MINUTE_IN_SECONDS
203
+			) {
204
+				unset($this->transients[ $transient_key ]);
205
+				$this->updateTransients();
206
+				return null;
207
+			}
208
+
209
+			// for non standard cache items, remove the key from our tracking,
210
+			// but proceed to retrieve the transient so that it also gets removed from the db
211
+			if ($this->transients[ $transient_key ] <= time()) {
212
+				unset($this->transients[ $transient_key ]);
213
+				$this->updateTransients();
214
+			}
215
+		}
216
+
217
+		$content = get_transient($transient_key);
218
+		return $content !== false ? $content : null;
219
+	}
220
+
221
+
222
+	/**
223
+	 * delete a single transient and remove tracking
224
+	 *
225
+	 * @param string $transient_key [required] full or partial transient key to be deleted
226
+	 */
227
+	public function delete($transient_key)
228
+	{
229
+		$this->deleteMany(array($transient_key));
230
+	}
231
+
232
+
233
+	/**
234
+	 * delete multiple transients and remove tracking
235
+	 *
236
+	 * @param array $transient_keys [required] array of full or partial transient keys to be deleted
237
+	 * @param bool  $force_delete   [optional] if true, then will not check incoming keys against those being tracked
238
+	 *                              and proceed directly to deleting those entries from the cache storage
239
+	 */
240
+	public function deleteMany(array $transient_keys, $force_delete = false)
241
+	{
242
+		$full_transient_keys = $force_delete ? $transient_keys : array();
243
+		if (empty($full_transient_keys)) {
244
+			foreach ($this->transients as $transient_key => $expiration) {
245
+				foreach ($transient_keys as $transient_key_to_delete) {
246
+					if (strpos($transient_key, $transient_key_to_delete) !== false) {
247
+						$full_transient_keys[] = $transient_key;
248
+					}
249
+				}
250
+			}
251
+		}
252
+		if ($this->deleteTransientKeys($full_transient_keys)) {
253
+			$this->updateTransients();
254
+		}
255
+	}
256
+
257
+
258
+	/**
259
+	 * sorts transients numerically by timestamp
260
+	 * then saves the transient schedule to a WP option
261
+	 */
262
+	private function updateTransients()
263
+	{
264
+		asort($this->transients, SORT_NUMERIC);
265
+		update_option(
266
+			TransientCacheStorage::TRANSIENT_SCHEDULE_OPTIONS_KEY,
267
+			$this->transients
268
+		);
269
+	}
270
+
271
+
272
+	/**
273
+	 * schedules a transient for cleanup by adding it to the transient tracking
274
+	 *
275
+	 * @param string $transient_key [required]
276
+	 * @param int    $expiration    [required]
277
+	 */
278
+	private function scheduleTransientCleanup($transient_key, $expiration)
279
+	{
280
+		// make sure a valid future timestamp is set
281
+		$expiration += $expiration < time() ? time() : 0;
282
+		// and round to the closest 15 minutes
283
+		$expiration = $this->roundTimestamp($expiration);
284
+		// save transients to clear using their ID as the key to avoid duplicates
285
+		$this->transients[ $transient_key ] = $expiration;
286
+		$this->updateTransients();
287
+	}
288
+
289
+
290
+	/**
291
+	 * Since our tracked transients are sorted by their timestamps
292
+	 * we can grab the first transient and see when it is scheduled for cleanup.
293
+	 * If that timestamp is less than or equal to the current time,
294
+	 * then cleanup is triggered
295
+	 */
296
+	public function checkTransientCleanupSchedule()
297
+	{
298
+		if (empty($this->transients)) {
299
+			return;
300
+		}
301
+		// when do we run the next cleanup job?
302
+		reset($this->transients);
303
+		$next_scheduled_cleanup = current($this->transients);
304
+		// if the next cleanup job is scheduled for the current hour
305
+		if ($next_scheduled_cleanup <= $this->current_time) {
306
+			if ($this->cleanupExpiredTransients()) {
307
+				$this->updateTransients();
308
+			}
309
+		}
310
+	}
311
+
312
+
313
+	/**
314
+	 * loops through the array of tracked transients,
315
+	 * compiles a list of those that have expired, and sends that list off for deletion.
316
+	 * Also removes any bad records from the transients array
317
+	 *
318
+	 * @return bool
319
+	 */
320
+	private function cleanupExpiredTransients()
321
+	{
322
+		$update = false;
323
+		// filter the query limit. Set to 0 to turn off garbage collection
324
+		$limit = (int) abs(
325
+			apply_filters(
326
+				'FHEE__TransientCacheStorage__clearExpiredTransients__limit',
327
+				50
328
+			)
329
+		);
330
+		// non-zero LIMIT means take out the trash
331
+		if ($limit) {
332
+			$transient_keys = array();
333
+			foreach ($this->transients as $transient_key => $expiration) {
334
+				if ($expiration > $this->current_time) {
335
+					continue;
336
+				}
337
+				if (! $expiration || ! $transient_key) {
338
+					unset($this->transients[ $transient_key ]);
339
+					$update = true;
340
+					continue;
341
+				}
342
+				$transient_keys[] = $transient_key;
343
+			}
344
+			// delete expired keys, but maintain value of $update if nothing is deleted
345
+			$update = $this->deleteTransientKeys($transient_keys, $limit) ? true : $update;
346
+			do_action('FHEE__TransientCacheStorage__clearExpiredTransients__end', $this);
347
+		}
348
+		return $update;
349
+	}
350
+
351
+
352
+	/**
353
+	 * calls delete_transient() on each transient key provided, up to the specified limit
354
+	 *
355
+	 * @param array $transient_keys [required]
356
+	 * @param int   $limit
357
+	 * @return bool
358
+	 */
359
+	private function deleteTransientKeys(array $transient_keys, $limit = 50)
360
+	{
361
+		if (empty($transient_keys)) {
362
+			return false;
363
+		}
364
+		$counter = 0;
365
+		foreach ($transient_keys as $transient_key) {
366
+			if ($counter === $limit) {
367
+				break;
368
+			}
369
+			// remove any transient prefixes
370
+			$transient_key = strpos($transient_key, '_transient_timeout_') === 0
371
+				? str_replace('_transient_timeout_', '', $transient_key)
372
+				: $transient_key;
373
+			$transient_key = strpos($transient_key, '_transient_') === 0
374
+				? str_replace('_transient_', '', $transient_key)
375
+				: $transient_key;
376
+			delete_transient($transient_key);
377
+			unset($this->transients[ $transient_key ]);
378
+			$counter++;
379
+		}
380
+		return $counter > 0;
381
+	}
382 382
 }
Please login to merge, or discard this patch.
Spacing   +10 added lines, -10 removed lines patch added patch discarded remove patch
@@ -57,7 +57,7 @@  discard block
 block discarded – undo
57 57
         // round current time down to closest 5 minutes to simplify scheduling
58 58
         $this->current_time = $this->roundTimestamp(time(), '5-minutes', false);
59 59
         $this->transients = (array) get_option(TransientCacheStorage::TRANSIENT_SCHEDULE_OPTIONS_KEY, array());
60
-        if (! (defined('DOING_AJAX') && DOING_AJAX) && $this->transient_cleanup_frequency !== 'off') {
60
+        if ( ! (defined('DOING_AJAX') && DOING_AJAX) && $this->transient_cleanup_frequency !== 'off') {
61 61
             add_action('shutdown', array($this, 'checkTransientCleanupSchedule'), 999);
62 62
         }
63 63
     }
@@ -190,7 +190,7 @@  discard block
 block discarded – undo
190 190
      */
191 191
     public function get($transient_key, $standard_cache = true)
192 192
     {
193
-        if (isset($this->transients[ $transient_key ])) {
193
+        if (isset($this->transients[$transient_key])) {
194 194
             // to avoid cache stampedes (AKA:dogpiles) for standard cache items,
195 195
             // check if known cache expires within the next minute,
196 196
             // and if so, remove it from our tracking and and return nothing.
@@ -199,17 +199,17 @@  discard block
 block discarded – undo
199 199
             // until it gets replaced with the refreshed content
200 200
             if (
201 201
                 $standard_cache
202
-                && $this->transients[ $transient_key ] - time() <= MINUTE_IN_SECONDS
202
+                && $this->transients[$transient_key] - time() <= MINUTE_IN_SECONDS
203 203
             ) {
204
-                unset($this->transients[ $transient_key ]);
204
+                unset($this->transients[$transient_key]);
205 205
                 $this->updateTransients();
206 206
                 return null;
207 207
             }
208 208
 
209 209
             // for non standard cache items, remove the key from our tracking,
210 210
             // but proceed to retrieve the transient so that it also gets removed from the db
211
-            if ($this->transients[ $transient_key ] <= time()) {
212
-                unset($this->transients[ $transient_key ]);
211
+            if ($this->transients[$transient_key] <= time()) {
212
+                unset($this->transients[$transient_key]);
213 213
                 $this->updateTransients();
214 214
             }
215 215
         }
@@ -282,7 +282,7 @@  discard block
 block discarded – undo
282 282
         // and round to the closest 15 minutes
283 283
         $expiration = $this->roundTimestamp($expiration);
284 284
         // save transients to clear using their ID as the key to avoid duplicates
285
-        $this->transients[ $transient_key ] = $expiration;
285
+        $this->transients[$transient_key] = $expiration;
286 286
         $this->updateTransients();
287 287
     }
288 288
 
@@ -334,8 +334,8 @@  discard block
 block discarded – undo
334 334
                 if ($expiration > $this->current_time) {
335 335
                     continue;
336 336
                 }
337
-                if (! $expiration || ! $transient_key) {
338
-                    unset($this->transients[ $transient_key ]);
337
+                if ( ! $expiration || ! $transient_key) {
338
+                    unset($this->transients[$transient_key]);
339 339
                     $update = true;
340 340
                     continue;
341 341
                 }
@@ -374,7 +374,7 @@  discard block
 block discarded – undo
374 374
                 ? str_replace('_transient_', '', $transient_key)
375 375
                 : $transient_key;
376 376
             delete_transient($transient_key);
377
-            unset($this->transients[ $transient_key ]);
377
+            unset($this->transients[$transient_key]);
378 378
             $counter++;
379 379
         }
380 380
         return $counter > 0;
Please login to merge, or discard this patch.
core/services/request/middleware/DetectLogin.php 1 patch
Indentation   +25 added lines, -25 removed lines patch added patch discarded remove patch
@@ -16,29 +16,29 @@
 block discarded – undo
16 16
 class DetectLogin extends Middleware
17 17
 {
18 18
 
19
-    /**
20
-     * converts a Request to a Response
21
-     *
22
-     * @param RequestInterface  $request
23
-     * @param ResponseInterface $response
24
-     * @return ResponseInterface
25
-     */
26
-    public function handleRequest(RequestInterface $request, ResponseInterface $response)
27
-    {
28
-        $this->request = $request;
29
-        $this->response = $response;
30
-        global $pagenow;
31
-        if (
32
-            in_array(
33
-                $pagenow,
34
-                array('wp-login.php', 'wp-register.php'),
35
-                true
36
-            )
37
-            && ! filter_var($request->getRequestParam('ee_load_on_login'), FILTER_VALIDATE_BOOLEAN)
38
-        ) {
39
-            $this->response->terminateRequest();
40
-        }
41
-        $this->response = $this->processRequestStack($this->request, $this->response);
42
-        return $this->response;
43
-    }
19
+	/**
20
+	 * converts a Request to a Response
21
+	 *
22
+	 * @param RequestInterface  $request
23
+	 * @param ResponseInterface $response
24
+	 * @return ResponseInterface
25
+	 */
26
+	public function handleRequest(RequestInterface $request, ResponseInterface $response)
27
+	{
28
+		$this->request = $request;
29
+		$this->response = $response;
30
+		global $pagenow;
31
+		if (
32
+			in_array(
33
+				$pagenow,
34
+				array('wp-login.php', 'wp-register.php'),
35
+				true
36
+			)
37
+			&& ! filter_var($request->getRequestParam('ee_load_on_login'), FILTER_VALIDATE_BOOLEAN)
38
+		) {
39
+			$this->response->terminateRequest();
40
+		}
41
+		$this->response = $this->processRequestStack($this->request, $this->response);
42
+		return $this->response;
43
+	}
44 44
 }
Please login to merge, or discard this patch.
core/services/container/DependencyInjector.php 2 patches
Indentation   +207 added lines, -207 removed lines patch added patch discarded remove patch
@@ -21,216 +21,216 @@
 block discarded – undo
21 21
 class DependencyInjector implements InjectorInterface
22 22
 {
23 23
 
24
-    /**
25
-     * @var CoffeePotInterface $coffee_pot
26
-     */
27
-    private $coffee_pot;
28
-
29
-    /**
30
-     * @var EEH_Array $array_helper
31
-     */
32
-    private $array_helper;
33
-
34
-    /**
35
-     * @var ReflectionClass[] $reflectors
36
-     */
37
-    private $reflectors;
38
-
39
-    /**
40
-     * @var ReflectionMethod[] $constructors
41
-     */
42
-    private $constructors;
43
-
44
-    /**
45
-     * @var ReflectionParameter[] $parameters
46
-     */
47
-    private $parameters;
48
-
49
-
50
-    /**
51
-     * DependencyInjector constructor
52
-     *
53
-     * @param CoffeePotInterface $coffee_pot
54
-     * @param EEH_Array          $array_helper
55
-     */
56
-    public function __construct(CoffeePotInterface $coffee_pot, EEH_Array $array_helper)
57
-    {
58
-        $this->coffee_pot = $coffee_pot;
59
-        $this->array_helper = $array_helper;
60
-    }
61
-
62
-
63
-    /**
64
-     * getReflectionClass
65
-     * checks if a ReflectionClass object has already been generated for a class
66
-     * and returns that instead of creating a new one
67
-     *
68
-     * @param string $class_name
69
-     * @return ReflectionClass
70
-     */
71
-    public function getReflectionClass($class_name)
72
-    {
73
-        if (
74
-            ! isset($this->reflectors[ $class_name ])
75
-            || ! $this->reflectors[ $class_name ] instanceof ReflectionClass
76
-        ) {
77
-            $this->reflectors[ $class_name ] = new ReflectionClass($class_name);
78
-        }
79
-        return $this->reflectors[ $class_name ];
80
-    }
81
-
82
-
83
-    /**
84
-     * getConstructor
85
-     * checks if a ReflectionMethod object has already been generated for the class constructor
86
-     * and returns that instead of creating a new one
87
-     *
88
-     * @param ReflectionClass $reflector
89
-     * @return ReflectionMethod
90
-     */
91
-    protected function getConstructor(ReflectionClass $reflector)
92
-    {
93
-        if (
94
-            ! isset($this->constructors[ $reflector->getName() ])
95
-            || ! $this->constructors[ $reflector->getName() ] instanceof ReflectionMethod
96
-        ) {
97
-            $this->constructors[ $reflector->getName() ] = $reflector->getConstructor();
98
-        }
99
-        return $this->constructors[ $reflector->getName() ];
100
-    }
101
-
102
-
103
-    /**
104
-     * getParameters
105
-     * checks if an array of ReflectionParameter objects has already been generated for the class constructor
106
-     * and returns that instead of creating a new one
107
-     *
108
-     * @param ReflectionMethod $constructor
109
-     * @return ReflectionParameter[]
110
-     */
111
-    protected function getParameters(ReflectionMethod $constructor)
112
-    {
113
-        if (! isset($this->parameters[ $constructor->class ])) {
114
-            $this->parameters[ $constructor->class ] = $constructor->getParameters();
115
-        }
116
-        return $this->parameters[ $constructor->class ];
117
-    }
118
-
119
-
120
-    /**
121
-     * resolveDependencies
122
-     * examines the constructor for the requested class to determine
123
-     * if any dependencies exist, and if they can be injected.
124
-     * If so, then those classes will be added to the array of arguments passed to the constructor
125
-     * PLZ NOTE: this is achieved by type hinting the constructor params
126
-     * For example:
127
-     *        if attempting to load a class "Foo" with the following constructor:
128
-     *        __construct( Bar $bar_class, Fighter $grohl_class )
129
-     *        then $bar_class and $grohl_class will be added to the $arguments array,
130
-     *        but only IF they are NOT already present in the incoming arguments array,
131
-     *        and the correct classes can be loaded
132
-     *
133
-     * @param RecipeInterface $recipe
134
-     * @param ReflectionClass $reflector
135
-     * @param array           $arguments
136
-     * @return array
137
-     * @throws UnexpectedValueException
138
-     */
139
-    public function resolveDependencies(RecipeInterface $recipe, ReflectionClass $reflector, $arguments = array())
140
-    {
141
-        // if arguments array is numerically and sequentially indexed, then we want it to remain as is,
142
-        // else wrap it in an additional array so that it doesn't get split into multiple parameters
143
-        $arguments = $this->array_helper->is_array_numerically_and_sequentially_indexed($arguments)
144
-            ? $arguments
145
-            : array($arguments);
146
-        $resolved_parameters = array();
147
-        // let's examine the constructor
148
-        // let's examine the constructor
149
-        $constructor = $this->getConstructor($reflector);
150
-        // whu? huh? nothing?
151
-        if (! $constructor) {
152
-            return $arguments;
153
-        }
154
-        // get constructor parameters
155
-        $params = $this->getParameters($constructor);
156
-        if (empty($params)) {
157
-            return $resolved_parameters;
158
-        }
159
-        $ingredients = $recipe->ingredients();
160
-        // and the keys for the incoming arguments array so that we can compare existing arguments with what is expected
161
-        $argument_keys = array_keys($arguments);
162
-        // now loop thru all of the constructors expected parameters
163
-        foreach ($params as $index => $param) {
164
-            if (! $param instanceof ReflectionParameter) {
165
-                continue;
166
-            }
167
-            // is this a dependency for a specific class ?
168
-            $param_class = $param->getClass() ? $param->getClass()->name : '';
169
-            $param_name = $param->getName() ? $param->getName() : '';
170
-            if (
24
+	/**
25
+	 * @var CoffeePotInterface $coffee_pot
26
+	 */
27
+	private $coffee_pot;
28
+
29
+	/**
30
+	 * @var EEH_Array $array_helper
31
+	 */
32
+	private $array_helper;
33
+
34
+	/**
35
+	 * @var ReflectionClass[] $reflectors
36
+	 */
37
+	private $reflectors;
38
+
39
+	/**
40
+	 * @var ReflectionMethod[] $constructors
41
+	 */
42
+	private $constructors;
43
+
44
+	/**
45
+	 * @var ReflectionParameter[] $parameters
46
+	 */
47
+	private $parameters;
48
+
49
+
50
+	/**
51
+	 * DependencyInjector constructor
52
+	 *
53
+	 * @param CoffeePotInterface $coffee_pot
54
+	 * @param EEH_Array          $array_helper
55
+	 */
56
+	public function __construct(CoffeePotInterface $coffee_pot, EEH_Array $array_helper)
57
+	{
58
+		$this->coffee_pot = $coffee_pot;
59
+		$this->array_helper = $array_helper;
60
+	}
61
+
62
+
63
+	/**
64
+	 * getReflectionClass
65
+	 * checks if a ReflectionClass object has already been generated for a class
66
+	 * and returns that instead of creating a new one
67
+	 *
68
+	 * @param string $class_name
69
+	 * @return ReflectionClass
70
+	 */
71
+	public function getReflectionClass($class_name)
72
+	{
73
+		if (
74
+			! isset($this->reflectors[ $class_name ])
75
+			|| ! $this->reflectors[ $class_name ] instanceof ReflectionClass
76
+		) {
77
+			$this->reflectors[ $class_name ] = new ReflectionClass($class_name);
78
+		}
79
+		return $this->reflectors[ $class_name ];
80
+	}
81
+
82
+
83
+	/**
84
+	 * getConstructor
85
+	 * checks if a ReflectionMethod object has already been generated for the class constructor
86
+	 * and returns that instead of creating a new one
87
+	 *
88
+	 * @param ReflectionClass $reflector
89
+	 * @return ReflectionMethod
90
+	 */
91
+	protected function getConstructor(ReflectionClass $reflector)
92
+	{
93
+		if (
94
+			! isset($this->constructors[ $reflector->getName() ])
95
+			|| ! $this->constructors[ $reflector->getName() ] instanceof ReflectionMethod
96
+		) {
97
+			$this->constructors[ $reflector->getName() ] = $reflector->getConstructor();
98
+		}
99
+		return $this->constructors[ $reflector->getName() ];
100
+	}
101
+
102
+
103
+	/**
104
+	 * getParameters
105
+	 * checks if an array of ReflectionParameter objects has already been generated for the class constructor
106
+	 * and returns that instead of creating a new one
107
+	 *
108
+	 * @param ReflectionMethod $constructor
109
+	 * @return ReflectionParameter[]
110
+	 */
111
+	protected function getParameters(ReflectionMethod $constructor)
112
+	{
113
+		if (! isset($this->parameters[ $constructor->class ])) {
114
+			$this->parameters[ $constructor->class ] = $constructor->getParameters();
115
+		}
116
+		return $this->parameters[ $constructor->class ];
117
+	}
118
+
119
+
120
+	/**
121
+	 * resolveDependencies
122
+	 * examines the constructor for the requested class to determine
123
+	 * if any dependencies exist, and if they can be injected.
124
+	 * If so, then those classes will be added to the array of arguments passed to the constructor
125
+	 * PLZ NOTE: this is achieved by type hinting the constructor params
126
+	 * For example:
127
+	 *        if attempting to load a class "Foo" with the following constructor:
128
+	 *        __construct( Bar $bar_class, Fighter $grohl_class )
129
+	 *        then $bar_class and $grohl_class will be added to the $arguments array,
130
+	 *        but only IF they are NOT already present in the incoming arguments array,
131
+	 *        and the correct classes can be loaded
132
+	 *
133
+	 * @param RecipeInterface $recipe
134
+	 * @param ReflectionClass $reflector
135
+	 * @param array           $arguments
136
+	 * @return array
137
+	 * @throws UnexpectedValueException
138
+	 */
139
+	public function resolveDependencies(RecipeInterface $recipe, ReflectionClass $reflector, $arguments = array())
140
+	{
141
+		// if arguments array is numerically and sequentially indexed, then we want it to remain as is,
142
+		// else wrap it in an additional array so that it doesn't get split into multiple parameters
143
+		$arguments = $this->array_helper->is_array_numerically_and_sequentially_indexed($arguments)
144
+			? $arguments
145
+			: array($arguments);
146
+		$resolved_parameters = array();
147
+		// let's examine the constructor
148
+		// let's examine the constructor
149
+		$constructor = $this->getConstructor($reflector);
150
+		// whu? huh? nothing?
151
+		if (! $constructor) {
152
+			return $arguments;
153
+		}
154
+		// get constructor parameters
155
+		$params = $this->getParameters($constructor);
156
+		if (empty($params)) {
157
+			return $resolved_parameters;
158
+		}
159
+		$ingredients = $recipe->ingredients();
160
+		// and the keys for the incoming arguments array so that we can compare existing arguments with what is expected
161
+		$argument_keys = array_keys($arguments);
162
+		// now loop thru all of the constructors expected parameters
163
+		foreach ($params as $index => $param) {
164
+			if (! $param instanceof ReflectionParameter) {
165
+				continue;
166
+			}
167
+			// is this a dependency for a specific class ?
168
+			$param_class = $param->getClass() ? $param->getClass()->name : '';
169
+			$param_name = $param->getName() ? $param->getName() : '';
170
+			if (
171 171
 // param is not a class but is specified in the list of ingredients for this Recipe
172
-                is_string($param_name) && isset($ingredients[ $param_name ])
173
-            ) {
174
-                // attempt to inject the dependency
175
-                $resolved_parameters[ $index ] = $ingredients[ $param_name ];
176
-            } elseif (
172
+				is_string($param_name) && isset($ingredients[ $param_name ])
173
+			) {
174
+				// attempt to inject the dependency
175
+				$resolved_parameters[ $index ] = $ingredients[ $param_name ];
176
+			} elseif (
177 177
 // param is specified in the list of ingredients for this Recipe
178
-                isset($ingredients[ $param_class ])
179
-            ) { // attempt to inject the dependency
180
-                $resolved_parameters[ $index ] = $this->injectDependency($reflector, $ingredients[ $param_class ]);
181
-            } elseif (
178
+				isset($ingredients[ $param_class ])
179
+			) { // attempt to inject the dependency
180
+				$resolved_parameters[ $index ] = $this->injectDependency($reflector, $ingredients[ $param_class ]);
181
+			} elseif (
182 182
 // param is not even a class
183
-                empty($param_class)
184
-                // and something already exists in the incoming arguments for this param
185
-                && isset($argument_keys[ $index ], $arguments[ $argument_keys[ $index ] ])
186
-            ) {
187
-                // add parameter from incoming arguments
188
-                $resolved_parameters[ $index ] = $arguments[ $argument_keys[ $index ] ];
189
-            } elseif (
183
+				empty($param_class)
184
+				// and something already exists in the incoming arguments for this param
185
+				&& isset($argument_keys[ $index ], $arguments[ $argument_keys[ $index ] ])
186
+			) {
187
+				// add parameter from incoming arguments
188
+				$resolved_parameters[ $index ] = $arguments[ $argument_keys[ $index ] ];
189
+			} elseif (
190 190
 // parameter is type hinted as a class, exists as an incoming argument, AND it's the correct class
191
-                ! empty($param_class)
192
-                && isset($argument_keys[ $index ], $arguments[ $argument_keys[ $index ] ])
193
-                && $arguments[ $argument_keys[ $index ] ] instanceof $param_class
194
-            ) {
195
-                // add parameter from incoming arguments
196
-                $resolved_parameters[ $index ] = $arguments[ $argument_keys[ $index ] ];
197
-            } elseif (
191
+				! empty($param_class)
192
+				&& isset($argument_keys[ $index ], $arguments[ $argument_keys[ $index ] ])
193
+				&& $arguments[ $argument_keys[ $index ] ] instanceof $param_class
194
+			) {
195
+				// add parameter from incoming arguments
196
+				$resolved_parameters[ $index ] = $arguments[ $argument_keys[ $index ] ];
197
+			} elseif (
198 198
 // parameter is type hinted as a class, and should be injected
199
-                ! empty($param_class)
200
-            ) {
201
-                // attempt to inject the dependency
202
-                $resolved_parameters[ $index ] = $this->injectDependency($reflector, $param_class);
203
-            } elseif ($param->isOptional()) {
204
-                $resolved_parameters[ $index ] = $param->getDefaultValue();
205
-            } else {
206
-                $resolved_parameters[ $index ] = null;
207
-            }
208
-        }
209
-        return $resolved_parameters;
210
-    }
211
-
212
-
213
-    /**
214
-     * @param ReflectionClass $reflector
215
-     * @param string          $param_class
216
-     * @return mixed
217
-     * @throws UnexpectedValueException
218
-     */
219
-    private function injectDependency(ReflectionClass $reflector, $param_class)
220
-    {
221
-        $dependency = $this->coffee_pot->brew($param_class);
222
-        if (! $dependency instanceof $param_class) {
223
-            throw new UnexpectedValueException(
224
-                sprintf(
225
-                    esc_html__(
226
-                        'Could not resolve dependency for "%1$s" for the "%2$s" class constructor.',
227
-                        'event_espresso'
228
-                    ),
229
-                    $param_class,
230
-                    $reflector->getName()
231
-                )
232
-            );
233
-        }
234
-        return $dependency;
235
-    }
199
+				! empty($param_class)
200
+			) {
201
+				// attempt to inject the dependency
202
+				$resolved_parameters[ $index ] = $this->injectDependency($reflector, $param_class);
203
+			} elseif ($param->isOptional()) {
204
+				$resolved_parameters[ $index ] = $param->getDefaultValue();
205
+			} else {
206
+				$resolved_parameters[ $index ] = null;
207
+			}
208
+		}
209
+		return $resolved_parameters;
210
+	}
211
+
212
+
213
+	/**
214
+	 * @param ReflectionClass $reflector
215
+	 * @param string          $param_class
216
+	 * @return mixed
217
+	 * @throws UnexpectedValueException
218
+	 */
219
+	private function injectDependency(ReflectionClass $reflector, $param_class)
220
+	{
221
+		$dependency = $this->coffee_pot->brew($param_class);
222
+		if (! $dependency instanceof $param_class) {
223
+			throw new UnexpectedValueException(
224
+				sprintf(
225
+					esc_html__(
226
+						'Could not resolve dependency for "%1$s" for the "%2$s" class constructor.',
227
+						'event_espresso'
228
+					),
229
+					$param_class,
230
+					$reflector->getName()
231
+				)
232
+			);
233
+		}
234
+		return $dependency;
235
+	}
236 236
 }
Please login to merge, or discard this patch.
Spacing   +26 added lines, -26 removed lines patch added patch discarded remove patch
@@ -71,12 +71,12 @@  discard block
 block discarded – undo
71 71
     public function getReflectionClass($class_name)
72 72
     {
73 73
         if (
74
-            ! isset($this->reflectors[ $class_name ])
75
-            || ! $this->reflectors[ $class_name ] instanceof ReflectionClass
74
+            ! isset($this->reflectors[$class_name])
75
+            || ! $this->reflectors[$class_name] instanceof ReflectionClass
76 76
         ) {
77
-            $this->reflectors[ $class_name ] = new ReflectionClass($class_name);
77
+            $this->reflectors[$class_name] = new ReflectionClass($class_name);
78 78
         }
79
-        return $this->reflectors[ $class_name ];
79
+        return $this->reflectors[$class_name];
80 80
     }
81 81
 
82 82
 
@@ -91,12 +91,12 @@  discard block
 block discarded – undo
91 91
     protected function getConstructor(ReflectionClass $reflector)
92 92
     {
93 93
         if (
94
-            ! isset($this->constructors[ $reflector->getName() ])
95
-            || ! $this->constructors[ $reflector->getName() ] instanceof ReflectionMethod
94
+            ! isset($this->constructors[$reflector->getName()])
95
+            || ! $this->constructors[$reflector->getName()] instanceof ReflectionMethod
96 96
         ) {
97
-            $this->constructors[ $reflector->getName() ] = $reflector->getConstructor();
97
+            $this->constructors[$reflector->getName()] = $reflector->getConstructor();
98 98
         }
99
-        return $this->constructors[ $reflector->getName() ];
99
+        return $this->constructors[$reflector->getName()];
100 100
     }
101 101
 
102 102
 
@@ -110,10 +110,10 @@  discard block
 block discarded – undo
110 110
      */
111 111
     protected function getParameters(ReflectionMethod $constructor)
112 112
     {
113
-        if (! isset($this->parameters[ $constructor->class ])) {
114
-            $this->parameters[ $constructor->class ] = $constructor->getParameters();
113
+        if ( ! isset($this->parameters[$constructor->class])) {
114
+            $this->parameters[$constructor->class] = $constructor->getParameters();
115 115
         }
116
-        return $this->parameters[ $constructor->class ];
116
+        return $this->parameters[$constructor->class];
117 117
     }
118 118
 
119 119
 
@@ -148,7 +148,7 @@  discard block
 block discarded – undo
148 148
         // let's examine the constructor
149 149
         $constructor = $this->getConstructor($reflector);
150 150
         // whu? huh? nothing?
151
-        if (! $constructor) {
151
+        if ( ! $constructor) {
152 152
             return $arguments;
153 153
         }
154 154
         // get constructor parameters
@@ -161,7 +161,7 @@  discard block
 block discarded – undo
161 161
         $argument_keys = array_keys($arguments);
162 162
         // now loop thru all of the constructors expected parameters
163 163
         foreach ($params as $index => $param) {
164
-            if (! $param instanceof ReflectionParameter) {
164
+            if ( ! $param instanceof ReflectionParameter) {
165 165
                 continue;
166 166
             }
167 167
             // is this a dependency for a specific class ?
@@ -169,41 +169,41 @@  discard block
 block discarded – undo
169 169
             $param_name = $param->getName() ? $param->getName() : '';
170 170
             if (
171 171
 // param is not a class but is specified in the list of ingredients for this Recipe
172
-                is_string($param_name) && isset($ingredients[ $param_name ])
172
+                is_string($param_name) && isset($ingredients[$param_name])
173 173
             ) {
174 174
                 // attempt to inject the dependency
175
-                $resolved_parameters[ $index ] = $ingredients[ $param_name ];
175
+                $resolved_parameters[$index] = $ingredients[$param_name];
176 176
             } elseif (
177 177
 // param is specified in the list of ingredients for this Recipe
178
-                isset($ingredients[ $param_class ])
178
+                isset($ingredients[$param_class])
179 179
             ) { // attempt to inject the dependency
180
-                $resolved_parameters[ $index ] = $this->injectDependency($reflector, $ingredients[ $param_class ]);
180
+                $resolved_parameters[$index] = $this->injectDependency($reflector, $ingredients[$param_class]);
181 181
             } elseif (
182 182
 // param is not even a class
183 183
                 empty($param_class)
184 184
                 // and something already exists in the incoming arguments for this param
185
-                && isset($argument_keys[ $index ], $arguments[ $argument_keys[ $index ] ])
185
+                && isset($argument_keys[$index], $arguments[$argument_keys[$index]])
186 186
             ) {
187 187
                 // add parameter from incoming arguments
188
-                $resolved_parameters[ $index ] = $arguments[ $argument_keys[ $index ] ];
188
+                $resolved_parameters[$index] = $arguments[$argument_keys[$index]];
189 189
             } elseif (
190 190
 // parameter is type hinted as a class, exists as an incoming argument, AND it's the correct class
191 191
                 ! empty($param_class)
192
-                && isset($argument_keys[ $index ], $arguments[ $argument_keys[ $index ] ])
193
-                && $arguments[ $argument_keys[ $index ] ] instanceof $param_class
192
+                && isset($argument_keys[$index], $arguments[$argument_keys[$index]])
193
+                && $arguments[$argument_keys[$index]] instanceof $param_class
194 194
             ) {
195 195
                 // add parameter from incoming arguments
196
-                $resolved_parameters[ $index ] = $arguments[ $argument_keys[ $index ] ];
196
+                $resolved_parameters[$index] = $arguments[$argument_keys[$index]];
197 197
             } elseif (
198 198
 // parameter is type hinted as a class, and should be injected
199 199
                 ! empty($param_class)
200 200
             ) {
201 201
                 // attempt to inject the dependency
202
-                $resolved_parameters[ $index ] = $this->injectDependency($reflector, $param_class);
202
+                $resolved_parameters[$index] = $this->injectDependency($reflector, $param_class);
203 203
             } elseif ($param->isOptional()) {
204
-                $resolved_parameters[ $index ] = $param->getDefaultValue();
204
+                $resolved_parameters[$index] = $param->getDefaultValue();
205 205
             } else {
206
-                $resolved_parameters[ $index ] = null;
206
+                $resolved_parameters[$index] = null;
207 207
             }
208 208
         }
209 209
         return $resolved_parameters;
@@ -219,7 +219,7 @@  discard block
 block discarded – undo
219 219
     private function injectDependency(ReflectionClass $reflector, $param_class)
220 220
     {
221 221
         $dependency = $this->coffee_pot->brew($param_class);
222
-        if (! $dependency instanceof $param_class) {
222
+        if ( ! $dependency instanceof $param_class) {
223 223
             throw new UnexpectedValueException(
224 224
                 sprintf(
225 225
                     esc_html__(
Please login to merge, or discard this patch.
core/db_classes/EE_Question_Option.class.php 1 patch
Indentation   +218 added lines, -218 removed lines patch added patch discarded remove patch
@@ -10,222 +10,222 @@
 block discarded – undo
10 10
 class EE_Question_Option extends EE_Soft_Delete_Base_Class implements EEI_Duplicatable
11 11
 {
12 12
 
13
-    /**
14
-     * Question Option Opt Group Name
15
-     *
16
-     * @access protected
17
-     * @var string
18
-     */
19
-    protected $_QSO_opt_group = null;
20
-
21
-
22
-    /**
23
-     *
24
-     * @param array  $props_n_values          incoming values
25
-     * @param string $timezone                incoming timezone (if not set the timezone set for the website will be
26
-     *                                        used.)
27
-     * @param array  $date_formats            incoming date_formats in an array where the first value is the
28
-     *                                        date_format and the second value is the time format
29
-     * @return EE_Attendee
30
-     */
31
-    public static function new_instance($props_n_values = array(), $timezone = null, $date_formats = array())
32
-    {
33
-        $has_object = parent::_check_for_object($props_n_values, __CLASS__, $timezone, $date_formats);
34
-        return $has_object ? $has_object : new self($props_n_values, false, $timezone, $date_formats);
35
-    }
36
-
37
-
38
-    /**
39
-     * @param array  $props_n_values  incoming values from the database
40
-     * @param string $timezone        incoming timezone as set by the model.  If not set the timezone for
41
-     *                                the website will be used.
42
-     * @return EE_Attendee
43
-     */
44
-    public static function new_instance_from_db($props_n_values = array(), $timezone = null)
45
-    {
46
-        return new self($props_n_values, true, $timezone);
47
-    }
48
-
49
-
50
-    /**
51
-     * Sets the option's key value
52
-     *
53
-     * @param string $value
54
-     * @return bool success
55
-     */
56
-    public function set_value($value)
57
-    {
58
-        $this->set('QSO_value', $value);
59
-    }
60
-
61
-
62
-    /**
63
-     * Sets the option's Display Text
64
-     *
65
-     * @param string $text
66
-     * @return bool success
67
-     */
68
-    public function set_desc($text)
69
-    {
70
-        $this->set('QSO_desc', $text);
71
-    }
72
-
73
-
74
-    /**
75
-     * Sets the order for this option
76
-     *
77
-     * @access public
78
-     * @param integer $order
79
-     * @return bool      $success
80
-     */
81
-    public function set_order($order)
82
-    {
83
-        $this->set('QSO_order', $order);
84
-    }
85
-
86
-
87
-    /**
88
-     * Sets the ID of the related question
89
-     *
90
-     * @param int $question_ID
91
-     * @return bool success
92
-     */
93
-    public function set_question_ID($question_ID)
94
-    {
95
-        $this->set('QST_ID', $question_ID);
96
-    }
97
-
98
-
99
-    /**
100
-     * Sets the option's opt_group
101
-     *
102
-     * @param string $text
103
-     * @return bool success
104
-     */
105
-    public function set_opt_group($text)
106
-    {
107
-        return $this->_QSO_opt_group = $text;
108
-    }
109
-
110
-
111
-    /**
112
-     * Gets the option's key value
113
-     *
114
-     * @return string
115
-     */
116
-    public function value()
117
-    {
118
-        return $this->get('QSO_value');
119
-    }
120
-
121
-
122
-    /**
123
-     * Gets the option's display text
124
-     *
125
-     * @return string
126
-     */
127
-    public function desc()
128
-    {
129
-        return $this->get('QSO_desc');
130
-    }
131
-
132
-
133
-    /**
134
-     * Returns whether this option has been deleted or not
135
-     *
136
-     * @return boolean
137
-     */
138
-    public function deleted()
139
-    {
140
-        return $this->get('QSO_deleted');
141
-    }
142
-
143
-
144
-    /**
145
-     * Returns the order or the Question Option
146
-     *
147
-     * @access public
148
-     * @return integer
149
-     */
150
-    public function order()
151
-    {
152
-        return $this->get('QSO_option');
153
-    }
154
-
155
-
156
-    /**
157
-     * Gets the related question's ID
158
-     *
159
-     * @return int
160
-     */
161
-    public function question_ID()
162
-    {
163
-        return $this->get('QST_ID');
164
-    }
165
-
166
-
167
-    /**
168
-     * Returns the question related to this question option
169
-     *
170
-     * @return EE_Question
171
-     */
172
-    public function question()
173
-    {
174
-        return $this->get_first_related('Question');
175
-    }
176
-
177
-
178
-    /**
179
-     * Gets the option's opt_group
180
-     *
181
-     * @return string
182
-     */
183
-    public function opt_group()
184
-    {
185
-        return $this->_QSO_opt_group;
186
-    }
187
-
188
-    /**
189
-     * Duplicates this question option. By default the new question option will be for the same question,
190
-     * but that can be overriden by setting the 'QST_ID' option
191
-     *
192
-     * @param array $options {
193
-     * @type int    $QST_ID  the QST_ID attribute of this question option, otherwise it will be for the same question
194
-     *                       as the original
195
-     */
196
-    public function duplicate($options = array())
197
-    {
198
-        $new_question_option = clone $this;
199
-        $new_question_option->set('QSO_ID', null);
200
-        if (
201
-            array_key_exists(
202
-                'QST_ID',
203
-                $options
204
-            )
205
-        ) {// use array_key_exists instead of isset because NULL might be a valid value
206
-            $new_question_option->set_question_ID($options['QST_ID']);
207
-        }
208
-        $new_question_option->save();
209
-    }
210
-
211
-    /**
212
-     * Gets the QSO_system value
213
-     *
214
-     * @return string|null
215
-     */
216
-    public function system()
217
-    {
218
-        return $this->get('QSO_system');
219
-    }
220
-
221
-    /**
222
-     * Sets QSO_system
223
-     *
224
-     * @param string $QSO_system
225
-     * @return bool
226
-     */
227
-    public function set_system($QSO_system)
228
-    {
229
-        return $this->set('QSO_system', $QSO_system);
230
-    }
13
+	/**
14
+	 * Question Option Opt Group Name
15
+	 *
16
+	 * @access protected
17
+	 * @var string
18
+	 */
19
+	protected $_QSO_opt_group = null;
20
+
21
+
22
+	/**
23
+	 *
24
+	 * @param array  $props_n_values          incoming values
25
+	 * @param string $timezone                incoming timezone (if not set the timezone set for the website will be
26
+	 *                                        used.)
27
+	 * @param array  $date_formats            incoming date_formats in an array where the first value is the
28
+	 *                                        date_format and the second value is the time format
29
+	 * @return EE_Attendee
30
+	 */
31
+	public static function new_instance($props_n_values = array(), $timezone = null, $date_formats = array())
32
+	{
33
+		$has_object = parent::_check_for_object($props_n_values, __CLASS__, $timezone, $date_formats);
34
+		return $has_object ? $has_object : new self($props_n_values, false, $timezone, $date_formats);
35
+	}
36
+
37
+
38
+	/**
39
+	 * @param array  $props_n_values  incoming values from the database
40
+	 * @param string $timezone        incoming timezone as set by the model.  If not set the timezone for
41
+	 *                                the website will be used.
42
+	 * @return EE_Attendee
43
+	 */
44
+	public static function new_instance_from_db($props_n_values = array(), $timezone = null)
45
+	{
46
+		return new self($props_n_values, true, $timezone);
47
+	}
48
+
49
+
50
+	/**
51
+	 * Sets the option's key value
52
+	 *
53
+	 * @param string $value
54
+	 * @return bool success
55
+	 */
56
+	public function set_value($value)
57
+	{
58
+		$this->set('QSO_value', $value);
59
+	}
60
+
61
+
62
+	/**
63
+	 * Sets the option's Display Text
64
+	 *
65
+	 * @param string $text
66
+	 * @return bool success
67
+	 */
68
+	public function set_desc($text)
69
+	{
70
+		$this->set('QSO_desc', $text);
71
+	}
72
+
73
+
74
+	/**
75
+	 * Sets the order for this option
76
+	 *
77
+	 * @access public
78
+	 * @param integer $order
79
+	 * @return bool      $success
80
+	 */
81
+	public function set_order($order)
82
+	{
83
+		$this->set('QSO_order', $order);
84
+	}
85
+
86
+
87
+	/**
88
+	 * Sets the ID of the related question
89
+	 *
90
+	 * @param int $question_ID
91
+	 * @return bool success
92
+	 */
93
+	public function set_question_ID($question_ID)
94
+	{
95
+		$this->set('QST_ID', $question_ID);
96
+	}
97
+
98
+
99
+	/**
100
+	 * Sets the option's opt_group
101
+	 *
102
+	 * @param string $text
103
+	 * @return bool success
104
+	 */
105
+	public function set_opt_group($text)
106
+	{
107
+		return $this->_QSO_opt_group = $text;
108
+	}
109
+
110
+
111
+	/**
112
+	 * Gets the option's key value
113
+	 *
114
+	 * @return string
115
+	 */
116
+	public function value()
117
+	{
118
+		return $this->get('QSO_value');
119
+	}
120
+
121
+
122
+	/**
123
+	 * Gets the option's display text
124
+	 *
125
+	 * @return string
126
+	 */
127
+	public function desc()
128
+	{
129
+		return $this->get('QSO_desc');
130
+	}
131
+
132
+
133
+	/**
134
+	 * Returns whether this option has been deleted or not
135
+	 *
136
+	 * @return boolean
137
+	 */
138
+	public function deleted()
139
+	{
140
+		return $this->get('QSO_deleted');
141
+	}
142
+
143
+
144
+	/**
145
+	 * Returns the order or the Question Option
146
+	 *
147
+	 * @access public
148
+	 * @return integer
149
+	 */
150
+	public function order()
151
+	{
152
+		return $this->get('QSO_option');
153
+	}
154
+
155
+
156
+	/**
157
+	 * Gets the related question's ID
158
+	 *
159
+	 * @return int
160
+	 */
161
+	public function question_ID()
162
+	{
163
+		return $this->get('QST_ID');
164
+	}
165
+
166
+
167
+	/**
168
+	 * Returns the question related to this question option
169
+	 *
170
+	 * @return EE_Question
171
+	 */
172
+	public function question()
173
+	{
174
+		return $this->get_first_related('Question');
175
+	}
176
+
177
+
178
+	/**
179
+	 * Gets the option's opt_group
180
+	 *
181
+	 * @return string
182
+	 */
183
+	public function opt_group()
184
+	{
185
+		return $this->_QSO_opt_group;
186
+	}
187
+
188
+	/**
189
+	 * Duplicates this question option. By default the new question option will be for the same question,
190
+	 * but that can be overriden by setting the 'QST_ID' option
191
+	 *
192
+	 * @param array $options {
193
+	 * @type int    $QST_ID  the QST_ID attribute of this question option, otherwise it will be for the same question
194
+	 *                       as the original
195
+	 */
196
+	public function duplicate($options = array())
197
+	{
198
+		$new_question_option = clone $this;
199
+		$new_question_option->set('QSO_ID', null);
200
+		if (
201
+			array_key_exists(
202
+				'QST_ID',
203
+				$options
204
+			)
205
+		) {// use array_key_exists instead of isset because NULL might be a valid value
206
+			$new_question_option->set_question_ID($options['QST_ID']);
207
+		}
208
+		$new_question_option->save();
209
+	}
210
+
211
+	/**
212
+	 * Gets the QSO_system value
213
+	 *
214
+	 * @return string|null
215
+	 */
216
+	public function system()
217
+	{
218
+		return $this->get('QSO_system');
219
+	}
220
+
221
+	/**
222
+	 * Sets QSO_system
223
+	 *
224
+	 * @param string $QSO_system
225
+	 * @return bool
226
+	 */
227
+	public function set_system($QSO_system)
228
+	{
229
+		return $this->set('QSO_system', $QSO_system);
230
+	}
231 231
 }
Please login to merge, or discard this patch.