WP_Filesystem_Direct

WordPress Filesystem Class for direct PHP file and folder manipulation.

Defined (1)

The class is defined in the following location(s).

/wp-admin/includes/class-wp-filesystem-direct.php  
  1. class WP_Filesystem_Direct extends WP_Filesystem_Base { 
  2.  
  3. /** 
  4. * constructor 
  5. * @access public 
  6. * @param mixed $arg ignored argument 
  7. */ 
  8. public function __construct($arg) { 
  9. $this->method = 'direct'; 
  10. $this->errors = new WP_Error(); 
  11.  
  12. /** 
  13. * Reads entire file into a string 
  14. * @access public 
  15. * @param string $file Name of the file to read. 
  16. * @return string|bool The function returns the read data or false on failure. 
  17. */ 
  18. public function get_contents($file) { 
  19. return @file_get_contents($file); 
  20.  
  21. /** 
  22. * Reads entire file into an array 
  23. * @access public 
  24. * @param string $file Path to the file. 
  25. * @return array|bool the file contents in an array or false on failure. 
  26. */ 
  27. public function get_contents_array($file) { 
  28. return @file($file); 
  29.  
  30. /** 
  31. * Write a string to a file 
  32. * @access public 
  33. * @param string $file Remote path to the file where to write the data. 
  34. * @param string $contents The data to write. 
  35. * @param int $mode Optional. The file permissions as octal number, usually 0644. 
  36. * Default false. 
  37. * @return bool False upon failure, true otherwise. 
  38. */ 
  39. public function put_contents( $file, $contents, $mode = false ) { 
  40. $fp = @fopen( $file, 'wb' ); 
  41. if ( ! $fp ) 
  42. return false; 
  43.  
  44. mbstring_binary_safe_encoding(); 
  45.  
  46. $data_length = strlen( $contents ); 
  47.  
  48. $bytes_written = fwrite( $fp, $contents ); 
  49.  
  50. reset_mbstring_encoding(); 
  51.  
  52. fclose( $fp ); 
  53.  
  54. if ( $data_length !== $bytes_written ) 
  55. return false; 
  56.  
  57. $this->chmod( $file, $mode ); 
  58.  
  59. return true; 
  60.  
  61. /** 
  62. * Gets the current working directory 
  63. * @access public 
  64. * @return string|bool the current working directory on success, or false on failure. 
  65. */ 
  66. public function cwd() { 
  67. return @getcwd(); 
  68.  
  69. /** 
  70. * Change directory 
  71. * @access public 
  72. * @param string $dir The new current directory. 
  73. * @return bool Returns true on success or false on failure. 
  74. */ 
  75. public function chdir($dir) { 
  76. return @chdir($dir); 
  77.  
  78. /** 
  79. * Changes file group 
  80. * @access public 
  81. * @param string $file Path to the file. 
  82. * @param mixed $group A group name or number. 
  83. * @param bool $recursive Optional. If set True changes file group recursively. Default false. 
  84. * @return bool Returns true on success or false on failure. 
  85. */ 
  86. public function chgrp($file, $group, $recursive = false) { 
  87. if ( ! $this->exists($file) ) 
  88. return false; 
  89. if ( ! $recursive ) 
  90. return @chgrp($file, $group); 
  91. if ( ! $this->is_dir($file) ) 
  92. return @chgrp($file, $group); 
  93. // Is a directory, and we want recursive 
  94. $file = trailingslashit($file); 
  95. $filelist = $this->dirlist($file); 
  96. foreach ($filelist as $filename) 
  97. $this->chgrp($file . $filename, $group, $recursive); 
  98.  
  99. return true; 
  100.  
  101. /** 
  102. * Changes filesystem permissions 
  103. * @access public 
  104. * @param string $file Path to the file. 
  105. * @param int $mode Optional. The permissions as octal number, usually 0644 for files,  
  106. * 0755 for dirs. Default false. 
  107. * @param bool $recursive Optional. If set True changes file group recursively. Default false. 
  108. * @return bool Returns true on success or false on failure. 
  109. */ 
  110. public function chmod($file, $mode = false, $recursive = false) { 
  111. if ( ! $mode ) { 
  112. if ( $this->is_file($file) ) 
  113. $mode = FS_CHMOD_FILE; 
  114. elseif ( $this->is_dir($file) ) 
  115. $mode = FS_CHMOD_DIR; 
  116. else 
  117. return false; 
  118.  
  119. if ( ! $recursive || ! $this->is_dir($file) ) 
  120. return @chmod($file, $mode); 
  121. // Is a directory, and we want recursive 
  122. $file = trailingslashit($file); 
  123. $filelist = $this->dirlist($file); 
  124. foreach ( (array)$filelist as $filename => $filemeta) 
  125. $this->chmod($file . $filename, $mode, $recursive); 
  126.  
  127. return true; 
  128.  
  129. /** 
  130. * Changes file owner 
  131. * @access public 
  132. * @param string $file Path to the file. 
  133. * @param mixed $owner A user name or number. 
  134. * @param bool $recursive Optional. If set True changes file owner recursively. 
  135. * Default false. 
  136. * @return bool Returns true on success or false on failure. 
  137. */ 
  138. public function chown($file, $owner, $recursive = false) { 
  139. if ( ! $this->exists($file) ) 
  140. return false; 
  141. if ( ! $recursive ) 
  142. return @chown($file, $owner); 
  143. if ( ! $this->is_dir($file) ) 
  144. return @chown($file, $owner); 
  145. // Is a directory, and we want recursive 
  146. $filelist = $this->dirlist($file); 
  147. foreach ($filelist as $filename) { 
  148. $this->chown($file . '/' . $filename, $owner, $recursive); 
  149. return true; 
  150.  
  151. /** 
  152. * Gets file owner 
  153. * @access public 
  154. * @param string $file Path to the file. 
  155. * @return string|bool Username of the user or false on error. 
  156. */ 
  157. public function owner($file) { 
  158. $owneruid = @fileowner($file); 
  159. if ( ! $owneruid ) 
  160. return false; 
  161. if ( ! function_exists('posix_getpwuid') ) 
  162. return $owneruid; 
  163. $ownerarray = posix_getpwuid($owneruid); 
  164. return $ownerarray['name']; 
  165.  
  166. /** 
  167. * Gets file permissions 
  168. * FIXME does not handle errors in fileperms() 
  169. * @access public 
  170. * @param string $file Path to the file. 
  171. * @return string Mode of the file (last 3 digits). 
  172. */ 
  173. public function getchmod($file) { 
  174. return substr( decoct( @fileperms( $file ) ), -3 ); 
  175.  
  176. /** 
  177. * @access public 
  178. * @param string $file 
  179. * @return string|false 
  180. */ 
  181. public function group($file) { 
  182. $gid = @filegroup($file); 
  183. if ( ! $gid ) 
  184. return false; 
  185. if ( ! function_exists('posix_getgrgid') ) 
  186. return $gid; 
  187. $grouparray = posix_getgrgid($gid); 
  188. return $grouparray['name']; 
  189.  
  190. /** 
  191. * @access public 
  192. * @param string $source 
  193. * @param string $destination 
  194. * @param bool $overwrite 
  195. * @param int $mode 
  196. * @return bool 
  197. */ 
  198. public function copy($source, $destination, $overwrite = false, $mode = false) { 
  199. if ( ! $overwrite && $this->exists($destination) ) 
  200. return false; 
  201.  
  202. $rtval = copy($source, $destination); 
  203. if ( $mode ) 
  204. $this->chmod($destination, $mode); 
  205. return $rtval; 
  206.  
  207. /** 
  208. * @access public 
  209. * @param string $source 
  210. * @param string $destination 
  211. * @param bool $overwrite 
  212. * @return bool 
  213. */ 
  214. public function move($source, $destination, $overwrite = false) { 
  215. if ( ! $overwrite && $this->exists($destination) ) 
  216. return false; 
  217.  
  218. // Try using rename first. if that fails (for example, source is read only) try copy. 
  219. if ( @rename($source, $destination) ) 
  220. return true; 
  221.  
  222. if ( $this->copy($source, $destination, $overwrite) && $this->exists($destination) ) { 
  223. $this->delete($source); 
  224. return true; 
  225. } else { 
  226. return false; 
  227.  
  228. /** 
  229. * @access public 
  230. * @param string $file 
  231. * @param bool $recursive 
  232. * @param string $type 
  233. * @return bool 
  234. */ 
  235. public function delete($file, $recursive = false, $type = false) { 
  236. if ( empty( $file ) ) // Some filesystems report this as /, which can cause non-expected recursive deletion of all files in the filesystem. 
  237. return false; 
  238. $file = str_replace( '\\', '/', $file ); // for win32, occasional problems deleting files otherwise 
  239.  
  240. if ( 'f' == $type || $this->is_file($file) ) 
  241. return @unlink($file); 
  242. if ( ! $recursive && $this->is_dir($file) ) 
  243. return @rmdir($file); 
  244.  
  245. // At this point it's a folder, and we're in recursive mode 
  246. $file = trailingslashit($file); 
  247. $filelist = $this->dirlist($file, true); 
  248.  
  249. $retval = true; 
  250. if ( is_array( $filelist ) ) { 
  251. foreach ( $filelist as $filename => $fileinfo ) { 
  252. if ( ! $this->delete($file . $filename, $recursive, $fileinfo['type']) ) 
  253. $retval = false; 
  254.  
  255. if ( file_exists($file) && ! @rmdir($file) ) 
  256. $retval = false; 
  257.  
  258. return $retval; 
  259. /** 
  260. * @access public 
  261. * @param string $file 
  262. * @return bool 
  263. */ 
  264. public function exists($file) { 
  265. return @file_exists($file); 
  266. /** 
  267. * @access public 
  268. * @param string $file 
  269. * @return bool 
  270. */ 
  271. public function is_file($file) { 
  272. return @is_file($file); 
  273. /** 
  274. * @access public 
  275. * @param string $path 
  276. * @return bool 
  277. */ 
  278. public function is_dir($path) { 
  279. return @is_dir($path); 
  280.  
  281. /** 
  282. * @access public 
  283. * @param string $file 
  284. * @return bool 
  285. */ 
  286. public function is_readable($file) { 
  287. return @is_readable($file); 
  288.  
  289. /** 
  290. * @access public 
  291. * @param string $file 
  292. * @return bool 
  293. */ 
  294. public function is_writable($file) { 
  295. return @is_writable($file); 
  296.  
  297. /** 
  298. * @access public 
  299. * @param string $file 
  300. * @return int 
  301. */ 
  302. public function atime($file) { 
  303. return @fileatime($file); 
  304.  
  305. /** 
  306. * @access public 
  307. * @param string $file 
  308. * @return int 
  309. */ 
  310. public function mtime($file) { 
  311. return @filemtime($file); 
  312.  
  313. /** 
  314. * @access public 
  315. * @param string $file 
  316. * @return int 
  317. */ 
  318. public function size($file) { 
  319. return @filesize($file); 
  320.  
  321. /** 
  322. * @access public 
  323. * @param string $file 
  324. * @param int $time 
  325. * @param int $atime 
  326. * @return bool 
  327. */ 
  328. public function touch($file, $time = 0, $atime = 0) { 
  329. if ($time == 0) 
  330. $time = time(); 
  331. if ($atime == 0) 
  332. $atime = time(); 
  333. return @touch($file, $time, $atime); 
  334.  
  335. /** 
  336. * @access public 
  337. * @param string $path 
  338. * @param mixed $chmod 
  339. * @param mixed $chown 
  340. * @param mixed $chgrp 
  341. * @return bool 
  342. */ 
  343. public function mkdir($path, $chmod = false, $chown = false, $chgrp = false) { 
  344. // Safe mode fails with a trailing slash under certain PHP versions. 
  345. $path = untrailingslashit($path); 
  346. if ( empty($path) ) 
  347. return false; 
  348.  
  349. if ( ! $chmod ) 
  350. $chmod = FS_CHMOD_DIR; 
  351.  
  352. if ( ! @mkdir($path) ) 
  353. return false; 
  354. $this->chmod($path, $chmod); 
  355. if ( $chown ) 
  356. $this->chown($path, $chown); 
  357. if ( $chgrp ) 
  358. $this->chgrp($path, $chgrp); 
  359. return true; 
  360.  
  361. /** 
  362. * @access public 
  363. * @param string $path 
  364. * @param bool $recursive 
  365. * @return bool 
  366. */ 
  367. public function rmdir($path, $recursive = false) { 
  368. return $this->delete($path, $recursive); 
  369.  
  370. /** 
  371. * @access public 
  372. * @param string $path 
  373. * @param bool $include_hidden 
  374. * @param bool $recursive 
  375. * @return bool|array 
  376. */ 
  377. public function dirlist($path, $include_hidden = true, $recursive = false) { 
  378. if ( $this->is_file($path) ) { 
  379. $limit_file = basename($path); 
  380. $path = dirname($path); 
  381. } else { 
  382. $limit_file = false; 
  383.  
  384. if ( ! $this->is_dir($path) ) 
  385. return false; 
  386.  
  387. $dir = @dir($path); 
  388. if ( ! $dir ) 
  389. return false; 
  390.  
  391. $ret = array(); 
  392.  
  393. while (false !== ($entry = $dir->read()) ) { 
  394. $struc = array(); 
  395. $struc['name'] = $entry; 
  396.  
  397. if ( '.' == $struc['name'] || '..' == $struc['name'] ) 
  398. continue; 
  399.  
  400. if ( ! $include_hidden && '.' == $struc['name'][0] ) 
  401. continue; 
  402.  
  403. if ( $limit_file && $struc['name'] != $limit_file) 
  404. continue; 
  405.  
  406. $struc['perms'] = $this->gethchmod($path.'/'.$entry); 
  407. $struc['permsn'] = $this->getnumchmodfromh($struc['perms']); 
  408. $struc['number'] = false; 
  409. $struc['owner'] = $this->owner($path.'/'.$entry); 
  410. $struc['group'] = $this->group($path.'/'.$entry); 
  411. $struc['size'] = $this->size($path.'/'.$entry); 
  412. $struc['lastmodunix']= $this->mtime($path.'/'.$entry); 
  413. $struc['lastmod'] = date('M j', $struc['lastmodunix']); 
  414. $struc['time'] = date('h:i:s', $struc['lastmodunix']); 
  415. $struc['type'] = $this->is_dir($path.'/'.$entry) ? 'd' : 'f'; 
  416.  
  417. if ( 'd' == $struc['type'] ) { 
  418. if ( $recursive ) 
  419. $struc['files'] = $this->dirlist($path . '/' . $struc['name'], $include_hidden, $recursive); 
  420. else 
  421. $struc['files'] = array(); 
  422.  
  423. $ret[ $struc['name'] ] = $struc; 
  424. $dir->close(); 
  425. unset($dir); 
  426. return $ret;