= count( $filename_parts ) || $equal_number >= count( $base_dir_parts ) ) break; if ( $filename_parts[$equal_number] != $base_dir_parts[$equal_number] ) break; } $relative_dir = str_repeat( '../', count( $base_dir_parts ) - $equal_number ); $relative_dir .= implode( '/', array_slice( $filename_parts, $equal_number ) ); return $relative_dir; } /** * Returns open basedirs * * @return array */ static public function get_open_basedirs() { $open_basedir_ini = ini_get( 'open_basedir' ); $open_basedirs = ( W3TC_WIN ? preg_split( '~[;,]~', $open_basedir_ini ) : explode( ':', $open_basedir_ini ) ); $result = array(); foreach ( $open_basedirs as $open_basedir ) { $open_basedir = trim( $open_basedir ); if ( !empty( $open_basedir ) && $open_basedir != '' ) { $result[] = Util_Environment::realpath( $open_basedir ); } } return $result; } /** * Checks if path is restricted by open_basedir * * @param string $path * @return boolean */ static public function check_open_basedir( $path ) { $path = Util_Environment::realpath( $path ); $open_basedirs = Util_File::get_open_basedirs(); if ( !count( $open_basedirs ) ) { return true; } foreach ( $open_basedirs as $open_basedir ) { if ( strstr( $path, $open_basedir ) !== false ) { return true; } } return false; } /** * Get the octal file permission number of a file or directory. * * @param string $file File path. * @return int */ public static function get_file_permissions( $file ) { if ( function_exists( 'fileperms' ) && $fileperms = @fileperms( $file ) ) { // phpcs:ignore $fileperms = 0777 & $fileperms; } else { clearstatcache(); $stat = @stat( $file ); // phpcs:ignore WordPress.PHP.NoSilencedErrors.Discouraged if ( $stat ) { $fileperms = 0777 & $stat['mode']; } else { $fileperms = 0; } } return intval( decoct( $fileperms ) ); } static public function get_file_owner( $file = '' ) { $fileowner = $filegroup = 'unknown'; if ( $file ) { if ( function_exists( 'fileowner' ) && function_exists( 'fileowner' ) ) { $fileowner = @fileowner( $file ); $filegroup = @filegroup( $file ); if ( function_exists( 'posix_getpwuid' ) && function_exists( 'posix_getgrgid' ) ) { $fileowner = @posix_getpwuid( $fileowner ); $fileowner = $fileowner['name']; $filegroup = @posix_getgrgid( $filegroup ); $filegroup = $filegroup['name']; } } } else { if ( function_exists( 'getmyuid' ) && function_exists( 'getmygid' ) ) { $fileowner = @getmyuid(); $filegroup = @getmygid(); if ( function_exists( 'posix_getpwuid' ) && function_exists( 'posix_getgrgid' ) ) { $fileowner = @posix_getpwuid( $fileowner ); $fileowner = $fileowner['name']; $filegroup = @posix_getgrgid( $filegroup ); $filegroup = $filegroup['name']; } } } return $fileowner . ':' . $filegroup; } /** * Creates W3TC_CACHE_TMP_DIR dir if required * * @throws Exception * @return string */ static public function create_tmp_dir() { if ( !is_dir( W3TC_CACHE_TMP_DIR ) || !is_writable( W3TC_CACHE_TMP_DIR ) ) { Util_File::mkdir_from( W3TC_CACHE_TMP_DIR, W3TC_CACHE_DIR ); if ( !is_dir( W3TC_CACHE_TMP_DIR ) || !is_writable( W3TC_CACHE_TMP_DIR ) ) { $e = error_get_last(); $description = ( isset( $e['message'] ) ? $e['message'] : '' ); throw new \Exception( 'Can\'t create folder ' . W3TC_CACHE_TMP_DIR . ': ' . $description ); } } return W3TC_CACHE_TMP_DIR; } /** * Atomically writes file inside W3TC_CACHE_DIR dir * * @param unknown $filename * @param unknown $content * @throws Exception * @return void */ static public function file_put_contents_atomic( $filename, $content ) { Util_File::create_tmp_dir(); $temp = tempnam( W3TC_CACHE_TMP_DIR, 'temp' ); try { if ( !( $f = @fopen( $temp, 'wb' ) ) ) { if ( file_exists( $temp ) ) @unlink( $temp ); throw new \Exception( 'Can\'t write to temporary file ' . $temp . '' ); } fwrite( $f, $content ); fclose( $f ); if ( !@rename( $temp, $filename ) ) { @unlink( $filename ); if ( !@rename( $temp, $filename ) ) { Util_File::mkdir_from( dirname( $filename ), W3TC_CACHE_DIR ); if ( !@rename( $temp, $filename ) ) { throw new \Exception( 'Can\'t write to file ' . $filename . '' ); } } } $chmod = 0644; if ( defined( 'FS_CHMOD_FILE' ) ) $chmod = FS_CHMOD_FILE; @chmod( $filename, $chmod ); } catch ( \Exception $ex ) { if ( file_exists( $temp ) ) @unlink( $temp ); throw $ex; } } /** * Takes a W3TC settings array and formats it to a PHP String * * @param unknown $data * @return string */ static public function format_data_as_settings_file( $data ) { $config = " $value ) $config .= Util_File::format_array_entry_as_settings_file_entry( 1, $key, $value ); $config .= ");"; return $config; } /** * Writes array item to file * * @param int $tabs * @param string $key * @param mixed $value * @return string */ static public function format_array_entry_as_settings_file_entry( $tabs, $key, $value ) { $item = str_repeat( "\t", $tabs ); if ( is_numeric( $key ) && (string)(int)$key === (string)$key ) { $item .= sprintf( "%d => ", $key ); } else { $item .= sprintf( "'%s' => ", addcslashes( $key, "'\\" ) ); } switch ( gettype( $value ) ) { case 'object': case 'array': $item .= "array(\r\n"; foreach ( (array)$value as $k => $v ) { $item .= Util_File::format_array_entry_as_settings_file_entry( $tabs + 1, $k, $v ); } $item .= sprintf( "%s),\r\n", str_repeat( "\t", $tabs ) ); return $item; case 'integer': $data = (string)$value; break; case 'double': $data = (string)$value; break; case 'boolean': $data = ( $value ? 'true' : 'false' ); break; case 'NULL': $data = 'null'; break; default: case 'string': $data = "'" . addcslashes( $value, "'\\" ) . "'"; break; } $item .= $data . ",\r\n"; return $item; } }