PageRenderTime 40ms CodeModel.GetById 13ms RepoModel.GetById 0ms app.codeStats 0ms

/lib/Cake/Utility/File.php

https://github.com/simkimsia/cake2-practice-app
PHP | 506 lines | 351 code | 23 blank | 132 comment | 33 complexity | a4ece9f42536edc2cd130ce3dad5a3f5 MD5 | raw file
  1. <?php
  2. /**
  3. * Convenience class for reading, writing and appending to files.
  4. *
  5. * PHP 5
  6. *
  7. * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
  8. * Copyright 2005-2011, Cake Software Foundation, Inc. (http://cakefoundation.org)
  9. *
  10. * Licensed under The MIT License
  11. * Redistributions of files must retain the above copyright notice.
  12. *
  13. * @copyright Copyright 2005-2011, Cake Software Foundation, Inc. (http://cakefoundation.org)
  14. * @link http://cakephp.org CakePHP(tm) Project
  15. * @package Cake.Utility
  16. * @since CakePHP(tm) v 0.2.9
  17. * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
  18. */
  19. /**
  20. * Included libraries.
  21. *
  22. */
  23. App::uses('Folder', 'Utility');
  24. /**
  25. * Convenience class for reading, writing and appending to files.
  26. *
  27. * @package Cake.Utility
  28. */
  29. class File {
  30. /**
  31. * Folder object of the File
  32. *
  33. * @var Folder
  34. */
  35. public $Folder = null;
  36. /**
  37. * Filename
  38. *
  39. * @var string
  40. */
  41. public $name = null;
  42. /**
  43. * file info
  44. *
  45. * @var string
  46. */
  47. public $info = array();
  48. /**
  49. * Holds the file handler resource if the file is opened
  50. *
  51. * @var resource
  52. */
  53. public $handle = null;
  54. /**
  55. * enable locking for file reading and writing
  56. *
  57. * @var boolean
  58. */
  59. public $lock = null;
  60. /**
  61. * path property
  62. *
  63. * Current file's absolute path
  64. *
  65. * @var mixed null
  66. */
  67. public $path = null;
  68. /**
  69. * Constructor
  70. *
  71. * @param string $path Path to file
  72. * @param boolean $create Create file if it does not exist (if true)
  73. * @param integer $mode Mode to apply to the folder holding the file
  74. */
  75. public function __construct($path, $create = false, $mode = 0755) {
  76. $this->Folder = new Folder(dirname($path), $create, $mode);
  77. if (!is_dir($path)) {
  78. $this->name = basename($path);
  79. }
  80. $this->pwd();
  81. $create && !$this->exists() && $this->safe($path) && $this->create();
  82. }
  83. /**
  84. * Closes the current file if it is opened
  85. *
  86. */
  87. public function __destruct() {
  88. $this->close();
  89. }
  90. /**
  91. * Creates the File.
  92. *
  93. * @return boolean Success
  94. */
  95. public function create() {
  96. $dir = $this->Folder->pwd();
  97. if (is_dir($dir) && is_writable($dir) && !$this->exists()) {
  98. $old = umask(0);
  99. if (touch($this->path)) {
  100. umask($old);
  101. return true;
  102. }
  103. }
  104. return false;
  105. }
  106. /**
  107. * Opens the current file with a given $mode
  108. *
  109. * @param string $mode A valid 'fopen' mode string (r|w|a ...)
  110. * @param boolean $force If true then the file will be re-opened even if its already opened, otherwise it won't
  111. * @return boolean True on success, false on failure
  112. */
  113. public function open($mode = 'r', $force = false) {
  114. if (!$force && is_resource($this->handle)) {
  115. return true;
  116. }
  117. clearstatcache();
  118. if ($this->exists() === false) {
  119. if ($this->create() === false) {
  120. return false;
  121. }
  122. }
  123. $this->handle = fopen($this->path, $mode);
  124. if (is_resource($this->handle)) {
  125. return true;
  126. }
  127. return false;
  128. }
  129. /**
  130. * Return the contents of this File as a string.
  131. *
  132. * @param string $bytes where to start
  133. * @param string $mode A `fread` compatible mode.
  134. * @param boolean $force If true then the file will be re-opened even if its already opened, otherwise it won't
  135. * @return mixed string on success, false on failure
  136. */
  137. public function read($bytes = false, $mode = 'rb', $force = false) {
  138. if ($bytes === false && $this->lock === null) {
  139. return file_get_contents($this->path);
  140. }
  141. if ($this->open($mode, $force) === false) {
  142. return false;
  143. }
  144. if ($this->lock !== null && flock($this->handle, LOCK_SH) === false) {
  145. return false;
  146. }
  147. if (is_int($bytes)) {
  148. return fread($this->handle, $bytes);
  149. }
  150. $data = '';
  151. while (!feof($this->handle)) {
  152. $data .= fgets($this->handle, 4096);
  153. }
  154. if ($this->lock !== null) {
  155. flock($this->handle, LOCK_UN);
  156. }
  157. if ($bytes === false) {
  158. $this->close();
  159. }
  160. return trim($data);
  161. }
  162. /**
  163. * Sets or gets the offset for the currently opened file.
  164. *
  165. * @param mixed $offset The $offset in bytes to seek. If set to false then the current offset is returned.
  166. * @param integer $seek PHP Constant SEEK_SET | SEEK_CUR | SEEK_END determining what the $offset is relative to
  167. * @return mixed True on success, false on failure (set mode), false on failure or integer offset on success (get mode)
  168. */
  169. public function offset($offset = false, $seek = SEEK_SET) {
  170. if ($offset === false) {
  171. if (is_resource($this->handle)) {
  172. return ftell($this->handle);
  173. }
  174. } elseif ($this->open() === true) {
  175. return fseek($this->handle, $offset, $seek) === 0;
  176. }
  177. return false;
  178. }
  179. /**
  180. * Prepares a ascii string for writing. Converts line endings to the
  181. * correct terminator for the current platform. If windows "\r\n" will be used
  182. * all other platforms will use "\n"
  183. *
  184. * @param string $data Data to prepare for writing.
  185. * @param boolean $forceWindows
  186. * @return string The with converted line endings.
  187. */
  188. public static function prepare($data, $forceWindows = false) {
  189. $lineBreak = "\n";
  190. if (DIRECTORY_SEPARATOR == '\\' || $forceWindows === true) {
  191. $lineBreak = "\r\n";
  192. }
  193. return strtr($data, array("\r\n" => $lineBreak, "\n" => $lineBreak, "\r" => $lineBreak));
  194. }
  195. /**
  196. * Write given data to this File.
  197. *
  198. * @param string $data Data to write to this File.
  199. * @param string $mode Mode of writing. {@link http://php.net/fwrite See fwrite()}.
  200. * @param string $force force the file to open
  201. * @return boolean Success
  202. */
  203. public function write($data, $mode = 'w', $force = false) {
  204. $success = false;
  205. if ($this->open($mode, $force) === true) {
  206. if ($this->lock !== null) {
  207. if (flock($this->handle, LOCK_EX) === false) {
  208. return false;
  209. }
  210. }
  211. if (fwrite($this->handle, $data) !== false) {
  212. $success = true;
  213. }
  214. if ($this->lock !== null) {
  215. flock($this->handle, LOCK_UN);
  216. }
  217. }
  218. return $success;
  219. }
  220. /**
  221. * Append given data string to this File.
  222. *
  223. * @param string $data Data to write
  224. * @param string $force force the file to open
  225. * @return boolean Success
  226. */
  227. public function append($data, $force = false) {
  228. return $this->write($data, 'a', $force);
  229. }
  230. /**
  231. * Closes the current file if it is opened.
  232. *
  233. * @return boolean True if closing was successful or file was already closed, otherwise false
  234. */
  235. public function close() {
  236. if (!is_resource($this->handle)) {
  237. return true;
  238. }
  239. return fclose($this->handle);
  240. }
  241. /**
  242. * Deletes the File.
  243. *
  244. * @return boolean Success
  245. */
  246. public function delete() {
  247. clearstatcache();
  248. if (is_resource($this->handle)) {
  249. fclose($this->handle);
  250. $this->handle = null;
  251. }
  252. if ($this->exists()) {
  253. return unlink($this->path);
  254. }
  255. return false;
  256. }
  257. /**
  258. * Returns the File info.
  259. *
  260. * @return string The File extension
  261. */
  262. public function info() {
  263. if ($this->info == null) {
  264. $this->info = pathinfo($this->path);
  265. }
  266. if (!isset($this->info['filename'])) {
  267. $this->info['filename'] = $this->name();
  268. }
  269. return $this->info;
  270. }
  271. /**
  272. * Returns the File extension.
  273. *
  274. * @return string The File extension
  275. */
  276. public function ext() {
  277. if ($this->info == null) {
  278. $this->info();
  279. }
  280. if (isset($this->info['extension'])) {
  281. return $this->info['extension'];
  282. }
  283. return false;
  284. }
  285. /**
  286. * Returns the File name without extension.
  287. *
  288. * @return string The File name without extension.
  289. */
  290. public function name() {
  291. if ($this->info == null) {
  292. $this->info();
  293. }
  294. if (isset($this->info['extension'])) {
  295. return basename($this->name, '.'.$this->info['extension']);
  296. } elseif ($this->name) {
  297. return $this->name;
  298. }
  299. return false;
  300. }
  301. /**
  302. * makes filename safe for saving
  303. *
  304. * @param string $name The name of the file to make safe if different from $this->name
  305. * @param string $ext The name of the extension to make safe if different from $this->ext
  306. * @return string $ext the extension of the file
  307. */
  308. public function safe($name = null, $ext = null) {
  309. if (!$name) {
  310. $name = $this->name;
  311. }
  312. if (!$ext) {
  313. $ext = $this->ext();
  314. }
  315. return preg_replace( "/(?:[^\w\.-]+)/", "_", basename($name, $ext));
  316. }
  317. /**
  318. * Get md5 Checksum of file with previous check of Filesize
  319. *
  320. * @param mixed $maxsize in MB or true to force
  321. * @return string md5 Checksum {@link http://php.net/md5_file See md5_file()}
  322. */
  323. public function md5($maxsize = 5) {
  324. if ($maxsize === true) {
  325. return md5_file($this->path);
  326. }
  327. $size = $this->size();
  328. if ($size && $size < ($maxsize * 1024) * 1024) {
  329. return md5_file($this->path);
  330. }
  331. return false;
  332. }
  333. /**
  334. * Returns the full path of the File.
  335. *
  336. * @return string Full path to file
  337. */
  338. public function pwd() {
  339. if (is_null($this->path)) {
  340. $this->path = $this->Folder->slashTerm($this->Folder->pwd()) . $this->name;
  341. }
  342. return $this->path;
  343. }
  344. /**
  345. * Returns true if the File exists.
  346. *
  347. * @return boolean true if it exists, false otherwise
  348. */
  349. public function exists() {
  350. return (file_exists($this->path) && is_file($this->path));
  351. }
  352. /**
  353. * Returns the "chmod" (permissions) of the File.
  354. *
  355. * @return string Permissions for the file
  356. */
  357. public function perms() {
  358. if ($this->exists()) {
  359. return substr(sprintf('%o', fileperms($this->path)), -4);
  360. }
  361. return false;
  362. }
  363. /**
  364. * Returns the Filesize
  365. *
  366. * @return integer size of the file in bytes, or false in case of an error
  367. */
  368. public function size() {
  369. if ($this->exists()) {
  370. return filesize($this->path);
  371. }
  372. return false;
  373. }
  374. /**
  375. * Returns true if the File is writable.
  376. *
  377. * @return boolean true if its writable, false otherwise
  378. */
  379. public function writable() {
  380. return is_writable($this->path);
  381. }
  382. /**
  383. * Returns true if the File is executable.
  384. *
  385. * @return boolean true if its executable, false otherwise
  386. */
  387. public function executable() {
  388. return is_executable($this->path);
  389. }
  390. /**
  391. * Returns true if the File is readable.
  392. *
  393. * @return boolean true if file is readable, false otherwise
  394. */
  395. public function readable() {
  396. return is_readable($this->path);
  397. }
  398. /**
  399. * Returns the File's owner.
  400. *
  401. * @return integer the Fileowner
  402. */
  403. public function owner() {
  404. if ($this->exists()) {
  405. return fileowner($this->path);
  406. }
  407. return false;
  408. }
  409. /**
  410. * Returns the File's group.
  411. *
  412. * @return integer the Filegroup
  413. */
  414. public function group() {
  415. if ($this->exists()) {
  416. return filegroup($this->path);
  417. }
  418. return false;
  419. }
  420. /**
  421. * Returns last access time.
  422. *
  423. * @return integer timestamp Timestamp of last access time
  424. */
  425. public function lastAccess() {
  426. if ($this->exists()) {
  427. return fileatime($this->path);
  428. }
  429. return false;
  430. }
  431. /**
  432. * Returns last modified time.
  433. *
  434. * @return integer timestamp Timestamp of last modification
  435. */
  436. public function lastChange() {
  437. if ($this->exists()) {
  438. return filemtime($this->path);
  439. }
  440. return false;
  441. }
  442. /**
  443. * Returns the current folder.
  444. *
  445. * @return Folder Current folder
  446. */
  447. public function &Folder() {
  448. return $this->Folder;
  449. }
  450. /**
  451. * Copy the File to $dest
  452. *
  453. * @param string $dest destination for the copy
  454. * @param boolean $overwrite Overwrite $dest if exists
  455. * @return boolean Succes
  456. */
  457. public function copy($dest, $overwrite = true) {
  458. if (!$this->exists() || is_file($dest) && !$overwrite) {
  459. return false;
  460. }
  461. return copy($this->path, $dest);
  462. }
  463. }