PageRenderTime 37ms CodeModel.GetById 14ms RepoModel.GetById 0ms app.codeStats 0ms

/htdocs/wp-admin/includes/class-wp-filesystem-base.php

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