BossBey File Manager
PHP:
8.2.30
OS:
Linux
User:
imagivibe
Root
/
home
/
imagivibe
/
public_html
/
wp-content
/
plugins
/
robin-image-optimizer
/
libs
/
addons
/
includes
/
classes
📤 Upload
📝 New File
📁 New Folder
Close
Editing: class.folder.php
<?php // Exit if accessed directly if ( ! defined( 'ABSPATH' ) ) { exit; } /** * Класс для работы с кастомными папками. * * @version 1.0 */ class WRIO_Folder { /** * @var string Folder path. */ protected $path = ''; /** * @var string SHA256 folder's path hash. */ protected $uid = ''; /** * @var int Number of files in current folder. */ protected $files_count = 0; /** * @var int Number of optimized files in current folder. */ protected $optimized_count = 0; /** * @var int Number of errors in current folder. */ protected $errors_count = 0; /** * WRIO_Folder constructor. * * @param array $params List of params set on the model. */ public function __construct( $params = [] ) { // нужна проверка пути foreach ( $params as $key => $value ) { $this->set( $key, $value ); } if ( ! $this->uid ) { $this->uid = hash( 'sha256', $this->path ); } } /** * Get specified object's property. * * @param string $property_name Property name. * * @return bool */ public function get( $property_name ) { if ( isset( $this->$property_name ) ) { return $this->$property_name; } return false; } /** * Set specified object's property. * * @param string $property_name Property name. * @param mixed $value Value to set. */ public function set( $property_name, $value ) { if ( isset( $this->$property_name ) ) { $this->$property_name = $value; } } /** * Convert object to associative array form. * * @return array */ public function toArray() { return [ 'path' => $this->path, 'files_count' => $this->files_count, 'uid' => $this->uid, 'optimized_count' => $this->optimized_count, 'errors_count' => $this->errors_count, ]; } /** * Обходит каталог и добавляет в индекс файлы * * @param mixed $offset отступ от начала * @param mixed $max_process_elements кол-во элементов за итерацию * * @return int Кол-во элементов, обработанных при индексировании */ public function indexing( $offset = 0, $max_process_elements = 100 ) { global $wpdb; $iterator = $this->getRecursiveIterator(); $allowed = $this->getAllowedFilesExt(); $files = []; $db_table = RIO_Process_Queue::table_name(); foreach ( $iterator as $file ) { $ext = substr( $file, strrpos( strtolower( $file ), '.' ) + 1 ); // получаем расширение файла if ( in_array( strtolower( $ext ), $allowed ) ) { // сделать путь относительно корня $files[] = $this->real_path_to_relative( $file->getPathname() ); } } $files = array_slice( $files, $offset, $max_process_elements ); foreach ( $files as $file ) { $file = wp_normalize_path( $file ); // $file_path = str_replace( $this->path, '', $file ); $file_uid = hash( 'sha256', str_replace( wp_normalize_path( ABSPATH ), '', $file ) ); $sql = $wpdb->prepare( "SELECT * FROM {$db_table} WHERE item_hash_alternative = %s AND item_hash = %s;", $this->uid, $file_uid ); $row = $wpdb->get_row( $sql ); if ( empty( $row ) ) { // если файла нет в индексе - добавляем $extra_data = new WRIO_CF_Image_Extra_Data( [ 'file_path' => $file, 'folder_relative_path' => $this->path, ] ); $optimization_data = new RIO_Process_Queue( [ 'item_type' => 'cf_image', 'item_hash' => $file_uid, // хэш пути к файлу 'item_hash_alternative' => $this->uid, // хэш директории будет сделан сеттером 'original_size' => 0, 'final_size' => 0, 'original_mime_type' => '', 'final_mime_type' => '', 'result_status' => 'unoptimized', 'processing_level' => '', 'extra_data' => $extra_data, ] ); $optimization_data->save(); } else { // делаем апдейт и выставляем ласт индекс дату. Потом у кого в индексе ласт индекс дата меньше заданной, того уже нет на диске } } return count( $files ); // сколько элементов обработано при индексировании. } /** * Проверяет индекс на наличие несуществующих файлов. * * Находит файлы, которые пользователь удалил из папки, но в индексе они ещё есть. * Удаляет из из индекса, вычитает из статистики * * @param mixed $offset отсутп от начала * @param mixed $max_process_elements кол-во элементов за итерацию * * @return int $processed Кол-во обработанных записей. Используется для расчёта отступа */ public function syncIndex( $offset = 0, $max_process_elements = 100 ) { global $wpdb; $db_table = RIO_Process_Queue::table_name(); $sql = $wpdb->prepare( "SELECT * FROM {$db_table} WHERE item_hash_alternative = %s LIMIT %d OFFSET %d;", $this->uid, $max_process_elements, $offset ); $rows = $wpdb->get_results( $sql ); $image_statistics = WRIO_Image_Statistic_Folders::get_instance(); $processed = 0; $deleted = 0; if ( ! empty( $rows ) ) { foreach ( $rows as $row ) { ++$processed; $cf_image = new WRIO_Folder_Image( $row->id, $row ); if ( ! $cf_image->isFileExists() ) { if ( $cf_image->isOptimized() ) { // если файл оптимизирован - вычитаем из статистики $optimization_data = $cf_image->getOptimizationData(); $optimized_size = $optimization_data->get_final_size(); $original_size = $optimization_data->get_original_size(); $webp_optimized_size = $optimization_data->get_extra_data()->get_webp_main_size(); $image_statistics->deductFromField( 'webp_optimized_size', $webp_optimized_size ); $image_statistics->deductFromField( 'optimized_size', $optimized_size ); $image_statistics->deductFromField( 'original_size', $original_size ); } // если файла нет на диске - удаляем из индекса $wpdb->delete( $db_table, [ 'id' => $cf_image->get( 'id' ), ], [ '%d' ] ); ++$deleted; } } $image_statistics->save(); $this->reCountOptimizedFiles(); } $processed = $processed - $deleted; return $processed; } /** * Get allowed list of extensions. * * @return array */ public function getAllowedFilesExt() { $allowed_formats = explode( ',', WRIO_Plugin::app()->getOption( 'allowed_formats', 'image/jpeg,image/png,image/gif' ) ); $allowed = []; foreach ( $allowed_formats as $format ) { if ( $format == 'image/jpeg' ) { $allowed[] = 'jpg'; $allowed[] = 'jpeg'; } elseif ( $format == 'image/png' ) { $allowed[] = 'png'; } } // $allowed = [ 'jpg', 'jpeg', 'png' ]; return $allowed; } /** * Count number of files in a folder. * * @return int */ public function countFiles() { $iterator = $this->getRecursiveIterator(); $allowed = $this->getAllowedFilesExt(); $count = 0; foreach ( $iterator as $file ) { $ext = substr( $file, strrpos( strtolower( $file ), '.' ) + 1 ); // получаем расширение файла if ( in_array( strtolower( $ext ), $allowed ) ) { ++$count; } } return $count; } /** * Count number of indexes files. * * @return null|string */ public function countIndexedFiles() { global $wpdb; $db_table = RIO_Process_Queue::table_name(); $sql_files = $wpdb->prepare( "SELECT COUNT(*) FROM {$db_table} WHERE item_type = %s AND item_hash_alternative = %s;", 'cf_image', $this->uid ); $files_count = $wpdb->get_var( $sql_files ); return $files_count; } public function reCountFiles() { $this->files_count = $this->countFiles(); return $this->files_count; } /** * Recount optimized files. * * @return int|null|string */ public function reCountOptimizedFiles() { global $wpdb; $db_table = RIO_Process_Queue::table_name(); $sql = "SELECT COUNT(*) FROM {$db_table} WHERE item_type = %s AND result_status = %s AND item_hash_alternative = %s;"; $sql_prepared = $wpdb->prepare( $sql, 'cf_image', RIO_Process_Queue::STATUS_SUCCESS, $this->uid ); $optimized_count = $wpdb->get_var( $sql_prepared ); $this->optimized_count = $optimized_count; return $this->optimized_count; } /** * Remove folder and deduct its size from optimized and original size. */ public function remove() { // удаляем файлы из индекса и переситываем стату global $wpdb; $db_table = RIO_Process_Queue::table_name(); $sql = "SELECT SUM(original_size) AS original_size, SUM(final_size) AS optimized_size FROM {$db_table} WHERE item_type = %s AND result_status = %s AND item_hash_alternative = %s"; $prepared_sql = $wpdb->prepare( $sql, 'cf_image', RIO_Process_Queue::STATUS_SUCCESS, $this->uid ); $sum = $wpdb->get_row( $prepared_sql ); // Deduct from statistics $image_statistics = WRIO_Image_Statistic_Folders::get_instance(); $webp_optimized_size = WRIO_Plugin::app()->updateOption( 'webp_optimized_size', 0 ); $image_statistics->deductFromField( 'webp_optimized_size', $webp_optimized_size ); $image_statistics->deductFromField( 'optimized_size', $sum->optimized_size ); $image_statistics->deductFromField( 'original_size', $sum->original_size ); $image_statistics->save(); // Delete from db $wpdb->delete( $db_table, [ 'item_hash_alternative' => $this->uid, 'item_type' => 'cf_image', ], [ '%s', '%s' ] ); } /** * Get absolute path from relative. * * Same as 'wp_ajax_wriop_browse_dir'. * * @return bool|string */ public function real_path() { if ( is_main_site() ) { $base_path = get_home_path(); } else { $upload_dir = wp_upload_dir(); $base_path = $upload_dir['basedir'] . '/'; } return realpath( $base_path . $this->path ); } /** * Returns the directory path relative to the site root * Input: /home/user/test/wp.com/wp-content/uploads/custom-folder/ * Output: /wp-content/uploads/custom-folder/ * * @param string $path Путь к директории. Может быть абсолютным. * * Same as 'wp_ajax_wriop_browse_dir'. * * @return string $relative_path относительный путь */ public function real_path_to_relative( $path ) { if ( is_main_site() ) { $base_path = untrailingslashit( get_home_path() ); } else { $upload_dir = wp_upload_dir(); $base_path = untrailingslashit( $upload_dir['basedir'] ); } $relative_path = str_replace( $base_path, '', $path ); return $relative_path; } /** * Get iterator to go scan files in directory. * * @return RecursiveIteratorIterator */ public function getRecursiveIterator() { $iterator = new RecursiveDirectoryIterator( $this->real_path() ); return new RecursiveIteratorIterator( $iterator ); } }
Save
Cancel