Completed
Push — master ( a52753...0d2e2e )
by David
02:32
created

Wordlift_Configuration_Service::update_key()   A

Complexity

Conditions 3
Paths 4

Size

Total Lines 21

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
nc 4
nop 2
dl 0
loc 21
rs 9.584
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
	 * WordLift's configured country code.
54
	 *
55
	 * @since 3.18.0
56
	 */
57
	const COUNTRY_CODE = 'country_code';
58
59
	/**
60
	 * The publisher entity post ID option name.
61
	 *
62
	 * @since 3.9.0
63
	 */
64
	const PUBLISHER_ID = 'publisher_id';
65
66
	/**
67
	 * The dataset URI option name
68
	 *
69
	 * @since 3.10.0
70
	 */
71
	const DATASET_URI = 'redlink_dataset_uri';
72
73
	/**
74
	 * The link by default option name.
75
	 *
76
	 * @since 3.11.0
77
	 */
78
	const LINK_BY_DEFAULT = 'link_by_default';
79
80
	/**
81
	 * The analytics enable option.
82
	 *
83
	 * @since 3.21.0
84
	 */
85
	const ANALYTICS_ENABLE = 'analytics_enable';
86
87
	/**
88
	 * The analytics entity uri dimension option.
89
	 *
90
	 * @since 3.21.0
91
	 */
92
	const ANALYTICS_ENTITY_URI_DIMENSION = 'analytics_entity_uri_dimension';
93
94
	/**
95
	 * The analytics entity type dimension option.
96
	 *
97
	 * @since 3.21.0
98
	 */
99
	const ANALYTICS_ENTITY_TYPE_DIMENSION = 'analytics_entity_type_dimension';
100
101
	/**
102
	 * The user preferences about sharing data option.
103
	 *
104
	 * @since 3.19.0
105
	 */
106
	const SEND_DIAGNOSTIC = 'send_diagnostic';
107
108
	/**
109
	 * The package type configuration key.
110
	 *
111
	 * @since 3.20.0
112
	 */
113
	const PACKAGE_TYPE = 'package_type';
114
115
	/**
116
	 * The {@link Wordlift_Log_Service} instance.
117
	 *
118
	 * @since 3.16.0
119
	 *
120
	 * @var \Wordlift_Log_Service $log The {@link Wordlift_Log_Service} instance.
121
	 */
122
	private $log;
123
124
	/**
125
	 * The Wordlift_Configuration_Service's singleton instance.
126
	 *
127
	 * @since  3.6.0
128
	 *
129
	 * @access private
130
	 * @var \Wordlift_Configuration_Service $instance Wordlift_Configuration_Service's singleton instance.
131
	 */
132
	private static $instance;
133
134
	/**
135
	 * Create a Wordlift_Configuration_Service's instance.
136
	 *
137
	 * @since 3.6.0
138
	 */
139
	public function __construct() {
140
141
		$this->log = Wordlift_Log_Service::get_logger( get_class() );
142
143
		self::$instance = $this;
144
145
	}
146
147
	/**
148
	 * Get the singleton instance.
149
	 *
150
	 * @return \Wordlift_Configuration_Service
151
	 * @since 3.6.0
152
	 *
153
	 */
154
	public static function get_instance() {
155
156
		return self::$instance;
157
	}
158
159
	/**
160
	 * Get a configuration given the option name and a key. The option value is
161
	 * expected to be an array.
162
	 *
163
	 * @param string $option The option name.
164
	 * @param string $key A key in the option value array.
165
	 * @param string $default The default value in case the key is not found (by default an empty string).
166
	 *
167
	 * @return mixed The configuration value or the default value if not found.
168
	 * @since 3.6.0
169
	 *
170
	 */
171
	private function get( $option, $key, $default = '' ) {
172
173
		$options = get_option( $option, array() );
174
175
		return isset( $options[ $key ] ) ? $options[ $key ] : $default;
176
	}
177
178
	/**
179
	 * Set a configuration parameter.
180
	 *
181
	 * @param string $option Name of option to retrieve. Expected to not be SQL-escaped.
182
	 * @param string $key The value key.
183
	 * @param mixed $value The value.
184
	 *
185
	 * @since 3.9.0
186
	 *
187
	 */
188
	private function set( $option, $key, $value ) {
189
190
		$values         = get_option( $option );
191
		$values         = isset( $values ) ? $values : array();
192
		$values[ $key ] = $value;
193
		update_option( $option, $values );
194
195
	}
