[44] | 1 | <?php
|
---|
| 2 | /**
|
---|
| 3 | * Base WordPress Filesystem.
|
---|
| 4 | *
|
---|
| 5 | * @package WordPress
|
---|
| 6 | * @subpackage Filesystem
|
---|
| 7 | */
|
---|
| 8 |
|
---|
| 9 | /**
|
---|
| 10 | * Base WordPress Filesystem class for which Filesystem implementations extend
|
---|
| 11 | *
|
---|
| 12 | * @since 2.5
|
---|
| 13 | */
|
---|
| 14 | class WP_Filesystem_Base {
|
---|
| 15 | /**
|
---|
| 16 | * Whether to display debug data for the connection or not.
|
---|
| 17 | *
|
---|
| 18 | * @since 2.5
|
---|
| 19 | * @access public
|
---|
| 20 | * @var bool
|
---|
| 21 | */
|
---|
| 22 | var $verbose = false;
|
---|
| 23 | /**
|
---|
| 24 | * Cached list of local filepaths to maped remote filepaths.
|
---|
| 25 | *
|
---|
| 26 | * @since 2.7
|
---|
| 27 | * @access private
|
---|
| 28 | * @var array
|
---|
| 29 | */
|
---|
| 30 | var $cache = array();
|
---|
| 31 |
|
---|
| 32 | /**
|
---|
| 33 | * The Access method of the current connection, Set automatically.
|
---|
| 34 | *
|
---|
| 35 | * @since 2.5
|
---|
| 36 | * @access public
|
---|
| 37 | * @var string
|
---|
| 38 | */
|
---|
| 39 | var $method = '';
|
---|
| 40 |
|
---|
| 41 | /**
|
---|
| 42 | * Returns the path on the remote filesystem of ABSPATH
|
---|
| 43 | *
|
---|
| 44 | * @since 2.7
|
---|
| 45 | * @access public
|
---|
| 46 | * @return string The location of the remote path.
|
---|
| 47 | */
|
---|
| 48 | function abspath() {
|
---|
| 49 | $folder = $this->find_folder(ABSPATH);
|
---|
| 50 | //Perhaps the FTP folder is rooted at the WordPress install, Check for wp-includes folder in root, Could have some false positives, but rare.
|
---|
| 51 | if ( ! $folder && $this->is_dir('/wp-includes') )
|
---|
| 52 | $folder = '/';
|
---|
| 53 | return $folder;
|
---|
| 54 | }
|
---|
| 55 | /**
|
---|
| 56 | * Returns the path on the remote filesystem of WP_CONTENT_DIR
|
---|
| 57 | *
|
---|
| 58 | * @since 2.7
|
---|
| 59 | * @access public
|
---|
| 60 | * @return string The location of the remote path.
|
---|
| 61 | */
|
---|
| 62 | function wp_content_dir() {
|
---|
| 63 | return $this->find_folder(WP_CONTENT_DIR);
|
---|
| 64 | }
|
---|
| 65 | /**
|
---|
| 66 | * Returns the path on the remote filesystem of WP_PLUGIN_DIR
|
---|
| 67 | *
|
---|
| 68 | * @since 2.7
|
---|
| 69 | * @access public
|
---|
| 70 | *
|
---|
| 71 | * @return string The location of the remote path.
|
---|
| 72 | */
|
---|
| 73 | function wp_plugins_dir() {
|
---|
| 74 | return $this->find_folder(WP_PLUGIN_DIR);
|
---|
| 75 | }
|
---|
| 76 | /**
|
---|
| 77 | * Returns the path on the remote filesystem of the Themes Directory
|
---|
| 78 | *
|
---|
| 79 | * @since 2.7
|
---|
| 80 | * @access public
|
---|
| 81 | *
|
---|
| 82 | * @return string The location of the remote path.
|
---|
| 83 | */
|
---|
| 84 | function wp_themes_dir() {
|
---|
| 85 | return $this->wp_content_dir() . '/themes';
|
---|
| 86 | }
|
---|
| 87 |
|
---|
| 88 | /**
|
---|
| 89 | * Locates a folder on the remote filesystem.
|
---|
| 90 | *
|
---|
| 91 | * Deprecated; use WP_Filesystem::abspath() or WP_Filesystem::wp_*_dir() methods instead.
|
---|
| 92 | *
|
---|
| 93 | * @since 2.5
|
---|
| 94 | * @deprecated 2.7
|
---|
| 95 | * @access public
|
---|
| 96 | *
|
---|
| 97 | * @param string $base The folder to start searching from
|
---|
| 98 | * @param bool $echo True to display debug information
|
---|
| 99 | * @return string The location of the remote path.
|
---|
| 100 | */
|
---|
| 101 | function find_base_dir($base = '.', $echo = false) {
|
---|
| 102 | _deprecated_function(__FUNCTION__, '2.7', 'WP_Filesystem::abspath() or WP_Filesystem::wp_*_dir()' );
|
---|
| 103 | $this->verbose = $echo;
|
---|
| 104 | return $this->abspath();
|
---|
| 105 | }
|
---|
| 106 | /**
|
---|
| 107 | * Locates a folder on the remote filesystem.
|
---|
| 108 | *
|
---|
| 109 | * Deprecated; use WP_Filesystem::abspath() or WP_Filesystem::wp_*_dir() methods instead.
|
---|
| 110 | *
|
---|
| 111 | * @since 2.5
|
---|
| 112 | * @deprecated 2.7
|
---|
| 113 | * @access public
|
---|
| 114 | *
|
---|
| 115 | * @param string $base The folder to start searching from
|
---|
| 116 | * @param bool $echo True to display debug information
|
---|
| 117 | * @return string The location of the remote path.
|
---|
| 118 | */
|
---|
| 119 | function get_base_dir($base = '.', $echo = false) {
|
---|
| 120 | _deprecated_function(__FUNCTION__, '2.7', 'WP_Filesystem::abspath() or WP_Filesystem::wp_*_dir()' );
|
---|
| 121 | $this->verbose = $echo;
|
---|
| 122 | return $this->abspath();
|
---|
| 123 | }
|
---|
| 124 |
|
---|
| 125 | /**
|
---|
| 126 | * Locates a folder on the remote filesystem.
|
---|
| 127 | *
|
---|
| 128 | * Assumes that on Windows systems, Stripping off the Drive letter is OK
|
---|
| 129 | * Sanitizes \\ to / in windows filepaths.
|
---|
| 130 | *
|
---|
| 131 | * @since 2.7
|
---|
| 132 | * @access public
|
---|
| 133 | *
|
---|
| 134 | * @param string $folder the folder to locate
|
---|
| 135 | * @return string The location of the remote path.
|
---|
| 136 | */
|
---|
| 137 | function find_folder($folder) {
|
---|
| 138 |
|
---|
| 139 | if ( strpos($this->method, 'ftp') !== false ) {
|
---|
| 140 | $constant_overrides = array( 'FTP_BASE' => ABSPATH, 'FTP_CONTENT_DIR' => WP_CONTENT_DIR, 'FTP_PLUGIN_DIR' => WP_PLUGIN_DIR );
|
---|
| 141 | foreach ( $constant_overrides as $constant => $dir )
|
---|
| 142 | if ( defined($constant) && $folder === $dir )
|
---|
| 143 | return trailingslashit(constant($constant));
|
---|
| 144 | } elseif ( 'direct' == $this->method ) {
|
---|
| 145 | return trailingslashit($folder);
|
---|
| 146 | }
|
---|
| 147 |
|
---|
| 148 | $folder = preg_replace('|^([a-z]{1}):|i', '', $folder); //Strip out windows driveletter if its there.
|
---|
| 149 | $folder = str_replace('\\', '/', $folder); //Windows path sanitiation
|
---|
| 150 |
|
---|
| 151 | if ( isset($this->cache[ $folder ] ) )
|
---|
| 152 | return $this->cache[ $folder ];
|
---|
| 153 |
|
---|
| 154 | if ( $this->exists($folder) ) { //Folder exists at that absolute path.
|
---|
| 155 | $folder = trailingslashit($folder);
|
---|
| 156 | $this->cache[ $folder ] = $folder;
|
---|
| 157 | return $folder;
|
---|
| 158 | }
|
---|
| 159 | if( $return = $this->search_for_folder($folder) )
|
---|
| 160 | $this->cache[ $folder ] = $return;
|
---|
| 161 | return $return;
|
---|
| 162 | }
|
---|
| 163 |
|
---|
| 164 | /**
|
---|
| 165 | * Locates a folder on the remote filesystem.
|
---|
| 166 | *
|
---|
| 167 | * Expects Windows sanitized path
|
---|
| 168 | *
|
---|
| 169 | * @since 2.7
|
---|
| 170 | * @access private
|
---|
| 171 | *
|
---|
| 172 | * @param string $folder the folder to locate
|
---|
| 173 | * @param string $base the folder to start searching from
|
---|
| 174 | * @param bool $loop if the function has recursed, Internal use only
|
---|
| 175 | * @return string The location of the remote path.
|
---|
| 176 | */
|
---|
| 177 | function search_for_folder($folder, $base = '.', $loop = false ) {
|
---|
| 178 | if ( empty( $base ) || '.' == $base )
|
---|
| 179 | $base = trailingslashit($this->cwd());
|
---|
| 180 |
|
---|
| 181 | $folder = untrailingslashit($folder);
|
---|
| 182 |
|
---|
| 183 | $folder_parts = explode('/', $folder);
|
---|
| 184 | $last_path = $folder_parts[ count($folder_parts) - 1 ];
|
---|
| 185 |
|
---|
| 186 | $files = $this->dirlist( $base );
|
---|
| 187 |
|
---|
| 188 | foreach ( $folder_parts as $key ) {
|
---|
| 189 | if ( $key == $last_path )
|
---|
| 190 | continue; //We want this to be caught by the next code block.
|
---|
| 191 |
|
---|
| 192 | //Working from /home/ to /user/ to /wordpress/ see if that file exists within the current folder,
|
---|
| 193 | // If its found, change into it and follow through looking for it.
|
---|
| 194 | // If it cant find WordPress down that route, it'll continue onto the next folder level, and see if that matches, and so on.
|
---|
| 195 | // If it reaches the end, and still cant find it, it'll return false for the entire function.
|
---|
| 196 | if ( isset($files[ $key ]) ){
|
---|
| 197 | //Lets try that folder:
|
---|
| 198 | $newdir = trailingslashit(path_join($base, $key));
|
---|
| 199 | if ( $this->verbose )
|
---|
| 200 | printf( __('Changing to %s') . '<br/>', $newdir );
|
---|
| 201 | if ( $ret = $this->search_for_folder( $folder, $newdir, $loop) )
|
---|
| 202 | return $ret;
|
---|
| 203 | }
|
---|
| 204 | }
|
---|
| 205 |
|
---|
| 206 | //Only check this as a last resort, to prevent locating the incorrect install. All above proceeedures will fail quickly if this is the right branch to take.
|
---|
| 207 | if (isset( $files[ $last_path ] ) ) {
|
---|
| 208 | if ( $this->verbose )
|
---|
| 209 | printf( __('Found %s') . '<br/>', $base . $last_path );
|
---|
| 210 | return trailingslashit($base . $last_path);
|
---|
| 211 | }
|
---|
| 212 | if ( $loop )
|
---|
| 213 | return false;//Prevent tihs function looping again.
|
---|
| 214 | //As an extra last resort, Change back to / if the folder wasnt found. This comes into effect when the CWD is /home/user/ but WP is at /var/www/.... mainly dedicated setups.
|
---|
| 215 | return $this->search_for_folder($folder, '/', true);
|
---|
| 216 |
|
---|
| 217 | }
|
---|
| 218 |
|
---|
| 219 | /**
|
---|
| 220 | * Returns the *nix style file permissions for a file
|
---|
| 221 | *
|
---|
| 222 | * From the PHP documentation page for fileperms()
|
---|
| 223 | *
|
---|
| 224 | * @link http://docs.php.net/fileperms
|
---|
| 225 | * @since 2.5
|
---|
| 226 | * @access public
|
---|
| 227 | *
|
---|
| 228 | * @param string $file string filename
|
---|
| 229 | * @return int octal representation of permissions
|
---|
| 230 | */
|
---|
| 231 | function gethchmod($file){
|
---|
| 232 | $perms = $this->getchmod($file);
|
---|
| 233 | if (($perms & 0xC000) == 0xC000) // Socket
|
---|
| 234 | $info = 's';
|
---|
| 235 | elseif (($perms & 0xA000) == 0xA000) // Symbolic Link
|
---|
| 236 | $info = 'l';
|
---|
| 237 | elseif (($perms & 0x8000) == 0x8000) // Regular
|
---|
| 238 | $info = '-';
|
---|
| 239 | elseif (($perms & 0x6000) == 0x6000) // Block special
|
---|
| 240 | $info = 'b';
|
---|
| 241 | elseif (($perms & 0x4000) == 0x4000) // Directory
|
---|
| 242 | $info = 'd';
|
---|
| 243 | elseif (($perms & 0x2000) == 0x2000) // Character special
|
---|
| 244 | $info = 'c';
|
---|
| 245 | elseif (($perms & 0x1000) == 0x1000)// FIFO pipe
|
---|
| 246 | $info = 'p';
|
---|
| 247 | else // Unknown
|
---|
| 248 | $info = 'u';
|
---|
| 249 |
|
---|
| 250 | // Owner
|
---|
| 251 | $info .= (($perms & 0x0100) ? 'r' : '-');
|
---|
| 252 | $info .= (($perms & 0x0080) ? 'w' : '-');
|
---|
| 253 | $info .= (($perms & 0x0040) ?
|
---|
| 254 | (($perms & 0x0800) ? 's' : 'x' ) :
|
---|
| 255 | (($perms & 0x0800) ? 'S' : '-'));
|
---|
| 256 |
|
---|
| 257 | // Group
|
---|
| 258 | $info .= (($perms & 0x0020) ? 'r' : '-');
|
---|
| 259 | $info .= (($perms & 0x0010) ? 'w' : '-');
|
---|
| 260 | $info .= (($perms & 0x0008) ?
|
---|
| 261 | (($perms & 0x0400) ? 's' : 'x' ) :
|
---|
| 262 | (($perms & 0x0400) ? 'S' : '-'));
|
---|
| 263 |
|
---|
| 264 | // World
|
---|
| 265 | $info .= (($perms & 0x0004) ? 'r' : '-');
|
---|
| 266 | $info .= (($perms & 0x0002) ? 'w' : '-');
|
---|
| 267 | $info .= (($perms & 0x0001) ?
|
---|
| 268 | (($perms & 0x0200) ? 't' : 'x' ) :
|
---|
| 269 | (($perms & 0x0200) ? 'T' : '-'));
|
---|
| 270 | return $info;
|
---|
| 271 | }
|
---|
| 272 |
|
---|
| 273 | /**
|
---|
| 274 | * Converts *nix style file permissions to a octal number.
|
---|
| 275 | *
|
---|
| 276 | * Converts '-rw-r--r--' to 0644
|
---|
| 277 | * From "info at rvgate dot nl"'s comment on the PHP documentation for chmod()
|
---|
| 278 | *
|
---|
| 279 | * @link http://docs.php.net/manual/en/function.chmod.php#49614
|
---|
| 280 | * @since 2.5
|
---|
| 281 | * @access public
|
---|
| 282 | *
|
---|
| 283 | * @param string $mode string *nix style file permission
|
---|
| 284 | * @return int octal representation
|
---|
| 285 | */
|
---|
| 286 | function getnumchmodfromh($mode) {
|
---|
| 287 | $realmode = '';
|
---|
| 288 | $legal = array('', 'w', 'r', 'x', '-');
|
---|
| 289 | $attarray = preg_split('//', $mode);
|
---|
| 290 |
|
---|
| 291 | for($i=0; $i < count($attarray); $i++)
|
---|
| 292 | if($key = array_search($attarray[$i], $legal))
|
---|
| 293 | $realmode .= $legal[$key];
|
---|
| 294 |
|
---|
| 295 | $mode = str_pad($realmode, 9, '-');
|
---|
| 296 | $trans = array('-'=>'0', 'r'=>'4', 'w'=>'2', 'x'=>'1');
|
---|
| 297 | $mode = strtr($mode,$trans);
|
---|
| 298 |
|
---|
| 299 | $newmode = '';
|
---|
| 300 | $newmode .= $mode[0] + $mode[1] + $mode[2];
|
---|
| 301 | $newmode .= $mode[3] + $mode[4] + $mode[5];
|
---|
| 302 | $newmode .= $mode[6] + $mode[7] + $mode[8];
|
---|
| 303 | return $newmode;
|
---|
| 304 | }
|
---|
| 305 |
|
---|
| 306 | /**
|
---|
| 307 | * Determines if the string provided contains binary characters.
|
---|
| 308 | *
|
---|
| 309 | * @since 2.7
|
---|
| 310 | * @access private
|
---|
| 311 | *
|
---|
| 312 | * @param string $text String to test against
|
---|
| 313 | * @return bool true if string is binary, false otherwise
|
---|
| 314 | */
|
---|
| 315 | function is_binary( $text ) {
|
---|
| 316 | return (bool) preg_match('|[^\x20-\x7E]|', $text); //chr(32)..chr(127)
|
---|
| 317 | }
|
---|
| 318 | }
|
---|
| 319 |
|
---|
| 320 | ?>
|
---|