PageRenderTime 49ms CodeModel.GetById 23ms RepoModel.GetById 0ms app.codeStats 1ms

/library/Zend/Search/Lucene/Storage/Directory/Filesystem.php

https://github.com/shevron/zf2
PHP | 346 lines | 189 code | 40 blank | 117 comment | 20 complexity | 96f7f694c2b5655d3e3ca86e87fb4746 MD5 | raw file
  1. <?php
  2. /**
  3. * Zend Framework (http://framework.zend.com/)
  4. *
  5. * @link http://github.com/zendframework/zf2 for the canonical source repository
  6. * @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
  7. * @license http://framework.zend.com/license/new-bsd New BSD License
  8. * @package Zend_Search
  9. */
  10. namespace Zend\Search\Lucene\Storage\Directory;
  11. use Zend\Search\Lucene;
  12. use Zend\Search\Lucene\Storage\Directory;
  13. use Zend\Search\Lucene\Storage\File;
  14. /**
  15. * FileSystem implementation of DirectoryInterface abstraction.
  16. *
  17. * @category Zend
  18. * @package Zend_Search_Lucene
  19. * @subpackage Storage
  20. */
  21. class Filesystem implements DirectoryInterface
  22. {
  23. /**
  24. * Filesystem path to the directory
  25. *
  26. * @var string
  27. */
  28. protected $_dirPath = null;
  29. /**
  30. * Cache for Zend_Search_Lucene_Storage_File_Filesystem objects
  31. * Array: filename => Zend_Search_Lucene_Storage_File object
  32. *
  33. * @var array
  34. * @throws \Zend\Search\Lucene\Exception\ExceptionInterface
  35. */
  36. protected $_fileHandlers;
  37. /**
  38. * Default file permissions
  39. *
  40. * @var integer
  41. */
  42. protected static $_defaultFilePermissions = 0666;
  43. /**
  44. * Get default file permissions
  45. *
  46. * @return integer
  47. */
  48. public static function getDefaultFilePermissions()
  49. {
  50. return self::$_defaultFilePermissions;
  51. }
  52. /**
  53. * Set default file permissions
  54. *
  55. * @param integer $mode
  56. */
  57. public static function setDefaultFilePermissions($mode)
  58. {
  59. self::$_defaultFilePermissions = $mode;
  60. }
  61. /**
  62. * Utility function to recursive directory creation
  63. *
  64. * @param string $dir
  65. * @param integer $mode
  66. * @param boolean $recursive
  67. * @return boolean
  68. */
  69. public static function mkdirs($dir, $mode = 0777, $recursive = true)
  70. {
  71. if (($dir === null) || $dir === '') {
  72. return false;
  73. }
  74. if (is_dir($dir) || $dir === '/') {
  75. return true;
  76. }
  77. if (self::mkdirs(dirname($dir), $mode, $recursive)) {
  78. return mkdir($dir, $mode);
  79. }
  80. return false;
  81. }
  82. /**
  83. * Object constructor
  84. * Checks if $path is a directory or tries to create it.
  85. *
  86. * @param string $path
  87. * @throws \Zend\Search\Lucene\Exception\InvalidArgumentException
  88. */
  89. public function __construct($path)
  90. {
  91. if (!is_dir($path)) {
  92. if (file_exists($path)) {
  93. throw new Lucene\Exception\InvalidArgumentException(
  94. 'Path exists, but it\'s not a directory'
  95. );
  96. } else {
  97. if (!self::mkdirs($path)) {
  98. throw new Lucene\Exception\InvalidArgumentException(
  99. "Can't create directory '$path'."
  100. );
  101. }
  102. }
  103. }
  104. $this->_dirPath = $path;
  105. $this->_fileHandlers = array();
  106. }
  107. /**
  108. * Closes the store.
  109. *
  110. * @return void
  111. */
  112. public function close()
  113. {
  114. foreach ($this->_fileHandlers as $fileObject) {
  115. $fileObject->close();
  116. }
  117. $this->_fileHandlers = array();
  118. }
  119. /**
  120. * Returns an array of strings, one for each file in the directory.
  121. *
  122. * @return array
  123. */
  124. public function fileList()
  125. {
  126. $result = array();
  127. $dirContent = opendir( $this->_dirPath );
  128. while (($file = readdir($dirContent)) !== false) {
  129. if (($file == '..')||($file == '.')) continue;
  130. if( !is_dir($this->_dirPath . '/' . $file) ) {
  131. $result[] = $file;
  132. }
  133. }
  134. closedir($dirContent);
  135. return $result;
  136. }
  137. /**
  138. * Creates a new, empty file in the directory with the given $filename.
  139. *
  140. * @param string $filename
  141. * @return \Zend\Search\Lucene\Storage\File\FileInterface
  142. */
  143. public function createFile($filename)
  144. {
  145. if (isset($this->_fileHandlers[$filename])) {
  146. $this->_fileHandlers[$filename]->close();
  147. }
  148. unset($this->_fileHandlers[$filename]);
  149. $this->_fileHandlers[$filename] = new File\Filesystem($this->_dirPath . '/' . $filename, 'w+b');
  150. // Set file permissions, but don't care about any possible failures, since file may be already
  151. // created by anther user which has to care about right permissions
  152. @chmod($this->_dirPath . '/' . $filename, self::$_defaultFilePermissions);
  153. return $this->_fileHandlers[$filename];
  154. }
  155. /**
  156. * Removes an existing $filename in the directory.
  157. *
  158. * @param string $filename
  159. * @throws \Zend\Search\Lucene\Exception\RuntimeException
  160. * @return void
  161. */
  162. public function deleteFile($filename)
  163. {
  164. if (isset($this->_fileHandlers[$filename])) {
  165. $this->_fileHandlers[$filename]->close();
  166. }
  167. unset($this->_fileHandlers[$filename]);
  168. global $php_errormsg;
  169. $trackErrors = ini_get('track_errors'); ini_set('track_errors', '1');
  170. if (!@unlink($this->_dirPath . '/' . $filename)) {
  171. ini_set('track_errors', $trackErrors);
  172. throw new Lucene\Exception\RuntimeException('Can\'t delete file: ' . $php_errormsg);
  173. }
  174. ini_set('track_errors', $trackErrors);
  175. }
  176. /**
  177. * Purge file if it's cached by directory object
  178. *
  179. * Method is used to prevent 'too many open files' error
  180. *
  181. * @param string $filename
  182. * @return void
  183. */
  184. public function purgeFile($filename)
  185. {
  186. if (isset($this->_fileHandlers[$filename])) {
  187. $this->_fileHandlers[$filename]->close();
  188. }
  189. unset($this->_fileHandlers[$filename]);
  190. }
  191. /**
  192. * Returns true if a file with the given $filename exists.
  193. *
  194. * @param string $filename
  195. * @return boolean
  196. */
  197. public function fileExists($filename)
  198. {
  199. return isset($this->_fileHandlers[$filename]) ||
  200. file_exists($this->_dirPath . '/' . $filename);
  201. }
  202. /**
  203. * Returns the length of a $filename in the directory.
  204. *
  205. * @param string $filename
  206. * @return integer
  207. */
  208. public function fileLength($filename)
  209. {
  210. if (isset( $this->_fileHandlers[$filename] )) {
  211. return $this->_fileHandlers[$filename]->size();
  212. }
  213. return filesize($this->_dirPath .'/'. $filename);
  214. }
  215. /**
  216. * Returns the UNIX timestamp $filename was last modified.
  217. *
  218. * @param string $filename
  219. * @return integer
  220. */
  221. public function fileModified($filename)
  222. {
  223. return filemtime($this->_dirPath .'/'. $filename);
  224. }
  225. /**
  226. * Renames an existing file in the directory.
  227. *
  228. * @param string $from
  229. * @param string $to
  230. * @throws \Zend\Search\Lucene\Exception\RuntimeException
  231. * @return void
  232. */
  233. public function renameFile($from, $to)
  234. {
  235. global $php_errormsg;
  236. if (isset($this->_fileHandlers[$from])) {
  237. $this->_fileHandlers[$from]->close();
  238. }
  239. unset($this->_fileHandlers[$from]);
  240. if (isset($this->_fileHandlers[$to])) {
  241. $this->_fileHandlers[$to]->close();
  242. }
  243. unset($this->_fileHandlers[$to]);
  244. if (file_exists($this->_dirPath . '/' . $to)) {
  245. if (!unlink($this->_dirPath . '/' . $to)) {
  246. throw new Lucene\Exception\RuntimeException(
  247. 'Delete operation failed'
  248. );
  249. }
  250. }
  251. $trackErrors = ini_get('track_errors');
  252. ini_set('track_errors', '1');
  253. $success = @rename($this->_dirPath . '/' . $from, $this->_dirPath . '/' . $to);
  254. if (!$success) {
  255. ini_set('track_errors', $trackErrors);
  256. throw new Lucene\Exception\RuntimeException($php_errormsg);
  257. }
  258. ini_set('track_errors', $trackErrors);
  259. return $success;
  260. }
  261. /**
  262. * Sets the modified time of $filename to now.
  263. *
  264. * @param string $filename
  265. * @return void
  266. */
  267. public function touchFile($filename)
  268. {
  269. return touch($this->_dirPath .'/'. $filename);
  270. }
  271. /**
  272. * Returns a Zend_Search_Lucene_Storage_File object for a given $filename in the directory.
  273. *
  274. * If $shareHandler option is true, then file handler can be shared between File Object
  275. * requests. It speed-ups performance, but makes problems with file position.
  276. * Shared handler are good for short atomic requests.
  277. * Non-shared handlers are useful for stream file reading (especial for compound files).
  278. *
  279. * @param string $filename
  280. * @param boolean $shareHandler
  281. * @return \Zend\Search\Lucene\Storage\File\FileInterface
  282. */
  283. public function getFileObject($filename, $shareHandler = true)
  284. {
  285. $fullFilename = $this->_dirPath . '/' . $filename;
  286. if (!$shareHandler) {
  287. return new File\Filesystem($fullFilename);
  288. }
  289. if (isset( $this->_fileHandlers[$filename] )) {
  290. $this->_fileHandlers[$filename]->seek(0);
  291. return $this->_fileHandlers[$filename];
  292. }
  293. $this->_fileHandlers[$filename] = new File\Filesystem($fullFilename);
  294. return $this->_fileHandlers[$filename];
  295. }
  296. }