Completed
Push — develop ( e9fbb0...dd1349 )
by David
02:54
created

Wordlift_Configuration_Service::get_instance()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 2
nc 1
nop 0
dl 0
loc 4
rs 10
c 0
b 0
f 0
1
<?php
2
/**
3
 * Wordlift_Configuration_Service class.
4
 *
5
 * The {@link Wordlift_Configuration_Service} class provides helper functions to get configuration parameter values.
6
 *
7
 * @link       https://wordlift.io
8
 *
9
 * @package    Wordlift
10
 * @since      3.6.0
11
 */
12
13
if ( ! defined( 'ABSPATH' ) ) {
14
	exit;
15
}
16
17
/**
18
 * Get WordLift's configuration settings stored in WordPress database.
19
 *
20
 * @since 3.6.0
21
 */
22
class Wordlift_Configuration_Service {
23
24
	/**
25
	 * The entity base path option name.
26
	 *
27
	 * @since 3.6.0
28
	 */
29
	const ENTITY_BASE_PATH_KEY = 'wl_entity_base_path';
30
31
	/**
32
	 * The skip wizard (admin installation wizard) option name.
33
	 *
34
	 * @since 3.9.0
35
	 */
36
	const SKIP_WIZARD = 'wl_skip_wizard';
37
38
	/**
39
	 * WordLift's key option name.
40
	 *
41
	 * @since 3.9.0
42
	 */
43
	const KEY = 'key';
44
45
	/**
46
	 * WordLift's configured language option name.
47
	 *
48
	 * @since 3.9.0
49
	 */
50
	const LANGUAGE = 'site_language';
51
52
	/**
53
	 * The publisher entity post ID option name.
54
	 *
55
	 * @since 3.9.0
56
	 */
57
	const PUBLISHER_ID = 'publisher_id';
58
59
	/**
60
	 * The dataset URI option name
61
	 *
62
	 * @since 3.10.0
63
	 */
64
	const DATASET_URI = 'redlink_dataset_uri';
65
66
	/**
67
	 * The link by default option name.
68
	 *
69
	 * @since 3.11.0
70
	 */
71
	const LINK_BY_DEFAULT = 'link_by_default';
72
73
	/**
74
	 * The Wordlift_Configuration_Service's singleton instance.
75
	 *
76
	 * @since  3.6.0
77
	 *
78
	 * @access private
79
	 * @var \Wordlift_Configuration_Service $instance Wordlift_Configuration_Service's singleton instance.
80
	 */
81
	private static $instance;
82
83
	/**
84
	 * Create a Wordlift_Configuration_Service's instance.
85
	 *
86
	 * @since 3.6.0
87
	 */
88
	public function __construct() {
89
90
		self::$instance = $this;
91
92
	}
93
94
	/**
95
	 * Get the singleton instance.
96
	 *
97
	 * @since 3.6.0
98
	 *
99
	 * @return \Wordlift_Configuration_Service
100
	 */
101
	public static function get_instance() {
102
103
		return self::$instance;
104
	}
105
106
	/**
107
	 * Get a configuration given the option name and a key. The option value is
108
	 * expected to be an array.
109
	 *
110
	 * @since 3.6.0
111
	 *
112
	 * @param string $option  The option name.
113
	 * @param string $key     A key in the option value array.
114
	 * @param string $default The default value in case the key is not found (by default an empty string).
115
	 *
116
	 * @return mixed The configuration value or the default value if not found.
117
	 */
118
	private function get( $option, $key, $default = '' ) {
119
120
		$options = get_option( $option, array() );
121
122
		return isset( $options[ $key ] ) ? $options[ $key ] : $default;
123
	}
124
125
	/**
126
	 * Set a configuration parameter.
127
	 *
128
	 * @since 3.9.0
129
	 *
130
	 * @param string $option Name of option to retrieve. Expected to not be SQL-escaped.
131
	 * @param string $key    The value key.
132
	 * @param mixed  $value  The value.
133
	 */
134 View Code Duplication
	private function set( $option, $key, $value ) {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
135
136
		$values         = get_option( $option );
137
		$values         = isset( $values ) ? $values : array();
138
		$values[ $key ] = $value;
139
		update_option( $option, $values );
140
141
	}
142
143
	/**
144
	 * Get the entity base path, by default 'entity'.
145
	 *
146
	 * @since 3.6.0
147
	 *
148
	 * @return string The entity base path.
149
	 */
150
	public function get_entity_base_path() {
151
152
		return $this->get( 'wl_general_settings', self::ENTITY_BASE_PATH_KEY, 'entity' );
153
	}
154
155
	/**
156
	 * Get the entity base path.
157
	 *
158
	 * @since 3.9.0
159
	 *
160
	 * @param string $value The entity base path.
161
	 */
162
	public function set_entity_base_path( $value ) {
163
164
		$this->set( 'wl_general_settings', self::ENTITY_BASE_PATH_KEY, $value );
165
	}
166
167
	/**
168
	 * Whether the installation skip wizard should be skipped.
169
	 *
170
	 * @since 3.9.0
171
	 *
172
	 * @return bool True if it should be skipped otherwise false.
173
	 */
174
	public function is_skip_wizard() {
175
176
		return $this->get( 'wl_general_settings', self::SKIP_WIZARD, false );
0 ignored issues
show
Documentation introduced by
false is of type boolean, but the function expects a string.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
177
	}
178
179
	/**
180
	 * Set the skip wizard parameter.
181
	 *
182
	 * @since 3.9.0
183
	 *
184
	 * @param bool $value True to skip the wizard. We expect a boolean value.
185
	 */
186
	public function set_skip_wizard( $value ) {
187
188
		$this->set( 'wl_general_settings', self::SKIP_WIZARD, true === $value );
189
190
	}
191
192
	/**
193
	 * Get WordLift's key.
194
	 *
195
	 * @since 3.9.0
196
	 *
197
	 * @return string WordLift's key or an empty string if not set.
198
	 */
199
	public function get_key() {
200
201
		return $this->get( 'wl_general_settings', self::KEY, '' );
202
	}
203
204
	/**
205
	 * Set WordLift's key.
206
	 *
207
	 * @since 3.9.0
208
	 *
209
	 * @param string $value WordLift's key.
210
	 */
211
	public function set_key( $value ) {
212
213
		$this->set( 'wl_general_settings', self::KEY, $value );
214
	}
215
216
	/**
217
	 * Get WordLift's configured language, by default 'en'.
218
	 *
219
	 * Note that WordLift's language is used when writing strings to the Linked Data dataset, not for the analysis.
220
	 *
221
	 * @since 3.9.0
222
	 *
223
	 * @return string WordLift's configured language code ('en' by default).
224
	 */
225
	public function get_language_code() {
226
227
		return $this->get( 'wl_general_settings', self::LANGUAGE, 'en' );
228
	}
229
230
	/**
231
	 * Set WordLift's language code, used when storing strings to the Linked Data dataset.
232
	 *
233
	 * @since 3.9.0
234
	 *
235
	 * @param string $value WordLift's language code.
236
	 */
237
	public function set_language_code( $value ) {
238
239
		$this->set( 'wl_general_settings', self::LANGUAGE, $value );
240
241
	}
242
243
	/**
244
	 * Get the publisher entity post id.
245
	 *
246
	 * The publisher entity post id points to an entity post which contains the data for the publisher used in schema.org
247
	 * Article markup.
248
	 *
249
	 * @since 3.9.0
250
	 *
251
	 * @return int|NULL The publisher entity post id or NULL if not set.
252
	 */
253
	public function get_publisher_id() {
254
255
		return $this->get( 'wl_general_settings', self::PUBLISHER_ID, null );
256
	}
257
258
	/**
259
	 * Set the publisher entity post id.
260
	 *
261
	 * @since 3.9.0
262
	 *
263
	 * @param int $value The publisher entity post id.
264
	 */
265
	public function set_publisher_id( $value ) {
266
267
		$this->set( 'wl_general_settings', self::PUBLISHER_ID, $value );
268
269
	}
270
271
	/**
272
	 * Get the dataset URI.
273
	 *
274
	 * @since 3.10.0
275
	 *
276
	 * @return string The dataset URI or an empty string if not set.
277
	 */
278
	public function get_dataset_uri() {
279
280
		return $this->get( 'wl_advanced_settings', self::DATASET_URI, null );
281
	}
282
283
	/**
284
	 * Set the dataset URI.
285
	 *
286
	 * @since 3.10.0
287
	 *
288
	 * @param string $value The dataset URI.
289
	 */
290
	public function set_dataset_uri( $value ) {
291
292
		$this->set( 'wl_advanced_settings', self::DATASET_URI, $value );
293
	}
294
295
	/**
296
	 * Intercept the change of the WordLift key in order to set the dataset URI.
297
	 *
298
	 * @since 3.11.0
299
	 *
300
	 * @param array $old_value The old settings.
301
	 * @param array $new_value The new settings.
302
	 */
303
	public function update_key( $old_value, $new_value ) {
304
305
		// Check the old key value and the new one. We're going to ask for the dataset URI only if the key has changed.
306
		$old_key = isset( $old_value['key'] ) ? $old_value['key'] : '';
307
		$new_key = isset( $new_value['key'] ) ? $new_value['key'] : '';
308
309
		// If the key hasn't changed, don't do anything.
310
		// WARN The 'update_option' hook is fired only if the new and old value are not equal
311
		if ( $old_key === $new_key ) {
312
			return;
313
		}
314
315
		// If the key is empty, empty the dataset URI.
316
		if ( '' === $new_key ) {
317
			$this->set_dataset_uri( '' );
318
		}
319
320
		// make the request to the remote server
321
		$this->get_remote_dataset_uri( $new_key );
322
	}
323
324
	/**
325
	 * Handle retrieving the dataset uri from the remote server.
326
	 *
327
	 * If a valid dataset uri is returned it is stored in the appropriate option,
328
	 * otherwise the option is set to empty string.
329
	 *
330
	 * @since 3.12.0
331
	 *
332
	 * @param string $key The key to be used
333
	 *
334
	 */
335
	private function get_remote_dataset_uri( $key ) {
336
		// Request the dataset URI.
337
		$response = wp_remote_get( $this->get_accounts_by_key_dataset_uri( $key ), unserialize( WL_REDLINK_API_HTTP_OPTIONS ) );
338
339
		// If the response is valid, then set the value.
340
		if ( ! is_wp_error( $response ) && 200 === (int) $response['response']['code'] ) {
341
			$this->set_dataset_uri( $response['body'] );
342
		} else {
343
			$this->set_dataset_uri( '' );
344
		}
345
	}
346
347
	/**
348
	 * Handle the edge case where a user submits the same key again
349
	 * when he does not have the dataset uri to regain it.
350
	 *
351
	 * This can not be handled in the normal option update hook because
352
	 * it is not being triggered when the save value equals to the one already
353
	 * in the DB.
354
	 *
355
	 * @since 3.12.0
356
	 *
357
	 * @param mixed $value     The new, unserialized option value.
358
	 * @param mixed $old_value The old option value.
359
	 *
360
	 * @return mixed The same value in the $value parameter
361
	 *
362
	 */
363
	function maybe_update_dataset_uri( $value, $old_value ) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
364
365
		// Check the old key value and the new one. Here we're only handling the
366
		// case where the key hasn't changed and the dataset URI isn't set. The
367
		// other case, i.e. a new key is inserted, is handled at `update_key`.
368
		$old_key = isset( $old_value['key'] ) ? $old_value['key'] : '';
369
		$new_key = isset( $value['key'] ) ? $value['key'] : '';
370
371
		$dataset_uri = $this->get_dataset_uri();
372
373
		if ( ! empty( $new_key ) && $new_key === $old_key && empty( $dataset_uri ) ) {
374
375
			// make the request to the remote server to try to get the dataset uri
376
			$this->get_remote_dataset_uri( $new_key );
377
		}
378
379
		return $value;
380
	}
