-
Notifications
You must be signed in to change notification settings - Fork 27
Fix plugin verification to detect directories without main PHP files #143
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
6d5287d
b255e2a
e567bbd
f1be4c5
9a4be37
97a5b26
2545381
51b669e
40f9fbc
890b94b
e3a4e71
e38a9b6
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -107,6 +107,12 @@ public function __invoke( $args, $assoc_args ) { | |
| continue; | ||
| } | ||
|
|
||
| // Check if the main plugin file exists | ||
| $main_file_path = WP_PLUGIN_DIR . '/' . $plugin->file; | ||
| if ( ! file_exists( $main_file_path ) ) { | ||
| WP_CLI::warning( "Plugin {$plugin->name} main file is missing: {$plugin->file}" ); | ||
| } | ||
|
|
||
| if ( false === $version ) { | ||
| WP_CLI::warning( "Could not retrieve the version for plugin {$plugin->name}, skipping." ); | ||
| ++$skips; | ||
|
|
@@ -222,24 +228,87 @@ private function get_plugin_version( $path ) { | |
| } | ||
|
|
||
| if ( ! array_key_exists( $path, $this->plugins_data ) ) { | ||
| return false; | ||
| // Try to detect version from any PHP file in the plugin directory | ||
| return $this->detect_version_from_directory( dirname( $path ) ); | ||
| } | ||
|
|
||
| return $this->plugins_data[ $path ]['Version']; | ||
| } | ||
|
|
||
| /** | ||
| * Attempts to detect plugin version from any PHP file in the plugin directory. | ||
| * | ||
| * This is used as a fallback when the main plugin file is missing or has no valid headers. | ||
| * | ||
| * @param string $plugin_dir Plugin directory name (relative to WP_PLUGIN_DIR). | ||
| * | ||
| * @return string|false Detected version, or false if not found. | ||
| */ | ||
| private function detect_version_from_directory( $plugin_dir ) { | ||
| $plugin_path = WP_PLUGIN_DIR . '/' . $plugin_dir; | ||
|
|
||
| // If it's not a directory (single-file plugin), we can't detect version | ||
| if ( ! is_dir( $plugin_path ) ) { | ||
| return false; | ||
| } | ||
|
|
||
| // Try scanning PHP files for Version header using WordPress's get_file_data() | ||
| $files = glob( $plugin_path . '/*.php' ); | ||
|
||
| if ( is_array( $files ) && ! empty( $files ) ) { | ||
| foreach ( $files as $file ) { | ||
| if ( is_readable( $file ) ) { | ||
| $file_data = get_file_data( | ||
| $file, | ||
| array( 'Version' => 'Version' ) | ||
| ); | ||
| if ( ! empty( $file_data['Version'] ) ) { | ||
| return $file_data['Version']; | ||
| } | ||
| } | ||
| } | ||
| } | ||
| // If glob() failed (returns false), version will just not be detected from PHP files | ||
|
|
||
| return false; | ||
| } | ||
swissspidy marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| /** | ||
| * Gets the names of all installed plugins. | ||
| * | ||
| * Includes both plugins detected by get_plugins() and plugin directories | ||
| * that exist on the filesystem but may not have valid headers. | ||
| * | ||
| * @return array<string> Names of all installed plugins. | ||
| */ | ||
| private function get_all_plugin_names() { | ||
| $names = array(); | ||
|
|
||
| // Get plugins from get_plugins() (those with valid headers) | ||
| foreach ( get_plugins() as $file => $details ) { | ||
| $names[] = Utils\get_plugin_name( $file ); | ||
| } | ||
|
|
||
| return $names; | ||
| // Also scan the filesystem for plugin directories | ||
| $plugin_dir = WP_PLUGIN_DIR; | ||
| if ( is_dir( $plugin_dir ) && is_readable( $plugin_dir ) ) { | ||
| $dirs = @scandir( $plugin_dir ); // phpcs:ignore WordPress.PHP.NoSilencedErrors.Discouraged | ||
| if ( false !== $dirs ) { | ||
| foreach ( $dirs as $dir ) { | ||
| // Skip special directories and files | ||
| if ( '.' === $dir || '..' === $dir ) { | ||
| continue; | ||
| } | ||
|
|
||
| $full_path = $plugin_dir . '/' . $dir; | ||
| // Only include real directories, not symlinks or files | ||
| if ( is_dir( $full_path ) && ! is_link( $full_path ) && ! in_array( $dir, $names, true ) ) { | ||
| $names[] = $dir; | ||
| } | ||
| } | ||
| } | ||
| } | ||
|
Comment on lines
+293
to
+309
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Consider refactoring this block to use if ( is_dir( $plugin_dir ) && is_readable( $plugin_dir ) ) {
try {
foreach ( new DirectoryIterator( $plugin_dir ) as $fileinfo ) {
if ( $fileinfo->isDot() || ! $fileinfo->isDir() || $fileinfo->isLink() ) {
continue;
}
$dir = $fileinfo->getFilename();
if ( ! in_array( $dir, $names, true ) ) {
$names[] = $dir;
}
}
} catch ( UnexpectedValueException $e ) {
WP_CLI::warning( "Could not scan plugin directory '{$plugin_dir}': " . $e->getMessage() );
}
} |
||
|
|
||
| return array_unique( $names ); | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
| } | ||
|
|
||
| /** | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The test scenario for verifying a plugin directory with
--allflag (lines 232-240) doesn't specify whether version detection succeeds or fails. If the version cannot be auto-detected from the renamed file, the plugin would be skipped with a "Could not retrieve the version" warning, not verified. The test should either verify that version detection succeeds from other PHP files in the directory, or it should expect the version warning and skip message. Consider adding explicit assertions about the version detection outcome.