|
1
|
|
|
<?php |
|
2
|
|
|
/* HEADER */ // phpcs:ignore |
|
3
|
|
|
|
|
4
|
|
|
global $jetpack_packages_classmap; |
|
5
|
|
|
global $jetpack_packages_filemap; |
|
6
|
|
|
|
|
7
|
|
|
if ( ! is_array( $jetpack_packages_classmap ) ) { |
|
8
|
|
|
$jetpack_packages_classmap = array(); |
|
9
|
|
|
} |
|
10
|
|
|
|
|
11
|
|
|
if ( ! is_array( $jetpack_packages_filemap ) ) { |
|
12
|
|
|
$jetpack_packages_filemap = array(); |
|
13
|
|
|
} |
|
14
|
|
|
|
|
15
|
|
|
/** |
|
16
|
|
|
* Adds the version of a package to the $jetpack_packages global array so that |
|
17
|
|
|
* the autoloader is able to find it. |
|
18
|
|
|
* |
|
19
|
|
|
* @param string $class_name Name of the class that you want to autoload. |
|
20
|
|
|
* @param string $version Version of the class. |
|
21
|
|
|
* @param string $path Absolute path to the class so that we can load it. |
|
22
|
|
|
*/ |
|
23
|
|
View Code Duplication |
function enqueue_package_class( $class_name, $version, $path ) { |
|
|
|
|
|
|
24
|
|
|
global $jetpack_packages_classmap; |
|
25
|
|
|
|
|
26
|
|
|
if ( ! isset( $jetpack_packages_classmap[ $class_name ] ) ) { |
|
27
|
|
|
$jetpack_packages_classmap[ $class_name ] = array( |
|
28
|
|
|
'version' => $version, |
|
29
|
|
|
'path' => $path, |
|
30
|
|
|
); |
|
31
|
|
|
|
|
32
|
|
|
return; |
|
33
|
|
|
} |
|
34
|
|
|
// If we have a @dev version set always use that one! |
|
35
|
|
|
if ( 'dev-' === substr( $jetpack_packages_classmap[ $class_name ]['version'], 0, 4 ) ) { |
|
36
|
|
|
return; |
|
37
|
|
|
} |
|
38
|
|
|
|
|
39
|
|
|
// Always favour the @dev version. Since that version is the same as bleeding edge. |
|
40
|
|
|
// We need to make sure that we don't do this in production! |
|
41
|
|
|
if ( 'dev-' === substr( $version, 0, 4 ) ) { |
|
42
|
|
|
$jetpack_packages_classmap[ $class_name ] = array( |
|
43
|
|
|
'version' => $version, |
|
44
|
|
|
'path' => $path, |
|
45
|
|
|
); |
|
46
|
|
|
|
|
47
|
|
|
return; |
|
48
|
|
|
} |
|
49
|
|
|
// Set the latest version! |
|
50
|
|
|
if ( version_compare( $jetpack_packages_classmap[ $class_name ]['version'], $version, '<' ) ) { |
|
51
|
|
|
$jetpack_packages_classmap[ $class_name ] = array( |
|
52
|
|
|
'version' => $version, |
|
53
|
|
|
'path' => $path, |
|
54
|
|
|
); |
|
55
|
|
|
} |
|
56
|
|
|
} |
|
57
|
|
|
|
|
58
|
|
|
/** |
|
59
|
|
|
* Adds the version of a package file to the $jetpack_packages_filemap global array so that |
|
60
|
|
|
* we can load the most recent version after 'plugins_loaded'. |
|
61
|
|
|
* |
|
62
|
|
|
* @param string $file_identifier Unique id to file assigned by composer based on package name and filename. |
|
63
|
|
|
* @param string $version Version of the file. |
|
64
|
|
|
* @param string $path Absolute path to the file so that we can load it. |
|
65
|
|
|
*/ |
|
66
|
|
View Code Duplication |
function enqueue_package_file( $file_identifier, $version, $path ) { |
|
|
|
|
|
|
67
|
|
|
global $jetpack_packages_filemap; |
|
68
|
|
|
|
|
69
|
|
|
if ( ! isset( $jetpack_packages_filemap[ $file_identifier ] ) ) { |
|
70
|
|
|
$jetpack_packages_filemap[ $file_identifier ] = array( |
|
71
|
|
|
'version' => $version, |
|
72
|
|
|
'path' => $path, |
|
73
|
|
|
); |
|
74
|
|
|
|
|
75
|
|
|
return; |
|
76
|
|
|
} |
|
77
|
|
|
// If we have a @dev version set always use that one! |
|
78
|
|
|
if ( 'dev-' === substr( $jetpack_packages_filemap[ $file_identifier ]['version'], 0, 4 ) ) { |
|
79
|
|
|
return; |
|
80
|
|
|
} |
|
81
|
|
|
|
|
82
|
|
|
// Always favour the @dev version. Since that version is the same as bleeding edge. |
|
83
|
|
|
// We need to make sure that we don't do this in production! |
|
84
|
|
|
if ( 'dev-' === substr( $version, 0, 4 ) ) { |
|
85
|
|
|
$jetpack_packages_filemap[ $file_identifier ] = array( |
|
86
|
|
|
'version' => $version, |
|
87
|
|
|
'path' => $path, |
|
88
|
|
|
); |
|
89
|
|
|
|
|
90
|
|
|
return; |
|
91
|
|
|
} |
|
92
|
|
|
// Set the latest version! |
|
93
|
|
|
if ( version_compare( $jetpack_packages_filemap[ $file_identifier ]['version'], $version, '<' ) ) { |
|
94
|
|
|
$jetpack_packages_filemap[ $file_identifier ] = array( |
|
95
|
|
|
'version' => $version, |
|
96
|
|
|
'path' => $path, |
|
97
|
|
|
); |
|
98
|
|
|
} |
|
99
|
|
|
} |
|
100
|
|
|
|
|
101
|
|
|
/** |
|
102
|
|
|
* Include latest version of all enqueued files. Should be called after all plugins are loaded. |
|
103
|
|
|
*/ |
|
104
|
|
|
function file_loader() { |
|
105
|
|
|
global $jetpack_packages_filemap; |
|
106
|
|
|
foreach ( $jetpack_packages_filemap as $file_identifier => $file_data ) { |
|
107
|
|
|
if ( empty( $GLOBALS['__composer_autoload_files'][ $file_identifier ] ) ) { |
|
108
|
|
|
require_once $file_data['path']; |
|
109
|
|
|
|
|
110
|
|
|
$GLOBALS['__composer_autoload_files'][ $file_identifier ] = true; |
|
111
|
|
|
} |
|
112
|
|
|
} |
|
113
|
|
|
} |
|
114
|
|
|
|
|
115
|
|
|
/** |
|
116
|
|
|
* Used for autoloading jetpack packages. |
|
117
|
|
|
* |
|
118
|
|
|
* @param string $class_name Class Name to load. |
|
119
|
|
|
*/ |
|
120
|
|
|
function autoloader( $class_name ) { |
|
121
|
|
|
global $jetpack_packages_classmap; |
|
122
|
|
|
|
|
123
|
|
|
if ( isset( $jetpack_packages_classmap[ $class_name ] ) ) { |
|
124
|
|
|
if ( file_exists( $jetpack_packages_classmap[ $class_name ]['path'] ) ) { |
|
125
|
|
|
require_once $jetpack_packages_classmap[ $class_name ]['path']; |
|
126
|
|
|
return true; |
|
127
|
|
|
} |
|
128
|
|
|
} |
|
129
|
|
|
|
|
130
|
|
|
return false; |
|
131
|
|
|
} |
|
132
|
|
|
|
|
133
|
|
|
/** |
|
134
|
|
|
* Used for running the code that initializes class and file maps. |
|
135
|
|
|
*/ |
|
136
|
|
|
function enqueue_files() { |
|
137
|
|
|
$active_plugins = get_active_plugins(); |
|
138
|
|
|
$paths = array_map( __NAMESPACE__ . '\create_map_path_array', $active_plugins ); |
|
139
|
|
|
|
|
140
|
|
|
foreach ( $paths as $path ) { |
|
141
|
|
|
if ( is_readable( $path['class'] ) ) { |
|
142
|
|
|
$class_map = require $path['class']; |
|
143
|
|
|
|
|
144
|
|
|
if ( is_array( $class_map ) ) { |
|
145
|
|
|
foreach ( $class_map as $class_name => $class_info ) { |
|
146
|
|
|
enqueue_package_class( $class_name, $class_info['version'], $class_info['path'] ); |
|
147
|
|
|
} |
|
148
|
|
|
} |
|
149
|
|
|
} |
|
150
|
|
|
|
|
151
|
|
|
if ( is_readable( $path['file'] ) ) { |
|
152
|
|
|
$file_map = require $path['file']; |
|
153
|
|
|
|
|
154
|
|
|
if ( is_array( $file_map ) ) { |
|
155
|
|
|
foreach ( $file_map as $file_identifier => $file_data ) { |
|
156
|
|
|
enqueue_package_file( $file_identifier, $file_data['version'], $file_data['path'] ); |
|
157
|
|
|
} |
|
158
|
|
|
} |
|
159
|
|
|
} |
|
160
|
|
|
} |
|
161
|
|
|
|
|
162
|
|
|
file_loader(); |
|
163
|
|
|
} |
|
164
|
|
|
|
|
165
|
|
|
/** |
|
166
|
|
|
* Returns an array containing the active plugins. If plugin is activating, it |
|
167
|
|
|
* is included in the array. |
|
168
|
|
|
* |
|
169
|
|
|
* @return Array An array of plugin names as strings. |
|
170
|
|
|
*/ |
|
171
|
|
|
function get_active_plugins() { |
|
172
|
|
|
$active_plugins = array_merge( |
|
173
|
|
|
is_multisite() |
|
174
|
|
|
? array_keys( get_site_option( 'active_sitewide_plugins', array() ) ) |
|
175
|
|
|
: array(), |
|
176
|
|
|
(array) get_option( 'active_plugins', array() ) |
|
177
|
|
|
); |
|
178
|
|
|
$current_plugin = get_current_plugin(); |
|
179
|
|
|
|
|
180
|
|
|
if ( ! in_array( $current_plugin, $active_plugins, true ) ) { |
|
181
|
|
|
// The current plugin isn't active, so it must be activating. Add it to the list. |
|
182
|
|
|
$active_plugins[] = $current_plugin; |
|
183
|
|
|
} |
|
184
|
|
|
|
|
185
|
|
|
// If the activating plugin is not the only activating plugin, we need to add others too. |
|
186
|
|
|
$active_plugins = array_unique( array_merge( $active_plugins, get_activating_plugins() ) ); |
|
187
|
|
|
|
|
188
|
|
|
return $active_plugins; |
|
189
|
|
|
} |
|
190
|
|
|
|
|
191
|
|
|
/** |
|
192
|
|
|
* Creates an array containing the paths to the classmap and filemap for the given plugin. |
|
193
|
|
|
* The filenames are the names of the files generated by the Jetpack Autoloader version >2.0. |
|
194
|
|
|
* |
|
195
|
|
|
* @param String $plugin The plugin string. |
|
196
|
|
|
* @return Array An array containing the paths to the plugin's classmap and filemap. |
|
197
|
|
|
*/ |
|
198
|
|
|
function create_map_path_array( $plugin ) { |
|
199
|
|
|
$plugin_path = plugin_dir_path( trailingslashit( WP_PLUGIN_DIR ) . $plugin ); |
|
200
|
|
|
|
|
201
|
|
|
return array( |
|
202
|
|
|
'class' => trailingslashit( $plugin_path ) . 'vendor/composer/jetpack_autoload_classmap.php', |
|
203
|
|
|
'file' => trailingslashit( $plugin_path ) . 'vendor/composer/jetpack_autoload_filemap.php', |
|
204
|
|
|
); |
|
205
|
|
|
} |
|
206
|
|
|
|
|
207
|
|
|
/** |
|
208
|
|
|
* Checks whether the current plugin is active. |
|
209
|
|
|
* |
|
210
|
|
|
* @return Boolean True if the current plugin is active, else false. |
|
211
|
|
|
*/ |
|
212
|
|
|
function is_current_plugin_active() { |
|
213
|
|
|
$active_plugins = (array) get_option( 'active_plugins', array() ); |
|
214
|
|
|
$current_plugin = get_current_plugin(); |
|
215
|
|
|
|
|
216
|
|
|
return in_array( $current_plugin, $active_plugins, true ); |
|
217
|
|
|
} |
|
218
|
|
|
|
|
219
|
|
|
/** |
|
220
|
|
|
* Returns the name of activating plugin if a plugin is activating via a request. |
|
221
|
|
|
* |
|
222
|
|
|
* @return Array The array of the activating plugins or empty array. |
|
223
|
|
|
*/ |
|
224
|
|
|
function get_activating_plugins() { |
|
225
|
|
|
|
|
226
|
|
|
// phpcs:disable WordPress.Security.NonceVerification.Recommended |
|
227
|
|
|
|
|
228
|
|
|
$action = isset( $_REQUEST['action'] ) ? $_REQUEST['action'] : false; |
|
229
|
|
|
$plugin = isset( $_REQUEST['plugin'] ) ? $_REQUEST['plugin'] : false; |
|
230
|
|
|
$nonce = isset( $_REQUEST['_wpnonce'] ) ? $_REQUEST['_wpnonce'] : false; |
|
231
|
|
|
|
|
232
|
|
|
/** |
|
233
|
|
|
* Note: we're not actually checking the nonce here becase it's too early |
|
234
|
|
|
* in the execution. The pluggable functions are not yet loaded to give |
|
235
|
|
|
* plugins a chance to plug their versions. Therefore we're doing the bare |
|
236
|
|
|
* minimum: checking whether the nonce exists and it's in the right place. |
|
237
|
|
|
* The request will fail later if the nonce doesn't pass the check. |
|
238
|
|
|
*/ |
|
239
|
|
|
|
|
240
|
|
|
// In case of a single plugin activation there will be a plugin slug. |
|
241
|
|
|
if ( 'activate' === $action && ! empty( $nonce ) ) { |
|
242
|
|
|
return array( wp_unslash( $plugin ) ); |
|
243
|
|
|
} |
|
244
|
|
|
|
|
245
|
|
|
$plugins = isset( $_REQUEST['checked'] ) ? $_REQUEST['checked'] : array(); |
|
246
|
|
|
|
|
247
|
|
|
// In case of bulk activation there will be an array of plugins. |
|
248
|
|
|
if ( 'activate-selected' === $action && ! empty( $nonce ) ) { |
|
249
|
|
|
return array_map( 'wp_unslash', $plugins ); |
|
250
|
|
|
} |
|
251
|
|
|
|
|
252
|
|
|
// phpcs:enable WordPress.Security.NonceVerification.Recommended |
|
253
|
|
|
|
|
254
|
|
|
return array(); |
|
255
|
|
|
} |
|
256
|
|
|
|
|
257
|
|
|
/** |
|
258
|
|
|
* Returns the name of the current plugin. |
|
259
|
|
|
* |
|
260
|
|
|
* @return String The name of the current plugin. |
|
261
|
|
|
*/ |
|
262
|
|
|
function get_current_plugin() { |
|
263
|
|
|
if ( ! function_exists( 'get_plugins' ) ) { |
|
264
|
|
|
require_once ABSPATH . 'wp-admin/includes/plugin.php'; |
|
265
|
|
|
} |
|
266
|
|
|
|
|
267
|
|
|
$dir = explode( '/', plugin_basename( __FILE__ ) )[0]; |
|
268
|
|
|
$file = array_keys( get_plugins( "/$dir" ) )[0]; |
|
269
|
|
|
return "$dir/$file"; |
|
270
|
|
|
} |
|
271
|
|
|
|
|
272
|
|
|
/** |
|
273
|
|
|
* Find the latest installed autoloader and set up the classmap and filemap. |
|
274
|
|
|
*/ |
|
275
|
|
|
function set_up_autoloader() { |
|
276
|
|
|
global $latest_autoloader_version; |
|
277
|
|
|
global $jetpack_packages_classmap; |
|
278
|
|
|
|
|
279
|
|
|
if ( ! is_current_plugin_active() ) { |
|
280
|
|
|
// The current plugin is activating, so reset the autoloader. |
|
281
|
|
|
$latest_autoloader_version = null; |
|
282
|
|
|
$jetpack_packages_classmap = array(); |
|
283
|
|
|
} |
|
284
|
|
|
|
|
285
|
|
|
$classmap_file = trailingslashit( dirname( __FILE__ ) ) . 'composer/jetpack_autoload_classmap.php'; |
|
286
|
|
|
$autoloader_packages = require $classmap_file; |
|
287
|
|
|
|
|
288
|
|
|
$current_autoloader_version = $autoloader_packages['Automattic\\Jetpack\\Autoloader\\AutoloadGenerator']['version']; |
|
289
|
|
|
$current_autoloader_path = trailingslashit( dirname( __FILE__ ) ) . 'autoload_packages.php'; |
|
290
|
|
|
|
|
291
|
|
|
// Find the latest autoloader. |
|
292
|
|
|
if ( ! $latest_autoloader_version ) { |
|
293
|
|
|
$autoloader_version = $current_autoloader_version; |
|
294
|
|
|
$autoloader_path = $current_autoloader_path; |
|
295
|
|
|
$current_plugin = get_current_plugin(); |
|
296
|
|
|
|
|
297
|
|
|
$active_plugins = get_active_plugins(); |
|
298
|
|
|
|
|
299
|
|
|
foreach ( $active_plugins as $plugin ) { |
|
300
|
|
|
if ( $current_plugin === $plugin ) { |
|
301
|
|
|
continue; |
|
302
|
|
|
} |
|
303
|
|
|
|
|
304
|
|
|
$plugin_path = plugin_dir_path( trailingslashit( WP_PLUGIN_DIR ) . $plugin ); |
|
305
|
|
|
$classmap_path = trailingslashit( $plugin_path ) . 'vendor/composer/jetpack_autoload_classmap.php'; |
|
306
|
|
|
if ( file_exists( $classmap_path ) ) { |
|
307
|
|
|
$packages = require $classmap_path; |
|
308
|
|
|
|
|
309
|
|
|
$current_version = $packages['Automattic\\Jetpack\\Autoloader\\AutoloadGenerator']['version']; |
|
310
|
|
|
|
|
311
|
|
|
// TODO: This comparison needs to properly handle dev versions. |
|
312
|
|
|
if ( version_compare( $autoloader_version, $current_version, '<' ) ) { |
|
313
|
|
|
$autoloader_version = $current_version; |
|
314
|
|
|
$autoloader_path = trailingslashit( $plugin_path ) . 'vendor/autoload_packages.php'; |
|
315
|
|
|
} |
|
316
|
|
|
} |
|
317
|
|
|
} |
|
318
|
|
|
|
|
319
|
|
|
$latest_autoloader_version = $autoloader_version; |
|
320
|
|
|
if ( $current_autoloader_path !== $autoloader_path ) { |
|
321
|
|
|
require $autoloader_path; |
|
322
|
|
|
} |
|
323
|
|
|
} |
|
324
|
|
|
|
|
325
|
|
|
// This is the latest autoloader, so generate the classmap and filemap and register the autoloader function. |
|
326
|
|
|
if ( empty( $jetpack_packages_classmap ) && $current_autoloader_version === $latest_autoloader_version ) { |
|
327
|
|
|
enqueue_files(); |
|
328
|
|
|
|
|
329
|
|
|
spl_autoload_register( __NAMESPACE__ . '\autoloader' ); |
|
330
|
|
|
|
|
331
|
|
|
$autoload_chain = spl_autoload_functions(); |
|
332
|
|
|
if ( in_array( 'Automattic\Jetpack\Autoloader\autoloader', $autoload_chain, true ) ) { |
|
333
|
|
|
// Move the old autoloader function to the end of the spl autoloader chaain. |
|
334
|
|
|
spl_autoload_unregister( 'Automattic\Jetpack\Autoloader\autoloader' ); |
|
335
|
|
|
spl_autoload_register( 'Automattic\Jetpack\Autoloader\autoloader' ); |
|
336
|
|
|
} |
|
337
|
|
|
} |
|
338
|
|
|
} |
|
339
|
|
|
|
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.