381
382
	/**
383
	 * Get the API URI to retrieve the dataset URI using the WordLift Key.
384
	 *
385
	 * @since 3.11.0
386
	 *
387
	 * @param string $key The WordLift key to use.
388
	 *
389
	 * @return string The API URI.
390
	 */
391
	public function get_accounts_by_key_dataset_uri( $key ) {
392
393
		return WL_CONFIG_WORDLIFT_API_URL_DEFAULT_VALUE . "accounts/key=$key/dataset_uri";
394
	}
395
396
	/**
397
	 * Get the `link by default` option.
398
	 *
399
	 * @since 3.13.0
400
	 *
401
	 * @return bool True if entities must be linked by default otherwise false.
402
	 */
403
	public function is_link_by_default() {
404
405
		return 'yes' === $this->get( 'wl_general_settings', self::LINK_BY_DEFAULT, 'yes' );
406
	}
407
408
	/**
409
	 * Set the `link by default` option.
410
	 *
411
	 * @since 3.13.0
412
	 *
413
	 * @param bool $value True to enabling linking by default, otherwise false.
414
	 */
415
	public function set_link_by_default( $value ) {
416
417
		$this->set( 'wl_general_settings', self::LINK_BY_DEFAULT, true === $value ? 'yes' : 'no' );
418
	}
419
420
}
421