Completed
Push — renovate/url-polyfill-1.x ( 01368d...f2aaf6 )
by
unknown
114:05 queued 106:27
created

Config   A

Complexity

Total Complexity 36

Size/Duplication

Total Lines 257
Duplicated Lines 4.28 %

Coupling/Cohesion

Components 1
Dependencies 6

Importance

Changes 0
Metric Value
dl 11
loc 257
rs 9.52
c 0
b 0
f 0
wmc 36
lcom 1
cbo 6

13 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 8 1
A ensure() 0 5 1
C on_plugins_loaded() 11 24 11
A ensure_class() 0 19 5
A ensure_feature() 0 26 4
A enable_tos() 0 3 1
A enable_tracking() 0 18 2
A enable_jitm() 0 10 2
A enable_sync() 0 5 1
A enable_connection() 0 5 1
A ensure_options_connection() 0 19 3
A set_feature_options() 0 7 2
A get_feature_options() 0 3 2

How to fix   Duplicated Code   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

1
<?php
2
/**
3
 * The base Jetpack configuration class file.
4
 *
5
 * @package automattic/jetpack-config
6
 */
7
8
namespace Automattic\Jetpack;
9
10
use Automattic\Jetpack\Connection\Manager;
11
use Automattic\Jetpack\JITMS\JITM as JITMS_JITM;
12
use Automattic\Jetpack\JITM as JITM;
13
use Automattic\Jetpack\Connection\Plugin;
14
use Automattic\Jetpack\Plugin\Tracking as Plugin_Tracking;
15
use Automattic\Jetpack\Sync\Main as Sync_Main;
16
17
/**
18
 * The configuration class.
19
 */
