WordPoints_Extension_Upgrader   C
last analyzed

Complexity

Total Complexity 54

Size/Duplication

Total Lines 567
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
dl 0
loc 567
rs 6.8539
c 0
b 0
f 0
wmc 54

12 Methods

Rating   Name   Duplication   Size   Complexity  
C correct_extension_dir_name() 0 28 7
C verify_package_signature() 0 70 7
B bulk_upgrade() 0 44 5
B do_upgrade() 0 58 7
A upgrade_strings() 0 22 1
A before_upgrades() 0 14 1
B after_upgrades() 0 27 4
B maybe_start_maintenance_mode() 0 18 6
A deactivate_extension_before_upgrade() 0 17 4
A bail_early() 0 14 2
C delete_old_extension() 0 36 7
A upgrade() 0 11 3

How to fix   Complexity   

Complex Class

Complex classes like WordPoints_Extension_Upgrader often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use WordPoints_Extension_Upgrader, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
/**
4
 * Extension upgrader class.
5
 *
6
 * @package WordPoints
7
 * @since   2.4.0
8
 */
9
10
/**
11
 * Upgrades extensions.
12
 *
13
 * This class is based on the WordPress Plugin_Upgrader class, and is designed to
14
 * upgrade/install extensions from a local zip, remote zip URL, or uploaded zip file.
15
 *
16
 * @see WP_Upgrader The WP Upgrader class.
17
 *
18
 * @since 2.4.0
19
 */
