Passed
Push — master ( 59650c...0b7aa3 )
by Chris
11:04 queued 06:15
created

MonsterInsights_Plugin_Upgrader::run()   C

Complexity

Conditions 16
Paths 56

Size

Total Lines 182
Code Lines 63

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 16
eloc 63
c 1
b 0
f 0
nc 56
nop 1
dl 0
loc 182
rs 5.5666

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
/** WP_Upgrader class */
4
require_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php';
5
6
/** Plugin_Upgrader class */
7
require_once ABSPATH . 'wp-admin/includes/class-plugin-upgrader.php';
8
9
10
/**
11
 * In WP 5.3 a PHP 5.6 splat operator (...$args) was added to WP_Upgrader_Skin::feedback().
12
 * We need to remove all calls to *Skin::feedback() method, as we can't override it in own Skins
13
 * without breaking support for PHP 5.3-5.5.
14
 *
15
 * @internal Please do not use this class outside of core MonsterInsights development. May be removed at any time.
16
 *
17
 * @since 7.10.6
18
 */
19
class MonsterInsights_Plugin_Upgrader extends Plugin_Upgrader {
20
21
	/**
22
	 * Run an upgrade/installation.
23
	 *
24
	 * Attempt to download the package (if it is not a local file), unpack it, and
25
	 * install it in the destination folder.
26
	 *
27
	 * @since 1.5.6.1
28
	 *
29
	 * @param array $options {
30
	 *     Array or string of arguments for upgrading/installing a package.
31
	 *
32
	 *     @type string $package                     The full path or URI of the package to install.
33
	 *                                               Default empty.
34
	 *     @type string $destination                 The full path to the destination folder.
35
	 *                                               Default empty.
36
	 *     @type bool   $clear_destination           Whether to delete any files already in the
37
	 *                                               destination folder. Default false.
38
	 *     @type bool   $clear_working               Whether to delete the files form the working
39
	 *                                               directory after copying to the destination.
40
	 *                                               Default false.
41
	 *     @type bool   $abort_if_destination_exists Whether to abort the installation if the destination
42
	 *                                               folder already exists. When true, `$clear_destination`
43
	 *                                               should be false. Default true.
44
	 *     @type bool   $is_multi                    Whether this run is one of multiple upgrade/installation
45
	 *                                               actions being performed in bulk. When true, the skin
46
	 *                                               WP_Upgrader::header() and WP_Upgrader::footer()
47
	 *                                               aren't called. Default false.
48
	 *     @type array  $hook_extra                  Extra arguments to pass to the filter hooks called by
49
	 *                                               WP_Upgrader::run().
50
	 * }
51
	 * @return array|false|WP_error The result from self::install_package() on success, otherwise a WP_Error,
52
	 *                              or false if unable to connect to the filesystem.
53
	 */
54
	public function run( $options ) {
55
56
		$defaults = array(
57
			'package'                     => '', // Please always pass this.
58
			'destination'                 => '', // And this
59
			'clear_destination'           => false,
60
			'abort_if_destination_exists' => true, // Abort if the Destination directory exists, Pass clear_destination as false please
61
			'clear_working'               => true,
62
			'is_multi'                    => false,
63
			'hook_extra'                  => array(), // Pass any extra $hook_extra args here, this will be passed to any hooked filters.
64
		);
65
66
		$options = wp_parse_args( $options, $defaults );
67
68
		/**
69
		 * Filter the package options before running an update.
70
		 *
71
		 * See also {@see 'upgrader_process_complete'}.
72
		 *
73
		 * @since 4.3.0
74
		 *
75
		 * @param array $options {
76
		 *     Options used by the upgrader.
77
		 *
78
		 *     @type string $package                     Package for update.
79
		 *     @type string $destination                 Update location.
80
		 *     @type bool   $clear_destination           Clear the destination resource.
81
		 *     @type bool   $clear_working               Clear the working resource.
82
		 *     @type bool   $abort_if_destination_exists Abort if the Destination directory exists.
83
		 *     @type bool   $is_multi                    Whether the upgrader is running multiple times.
84
		 *     @type array  $hook_extra {
85
		 *         Extra hook arguments.
86
		 *
87
		 *         @type string $action               Type of action. Default 'update'.
88
		 *         @type string $type                 Type of update process. Accepts 'plugin', 'theme', or 'core'.
89
		 *         @type bool   $bulk                 Whether the update process is a bulk update. Default true.
90
		 *         @type string $plugin               Path to the plugin file relative to the plugins directory.
91
		 *         @type string $theme                The stylesheet or template name of the theme.
92
		 *         @type string $language_update_type The language pack update type. Accepts 'plugin', 'theme',
93
		 *                                            or 'core'.
94
		 *         @type object $language_update      The language pack update offer.
95
		 *     }
96
		 * }
97
		 */
98
		$options = apply_filters( 'upgrader_package_options', $options );
99
100
		if ( ! $options['is_multi'] ) { // call $this->header separately if running multiple times
101
			$this->skin->header();
102
		}
103
104
		// Connect to the Filesystem first.
105
		$res = $this->fs_connect( array( WP_CONTENT_DIR, $options['destination'] ) );
106
		// Mainly for non-connected filesystem.
107
		if ( ! $res ) {
108
			if ( ! $options['is_multi'] ) {
109
				$this->skin->footer();
110
			}
111
			return false;
112
		}
113
114
		$this->skin->before();
115
116
		if ( is_wp_error( $res ) ) {
117
			$this->skin->error( $res );
0 ignored issues
show
Bug introduced by
It seems like $res can also be of type true; however, parameter $errors of WP_Upgrader_Skin::error() does only seem to accept WP_Error|string, maybe add an additional type check? ( Ignorable by Annotation )

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

117
			$this->skin->error( /** @scrutinizer ignore-type */ $res );
Loading history...
118
			$this->skin->after();
119
			if ( ! $options['is_multi'] ) {
120
				$this->skin->footer();
121
			}
122
			return $res;
123
		}
124
125
		/*
126
		 * Download the package (Note, This just returns the filename
127
		 * of the file if the package is a local file)
128
		 */
129
		$download = $this->download_package( $options['package'], true );
130
131
		// Allow for signature soft-fail.
132
		// WARNING: This may be removed in the future.
133
		if ( is_wp_error( $download ) && $download->get_error_data( 'softfail-filename' ) ) {
134
135
			// Don't output the 'no signature could be found' failure message for now.
136
			if ( 'signature_verification_no_signature' != $download->get_error_code() || WP_DEBUG ) {
137
				// Outout the failure error as a normal feedback, and not as an error:
138
				//$this->skin->feedback( $download->get_error_message() );
139
140
				// Report this failure back to WordPress.org for debugging purposes.
141
				wp_version_check(
142
					array(
143
						'signature_failure_code' => $download->get_error_code(),
144
						'signature_failure_data' => $download->get_error_data(),
145
					)
146
				);
147
			}
148
149
			// Pretend this error didn't happen.
150
			$download = $download->get_error_data( 'softfail-filename' );
151
		}
152
153
		if ( is_wp_error( $download ) ) {
154
			$this->skin->error( $download );
155
			$this->skin->after();
156
			if ( ! $options['is_multi'] ) {
157
				$this->skin->footer();
158
			}
159
			return $download;
160
		}
161
162
		$delete_package = ( $download != $options['package'] ); // Do not delete a "local" file
163
164
		// Unzips the file into a temporary directory.
165
		$working_dir = $this->unpack_package( $download, $delete_package );
166
		if ( is_wp_error( $working_dir ) ) {
167
			$this->skin->error( $working_dir );
168
			$this->skin->after();
169
			if ( ! $options['is_multi'] ) {
170
				$this->skin->footer();
171
			}
172
			return $working_dir;
173
		}
174
175
		// With the given options, this installs it to the destination directory.
176
		$result = $this->install_package(
177
			array(
178
				'source'                      => $working_dir,
179
				'destination'                 => $options['destination'],
180
				'clear_destination'           => $options['clear_destination'],
181
				'abort_if_destination_exists' => $options['abort_if_destination_exists'],
182
				'clear_working'               => $options['clear_working'],
183
				'hook_extra'                  => $options['hook_extra'],
184
			)
185
		);
186
187
		$this->skin->set_result( $result );
0 ignored issues
show
Bug introduced by
It seems like $result can also be of type array; however, parameter $result of WP_Upgrader_Skin::set_result() does only seem to accept WP_Error|boolean|string, maybe add an additional type check? ( Ignorable by Annotation )

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

187
		$this->skin->set_result( /** @scrutinizer ignore-type */ $result );
Loading history...
188
		if ( is_wp_error( $result ) ) {
189
			$this->skin->error( $result );
0 ignored issues
show
Bug introduced by
It seems like $result can also be of type array; however, parameter $errors of WP_Upgrader_Skin::error() does only seem to accept WP_Error|string, maybe add an additional type check? ( Ignorable by Annotation )

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

189
			$this->skin->error( /** @scrutinizer ignore-type */ $result );
Loading history...
190
			//$this->skin->feedback( 'process_failed' );
191
		} else {
192
			// Installation succeeded.
193
			//$this->skin->feedback( 'process_success' );
194
		}
195
196
		$this->skin->after();
197
198
		if ( ! $options['is_multi'] ) {
199
200
			/**
201
			 * Fire when the upgrader process is complete.
202
			 *
203
			 * See also {@see 'upgrader_package_options'}.
204
			 *
205
			 * @since 3.6.0
206
			 * @since 3.7.0 Added to WP_Upgrader::run().
207
			 * @since 4.6.0 `$translations` was added as a possible argument to `$hook_extra`.
208
			 *
209
			 * @param WP_Upgrader $this WP_Upgrader instance. In other contexts, $this, might be a
210
			 *                          Theme_Upgrader, Plugin_Upgrader, Core_Upgrade, or Language_Pack_Upgrader instance.
211
			 * @param array       $hook_extra {
212
			 *     Array of bulk item update data.
213
			 *
214
			 *     @type string $action       Type of action. Default 'update'.
215
			 *     @type string $type         Type of update process. Accepts 'plugin', 'theme', 'translation', or 'core'.
216
			 *     @type bool   $bulk         Whether the update process is a bulk update. Default true.
217
			 *     @type array  $plugins      Array of the basename paths of the plugins' main files.
218
			 *     @type array  $themes       The theme slugs.
219
			 *     @type array  $translations {
220
			 *         Array of translations update data.
221
			 *
222
			 *         @type string $language The locale the translation is for.
223
			 *         @type string $type     Type of translation. Accepts 'plugin', 'theme', or 'core'.
224
			 *         @type string $slug     Text domain the translation is for. The slug of a theme/plugin or
225
			 *                                'default' for core translations.
226
			 *         @type string $version  The version of a theme, plugin, or core.
227
			 *     }
228
			 * }
229
			 */
230
			do_action( 'upgrader_process_complete', $this, $options['hook_extra'] );
231
232
			$this->skin->footer();
233
		}
234
235
		return $result;
236
	}
237
238
	/**
239
	 * Toggle maintenance mode for the site.
240
	 *
241
	 * Create/delete the maintenance file to enable/disable maintenance mode.
242
	 *
243
	 * @since 2.8.0
244
	 *
245
	 * @global WP_Filesystem_Base $wp_filesystem Subclass
246
	 *
247
	 * @param bool $enable True to enable maintenance mode, false to disable.
248
	 */
249
	public function maintenance_mode( $enable = false ) {
250
		global $wp_filesystem;
251
		$file = $wp_filesystem->abspath() . '.maintenance';
252
		if ( $enable ) {
253
			//$this->skin->feedback( 'maintenance_start' );
254
			// Create maintenance file to signal that we are upgrading
255
			$maintenance_string = '<?php $upgrading = ' . time() . '; ?>';
256
			$wp_filesystem->delete( $file );
257
			$wp_filesystem->put_contents( $file, $maintenance_string, FS_CHMOD_FILE );
258
		} elseif ( ! $enable && $wp_filesystem->exists( $file ) ) {
0 ignored issues
show
introduced by
The condition $enable is always false.
Loading history...
259
			//$this->skin->feedback( 'maintenance_end' );
260
			$wp_filesystem->delete( $file );
261
		}
262
	}
263
264
	/**
265
	 * Download a package.
266
	 *
267
	 * @since 2.8.0
268
	 *
269
	 * @param string $package          The URI of the package. If this is the full path to an
270
	 *                                 existing local file, it will be returned untouched.
271
	 * @param bool   $check_signatures Whether to validate file signatures. Default false.
272
	 * @return string|WP_Error The full path to the downloaded package file, or a WP_Error object.
273
	 */
274
	public function download_package( $package, $check_signatures = false ) {
275
276
		/**
277
		 * Filter whether to return the package.
278
		 *
279
		 * @since 3.7.0
280
		 *
281
		 * @param bool        $reply   Whether to bail without returning the package.
282
		 *                             Default false.
283
		 * @param string      $package The package file name.
284
		 * @param WP_Upgrader $this    The WP_Upgrader instance.
285
		 */
286
		$reply = apply_filters( 'upgrader_pre_download', false, $package, $this );
287
		if ( false !== $reply ) {
288
			return $reply;
289
		}
290
291
		if ( ! preg_match( '!^(http|https|ftp)://!i', $package ) && file_exists( $package ) ) { //Local file or remote?
292
			return $package; //must be a local file..
293
		}
294
295
		if ( empty( $package ) ) {
296
			return new WP_Error( 'no_package', $this->strings['no_package'] );
297
		}
298
299
		//$this->skin->feedback( 'downloading_package', $package );
300
301
		$download_file = download_url( $package, 300, $check_signatures );
302
303
		if ( is_wp_error( $download_file ) && ! $download_file->get_error_data( 'softfail-filename' ) ) {
304
			return new WP_Error( 'download_failed', $this->strings['download_failed'], $download_file->get_error_message() );
305
		}
306
307
		return $download_file;
308
	}
309
310
	/**
311
	 * Unpack a compressed package file.
312
	 *
313
	 * @since 2.8.0
314
	 *
315
	 * @global WP_Filesystem_Base $wp_filesystem WordPress filesystem subclass.
316
	 *
317
	 * @param string $package        Full path to the package file.
318
	 * @param bool   $delete_package Optional. Whether to delete the package file after attempting
319
	 *                               to unpack it. Default true.
320
	 * @return string|WP_Error The path to the unpacked contents, or a WP_Error on failure.
321
	 */
322
	public function unpack_package( $package, $delete_package = true ) {
323
		global $wp_filesystem;
324
325
		//$this->skin->feedback( 'unpack_package' );
326
327
		$upgrade_folder = $wp_filesystem->wp_content_dir() . 'upgrade/';
328
329
		//Clean up contents of upgrade directory beforehand.
330
		$upgrade_files = $wp_filesystem->dirlist( $upgrade_folder );
331
		if ( ! empty( $upgrade_files ) ) {
332
			foreach ( $upgrade_files as $file ) {
333
				$wp_filesystem->delete( $upgrade_folder . $file['name'], true );
334
			}
335
		}
336
337
		// We need a working directory - Strip off any .tmp or .zip suffixes
338
		$working_dir = $upgrade_folder . basename( basename( $package, '.tmp' ), '.zip' );
339
340
		// Clean up working directory
341
		if ( $wp_filesystem->is_dir( $working_dir ) ) {
342
			$wp_filesystem->delete( $working_dir, true );
343
		}
344
345
		// Unzip package to working directory
346
		$result = unzip_file( $package, $working_dir );
347
348
		// Once extracted, delete the package if required.
349
		if ( $delete_package ) {
350
			unlink( $package );
351
		}
352
353
		if ( is_wp_error( $result ) ) {
354
			$wp_filesystem->delete( $working_dir, true );
355
			if ( 'incompatible_archive' == $result->get_error_code() ) {
356
				return new WP_Error( 'incompatible_archive', $this->strings['incompatible_archive'], $result->get_error_data() );
357
			}
358
			return $result;
359
		}
360
361
		return $working_dir;
362
	}
363
364
	/**
365
	 * Install a package.
366
	 *
367
	 * Copies the contents of a package form a source directory, and installs them in
368
	 * a destination directory. Optionally removes the source. It can also optionally
369
	 * clear out the destination folder if it already exists.
370
	 *
371
	 * @since 2.8.0
372
	 *
373
	 * @global WP_Filesystem_Base $wp_filesystem        WordPress filesystem subclass.
374
	 * @global array              $wp_theme_directories
375
	 *
376
	 * @param array|string $args {
377
	 *     Optional. Array or string of arguments for installing a package. Default empty array.
378
	 *
379
	 *     @type string $source                      Required path to the package source. Default empty.
380
	 *     @type string $destination                 Required path to a folder to install the package in.
381
	 *                                               Default empty.
382
	 *     @type bool   $clear_destination           Whether to delete any files already in the destination
383
	 *                                               folder. Default false.
384
	 *     @type bool   $clear_working               Whether to delete the files form the working directory
385
	 *                                               after copying to the destination. Default false.
386
	 *     @type bool   $abort_if_destination_exists Whether to abort the installation if
387
	 *                                               the destination folder already exists. Default true.
388
	 *     @type array  $hook_extra                  Extra arguments to pass to the filter hooks called by
389
	 *                                               WP_Upgrader::install_package(). Default empty array.
390
	 * }
391
	 *
392
	 * @return array|WP_Error The result (also stored in `WP_Upgrader::$result`), or a WP_Error on failure.
393
	 */
394
	public function install_package( $args = array() ) {
395
		global $wp_filesystem, $wp_theme_directories;
396
397
		$defaults = array(
398
			'source'                      => '', // Please always pass this
399
			'destination'                 => '', // and this
400
			'clear_destination'           => false,
401
			'clear_working'               => false,
402
			'abort_if_destination_exists' => true,
403
			'hook_extra'                  => array(),
404
		);
405
406
		$args = wp_parse_args( $args, $defaults );
407
408
		// These were previously extract()'d.
409
		$source            = $args['source'];
410
		$destination       = $args['destination'];
411
		$clear_destination = $args['clear_destination'];
412
413
		set_time_limit( 300 );
414
415
		if ( empty( $source ) || empty( $destination ) ) {
416
			return new WP_Error( 'bad_request', $this->strings['bad_request'] );
417
		}
418
		//$this->skin->feedback( 'installing_package' );
419
420
		/**
421
		 * Filter the install response before the installation has started.
422
		 *
423
		 * Returning a truthy value, or one that could be evaluated as a WP_Error
424
		 * will effectively short-circuit the installation, returning that value
425
		 * instead.
426
		 *
427
		 * @since 2.8.0
428
		 *
429
		 * @param bool|WP_Error $response   Response.
430
		 * @param array         $hook_extra Extra arguments passed to hooked filters.
431
		 */
432
		$res = apply_filters( 'upgrader_pre_install', true, $args['hook_extra'] );
433
434
		if ( is_wp_error( $res ) ) {
435
			return $res;
436
		}
437
438
		//Retain the Original source and destinations
439
		$remote_source     = $args['source'];
440
		$local_destination = $destination;
441
442
		$source_files       = array_keys( $wp_filesystem->dirlist( $remote_source ) );
443
		$remote_destination = $wp_filesystem->find_folder( $local_destination );
444
445
		//Locate which directory to copy to the new folder, This is based on the actual folder holding the files.
446
		if ( 1 == count( $source_files ) && $wp_filesystem->is_dir( trailingslashit( $args['source'] ) . $source_files[0] . '/' ) ) { //Only one folder? Then we want its contents.
447
			$source = trailingslashit( $args['source'] ) . trailingslashit( $source_files[0] );
448
		} elseif ( count( $source_files ) == 0 ) {
449
			return new WP_Error( 'incompatible_archive_empty', $this->strings['incompatible_archive'], $this->strings['no_files'] ); // There are no files?
450
		} else { // It's only a single file, the upgrader will use the folder name of this file as the destination folder. Folder name is based on zip filename.
451
			$source = trailingslashit( $args['source'] );
452
		}
453
454
		/**
455
		 * Filter the source file location for the upgrade package.
456
		 *
457
		 * @since 2.8.0
458
		 * @since 4.4.0 The $hook_extra parameter became available.
459
		 *
460
		 * @param string      $source        File source location.
461
		 * @param string      $remote_source Remote file source location.
462
		 * @param WP_Upgrader $this          WP_Upgrader instance.
463
		 * @param array       $hook_extra    Extra arguments passed to hooked filters.
464
		 */
465
		$source = apply_filters( 'upgrader_source_selection', $source, $remote_source, $this, $args['hook_extra'] );
466
467
		if ( is_wp_error( $source ) ) {
468
			return $source;
469
		}
470
471
		// Has the source location changed? If so, we need a new source_files list.
472
		if ( $source !== $remote_source ) {
473
			$source_files = array_keys( $wp_filesystem->dirlist( $source ) );
474
		}
475
476
		/*
477
		 * Protection against deleting files in any important base directories.
478
		 * Theme_Upgrader & Plugin_Upgrader also trigger this, as they pass the
479
		 * destination directory (WP_PLUGIN_DIR / wp-content/themes) intending
480
		 * to copy the directory into the directory, whilst they pass the source
481
		 * as the actual files to copy.
482
		 */
483
		$protected_directories = array( ABSPATH, WP_CONTENT_DIR, WP_PLUGIN_DIR, WP_CONTENT_DIR . '/themes' );
484
485
		if ( is_array( $wp_theme_directories ) ) {
486
			$protected_directories = array_merge( $protected_directories, $wp_theme_directories );
487
		}
488
489
		if ( in_array( $destination, $protected_directories ) ) {
490
			$remote_destination = trailingslashit( $remote_destination ) . trailingslashit( basename( $source ) );
491
			$destination        = trailingslashit( $destination ) . trailingslashit( basename( $source ) );
492
		}
493
494
		if ( $clear_destination ) {
495
			// We're going to clear the destination if there's something there.
496
			//$this->skin->feedback( 'remove_old' );
497
498
			$removed = $this->clear_destination( $remote_destination );
499
500
			/**
501
			 * Filter whether the upgrader cleared the destination.
502
			 *
503
			 * @since 2.8.0
504
			 *
505
			 * @param mixed  $removed            Whether the destination was cleared. true on success, WP_Error on failure
506
			 * @param string $local_destination  The local package destination.
507
			 * @param string $remote_destination The remote package destination.
508
			 * @param array  $hook_extra         Extra arguments passed to hooked filters.
509
			 */
510
			$removed = apply_filters( 'upgrader_clear_destination', $removed, $local_destination, $remote_destination, $args['hook_extra'] );
511
512
			if ( is_wp_error( $removed ) ) {
513
				return $removed;
514
			}
515
		} elseif ( $args['abort_if_destination_exists'] && $wp_filesystem->exists( $remote_destination ) ) {
516
			//If we're not clearing the destination folder and something exists there already, Bail.
517
			//But first check to see if there are actually any files in the folder.
518
			$_files = $wp_filesystem->dirlist( $remote_destination );
519
			if ( ! empty( $_files ) ) {
520
				$wp_filesystem->delete( $remote_source, true ); //Clear out the source files.
521
				return new WP_Error( 'folder_exists', $this->strings['folder_exists'], $remote_destination );
522
			}
523
		}
524
525
		//Create destination if needed
526
		if ( ! $wp_filesystem->exists( $remote_destination ) ) {
527
			if ( ! $wp_filesystem->mkdir( $remote_destination, FS_CHMOD_DIR ) ) {
528
				return new WP_Error( 'mkdir_failed_destination', $this->strings['mkdir_failed'], $remote_destination );
529
			}
530
		}
531
		// Copy new version of item into place.
532
		$result = copy_dir( $source, $remote_destination );
533
		if ( is_wp_error( $result ) ) {
534
			if ( $args['clear_working'] ) {
535
				$wp_filesystem->delete( $remote_source, true );
536
			}
537
			return $result;
538
		}
539
540
		//Clear the Working folder?
541
		if ( $args['clear_working'] ) {
542
			$wp_filesystem->delete( $remote_source, true );
543
		}
544
545
		$destination_name = basename( str_replace( $local_destination, '', $destination ) );
546
		if ( '.' == $destination_name ) {
547
			$destination_name = '';
548
		}
549
550
		$this->result = compact( 'source', 'source_files', 'destination', 'destination_name', 'local_destination', 'remote_destination', 'clear_destination' );
551
552
		/**
553
		 * Filter the installation response after the installation has finished.
554
		 *
555
		 * @since 2.8.0
556
		 *
557
		 * @param bool  $response   Installation response.
558
		 * @param array $hook_extra Extra arguments passed to hooked filters.
559
		 * @param array $result     Installation result data.
560
		 */
561
		$res = apply_filters( 'upgrader_post_install', true, $args['hook_extra'], $this->result );
562
563
		if ( is_wp_error( $res ) ) {
564
			$this->result = $res;
0 ignored issues
show
Documentation Bug introduced by
It seems like $res can also be of type true. However, the property $result is declared as type WP_Error|array. Maybe add an additional type check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.

For example, imagine you have a variable $accountId that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to the id property of an instance of the Account class. This class holds a proper account, so the id value must no longer be false.

Either this assignment is in error or a type check should be added for that assignment.

class Id
{
    public $id;

    public function __construct($id)
    {
        $this->id = $id;
    }

}

class Account
{
    /** @var  Id $id */
    public $id;
}

$account_id = false;

if (starsAreRight()) {
    $account_id = new Id(42);
}

$account = new Account();
if ($account instanceof Id)
{
    $account->id = $account_id;
}
Loading history...
565
			return $res;
566
		}
567
568
		//Bombard the calling function will all the info which we've just used.
569
		return $this->result;
570
	}
571
}
572