/var/www/html_it/wp-content/plugins/woocommerce/src/Internal/Utilities/FilesystemUtil.php


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
<?php
declare( strict_types );

namespace 
Automattic\WooCommerce\Internal\Utilities;

use 
Automattic\Jetpack\Constants;
use 
Automattic\WooCommerce\Proxies\LegacyProxy;
use 
Exception;
use 
WP_Filesystem_Base;

/**
 * FilesystemUtil class.
 */
class FilesystemUtil {
    
/**
     * Wrapper to retrieve the class instance contained in the $wp_filesystem global, after initializing if necessary.
     *
     * @return WP_Filesystem_Base
     * @throws Exception Thrown when the filesystem fails to initialize.
     */
    
public static function get_wp_filesystem(): WP_Filesystem_Base {
        global 
$wp_filesystem;

        if ( ! 
$wp_filesystem instanceof WP_Filesystem_Base ) {
            
$initialized self::initialize_wp_filesystem();

            if ( 
false === $initialized ) {
                throw new 
Exception'The WordPress filesystem could not be initialized.' );
            }
        }

        return 
$wp_filesystem;
    }

    
/**
     * Get the WP filesystem method, with a fallback to 'direct' if no FS_METHOD constant exists and there are not FTP related options/credentials set.
     *
     * @return string|false The name of the WP filesystem method to use.
     */
    
public static function get_wp_filesystem_method_or_direct() {
        
$proxy wc_get_container()->getLegacyProxy::class );
        if ( ! 
self::constant_exists'FS_METHOD' ) && false === $proxy->call_function'get_option''ftp_credentials' ) && ! self::constant_exists'FTP_HOST' ) ) {
            return 
'direct';
        }

        
$method $proxy->call_function'get_filesystem_method' );
        if ( 
$method ) {
            return 
$method;
        }

        return 
'direct';
    }

    
/**
     * Check if a constant exists and is not null.
     *
     * @param string $name Constant name.
     * @return bool True if the constant exists and its value is not null.
     */
    
private static function constant_existsstring $name ): bool {
        return 
Constants::is_defined$name ) && ! is_nullConstants::get_constant$name ) );
    }

    
/**
     * Recursively creates a directory (if it doesn't exist) and adds an empty index.html and a .htaccess to prevent
     * directory listing.
     *
     * @since 9.3.0
     *
     * @param string $path Directory to create.
     * @throws \Exception In case of error.
     */
    
public static function mkdir_p_not_indexablestring $path ): void {
        
$wp_fs self::get_wp_filesystem();

        if ( 
$wp_fs->is_dir$path ) ) {
            return;
        }

        if ( ! 
wp_mkdir_p$path ) ) {
            throw new 
\Exceptionesc_htmlsprintf'Could not create directory: %s.'wp_basename$path ) ) ) );
        }

        
$files = array(
            
'.htaccess'  => 'deny from all',
            
'index.html' => '',
        );

        foreach ( 
$files as $name => $content ) {
            
$wp_fs->put_contentstrailingslashit$path ) . $name$content );
        }
    }

    
/**
     * Wrapper to initialize the WP filesystem with defined credentials if they are available.
     *
     * @return bool True if the $wp_filesystem global was successfully initialized.
     */
    
protected static function initialize_wp_filesystem(): bool {
        global 
$wp_filesystem;

        if ( 
$wp_filesystem instanceof WP_Filesystem_Base ) {
            return 
true;
        }

        require_once 
ABSPATH 'wp-admin/includes/file.php';

        
$method      self::get_wp_filesystem_method_or_direct();
        
$initialized false;

        if ( 
'direct' === $method ) {
            
$initialized WP_Filesystem();
        } elseif ( 
false !== $method ) {
            
// See https://core.trac.wordpress.org/changeset/56341.
            
ob_start();
            
$credentials request_filesystem_credentials'' );
            
ob_end_clean();

            
$initialized $credentials && WP_Filesystem$credentials );
        }

        return 
is_null$initialized ) ? false $initialized;
    }

    
/**
     * Validate that a file path is a valid upload path.
     *
     * @param string $path The path to validate.
     * @throws \Exception If the file path is not a valid upload path.
     */
    
public static function validate_upload_file_pathstring $path ): void {
        
$wp_filesystem self::get_wp_filesystem();

        
// File must exist and be readable.
        
$is_valid_file $wp_filesystem->is_readable$path );

        
// Check that file is within an allowed location.
        
if ( $is_valid_file ) {
            
$is_valid_file self::file_is_in_directory$path$wp_filesystem->abspath() );
            if ( ! 
$is_valid_file ) {
                
$upload_dir    wp_get_upload_dir();
                
$is_valid_file false === $upload_dir['error'] && self::file_is_in_directory$path$upload_dir['basedir'] );
            }
        }

        if ( ! 
$is_valid_file ) {
            throw new 
\Exceptionesc_html__'File path is not a valid upload path.''woocommerce' ) );
        }
    }

    
/**
     * Check if a given file is inside a given directory.
     *
     * @param string $file_path The full path of the file to check.
     * @param string $directory The path of the directory to check.
     * @return bool True if the file is inside the directory.
     */
    
private static function file_is_in_directorystring $file_pathstring $directory ): bool {
        
// Extract protocol if it exists.
        
$protocol '';
        if ( 
preg_match'#^([a-z0-9]+://)#i'$file_path$matches ) ) {
            
$protocol  $matches[1];
            
$file_path preg_replace'#^[a-z0-9]+://#i'''$file_path );
        }

        
$file_path = (string) new URL$file_path ); // This resolves '/../' sequences.
        
$file_path preg_replace'/^file:\\/\\//'$protocol$file_path );
        
$file_path preg_replace'/^file:\\/\\//'''$file_path );

        return 
=== striposwp_normalize_path$file_path ), trailingslashitwp_normalize_path$directory ) ) );
    }
}