Completed
Push — add/connection_plugins_active_... ( f600c4...244713 )
by
unknown
149:49 queued 143:21
created

Config::is_configured()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

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