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 ) { |
|
|
|
|
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
|
|
|
|
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.