Sindbad~EG File Manager
<?php
namespace WebpConverter\Conversion;
use WebpConverter\Conversion\Format\AvifFormat;
use WebpConverter\Conversion\Format\FormatFactory;
use WebpConverter\Conversion\Format\WebpFormat;
use WebpConverter\Error\Detector\RewritesErrorsDetector;
use WebpConverter\PluginData;
use WebpConverter\Service\ServerConfigurator;
use WebpConverter\Service\StatsManager;
use WebpConverter\Settings\Option\ExtraFeaturesOption;
use WebpConverter\Settings\Option\ServiceModeOption;
use WebpConverter\Settings\Option\SupportedDirectoriesOption;
use WebpConverter\Settings\Option\SupportedExtensionsOption;
/**
* Returns tree of paths to files to conversion.
*/
class FilesTreeFinder {
/**
* @var PluginData
*/
private $plugin_data;
/**
* @var ServerConfigurator
*/
private $server_configurator;
/**
* @var StatsManager
*/
private $stats_manager;
/**
* @var OutputPathGenerator
*/
private $output_path;
/**
* @var int[]
*/
private $files_converted;
/**
* @var int[]
*/
private $files_unconverted;
public function __construct(
PluginData $plugin_data,
FormatFactory $format_factory,
?ServerConfigurator $server_configurator = null,
?StatsManager $stats_manager = null,
?OutputPathGenerator $output_path = null
) {
$this->plugin_data = $plugin_data;
$this->server_configurator = $server_configurator ?: new ServerConfigurator();
$this->stats_manager = $stats_manager ?: new StatsManager();
$this->output_path = $output_path ?: new OutputPathGenerator( $format_factory );
}
/**
* Returns list of source images for directory.
*
* @param string[] $output_formats Allowed extensions.
*
* @return mixed[] {
* @type int[] $files_converted .
* @type int[] $files_unconverted .
* @type mixed[] $files_tree .
* }
* @internal
*/
public function get_tree( array $output_formats ): array {
$this->server_configurator->set_memory_limit();
$this->server_configurator->set_execution_time( 900 );
foreach ( $output_formats as $output_format ) {
$this->files_converted[ $output_format ] = 0;
$this->files_unconverted[ $output_format ] = 0;
}
$plugin_settings = $this->plugin_data->get_plugin_settings();
$force_convert_deleted = ( ! in_array( ExtraFeaturesOption::OPTION_VALUE_ONLY_SMALLER, $plugin_settings[ ExtraFeaturesOption::OPTION_NAME ] ) );
$force_convert_crashed = ( $plugin_settings[ ServiceModeOption::OPTION_NAME ] === 'yes' );
$values = [];
foreach ( $plugin_settings[ SupportedDirectoriesOption::OPTION_NAME ] as $dir_name ) {
$source_dir = apply_filters( 'webpc_dir_path', '', $dir_name );
$values[] = $this->find_tree_in_directory(
$source_dir,
$plugin_settings[ SupportedExtensionsOption::OPTION_NAME ],
$output_formats,
$force_convert_deleted,
$force_convert_crashed
);
}
$this->stats_manager->set_images_webp_all( ( $this->files_converted[ WebpFormat::FORMAT_EXTENSION ] ?? 0 ) + ( $this->files_unconverted[ WebpFormat::FORMAT_EXTENSION ] ?? 0 ) );
$this->stats_manager->set_images_webp_unconverted( $this->files_unconverted[ WebpFormat::FORMAT_EXTENSION ] ?? 0 );
$this->stats_manager->set_images_avif_all( ( $this->files_converted[ AvifFormat::FORMAT_EXTENSION ] ?? 0 ) + ( $this->files_unconverted[ AvifFormat::FORMAT_EXTENSION ] ?? 0 ) );
$this->stats_manager->set_images_avif_unconverted( $this->files_unconverted[ AvifFormat::FORMAT_EXTENSION ] ?? 0 );
return [
'files_converted' => $this->files_converted,
'files_unconverted' => $this->files_unconverted,
'files_tree' => $values,
];
}
/**
* Returns list of source images as tree.
*
* @param string $dir_path Server path of source directory.
* @param string[] $source_formats Allowed extensions.
* @param string[] $output_formats Allowed extensions.
* @param bool $force_convert_deleted Skip .deleted files.
* @param bool $force_convert_crashed Skip .crashed files.
* @param int $nesting_level .
*
* @return mixed[]
*/
private function find_tree_in_directory(
string $dir_path,
array $source_formats,
array $output_formats,
bool $force_convert_deleted,
bool $force_convert_crashed,
int $nesting_level = 0
): array {
$paths = scandir( $dir_path );
$list = [
'name' => basename( $dir_path ),
'items' => [],
'files' => [],
'count' => 0,
];
if ( ! is_array( $paths ) ) {
return $list;
}
if ( $nesting_level === 0 ) {
$paths = array_diff( $paths, [ basename( RewritesErrorsDetector::PATH_OUTPUT_FILE_PNG ) ] );
}
sort( $paths, SORT_NATURAL | SORT_FLAG_CASE );
foreach ( $paths as $path ) {
$current_path = $dir_path . '/' . $path;
if ( is_dir( $current_path ) ) {
if ( apply_filters( 'webpc_supported_source_directory', true, basename( $current_path ), $current_path ) ) {
$children = $this->find_tree_in_directory( $current_path, $source_formats, $output_formats, $force_convert_deleted, $force_convert_crashed, ( $nesting_level + 1 ) );
if ( $children['items'] || $children['files'] ) {
$list['items'][] = $children;
}
}
} else {
$filename = basename( $current_path );
$parts = array_reverse( explode( '.', $filename ) );
if ( in_array( strtolower( $parts[0] ), $source_formats ) && ! in_array( strtolower( $parts[1] ?? '' ), ExcludedPathsOperator::EXCLUDED_SUB_EXTENSIONS ) ) {
if ( apply_filters( 'webpc_supported_source_file', true, $filename, $current_path )
&& ! $this->is_converted_file( $current_path, $output_formats, $force_convert_deleted, $force_convert_crashed ) ) {
$list['files'][] = $path;
}
}
}
}
$list['count'] = $this->calculate_tree_count( $list );
return $list;
}
/**
* @param string $source_path .
* @param string[] $output_formats .
* @param bool $force_convert_deleted Skip .deleted files.
* @param bool $force_convert_crashed Skip .crashed files.
*
* @return bool
*/
private function is_converted_file( string $source_path, array $output_formats, bool $force_convert_deleted, bool $force_convert_crashed ): bool {
$is_not_converted = false;
foreach ( $output_formats as $output_format ) {
$output_path = $this->output_path->get_path( $source_path, false, $output_format );
if ( $output_path === null ) {
continue;
}
if ( file_exists( $output_path ) ) {
$this->files_converted[ $output_format ]++;
} elseif ( ! $force_convert_deleted && file_exists( $output_path . '.' . LargerFilesOperator::DELETED_FILE_EXTENSION ) ) {
$this->files_converted[ $output_format ]++;
} elseif ( ! $force_convert_crashed && file_exists( $output_path . '.' . CrashedFilesOperator::CRASHED_FILE_EXTENSION ) ) {
$this->files_converted[ $output_format ]++;
} else {
$this->files_unconverted[ $output_format ]++;
$is_not_converted = true;
}
}
return ! $is_not_converted;
}
/**
* @param mixed[] $tree .
*
* @return int
*/
private function calculate_tree_count( array $tree ): int {
$count = count( $tree['files'] );
foreach ( $tree['items'] as $tree_item ) {
$count += $this->calculate_tree_count( $tree_item );
}
return $count;
}
}
Sindbad File Manager Version 1.0, Coded By Sindbad EG ~ The Terrorists