20
class Config {
21
22
	const FEATURE_ENSURED         = 1;
23
	const FEATURE_NOT_AVAILABLE   = 0;
24
	const FEATURE_ALREADY_ENSURED = -1;
25
26
	/**
27
	 * The initial setting values.
28
	 *
29
	 * @var Array
30
	 */
31
	protected $config = array(
32
		'jitm'       => false,
33
		'connection' => false,
34
		'sync'       => false,
35
		'tracking'   => false,
36
		'tos'        => false,
37
	);
38
39
	/**
40
	 * Initialization options stored here.
41
	 *
42
	 * @var array
43
	 */
44
	protected $feature_options = array();
45
46
	/**
47
	 * Creates the configuration class instance.
48
	 */
49
	public function __construct() {
50
		/**
51
		 * Adding the config handler to run on priority 2 because the class itself is
52
		 * being constructed on priority 1.
53
		 */
54
		add_action( 'plugins_loaded', array( $this, 'on_plugins_loaded' ), 2 );
55
56
	}
57
58
	/**
59
	 * Require a feature to be initialized. It's up to the package consumer to actually add
60
	 * the package to their composer project. Declaring a requirement using this method
61
	 * instructs the class to initialize it.
62
	 *
63
	 * @param String $feature the feature slug.
64
	 * @param array  $options Additional options, optional.
65
	 */
66
	public function ensure( $feature, array $options = array() ) {
67
		$this->config[ $feature ] = true;
68
69
		$this->set_feature_options( $feature, $options );
70
	}
71
72
	/**
73
	 * Runs on plugins_loaded hook priority with priority 2.
74
	 *
75
	 * @action plugins_loaded
76
	 */
77
	public function on_plugins_loaded() {
78
		if ( $this->config['connection'] ) {
79
			$this->ensure_class( 'Automattic\Jetpack\Connection\Manager' )
80
				&& $this->ensure_feature( 'connection' );
81
		}
82
83 View Code Duplication
		if ( $this->config['tracking'] ) {
84
			$this->ensure_class( 'Automattic\Jetpack\Terms_Of_Service' )
85
				&& $this->ensure_class( 'Automattic\Jetpack\Tracking' )
86
				&& $this->ensure_feature( 'tracking' );
87
		}
88
89
		if ( $this->config['sync'] ) {
90
			$this->ensure_class( 'Automattic\Jetpack\Sync\Main' )
91
				&& $this->ensure_feature( 'sync' );
92
		}
93
94 View Code Duplication
		if ( $this->config['jitm'] ) {
95
			// Check for the JITM class in both namespaces. The namespace was changed in jetpack-jitm v1.6.
96
			( $this->ensure_class( 'Automattic\Jetpack\JITMS\JITM', false )
97
				|| $this->ensure_class( 'Automattic\Jetpack\JITM' ) )
98
			&& $this->ensure_feature( 'jitm' );
99
		}
100
	}
101
102
	/**
103
	 * Returns true if the required class is available and alerts the user if it's not available
104
	 * in case the site is in debug mode.
105
	 *
106
	 * @param String  $classname a fully qualified class name.
107
	 * @param Boolean $log_notice whether the E_USER_NOTICE should be generated if the class is not found.
108
	 *
109
	 * @return Boolean whether the class is available.
110
	 */
111
	protected function ensure_class( $classname, $log_notice = true ) {
112
		$available = class_exists( $classname );
113
114
		if ( $log_notice && ! $available && defined( 'WP_DEBUG' ) && WP_DEBUG ) {
115
			trigger_error( // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_trigger_error
116
				sprintf(
117
					/* translators: %1$s is a PHP class name. */
118
					esc_html__(
119
						'Unable to load class %1$s. Please add the package that contains it using composer and make sure you are requiring the Jetpack autoloader',
120
						'jetpack'
121
					),
122
					esc_html( $classname )
123
				),
124
				E_USER_NOTICE
125
			);
126
		}
127
128
		return $available;
129
	}
130
131
	/**
132
	 * Ensures a feature is enabled, sets it up if it hasn't already been set up.
133
	 * Run the options method (if exists) every time the method is called.
134
	 *
135
	 * @param String $feature slug of the feature.
136
	 * @return Integer either FEATURE_ENSURED, FEATURE_ALREADY_ENSURED or FEATURE_NOT_AVAILABLE constants.
137
	 */
138
	protected function ensure_feature( $feature ) {
139
		$method = 'enable_' . $feature;
140
		if ( ! method_exists( $this, $method ) ) {
141
			return self::FEATURE_NOT_AVAILABLE;
142
		}
143
144
		$method_options = 'ensure_options_' . $feature;
145
		if ( method_exists( $this, $method_options ) ) {
146
			$this->{ $method_options }();
147
		}
148
149
		if ( did_action( 'jetpack_feature_' . $feature . '_enabled' ) ) {
150
			return self::FEATURE_ALREADY_ENSURED;
151
		}
152
153
		$this->{ $method }();
154
155
		/**
156
		 * Fires when a specific Jetpack package feature is initalized using the Config package.
157
		 *
158
		 * @since 8.2.0
159
		 */
160
		do_action( 'jetpack_feature_' . $feature . '_enabled' );
161
162
		return self::FEATURE_ENSURED;
163
	}
164
165
	/**
166
	 * Dummy method to enable Terms of Service.
167
	 */
168
	protected function enable_tos() {
169
		return true;
170
	}
171
172
	/**
173
	 * Enables the tracking feature. Depends on the Terms of Service package, so enables it too.
174
	 */
175
	protected function enable_tracking() {
176
177
		// Enabling dependencies.
178
		$this->ensure_feature( 'tos' );
179
180
		$terms_of_service = new Terms_Of_Service();
181
		$tracking         = new Plugin_Tracking();
182
		if ( $terms_of_service->has_agreed() ) {
183
			add_action( 'init', array( $tracking, 'init' ) );
184
		} else {
185
			/**
186
			 * Initialize tracking right after the user agrees to the terms of service.
187
			 */
188
			add_action( 'jetpack_agreed_to_terms_of_service', array( $tracking, 'init' ) );
189
		}
190
191
		return true;
192
	}
193
194
	/**
195
	 * Enables the JITM feature.
196
	 */
197
	protected function enable_jitm() {
198
		if ( class_exists( 'Automattic\Jetpack\JITMS\JITM' ) ) {
199
			JITMS_JITM::configure();
200
		} else {
201
			// Provides compatibility with jetpack-jitm <v1.6.
202
			JITM::configure();
203
		}
204
205
		return true;
206
	}
207
208
	/**
209
	 * Enables the Sync feature.
210
	 */
211
	protected function enable_sync() {
212
		Sync_Main::configure();
213
214
		return true;
215
	}
216
217
	/**
218
	 * Enables the Connection feature.
219
	 */
220
	protected function enable_connection() {
221
		Manager::configure();
222
223
		return true;
224
	}
225
226
	/**
227
	 * Setup the Connection options.
228
	 */
229
	protected function ensure_options_connection() {
230
		$options = $this->get_feature_options( 'connection' );
231
232
		if ( ! empty( $options['slug'] ) ) {
233
			// The `slug` and `name` are removed from the options because they need to be passed as arguments.
234
			$slug = $options['slug'];
235
			unset( $options['slug'] );
236
237
			$name = $slug;
238
			if ( ! empty( $options['name'] ) ) {
239
				$name = $options['name'];
240
				unset( $options['name'] );
241
			}
242
243
			( new Plugin( $slug ) )->add( $name, $options );
244
		}
245
246
		return true;
247
	}
248
249
	/**
250
	 * Temporary save initialization options for a feature.
251
	 *
252
	 * @param string $feature The feature slug.
253
	 * @param array  $options The options.
254
	 *
255
	 * @return bool
256
	 */
257
	protected function set_feature_options( $feature, array $options ) {
258
		if ( $options ) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $options of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
259
			$this->feature_options[ $feature ] = $options;
260
		}
261
262
		return true;
263
	}
264
265
	/**
266
	 * Get initialization options for a feature from the temporary storage.
267
	 *
268
	 * @param string $feature The feature slug.
269
	 *
270
	 * @return array
271
	 */
272
	protected function get_feature_options( $feature ) {
273
		return empty( $this->feature_options[ $feature ] ) ? array() : $this->feature_options[ $feature ];
274
	}
275
276
}
277