PageRenderTime 28ms CodeModel.GetById 26ms RepoModel.GetById 0ms app.codeStats 0ms

/XoopsEngine/htdocs/class/file/file.php

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