196
197
	/**
198
	 * Get the entity base path, by default 'entity'.
199
	 *
200
	 * @return string The entity base path.
201
	 * @since 3.6.0
202
	 *
203
	 */
204
	public function get_entity_base_path() {
205
206
		return $this->get( 'wl_general_settings', self::ENTITY_BASE_PATH_KEY, 'entity' );
207
	}
208
209
	/**
210
	 * Get the entity base path.
211
	 *
212
	 * @param string $value The entity base path.
213
	 *
214
	 * @since 3.9.0
215
	 *
216
	 */
217
	public function set_entity_base_path( $value ) {
218
219
		$this->set( 'wl_general_settings', self::ENTITY_BASE_PATH_KEY, $value );
220
221
	}
222
223
	/**
224
	 * Whether the installation skip wizard should be skipped.
225
	 *
226
	 * @return bool True if it should be skipped otherwise false.
227
	 * @since 3.9.0
228
	 *
229
	 */
230
	public function is_skip_wizard() {
231
232
		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...
233
	}
234
235
	/**
236
	 * Set the skip wizard parameter.
237
	 *
238
	 * @param bool $value True to skip the wizard. We expect a boolean value.
239
	 *
240
	 * @since 3.9.0
241
	 *
242
	 */
243
	public function set_skip_wizard( $value ) {
244
245
		$this->set( 'wl_general_settings', self::SKIP_WIZARD, true === $value );
246
247
	}
248
249
	/**
250
	 * Get WordLift's key.
251
	 *
252
	 * @return string WordLift's key or an empty string if not set.
253
	 * @since 3.9.0
254
	 *
255
	 */
256
	public function get_key() {
257
258
		return $this->get( 'wl_general_settings', self::KEY, '' );
259
	}
260
261
	/**
262
	 * Set WordLift's key.
263
	 *
264
	 * @param string $value WordLift's key.
265
	 *
266
	 * @since 3.9.0
267
	 *
268
	 */
269
	public function set_key( $value ) {
270
271
		$this->set( 'wl_general_settings', self::KEY, $value );
272
	}
273
274
	/**
275
	 * Get WordLift's configured language, by default 'en'.
276
	 *
277
	 * Note that WordLift's language is used when writing strings to the Linked Data dataset, not for the analysis.
278
	 *
279
	 * @return string WordLift's configured language code ('en' by default).
280
	 * @since 3.9.0
281
	 *
282
	 */
283
	public function get_language_code() {
284
285
		return $this->get( 'wl_general_settings', self::LANGUAGE, 'en' );
286
	}
287
288
	/**
289
	 * Set WordLift's language code, used when storing strings to the Linked Data dataset.
290
	 *
291
	 * @param string $value WordLift's language code.
292
	 *
293
	 * @since 3.9.0
294
	 *
295
	 */
296
	public function set_language_code( $value ) {
297
298
		$this->set( 'wl_general_settings', self::LANGUAGE, $value );
299
300
	}
301
302
	/**
303
	 * Set the user preferences about sharing diagnostic with us.
304
	 *
305
	 * @param string $value The user preferences(yes/no).
306
	 *
307
	 * @since 3.19.0
308
	 *
309
	 */
310
	public function set_diagnostic_preferences( $value ) {
311
312
		$this->set( 'wl_general_settings', self::SEND_DIAGNOSTIC, $value );
313
314
	}
315
316
	/**
317
	 * Get the user preferences about sharing diagnostic.
318
	 *
319
	 * @since 3.19.0
320
	 */
321
	public function get_diagnostic_preferences() {
322
323
		return $this->get( 'wl_general_settings', self::SEND_DIAGNOSTIC, 'no' );
324
	}
325
326
	/**
327
	 * Get WordLift's configured country code, by default 'us'.
328
	 *
329
	 * @return string WordLift's configured country code ('us' by default).
330
	 * @since 3.18.0
331
	 *
332
	 */
333
	public function get_country_code() {
334
335
		return $this->get( 'wl_general_settings', self::COUNTRY_CODE, 'us' );
336
	}
337
338
	/**
339
	 * Set WordLift's country code.
340
	 *
341
	 * @param string $value WordLift's country code.
342
	 *
343
	 * @since 3.18.0
344
	 *
345
	 */
