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 $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
|
|
|
// TODO: Needs to traverse through the classmaps/filemaps of all of the active plugins. |
138
|
|
|
$class_map = require dirname( __FILE__ ) . '/composer/jetpack_autoload_classmap.php'; |
139
|
|
|
|
140
|
|
|
foreach ( $class_map as $class_name => $class_info ) { |
141
|
|
|
enqueue_package_class( $class_name, $class_info['version'], $class_info['path'] ); |
142
|
|
|
} |
143
|
|
|
|
144
|
|
|
$autoload_file = dirname( __FILE__ ) . '/composer/jetpack_autoload_filemap.php'; |
145
|
|
|
|
146
|
|
|
$include_files = file_exists( $autoload_file ) ? require $autoload_file : array(); |
147
|
|
|
|
148
|
|
|
foreach ( $include_files as $file_identifier => $file_data ) { |
149
|
|
|
enqueue_package_file( $file_identifier, $file_data['version'], $file_data['path'] ); |
150
|
|
|
} |
151
|
|
|
|
152
|
|
|
// TODO: The plugins_loaded action checks aren't necessary anymore. |
153
|
|
|
if ( |
154
|
|
|
function_exists( 'has_action' ) |
155
|
|
|
&& function_exists( 'did_action' ) |
156
|
|
|
&& ! did_action( 'plugins_loaded' ) |
157
|
|
|
&& false === has_action( 'plugins_loaded', __NAMESPACE__ . '\file_loader' ) |
158
|
|
|
) { |
159
|
|
|
// Add action if it has not been added and has not happened yet. |
160
|
|
|
// Priority -10 to load files as early as possible in case plugins try to use them during `plugins_loaded`. |
161
|
|
|
add_action( 'plugins_loaded', __NAMESPACE__ . '\file_loader', 0, -10 ); |
162
|
|
|
|
163
|
|
|
} elseif ( |
164
|
|
|
! function_exists( 'did_action' ) |
165
|
|
|
|| did_action( 'plugins_loaded' ) |
166
|
|
|
) { |
167
|
|
|
file_loader(); // Either WordPress is not loaded or plugin is doing it wrong. Either way we'll load the files so nothing breaks. |
168
|
|
|
} |
169
|
|
|
} |
170
|
|
|
|
171
|
|
|
/** |
172
|
|
|
* Find the latest installed autoloader and set up the classmap and filemap. |
173
|
|
|
*/ |
174
|
|
|
function set_up_autoloader() { |
175
|
|
|
global $latest_autoloader_version; |
176
|
|
|
global $jetpack_packages_classmap; |
177
|
|
|
|
178
|
|
|
$classmap_file = trailingslashit( dirname( __FILE__ ) ) . 'composer/jetpack_autoload_classmap.php'; |
179
|
|
|
$autoloader_packages = require $classmap_file; |
180
|
|
|
|
181
|
|
|
$loaded_autoloader_version = $autoloader_packages['Automattic\\Jetpack\\Autoloader\\AutoloadGenerator']['version']; |
182
|
|
|
|
183
|
|
|
$autoloader_version = $loaded_autoloader_version; |
184
|
|
|
$autoloader_path = __FILE__; |
185
|
|
|
|
186
|
|
|
// Find the latest autoloader. |
187
|
|
|
if ( ! $latest_autoloader_version ) { |
188
|
|
|
$active_plugins = (array) get_option( 'active_plugins', array() ); |
189
|
|
|
|
190
|
|
|
foreach ( $active_plugins as $plugin ) { |
191
|
|
|
$plugin_path = plugin_dir_path( trailingslashit( WP_PLUGIN_DIR ) . $plugin ); |
192
|
|
|
$classmap_path = trailingslashit( $plugin_path ) . 'vendor/composer/jetpack_autoload_classmap.php'; |
193
|
|
|
if ( file_exists( $classmap_path ) ) { |
194
|
|
|
$packages = require $classmap_path; |
195
|
|
|
|
196
|
|
|
$current_version = $packages['Automattic\\Jetpack\\Autoloader\\AutoloadGenerator']['version']; |
197
|
|
|
|
198
|
|
|
// TODO: This comparison needs to properly handle dev versions. |
199
|
|
|
if ( version_compare( $autoloader_version, $current_version, '<' ) ) { |
200
|
|
|
$autoloader_version = $current_version; |
201
|
|
|
$autoloader_path = trailingslashit( $plugin_path ) . 'vendor/autoload_packages.php'; |
202
|
|
|
} |
203
|
|
|
} |
204
|
|
|
} |
205
|
|
|
|
206
|
|
|
$latest_autoloader_version = $autoloader_version; |
207
|
|
|
if ( __FILE__ !== $autoloader_path ) { |
208
|
|
|
require $autoloader_path; |
209
|
|
|
} |
210
|
|
|
} |
211
|
|
|
|
212
|
|
|
// This is the latest autoloader, so generate the classmap and filemap and register the autoloader function. |
213
|
|
|
if ( empty( $jetpack_packages_classmap ) && $loaded_autoloader_version === $latest_autoloader_version ) { |
214
|
|
|
enqueue_files(); |
215
|
|
|
|
216
|
|
|
spl_autoload_register( __NAMESPACE__ . '\autoloader' ); |
217
|
|
|
|
218
|
|
|
$autoload_chain = spl_autoload_functions(); |
219
|
|
|
if ( in_array( 'Automattic\Jetpack\Autoloader\autoloader', $autoload_chain, true ) ) { |
220
|
|
|
// Move the old autoloader function to the end of the spl autoloader chaain. |
221
|
|
|
spl_autoload_unregister( 'Automattic\Jetpack\Autoloader\autoloader' ); |
222
|
|
|
spl_autoload_register( 'Automattic\Jetpack\Autoloader\autoloader' ); |
223
|
|
|
} |
224
|
|
|
} |
225
|
|
|
} |
226
|
|
|
|
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.