diff --git a/includes/Checker/Checks/Plugin_Repo/File_Type_Check.php b/includes/Checker/Checks/Plugin_Repo/File_Type_Check.php index bf90778c..7ecea7ac 100644 --- a/includes/Checker/Checks/Plugin_Repo/File_Type_Check.php +++ b/includes/Checker/Checks/Plugin_Repo/File_Type_Check.php @@ -302,6 +302,49 @@ function ( $file ) use ( $plugin_path ) { ); } } + + // Duplicated names in different folders. + $folders = array(); + foreach ( $files as $file ) { + $folder = str_replace( basename( $file ), '', $file ); + if ( empty( $folder ) ) { + continue; + } + $folders[] = $folder; + } + $folders = array_unique( $folders ); + $folders_lowercase = array_map( 'strtolower', $folders ); + $case_sensitive_folders = array_unique( array_diff_assoc( $folders_lowercase, array_unique( $folders_lowercase ) ) ); + + if ( ! empty( $case_sensitive_folders ) ) { + $this->add_result_error_for_file( + $result, + __( 'Multiple folders with the same name but different case were found. This can be problematic on certain file systems.', 'plugin-check' ), + 'case_sensitive_folders', + implode( ', ', $case_sensitive_folders ), + 0, + 0, + '', + 8 + ); + } + + // Duplicated names in same folder. + $files_lowercase = array_map( 'strtolower', $files ); + $case_sensitive_files = array_unique( array_diff_assoc( $files_lowercase, array_unique( $files_lowercase ) ) ); + + if ( ! empty( $case_sensitive_files ) ) { + $this->add_result_error_for_file( + $result, + __( 'Multiple files with the same name but different case were found. This can be problematic on certain file systems.', 'plugin-check' ), + 'case_sensitive_files', + implode( ', ', $case_sensitive_files ), + 0, + 0, + '', + 8 + ); + } } /** diff --git a/tests/phpunit/tests/Checker/Checks/File_Type_Check_Tests.php b/tests/phpunit/tests/Checker/Checks/File_Type_Check_Tests.php index a91c197f..cb7bfbe3 100644 --- a/tests/phpunit/tests/Checker/Checks/File_Type_Check_Tests.php +++ b/tests/phpunit/tests/Checker/Checks/File_Type_Check_Tests.php @@ -128,6 +128,48 @@ public function test_run_with_badly_named_errors() { $this->assertCount( 1, wp_list_filter( $errors['badly|file%name!@#$%^&*()+=[]{};:"\'<>,?|`~.php'][0][0], array( 'code' => 'badly_named_files' ) ) ); } + public function test_run_with_case_sensitive_named_errors() { + // Initialize the Check_Context with a plugin path that mimics the directory structure. + $check_context = new Check_Context( UNIT_TESTS_PLUGIN_DIR . 'test-plugin-file-type-badly-named-files-errors/load.php' ); + + // Create an empty Check_Result instance for this context. + $check_result = new Check_Result( $check_context ); + + // Initialize the File_Type_Check instance. + $check = new File_Type_Check(); + + // Use reflection to make protected method accessible. + $reflection = new ReflectionClass( $check ); + $check_files_method = $reflection->getMethod( 'look_for_badly_named_files' ); + $check_files_method->setAccessible( true ); + + // Define the custom file list with duplicate names as they would appear in a plugin directory. + $custom_files = array( + UNIT_TESTS_PLUGIN_DIR . 'test-plugin-file-type-badly-named-files-errors/custom-file.php', + UNIT_TESTS_PLUGIN_DIR . 'test-plugin-file-type-badly-named-files-errors/Custom-File.php', + UNIT_TESTS_PLUGIN_DIR . 'test-plugin-file-type-badly-named-files-errors/custom-FILE.php', + ); + + // Invoke method with the Check_Result instance and custom file list. + $result = $check_files_method->invoke( $check, $check_result, $custom_files ); + + $errors = $check_result->get_errors(); + + $this->assertCount( 1, wp_list_filter( $errors['custom-file.php'][0][0], array( 'code' => 'case_sensitive_files' ) ) ); + + // Define the custom file list with duplicate folder names as they would appear in a plugin directory. + $custom_files = array( + UNIT_TESTS_PLUGIN_DIR . 'test-plugin-file-type-badly-named-files-errors/sub directory/file-1.php', + UNIT_TESTS_PLUGIN_DIR . 'test-plugin-file-type-badly-named-files-errors/Sub Directory/file-2.php', + ); + + // Invoke method with the Check_Result instance and custom file list. + $result = $check_files_method->invoke( $check, $check_result, $custom_files ); + $errors = $check_result->get_errors(); + + $this->assertCount( 1, wp_list_filter( $errors['sub directory/'][0][0], array( 'code' => 'case_sensitive_folders' ) ) ); + } + public function test_run_with_library_core_errors() { $check_context = new Check_Context( UNIT_TESTS_PLUGIN_DIR . 'test-plugin-file-type-library-core-errors/load.php' ); $check_result = new Check_Result( $check_context );