346
	public function set_country_code( $value ) {
347
348
		$this->set( 'wl_general_settings', self::COUNTRY_CODE, $value );
349
350
	}
351
352
	/**
353
	 * Get the publisher entity post id.
354
	 *
355
	 * The publisher entity post id points to an entity post which contains the data for the publisher used in schema.org
356
	 * Article markup.
357
	 *
358
	 * @return int|NULL The publisher entity post id or NULL if not set.
359
	 * @since 3.9.0
360
	 *
361
	 */
362
	public function get_publisher_id() {
363
364
		return $this->get( 'wl_general_settings', self::PUBLISHER_ID, null );
365
	}
366
367
	/**
368
	 * Set the publisher entity post id.
369
	 *
370
	 * @param int $value The publisher entity post id.
371
	 *
372
	 * @since 3.9.0
373
	 *
374
	 */
375
	public function set_publisher_id( $value ) {
376
377
		$this->set( 'wl_general_settings', self::PUBLISHER_ID, $value );
378
379
	}
380
381
	/**
382
	 * Get the dataset URI.
383
	 *
384
	 * @return string The dataset URI or an empty string if not set.
385
	 * @since 3.10.0
386
	 *
387
	 */
388
	public function get_dataset_uri() {
389
390
		return $this->get( 'wl_advanced_settings', self::DATASET_URI, null );
391
	}
392
393
	/**
394
	 * Set the dataset URI.
395
	 *
396
	 * @param string $value The dataset URI.
397
	 *
398
	 * @since 3.10.0
399
	 *
400
	 */
401
	public function set_dataset_uri( $value ) {
402
403
		$this->set( 'wl_advanced_settings', self::DATASET_URI, $value );
404
	}
405
406
	/**
407
	 * Get the package type.
408
	 *
409
	 * @return string The package type or an empty string if not set.
410
	 * @since 3.20.0
411
	 *
412
	 */
413
	public function get_package_type() {
414
415
		return $this->get( 'wl_advanced_settings', self::PACKAGE_TYPE, null );
416
	}
417
418
	/**
419
	 * Set the package type.
420
	 *
421
	 * @param string $value The package type.
422
	 *
423
	 * @since 3.20.0
424
	 *
425
	 */
426
	public function set_package_type( $value ) {
427
428
		$this->set( 'wl_advanced_settings', self::PACKAGE_TYPE, $value );
429
	}
430
431
	/**
432
	 * Intercept the change of the WordLift key in order to set the dataset URI.
433
	 *
434
	 *
435
	 * @since 3.20.0 as of #761, we save settings every time a key is set, not only when the key changes, so to
436
	 *               store the configuration parameters such as country or language.
437
	 * @since 3.11.0
438
	 *
439
	 * @see https://github.com/insideout10/wordlift-plugin/issues/761
440
	 *
441
	 * @param array $old_value The old settings.
442
	 * @param array $new_value The new settings.
443
	 */
444
	public function update_key( $old_value, $new_value ) {
0 ignored issues
show
Unused Code introduced by
The parameter $old_value is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
445
446
		// Check the old key value and the new one. We're going to ask for the dataset URI only if the key has changed.
447
		// $old_key = isset( $old_value['key'] ) ? $old_value['key'] : '';
448
		$new_key = isset( $new_value['key'] ) ? $new_value['key'] : '';
449
450
		// If the key hasn't changed, don't do anything.
451
		// WARN The 'update_option' hook is fired only if the new and old value are not equal.
452
		//		if ( $old_key === $new_key ) {
453
		//			return;
454
		//		}
455
456
		// If the key is empty, empty the dataset URI.
457
		if ( '' === $new_key ) {
458
			$this->set_dataset_uri( '' );
459
		}
460
461
		// make the request to the remote server.
462
		$this->get_remote_dataset_uri( $new_key );
463
464
	}
465
466
	/**
467
	 * Handle retrieving the dataset uri from the remote server.
468
	 *
469
	 * If a valid dataset uri is returned it is stored in the appropriate option,
470
	 * otherwise the option is set to empty string.
471
	 *
472
	 * @param string $key The key to be used.
473
	 *
474
	 * @since 3.12.0
475
	 *
476
	 * @since 3.17.0 send the site URL and get the dataset URI.
477
	 */