20
class WordPoints_Extension_Upgrader extends WordPoints_Module_Installer {
21
22
	/**
23
	 * Whether we are performing a bulk upgrade.
24
	 *
25
	 * @since 2.4.0
26
	 *
27
	 * @var bool
28
	 */
29
	protected $bulk = false;
30
31
	/**
32
	 * Whether the upgrade routine bailed out early.
33
	 *
34
	 * @since 2.4.0
35
	 *
36
	 * @var bool
37
	 */
38
	protected $bailed_early = false;
39
40
	/**
41
	 * The extension server API being used for the extension currently being updated.
42
	 *
43
	 * @since 2.5.0
44
	 *
45
	 * @var WordPoints_Extension_Server_APII
46
	 */
47
	protected $wordpoints_extension_api;
48
49
	/**
50
	 * The extension server API data for the extension currently being updated.
51
	 *
52
	 * @since 2.5.0
53
	 *
54
	 * @var WordPoints_Extension_Server_API_Extension_DataI
55
	 */
56
	protected $wordpoints_extension_data;
57
58
	/**
59
	 * Sets up the strings for an extension upgrade.
60
	 *
61
	 * @since 2.4.0
62
	 */
63
	protected function upgrade_strings() {
64
65
		$upgrade_strings = array(
66
			'up_to_date'                => esc_html__( 'The extension is at the latest version.', 'wordpoints' ),
0 ignored issues
show
Bug introduced by
The function esc_html__ was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

66
			'up_to_date'                => /** @scrutinizer ignore-call */ esc_html__( 'The extension is at the latest version.', 'wordpoints' ),
Loading history...
67
			'no_package'                => esc_html__( 'Update package not available.', 'wordpoints' ),
68
			'no_server'                 => esc_html__( 'That extension cannot be updated, because there is no server specified to receive updates through.', 'wordpoints' ),
69
			'api_not_found'             => esc_html__( 'That extension cannot be updated, because there is no API installed that can communicate with that server.', 'wordpoints' ),
70
			'api_updates_not_supported' => esc_html__( 'That extension cannot be updated, because the API used to communicate with that server does not support updates.', 'wordpoints' ),
71
			// translators: Update package URL.
72
			'downloading_package'       => sprintf( esc_html__( 'Downloading update from %s&#8230;', 'wordpoints' ), '<span class="code">%s</span>' ),
73
			'verifying_package'         => esc_html__( 'Verifying the update&#8230;', 'wordpoints' ),
74
			// translators: Support forums link.
75
			'verifying_package_failed'  => wp_kses_data( sprintf( __( 'Verifying the update failed. The update was not installed, because the package may have been modified by an attacker. Please <a href="%s">report this failure</a>.', 'wordpoints' ), 'https://wordpress.org/support/plugin/wordpoints' ) ),
0 ignored issues
show
Bug introduced by
The function wp_kses_data was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

75
			'verifying_package_failed'  => /** @scrutinizer ignore-call */ wp_kses_data( sprintf( __( 'Verifying the update failed. The update was not installed, because the package may have been modified by an attacker. Please <a href="%s">report this failure</a>.', 'wordpoints' ), 'https://wordpress.org/support/plugin/wordpoints' ) ),
Loading history...
Bug introduced by
The function __ was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

75
			'verifying_package_failed'  => wp_kses_data( sprintf( /** @scrutinizer ignore-call */ __( 'Verifying the update failed. The update was not installed, because the package may have been modified by an attacker. Please <a href="%s">report this failure</a>.', 'wordpoints' ), 'https://wordpress.org/support/plugin/wordpoints' ) ),
Loading history...
76
			'unpack_package'            => esc_html__( 'Unpacking the update&#8230;', 'wordpoints' ),
77
			'remove_old'                => esc_html__( 'Removing the old version of the extension&#8230;', 'wordpoints' ),
78
			'remove_old_failed'         => esc_html__( 'Could not remove the old extension.', 'wordpoints' ),
79
			'process_failed'            => esc_html__( 'Extension update failed.', 'wordpoints' ),
80
			'process_success'           => esc_html__( 'Extension updated successfully.', 'wordpoints' ),
81
			'not_installed'             => esc_html__( 'That extension cannot be updated, because it is not installed.', 'wordpoints' ),
82
		);
83
84
		$this->strings = array_merge( $this->strings, $upgrade_strings );
0 ignored issues
show
Bug Best Practice introduced by
The property strings does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
85
	}
86
87
	/**
88
	 * Upgrades an extension.
89
	 *
90
	 * @since 2.4.0
91
	 *
92
	 * @param string $extension_file Basename path to the extension file.
93
	 * @param array  $args           {
94
	 *        Optional arguments.
95
	 *
96
	 *        @type bool $clear_update_cache Whether the to clear the update cache.
97
	 *                                       The default is true.
98
	 * }
99
	 *
100
	 * @return bool|WP_Error True on success, false or a WP_Error on failure.
0 ignored issues
show
Bug introduced by
The type WP_Error was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
101
	 */
102
	public function upgrade( $extension_file, $args = array() ) {
103
104
		$args   = $this->before_upgrades( $args );
105
		$result = $this->do_upgrade( $extension_file );
106
		$this->after_upgrades( $extension_file, $args );
107
108
		if ( ! $result || is_wp_error( $result ) ) {
0 ignored issues
show
Bug introduced by
The function is_wp_error was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

108
		if ( ! $result || /** @scrutinizer ignore-call */ is_wp_error( $result ) ) {
Loading history...
109
			return $result;
110
		}
111
112
		return true;
113
	}
114
115
	/**
116
	 * Performs a bulk upgrade.
117
	 *
118
	 * @since 2.4.0
119
	 *
120
	 * @param string[] $extensions Array of basename paths to the extensions.
121
	 * @param array    $args       {
122
	 *
123
	 *        @type bool $clear_update_cache Whether the to clear the update cache.
124
	 *                                       Default is true.
125
	 * }
126
	 *
127
	 * @return array|false The result of each update, indexed by extension, or false if
128
	 *                     unable to perform the upgrades.
129
	 */
130
	public function bulk_upgrade( $extensions, $args = array() ) {
131
132
		$this->bulk = true;
133
134
		$args = $this->before_upgrades( $args );
135
136
		$this->skin->header();
137
138
		// Connect to the Filesystem first.
139
		if ( ! $this->fs_connect( array( WP_CONTENT_DIR, wordpoints_extensions_dir() ) ) ) {
0 ignored issues
show
Bug introduced by
The constant WP_CONTENT_DIR was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
140
141
			$this->skin->footer();
142
			return false;
143
		}
144
145
		$this->skin->bulk_header();
146
147
		$this->maybe_start_maintenance_mode( $extensions );
148
149
		$results = array();
150
151
		$this->update_count   = count( $extensions );
0 ignored issues
show
Bug Best Practice introduced by
The property update_count does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
152
		$this->update_current = 0;
0 ignored issues
show
Bug Best Practice introduced by
The property update_current does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
153
154
		foreach ( $extensions as $extension ) {
155
156
			$this->update_current++;
157
158
			$results[ $extension ] = $this->do_upgrade( $extension );
159
160
			// Prevent credentials auth screen from displaying multiple times.
161
			if ( false === $results[ $extension ] && ! $this->bailed_early ) {
162
				break;
163
			}
164
		}
165
166
		$this->maintenance_mode( false );
167
168
		$this->skin->bulk_footer();
169
		$this->skin->footer();
170
171
		$this->after_upgrades( $extensions, $args );
172
173
		return $results;
174
175
	} // End public function bulk_upgrade().
176
177
	/**
178
	 * Sets up before running the upgrades.
179
	 *
180
	 * @since 2.4.0
181
	 *
182
	 * @param array $args The arguments passed to the upgrader.
183
	 *
184
	 * @return array The parsed upgrader arguments.
185
	 */
186
	protected function before_upgrades( $args ) {
187
188
		$args = wp_parse_args( $args, array( 'clear_update_cache' => true ) );
0 ignored issues
show
Bug introduced by
The function wp_parse_args was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

188
		$args = /** @scrutinizer ignore-call */ wp_parse_args( $args, array( 'clear_update_cache' => true ) );
Loading history...
189
190
		$this->init();
191
		$this->upgrade_strings();
192
193
		add_filter( 'upgrader_clear_destination', array( $this, 'delete_old_extension' ), 10, 4 );
0 ignored issues
show
Bug introduced by
The function add_filter was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

193
		/** @scrutinizer ignore-call */ 
194
  add_filter( 'upgrader_clear_destination', array( $this, 'delete_old_extension' ), 10, 4 );
Loading history...
194
		add_filter( 'upgrader_source_selection', array( $this, 'check_package' ) );
195
		add_filter( 'upgrader_source_selection', array( $this, 'correct_extension_dir_name' ), 10, 4 );
196
		add_filter( 'upgrader_pre_download', array( $this, 'verify_package_signature' ), 10, 3 );
197
		add_filter( 'upgrader_pre_install', array( $this, 'deactivate_extension_before_upgrade' ), 10, 2 );
198
199
		return $args;
200
	}
201
202
	/**
203
	 * Upgrades an extension.
204
	 *
205
	 * This is the real meat of the upgrade functions.
206
	 *
207
	 * @since 2.4.0
208
	 *
209
	 * @param string $extension_file Basename path to the extension file.
210
	 *
211
	 * @return bool|array|WP_Error Returns true or an array on success, false or a
212
	 *                             WP_Error on failure.
213
	 */
214
	protected function do_upgrade( $extension_file ) {
215
216
		$this->bailed_early = false;
217
218
		$extensions = wordpoints_get_modules();
219
220
		if ( ! isset( $extensions[ $extension_file ] ) ) {
221
			$this->bail_early( 'not_installed' );
222
			return false;
223
		}
224
225
		$extension_data = $extensions[ $extension_file ];
226
227
		if ( $this->skin instanceof WordPoints_Extension_Upgrader_Skin_Bulk ) {
228
			$this->skin->set_extension( $extension_file );
229
		}
230
231
		if ( ! wordpoints_get_extension_updates()->has_update( $extension_file ) ) {
232
			$this->bail_early( 'up_to_date', 'feedback' );
233
			return true;
234
		}
235
236
		$server = wordpoints_get_server_for_extension( $extension_data );
237
238
		if ( ! $server ) {
239
			$this->bail_early( 'no_server' );
240
			return false;
241
		}
242
243
		$api = $server->get_api();
244
245
		if ( false === $api ) {
246
			$this->bail_early( 'api_not_found' );
247
			return false;
248
		}
249
250
		if ( ! $api instanceof WordPoints_Extension_Server_API_Updates_InstallableI ) {
251
			$this->bail_early( 'api_updates_not_supported' );
252
			return false;
253
		}
254
255
		$extension_data = new WordPoints_Extension_Server_API_Extension_Data(
256
			$extension_data['ID']
257
			, $server
258
		);
259
260
		$this->wordpoints_extension_api  = $api;
261
		$this->wordpoints_extension_data = $extension_data;
262
263
		return $this->run(
264
			array(
265
				'package'           => $api->get_extension_package_url( $extension_data ),
266
				'destination'       => wordpoints_extensions_dir(),
267
				'clear_destination' => true,
268
				'clear_working'     => true,
269
				'is_multi'          => $this->bulk,
270
				'hook_extra'        => array(
271
					'wordpoints_extension' => $extension_file,
272
				),
273
			)
274
		);
275
276
	} // End protected function do_upgrade().
277
278
	/**
279
	 * Cleans up after the upgrades.
280
	 *
281
	 * @since 2.4.0
282
	 *
283
	 * @param string|string[] $extensions The extension(s) being upgraded.
284
	 * @param array           $args       The arguments passed to the upgrader.
285
	 */
286
	protected function after_upgrades( $extensions, $args ) {
287
288
		remove_filter( 'upgrader_source_selection', array( $this, 'check_package' ) );
0 ignored issues
show
Bug introduced by
The function remove_filter was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

288
		/** @scrutinizer ignore-call */ 
289
  remove_filter( 'upgrader_source_selection', array( $this, 'check_package' ) );
Loading history...
289
		remove_filter( 'upgrader_source_selection', array( $this, 'correct_extension_dir_name' ) );
290
		remove_filter( 'upgrader_clear_destination', array( $this, 'delete_old_extension' ) );
291
		remove_filter( 'upgrader_pre_download', array( $this, 'verify_package_signature' ) );
292
		remove_filter( 'upgrader_pre_install', array( $this, 'deactivate_extension_before_upgrade' ) );
293
294
		if ( ! $this->bulk ) {
295
			if ( ! $this->skin->result || is_wp_error( $this->skin->result ) ) {
0 ignored issues
show
Bug introduced by
The function is_wp_error was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

295
			if ( ! $this->skin->result || /** @scrutinizer ignore-call */ is_wp_error( $this->skin->result ) ) {
Loading history...
296
				return;
297
			}
298
		}
299
300
		// Force refresh of extension update cache.
301
		wordpoints_clean_extensions_cache( $args['clear_update_cache'] );
302
303
		$details = array(
304
			'action' => 'update',
305
			'type'   => 'wordpoints_extension',
306
			'bulk'   => $this->bulk,
307
		);
308
309
		/**
310
		 * This action is documented in /wp-admin/includes/class-wp-upgrader.php.
311
		 */
312
		do_action( 'upgrader_process_complete', $this, $details, $extensions ); // WPCS: prefix OK.
0 ignored issues
show
Bug introduced by
The function do_action was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

312
		/** @scrutinizer ignore-call */ 
313
  do_action( 'upgrader_process_complete', $this, $details, $extensions ); // WPCS: prefix OK.
Loading history...
313
	}
314
315
	/**
316
	 * Bail early before finishing a process normally.
317
	 *
318
	 * @since 2.4.0
319
	 *
320
	 * @param string $message Slug for the message to show the user.
321
	 * @param string $type    The type of message, 'error' (default), or 'feedback'.
322
	 */
323
	protected function bail_early( $message, $type = 'error' ) {
324
325
		$this->bailed_early = true;
326
327
		$this->skin->before();
328
		$this->skin->set_result( false );
329
330
		if ( 'feedback' === $type ) {
331
			$this->skin->feedback( $message );
332
		} else {
333
			$this->skin->error( $message );
334
		}
335
336
		$this->skin->after();
337
	}
338
339
	/**
340
	 * Conditionally starts maintenance mode, only if necessary.
341
	 *
342
	 * Used when performing bulk updates.
343
	 *
344
	 * Only start maintenance mode if:
345
	 * - running Multisite and there are one or more extensions specified, OR
346
	 * - an extension with an update available is currently active.
347
	 *
348
	 * @since 2.4.0
349
	 *
350
	 * @param string[] $extensions The extensions being upgraded in bulk.
351
	 */
352
	public function maybe_start_maintenance_mode( $extensions ) {
353
354
		if ( is_multisite() && ! empty( $extensions ) ) {
0 ignored issues
show
Bug introduced by
The function is_multisite was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

354
		if ( /** @scrutinizer ignore-call */ is_multisite() && ! empty( $extensions ) ) {
Loading history...
355
356
			$this->maintenance_mode( true );
357
358
		} else {
359
360
			$updates = wordpoints_get_extension_updates();
361
362
			foreach ( $extensions as $extension ) {
363
364
				if (
365
					is_wordpoints_module_active( $extension )
366
					&& $updates->has_update( $extension )
367
				) {
368
					$this->maintenance_mode( true );
369
					break;
370
				}
371
			}
372
		}
373
	}
374
375
	/**
376
	 * Makes sure an extension is inactive before it is upgraded.
377
	 *
378
	 * @since 2.4.0
379
	 *
380
	 * @WordPress\filter upgrader_pre_install Added by self::upgrade().
381
	 *
382
	 * @param bool|WP_Error $return True if we should do the upgrade, a WP_Error otherwise.
383
	 * @param array         $data   Data about the upgrade: what extension is being upgraded.
384
	 *
385
	 * @return bool|WP_Error A WP_Error on failure, otherwise nothing.
386
	 */
387
	public function deactivate_extension_before_upgrade( $return, $data ) {
388
389
		if ( is_wp_error( $return ) ) {
0 ignored issues
show
Bug introduced by
The function is_wp_error was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

389
		if ( /** @scrutinizer ignore-call */ is_wp_error( $return ) ) {
Loading history...
390
			return $return;
391
		}
392
393
		if ( empty( $data['wordpoints_extension'] ) ) {
394
			return new WP_Error( 'bad_request', $this->strings['bad_request'] );
395
		}
396
397
		if ( is_wordpoints_module_active( $data['wordpoints_extension'] ) ) {
398
399
			// Deactivate the extension silently (the actions won't be fired).
400
			wordpoints_deactivate_modules( array( $data['wordpoints_extension'] ), true );
401
		}
402
403
		return $return;
404
	}
405
406
	/**
407
	 * Ensures that an extension folder will have the correct name.
408
	 *
409
	 * @since 2.4.0
410
	 *
411
	 * @WordPress\filter upgrader_source_selection Added by self::upgrade().
412
	 *
413
	 * @param string      $source        The path to the extension source.
414
	 * @param array       $remote_source The remote source of the extension.
415
	 * @param WP_Upgrader $upgrader      The upgrader instance.
0 ignored issues
show
Bug introduced by
The type WP_Upgrader was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
416
	 * @param array       $data          Data about the upgrade.
417
	 *
418
	 * @return string The extension folder.
419
	 */
420
	public function correct_extension_dir_name( $source, $remote_source, $upgrader, $data ) {
421
422
		global $wp_filesystem;
423
424
		if ( is_wp_error( $source ) ) {
0 ignored issues
show
Bug introduced by
The function is_wp_error was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

424
		if ( /** @scrutinizer ignore-call */ is_wp_error( $source ) ) {
Loading history...
425
			return $source;
426
		}
427
428
		if ( $upgrader !== $this || ! isset( $data['wordpoints_extension'] ) ) {
429
			return $source;
430
		}
431
432
		$source_name    = basename( $source );
433
		$extension_name = dirname( $data['wordpoints_extension'] );
434
435
		if ( '.' === $extension_name || $source_name === $extension_name ) {
436
			return $source;
437
		}
438
439
		$correct_source = dirname( $source ) . '/' . $extension_name;
440
441
		$moved = $wp_filesystem->move( $source, $correct_source );
442
443
		if ( ! $moved ) {
444
			return new WP_Error( 'wordpoints_incorrect_source_name', $this->strings['incorrect_source_name'] );
445
		}
446
447
		return $correct_source;
448
	}
449
450
	/**
451
	 * Deletes the old extension before installing the new one.
452
	 *
453
	 * @since 2.4.0
454
	 *
455
	 * @WordPress\filter upgrader_clear_destination Added by self::upgrade() and
456
	 *                                              self::bulk_upgrade().
457
	 *
458
	 * @param true|WP_Error $removed            Whether the destination folder has been removed.
459
	 * @param string        $local_destination  The local path to the destination folder.
460
	 * @param string        $remote_destination The remote path to the destination folder.
461
	 * @param array         $data               Data for the upgrade: what extension is being upgraded.
462
	 *
463
	 * @return true|WP_Error True on success, a WP_Error on failure.
464
	 */
465
	public function delete_old_extension( $removed, $local_destination, $remote_destination, $data ) {
466
467
		global $wp_filesystem;
468
469
		if ( is_wp_error( $removed ) ) {
0 ignored issues
show
Bug introduced by
The function is_wp_error was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

469
		if ( /** @scrutinizer ignore-call */ is_wp_error( $removed ) ) {
Loading history...
470
			return $removed;
471
		}
472
473
		if ( empty( $data['wordpoints_extension'] ) ) {
474
			return new WP_Error( 'bad_request', $this->strings['bad_request'] );
475
		}
476
477
		$extensions_dir     = $wp_filesystem->find_folder( wordpoints_extensions_dir() );
478
		$this_extension_dir = trailingslashit( dirname( $extensions_dir . $data['wordpoints_extension'] ) );
0 ignored issues
show
Bug introduced by
The function trailingslashit was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

478
		$this_extension_dir = /** @scrutinizer ignore-call */ trailingslashit( dirname( $extensions_dir . $data['wordpoints_extension'] ) );
Loading history...
479
480
		// Make sure it hasn't already been removed somehow.
481
		if ( ! $wp_filesystem->exists( $this_extension_dir ) ) {
482
			return $removed;
483
		}
484
485
		/*
486
		 * If the extension is in its own directory, recursively delete the directory.
487
		 * Do a base check on if the extension includes the directory separator AND that
488
		 * it's not the root extensions folder. If not, just delete the single file.
489
		 */
490
		if ( strpos( $data['wordpoints_extension'], '/' ) && $this_extension_dir !== $extensions_dir ) {
491
			$deleted = $wp_filesystem->delete( $this_extension_dir, true );
492
		} else {
493
			$deleted = $wp_filesystem->delete( $extensions_dir . $data['wordpoints_extension'] );
494
		}
495
496
		if ( ! $deleted ) {
497
			return new WP_Error( 'remove_old_failed', $this->strings['remove_old_failed'] );
498
		}
499
500
		return true;
501
	}
502
503
	/**
504
	 * Verifies the signature of the update package before unpacking it.
505
	 *
506
	 * @since 2.5.0
507
	 *
508
	 * @WordPress\filter upgrader_pre_download Added by self::upgrade().
509
	 *
510
	 * @param bool|WP_Error $return   True if we should do the upgrade, a WP_Error
511
	 *                                otherwise.
512
	 * @param string        $package  The package URL.
513
	 * @param WP_Upgrader   $upgrader The upgrader.
514
	 *
515
	 * @return bool|WP_Error A WP_Error on failure, otherwise nothing.
516
	 */
517
	public function verify_package_signature( $return, $package, $upgrader ) {
518
519
		if ( is_wp_error( $return ) ) {
0 ignored issues
show
Bug introduced by
The function is_wp_error was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

519
		if ( /** @scrutinizer ignore-call */ is_wp_error( $return ) ) {
Loading history...
520
			return $return;
521
		}
522
523
		if ( $upgrader !== $this ) {
524
			return $return;
525
		}
526
527
		// WARNING: In 3.0.0 we will change this to abort the update.
528
		if ( ! $this->wordpoints_extension_api instanceof WordPoints_Extension_Server_API_Updates_Signed_Ed25519I ) {
529
530
			_doing_it_wrong(
0 ignored issues
show
Bug introduced by
The function _doing_it_wrong was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

530
			/** @scrutinizer ignore-call */ 
531
   _doing_it_wrong(
Loading history...
531
				__METHOD__
532
				, 'Extension server APIs should use digital signatures to verify packages.'
533
				, '2.5.0'
534
			);
535
536
			return $return;
537
		}
538
539
		$public_key = $this->wordpoints_extension_api->get_extension_public_key_ed25519(
540
			$this->wordpoints_extension_data
541
		);
542
543
		// WARNING: In 3.0.0 we will change this to abort the update.
544
		if ( ! $public_key ) {
545
546
			_doing_it_wrong(
547
				__METHOD__
548
				, 'Extension server APIs should use digital signatures to verify packages.'
549
				, '2.5.0'
550
			);
551
552
			return $return;
553
		}
554
555
		remove_filter( 'upgrader_pre_download', array( $this, 'verify_package_signature' ) );
0 ignored issues
show
Bug introduced by
The function remove_filter was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

555
		/** @scrutinizer ignore-call */ 
556
  remove_filter( 'upgrader_pre_download', array( $this, 'verify_package_signature' ) );
Loading history...
556
557
		$download_file = $this->download_package( $package );
558
559
		add_filter( 'upgrader_pre_download', array( $this, 'verify_package_signature' ), 10, 3 );
0 ignored issues
show
Bug introduced by
The function add_filter was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

559
		/** @scrutinizer ignore-call */ 
560
  add_filter( 'upgrader_pre_download', array( $this, 'verify_package_signature' ), 10, 3 );
Loading history...
560
561
		if ( is_wp_error( $download_file ) ) {
562
			return $download_file;
563
		}
564
565
		$this->skin->feedback( 'verifying_package' );
566
567
		$ed25519_check = wordpoints_verify_file_ed25519(
568
			$download_file
569
			, $public_key
570
			, $this->wordpoints_extension_api->get_extension_package_signature_ed25519(
571
				$this->wordpoints_extension_data
572
			)
573
		);
574
575
		if ( is_wp_error( $ed25519_check ) ) {
576
577
			/** @var WP_Error $ed25519_check */
578
			$ed25519_check->add(
579
				'verifying_package_failed'
580
				, $this->strings['verifying_package_failed']
581
			);
582
583
			return $ed25519_check;
584
		}
585
586
		return $download_file;
587
	}
588
589
} // End class WordPoints_Extension_Upgrader.
590
591
// EOF
592