PageRenderTime 32ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 0ms

/cake/libs/file.php

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