478
	public function get_remote_dataset_uri( $key ) {
479
480
		$this->log->trace( 'Getting the remote dataset URI and package type...' );
481
482
		if ( empty( $key ) ) {
483
			$this->log->warn( 'Key set to empty value.' );
484
485
			$this->set_dataset_uri( '' );
486
			$this->set_package_type( null );
487
488
			return;
489
		}
490
491
		/**
492
		 * Allow 3rd parties to change the site_url.
493
		 *
494
		 * @param string $site_url The site url.
495
		 *
496
		 * @see https://github.com/insideout10/wordlift-plugin/issues/850
497
		 *
498
		 * @since 3.20.0
499
		 *
500
		 */
501
		$home_url    = defined( 'WP_HOME' ) ? WP_HOME : get_option( 'home' );
502
		$site_url = apply_filters( 'wl_production_site_url', $home_url );
503
504
		// Build the URL.
505
		$url = $this->get_accounts()
506
		       . '?key=' . rawurlencode( $key )
507
		       . '&url=' . rawurlencode( $site_url )
508
		       . '&country=' . $this->get_country_code()
509
		       . '&language=' . $this->get_language_code();
510
511
		$args = wp_parse_args( unserialize( WL_REDLINK_API_HTTP_OPTIONS ), array(
512
			'method' => 'PUT',
513
		) );
514
515
		$response = wp_remote_request( $url, $args );
516
517
		// The response is an error.
518
		if ( is_wp_error( $response ) ) {
519
			$this->log->error( 'An error occurred setting the dataset URI: ' . $response->get_error_message() );
520
521
			$this->set_dataset_uri( '' );
522
			$this->set_package_type( null );
523
524
			return;
525
		}
526
527
		// The response is not OK.
528
		if ( 200 !== (int) $response['response']['code'] ) {
529
			$this->log->error( "Unexpected status code when opening URL $url: " . $response['response']['code'] );
530
531
			$this->set_dataset_uri( '' );
532
			$this->set_package_type( null );
533
534
			return;
535
		}
536
537
		/*
538
		 * We also store the package type.
539
		 *
540
		 * @since 3.20.0
541
		 */
542
		$json         = json_decode( $response['body'] );
543
		$dataset_uri  = $json->datasetURI;
544
		$package_type = isset( $json->packageType ) ? $json->packageType : null;
545
546
		$this->log->info( "Updating [ dataset uri :: $dataset_uri ][ package type :: $package_type ]..." );
547
548
		$this->set_dataset_uri( $dataset_uri );
549
		$this->set_package_type( $package_type );
550
551
	}
552
553
	/**
554
	 * Handle the edge case where a user submits the same key again
555
	 * when he does not have the dataset uri to regain it.
556
	 *
557
	 * This can not be handled in the normal option update hook because
558
	 * it is not being triggered when the save value equals to the one already
559
	 * in the DB.
560
	 *
561
	 * @param mixed $value The new, unserialized option value.
562
	 * @param mixed $old_value The old option value.
563
	 *
564
	 * @return mixed The same value in the $value parameter
565
	 * @since 3.12.0
566
	 *
567
	 */
568
	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...
569
570
		// Check the old key value and the new one. Here we're only handling the
571
		// case where the key hasn't changed and the dataset URI isn't set. The
572
		// other case, i.e. a new key is inserted, is handled at `update_key`.
573
		$old_key = isset( $old_value['key'] ) ? $old_value['key'] : '';
574
		$new_key = isset( $value['key'] ) ? $value['key'] : '';
575
576
		$dataset_uri = $this->get_dataset_uri();
577
578
		if ( ! empty( $new_key ) && $new_key === $old_key && empty( $dataset_uri ) ) {
579
580
			// make the request to the remote server to try to get the dataset uri.
581
			$this->get_remote_dataset_uri( $new_key );
582
		}
583
584
		return $value;
585
	}
586
587
	/**
588
	 * Get the API URI to retrieve the dataset URI using the WordLift Key.
589
	 *
590
	 * @param string $key The WordLift key to use.
591
	 *
592
	 * @return string The API URI.
593
	 * @since 3.11.0
594
	 *
595
	 */
596
	public function get_accounts_by_key_dataset_uri( $key ) {
597
598
		return WL_CONFIG_WORDLIFT_API_URL_DEFAULT_VALUE . "accounts/key=$key/dataset_uri";
599
	}
