Server IP : 172.67.157.199 / Your IP : 3.140.196.185 [ Web Server : Apache System : Linux b70eb322-3aee-0c53-7c82-0db91281f2c6.secureserver.net 6.1.90-1.el9.elrepo.x86_64 #1 SMP PREEMPT_DYNAMIC Thu May 2 12:09:22 EDT 2024 x86_64 User : root ( 0) PHP Version : 8.0.30.2 Disable Function : NONE Domains : 0 Domains MySQL : ON | cURL : ON | WGET : ON | Perl : OFF | Python : OFF | Sudo : OFF | Pkexec : OFF Directory : /var/www/wp-content/plugins/defender-security/framework/base/ |
Upload File : |
<?php /** * Base file class. * * @package Calotes\Base */ namespace Calotes\Base; use FilesystemIterator; use RecursiveIteratorIterator; use RecursiveDirectoryIterator; use RecursiveCallbackFilterIterator; /** * Represents a file object and provides methods for retrieving directory tree. */ class File { const ENGINE_SPL = 'spl', ENGINE_SCANDIR = 'scan_dir', ENGINE_OPENDIR = 'open_dir'; /** * Engine use to create a dir tree * * @var string */ public $engine = ''; /** * Absolute path to a folder need to create a dir tre * * @var string */ public $path = ''; /** * Is the result including file? * * @var bool */ public $include_file = true; /** * Is the result include dir * * @var bool */ public $include_dir = true; /** * Whether to include hidden files/directories. * * @var bool */ public $include_hidden = false; /** * This is where to define the rules for exclude files out of the result * 'ext'=>array('jpg','gif') file extension you don't want appear in the result * 'path'=>array('/tmp/file1.txt','/tmp/file2') absolute path to files * 'dir'=>array('/tmp/','/dir/') absolute path to the directory you dont want to include files * 'filename'=>array('abc*') file name you don't want to include, can be regex, * * @var array */ public $exclude = array(); /** * This is where to define the rules for include files, please note that if $include is provided, the $exclude * will get ignored * 'ext'=>array('jpg','gif') file extension you don't want appear in the result * 'path'=>array('/tmp/file1.txt','/tmp/file2') absolute path to files * 'dir'=>array('/tmp/','/dir/') absolute path to the directory you dont want to include files * 'filename'=>array('abc*') file name you don't want to include, can be regex. * * @var array */ public $include = array(); /** * Does this search recursive * * @var bool */ public $is_recursive = true; /** * If provided, only search file smaller than this * * @var bool */ public $max_filesize = false; /** * Constructor for the File class. * * @param string $path The path to the directory. * @param bool $include_file Whether to include files in the directory. * @param bool $include_dir Whether to include directories in the directory. * @param array $include_rules The rules for including files/directories. * @param array $exclude The rules for excluding files/directories. * @param bool $is_recursive Whether to recursively search the directory. * @param bool $include_hidden Whether to include hidden files/directories. * @param bool $max_filesize The maximum filesize to include. */ public function __construct( $path, $include_file = true, $include_dir = false, $include_rules = array(), $exclude = array(), $is_recursive = true, $include_hidden = false, $max_filesize = false ) { $this->path = $path; $this->include_file = $include_file; $this->include_dir = $include_dir; $this->include = $include_rules; $this->exclude = $exclude; $this->is_recursive = $is_recursive; $this->engine = self::ENGINE_SCANDIR; $this->include_hidden = $include_hidden; $this->max_filesize = $max_filesize; } /** * Retrieves the directory tree based on the specified engine. * * @return array The directory tree. */ public function get_dir_tree() { $result = array(); if ( ! is_dir( $this->path ) ) { return $result; } if ( self::ENGINE_SPL === $this->engine ) { $result = $this->get_dir_tree_by_spl(); } elseif ( self::ENGINE_SCANDIR === $this->engine ) { $result = $this->get_dir_tree_by_scandir(); } elseif ( self::ENGINE_OPENDIR === $this->engine ) { $result = $this->get_dir_tree_by_open_dir(); } return $result; } /** * Create a dir tree by SPL library * * @return array */ private function get_dir_tree_by_spl() { $path = $this->path; $data = array(); if ( $this->is_recursive ) { $directory_flag = FilesystemIterator::KEY_AS_PATHNAME | FilesystemIterator::CURRENT_AS_FILEINFO | FilesystemIterator::UNIX_PATHS | FilesystemIterator::SKIP_DOTS; $directory = new RecursiveDirectoryIterator( $path, $directory_flag ); if ( ! empty( $this->include ) || ! empty( $this->exclude ) ) { $directory = new RecursiveCallbackFilterIterator( $directory, array( &$this, 'filter_directory', ) ); } $tree = new RecursiveIteratorIterator( $directory, RecursiveIteratorIterator::SELF_FIRST ); if ( true !== $this->is_recursive ) { $tree->setMaxDepth( $this->is_recursive ); } } else { $tree = new FilesystemIterator( $path ); } foreach ( $tree as $file ) { $real_path = $file->getRealPath(); $is_hidden = explode( DIRECTORY_SEPARATOR . '.', $real_path ); if ( count( $is_hidden ) > 1 && false === $this->include_hidden ) { continue; } if ( false === $this->is_recursive ) { // Have to filter this, for un recursive. if ( ! empty( $this->include ) || ! empty( $this->exclude ) ) { if ( false === $this->filter_directory( $real_path ) ) { continue; } } } if ( false === $this->include_file && $file->isFile() ) { continue; } if ( false === $this->include_dir && $file->isDir() ) { continue; } if ( $file->isFile() && is_numeric( $this->max_filesize ) ) { // Convert max to bytes. $max_size = $this->max_filesize * ( pow( 1024, 2 ) ); if ( $file->getSize() > $max_size ) { continue; } } $data[] = $real_path; } return $data; } /** * Retrieves the directory tree using the scandir function. * * @param string|null $path The path of the directory to retrieve the tree from. If null, it uses the path * property of the object. * * @return array The array containing the directory tree. */ private function get_dir_tree_by_scandir( $path = null ) { if ( is_null( $path ) ) { $path = $this->path; } $path = rtrim( $path, DIRECTORY_SEPARATOR ) . DIRECTORY_SEPARATOR; $rfiles = scandir( $path ); $data = array(); foreach ( $rfiles as $rfile ) { if ( '.' === $rfile || '..' === $rfile ) { continue; } if ( '.' === substr( pathinfo( $rfile, PATHINFO_BASENAME ), 0, 1 ) && false === $this->include_hidden ) { // Hidden files, move on. continue; } $real_path = $path . $rfile; $type = filetype( $real_path ); if ( ( ! empty( $this->include ) || ! empty( $this->exclude ) ) && ( false === $this->filter_directory( $real_path, $type ) ) ) { continue; } if ( 'file' === $type && true === $this->include_file ) { if ( is_numeric( $this->max_filesize ) ) { $max_size = $this->max_filesize * ( pow( 1024, 2 ) ); if ( filesize( $real_path ) > $max_size ) { continue; } else { $data[] = $real_path; } } else { $data[] = $real_path; } } if ( 'dir' === $type ) { if ( $this->include_dir ) { $data[] = $real_path; } if ( $this->is_recursive ) { $tdata = $this->get_dir_tree_by_scandir( $real_path ); $data = array_merge( $data, $tdata ); } } } return $data; } /** * Query files on path using opendir&readir * * @param mixed $path The path of the directory to retrieve the tree from. * * @return array * @since 1.0.5 */ private function get_dir_tree_by_open_dir( $path = null ) { if ( is_null( $path ) ) { $path = $this->path; } $path = rtrim( $path, DIRECTORY_SEPARATOR ) . DIRECTORY_SEPARATOR; $data = array(); $dh = opendir( $path ); if ( $dh ) { // Assignment in condition is for comparison. while ( ( $file = readdir( $dh ) ) !== false ) { // phpcs:ignore Generic.CodeAnalysis.AssignmentInCondition.FoundInWhileCondition if ( '.' === $file || '..' === $file ) { continue; } $real_path = $path . $file; if ( '.' === substr( pathinfo( $real_path, PATHINFO_BASENAME ), 0, 1 ) ) { // Hidden files, move on. continue; } if ( ( ! empty( $this->include ) || ! empty( $this->exclude ) ) && ( false === $this->filter_directory( $real_path ) ) ) { continue; } $type = filetype( $real_path ); if ( 'file' === $type && true === $this->include_file ) { if ( is_numeric( $this->max_filesize ) ) { $max_size = $this->max_filesize * ( pow( 1024, 2 ) ); if ( filesize( $real_path ) > $max_size ) { continue; } else { $data[] = $real_path; } } else { $data[] = $real_path; } } if ( 'dir' === $type ) { if ( $this->include_dir ) { $data[] = $real_path; } if ( $this->is_recursive ) { $tdata = $this->get_dir_tree_by_open_dir( $real_path ); $data = array_merge( $data, $tdata ); } } } closedir( $dh ); } return $data; } /** * Filter for recursive directory tree * * @param mixed $current The path of the directory. * @param mixed $filetype The type of the file. * * @return bool|void */ public function filter_directory( $current, $filetype = null ) { if ( ! empty( $this->include ) ) { return $this->filter_include( $current, $filetype ); } elseif ( ! empty( $this->exclude ) ) { return $this->filter_exclude( $current, $filetype ); } } /** * Filter directories based on inclusion rules. * * @param string $path The path of the directory to be filtered. * @param string|null $filetype The type of the file to be filtered. Default is null. * * @return bool Returns true if the directory passes the inclusion rules, false otherwise. */ private function filter_include( $path, $filetype = null ) { $include = $this->include; $exclude = $this->exclude; $applied = 0; $dir_include = isset( $include['dir'] ) ? $include['dir'] : array(); $dir_exclude = isset( $exclude['dir'] ) ? $exclude['dir'] : array(); if ( ! is_null( $filetype ) ) { $type = $filetype; } else { $type = filetype( $path ); } if ( is_array( $dir_include ) && count( $dir_include ) ) { if ( is_array( $dir_exclude ) ) { foreach ( $dir_exclude as $dir ) { if ( 0 === strpos( $path, $dir ) ) { // exclude matched, we won't list this. Move to next loop. continue; } } } foreach ( $dir_include as $dir ) { if ( 0 === strpos( $path, $dir ) ) { return true; } } ++$applied; } // Next extension. $ext_include = isset( $include['ext'] ) ? $include['ext'] : array(); if ( is_array( $ext_include ) && count( $ext_include ) && 'file' === $type ) { // We will uses foreach and strcasecmp instead of regex cause it faster. foreach ( $ext_include as $ext ) { if ( strcasecmp( pathinfo( $path, PATHINFO_EXTENSION ), $ext ) === 0 ) { // Match. return true; } } ++$applied; } // Now filename. $filename_include = isset( $include['filename'] ) ? $include['filename'] : array(); if ( is_array( $filename_include ) && count( $filename_include ) && 'file' === $type ) { foreach ( $filename_include as $filename ) { if ( preg_match( '/' . $filename . '/', pathinfo( $path, PATHINFO_BASENAME ) ) ) { return true; } } ++$applied; } // Now abs path. $path_include = isset( $include['path'] ) ? $include['path'] : array(); if ( is_array( $path_include ) && count( $path_include ) && 'file' === $type ) { foreach ( $path_include as $p ) { if ( strcmp( $p, $path ) === 0 ) { return true; } } ++$applied; } if ( 0 === $applied ) { return true; } return false; } /** * Filter out excluded files or directories based on different criteria. * * @param string $path The path of the file or directory to be checked. * @param string|null $filetype The type of the file or directory. If null, it will be determined using the * `filetype` function. * * @return bool Returns true if the file or directory should be included, false otherwise. */ private function filter_exclude( $path, $filetype = null ) { $exclude = $this->exclude; // First filer dir, or file inside dir. if ( ! is_null( $filetype ) ) { $type = $filetype; } else { $type = filetype( $path ); } $dir_exclude = isset( $exclude['dir'] ) ? $exclude['dir'] : array(); if ( is_array( $dir_exclude ) && count( $dir_exclude ) ) { foreach ( $dir_exclude as $dir ) { if ( strpos( $path, $dir ) === 0 ) { return false; } } } // Next extension. $ext_exclude = isset( $exclude['ext'] ) ? $exclude['ext'] : array(); if ( is_array( $ext_exclude ) && count( $ext_exclude ) && 'file' === $type ) { // We will use foreach and strcasecmp instead of regex cause it faster. foreach ( $ext_exclude as $ext ) { if ( strcasecmp( pathinfo( $path, PATHINFO_EXTENSION ), $ext ) === 0 ) { // Match. return false; } } } // Now filename. $filename_exclude = isset( $exclude['filename'] ) ? $exclude['filename'] : array(); if ( is_array( $filename_exclude ) && count( $filename_exclude ) && 'file' === $type ) { foreach ( $filename_exclude as $filename ) { if ( preg_match( '/' . $filename . '/', pathinfo( $path, PATHINFO_BASENAME ) ) ) { return false; } } } // Now abs path. $path_exclude = isset( $exclude['path'] ) ? $exclude['path'] : array(); if ( is_array( $path_exclude ) && count( $path_exclude ) && 'file' === $type ) { foreach ( $path_exclude as $p ) { if ( strcmp( $p, $path ) === 0 ) { return false; } } } return true; } }