Completed
Push — try/find_latest_autoloader ( 4ce307...807460 )
by
unknown
06:53
created

functions.php ➔ autoloader()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 12

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
nc 3
nop 1
dl 0
loc 12
rs 9.8666
c 0
b 0
f 0
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 ) {
0 ignored issues
show
Duplication introduced by
This function seems to be duplicated in your project.

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.

Loading history...
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 ) {
0 ignored issues
show
Duplication introduced by
This function seems to be duplicated in your project.

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.

Loading history...
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