600
601
	/**
602
	 * Get the API URI to retrieve the account info using the WordLift Key.
603
	 *
604
	 * @param string $key The WordLift key to use.
605
	 *
606
	 * @return string The API URI.
607
	 * @since 3.26.0
608
	 *
609
	 */
610
	public function get_accounts_info_by_key( $key ) {
0 ignored issues
show
Unused Code introduced by
The parameter $key is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
611
612
		return WL_CONFIG_WORDLIFT_API_URL_DEFAULT_VALUE . "accounts/info";
613
	}
614
615
	/**
616
	 * Get the `accounts` end point.
617
	 *
618
	 * @return string The `accounts` end point.
619
	 * @since 3.16.0
620
	 *
621
	 */
622
	public function get_accounts() {
623
624
		return WL_CONFIG_WORDLIFT_API_URL_DEFAULT_VALUE . 'accounts';
625
	}
626
627
	/**
628
	 * Get the `link by default` option.
629
	 *
630
	 * @return bool True if entities must be linked by default otherwise false.
631
	 * @since 3.13.0
632
	 *
633
	 */
634
	public function is_link_by_default() {
635
636
		return 'yes' === $this->get( 'wl_general_settings', self::LINK_BY_DEFAULT, 'yes' );
637
	}
638
639
	/**
640
	 * Set the `link by default` option.
641
	 *
642
	 * @param bool $value True to enabling linking by default, otherwise false.
643
	 *
644
	 * @since 3.13.0
645
	 *
646
	 */
647
	public function set_link_by_default( $value ) {
648
649
		$this->set( 'wl_general_settings', self::LINK_BY_DEFAULT, true === $value ? 'yes' : 'no' );
650
	}
651
652
	/**
653
	 * Get the 'analytics-enable' option.
654
	 *
655
	 * @return string 'no' or 'yes' representing bool.
656
	 * @since 3.21.0
657
	 *
658
	 */
659
	public function is_analytics_enable() {
660
		return 'yes' === $this->get( 'wl_analytics_settings', self::ANALYTICS_ENABLE, 'no' );
661
	}
662
663
	/**
664
	 * Set the `analytics-enable` option.
665
	 *
666
	 * @param bool $value True to enabling analytics, otherwise false.
667
	 *
668
	 * @since 3.21.0
669
	 *
670
	 */
671
	public function set_is_analytics_enable( $value ) {
672
673
		$this->set( 'wl_general_settings', self::ANALYTICS_ENABLE, true === $value ? 'yes' : 'no' );
674
	}
675
676
	/**
677
	 * Get the 'analytics-entity-uri-dimention' option.
678
	 *
679
	 * @return int
680
	 * @since 3.21.0
681
	 *
682
	 */
683
	public function get_analytics_entity_uri_dimension() {
684
		return (int) $this->get( 'wl_analytics_settings', self::ANALYTICS_ENTITY_URI_DIMENSION, 1 );
685
	}
686
687
	/**
688
	 * Get the 'analytics-entity-type-dimension' option.
689
	 *
690
	 * @return int
691
	 * @since 3.21.0
692
	 *
693
	 */
694
	public function get_analytics_entity_type_dimension() {
695
		return $this->get( 'wl_analytics_settings', self::ANALYTICS_ENTITY_TYPE_DIMENSION, 2 );
696
	}
697
698
	/**
699
	 * Get the URL to perform autocomplete request.
700
	 *
701
	 * @return string The URL to call to perform the autocomplete request.
702
	 * @since 3.15.0
703
	 *
704
	 */
705
	public function get_autocomplete_url() {
706
707
		return WL_CONFIG_WORDLIFT_API_URL_DEFAULT_VALUE . 'autocomplete';
708
709
	}
710
711
	/**
712
	 * Get the URL to perform feedback deactivation request.
713
	 *
714
	 * @return string The URL to call to perform the feedback deactivation request.
715
	 * @since 3.19.0
716
	 *
717
	 */
718
	public function get_deactivation_feedback_url() {
719
720
		return WL_CONFIG_WORDLIFT_API_URL_DEFAULT_VALUE . 'feedbacks';
721
722
	}
723
724
	/**
725
	 * Get the base API URL.
726
	 *
727
	 * @return string The base API URL.
728
	 * @since 3.20.0
729
	 *
730
	 */
731
	public function get_api_url() {
732
733
		return WL_CONFIG_WORDLIFT_API_URL_DEFAULT_VALUE;
734
	}
735
736
}
737