/library/Zend/Filter/File/Rename.php

https://github.com/bruisedlee/zf2 · PHP · 304 lines · 159 code · 40 blank · 105 comment · 36 complexity · f24c7e20af31aad62cd9e10087e75c4e MD5 · raw file

  1. <?php
  2. /**
  3. * Zend Framework
  4. *
  5. * LICENSE
  6. *
  7. * This source file is subject to the new BSD license that is bundled
  8. * with this package in the file LICENSE.txt.
  9. * It is also available through the world-wide-web at this URL:
  10. * http://framework.zend.com/license/new-bsd
  11. * If you did not receive a copy of the license and are unable to
  12. * obtain it through the world-wide-web, please send an email
  13. * to license@zend.com so we can send you a copy immediately.
  14. *
  15. * @category Zend
  16. * @package Zend_Filter
  17. * @copyright Copyright (c) 2005-2011 Zend Technologies USA Inc. (http://www.zend.com)
  18. * @license http://framework.zend.com/license/new-bsd New BSD License
  19. */
  20. /**
  21. * @namespace
  22. */
  23. namespace Zend\Filter\File;
  24. use Zend\Filter,
  25. Zend\Filter\Exception;
  26. /**
  27. * @uses Zend\Filter\Exception
  28. * @uses Zend\Filter\AbstractFilter
  29. * @category Zend
  30. * @package Zend_Filter
  31. * @copyright Copyright (c) 2005-2011 Zend Technologies USA Inc. (http://www.zend.com)
  32. * @license http://framework.zend.com/license/new-bsd New BSD License
  33. */
  34. class Rename extends Filter\AbstractFilter
  35. {
  36. /**
  37. * Internal array of array(source, target, overwrite)
  38. */
  39. protected $_files = array();
  40. /**
  41. * Class constructor
  42. *
  43. * Options argument may be either a string, a Zend_Config object, or an array.
  44. * If an array or Zend_Config object, it accepts the following keys:
  45. * 'source' => Source filename or directory which will be renamed
  46. * 'target' => Target filename or directory, the new name of the sourcefile
  47. * 'overwrite' => Shall existing files be overwritten ?
  48. *
  49. * @param string|array $options Target file or directory to be renamed
  50. * @param string $target Source filename or directory (deprecated)
  51. * @param bool $overwrite Should existing files be overwritten (deprecated)
  52. * @return void
  53. */
  54. public function __construct($options)
  55. {
  56. if ($options instanceof \Zend\Config\Config) {
  57. $options = $options->toArray();
  58. } elseif (is_string($options)) {
  59. $options = array('target' => $options);
  60. } elseif (!is_array($options)) {
  61. throw new Exception\InvalidArgumentException('Invalid options argument provided to filter');
  62. }
  63. if (1 < func_num_args()) {
  64. $argv = func_get_args();
  65. array_shift($argv);
  66. $source = array_shift($argv);
  67. $overwrite = false;
  68. if (!empty($argv)) {
  69. $overwrite = array_shift($argv);
  70. }
  71. $options['source'] = $source;
  72. $options['overwrite'] = $overwrite;
  73. }
  74. $this->setFile($options);
  75. }
  76. /**
  77. * Returns the files to rename and their new name and location
  78. *
  79. * @return array
  80. */
  81. public function getFile()
  82. {
  83. return $this->_files;
  84. }
  85. /**
  86. * Sets a new file or directory as target, deleting existing ones
  87. *
  88. * Array accepts the following keys:
  89. * 'source' => Source filename or directory which will be renamed
  90. * 'target' => Target filename or directory, the new name of the sourcefile
  91. * 'overwrite' => Shall existing files be overwritten ?
  92. *
  93. * @param string|array $options Old file or directory to be rewritten
  94. * @return \Zend\Filter\File\Rename
  95. */
  96. public function setFile($options)
  97. {
  98. $this->_files = array();
  99. $this->addFile($options);
  100. return $this;
  101. }
  102. /**
  103. * Adds a new file or directory as target to the existing ones
  104. *
  105. * Array accepts the following keys:
  106. * 'source' => Source filename or directory which will be renamed
  107. * 'target' => Target filename or directory, the new name of the sourcefile
  108. * 'overwrite' => Shall existing files be overwritten ?
  109. *
  110. * @param string|array $options Old file or directory to be rewritten
  111. * @return \Zend\Filter\File\Rename
  112. */
  113. public function addFile($options)
  114. {
  115. if (is_string($options)) {
  116. $options = array('target' => $options);
  117. } elseif (!is_array($options)) {
  118. throw new Exception\InvalidArgumentException('Invalid options to rename filter provided');
  119. }
  120. $this->_convertOptions($options);
  121. return $this;
  122. }
  123. /**
  124. * Returns only the new filename without moving it
  125. * But existing files will be erased when the overwrite option is true
  126. *
  127. * @param string $value Full path of file to change
  128. * @param boolean $source Return internal informations
  129. * @return string The new filename which has been set
  130. */
  131. public function getNewName($value, $source = false)
  132. {
  133. $file = $this->_getFileName($value);
  134. if ($file['source'] == $file['target']) {
  135. return $value;
  136. }
  137. if (!file_exists($file['source'])) {
  138. return $value;
  139. }
  140. if (($file['overwrite'] == true) && (file_exists($file['target']))) {
  141. unlink($file['target']);
  142. }
  143. if (file_exists($file['target'])) {
  144. throw new Exception\InvalidArgumentException(sprintf("File '%s' could not be renamed. It already exists.", $value));
  145. }
  146. if ($source) {
  147. return $file;
  148. }
  149. return $file['target'];
  150. }
  151. /**
  152. * Defined by Zend\Filter\Filter
  153. *
  154. * Renames the file $value to the new name set before
  155. * Returns the file $value, removing all but digit characters
  156. *
  157. * @param string $value Full path of file to change
  158. * @throws \Zend\Filter\Exception
  159. * @return string The new filename which has been set, or false when there were errors
  160. */
  161. public function filter($value)
  162. {
  163. $file = $this->getNewName($value, true);
  164. if (is_string($file)) {
  165. return $file;
  166. }
  167. $result = rename($file['source'], $file['target']);
  168. if ($result !== true) {
  169. throw new Exception\RuntimeException(sprintf("File '%s' could not be renamed. An error occured while processing the file.", $value));
  170. }
  171. return $file['target'];
  172. }
  173. /**
  174. * Internal method for creating the file array
  175. * Supports single and nested arrays
  176. *
  177. * @param array $options
  178. * @return array
  179. */
  180. protected function _convertOptions($options)
  181. {
  182. $files = array();
  183. foreach ($options as $key => $value) {
  184. if (is_array($value)) {
  185. $this->_convertOptions($value);
  186. continue;
  187. }
  188. switch ($key) {
  189. case "source":
  190. $files['source'] = (string) $value;
  191. break;
  192. case 'target' :
  193. $files['target'] = (string) $value;
  194. break;
  195. case 'overwrite' :
  196. $files['overwrite'] = (boolean) $value;
  197. break;
  198. default:
  199. break;
  200. }
  201. }
  202. if (empty($files)) {
  203. return $this;
  204. }
  205. if (empty($files['source'])) {
  206. $files['source'] = '*';
  207. }
  208. if (empty($files['target'])) {
  209. $files['target'] = '*';
  210. }
  211. if (empty($files['overwrite'])) {
  212. $files['overwrite'] = false;
  213. }
  214. $found = false;
  215. foreach ($this->_files as $key => $value) {
  216. if ($value['source'] == $files['source']) {
  217. $this->_files[$key] = $files;
  218. $found = true;
  219. }
  220. }
  221. if (!$found) {
  222. $count = count($this->_files);
  223. $this->_files[$count] = $files;
  224. }
  225. return $this;
  226. }
  227. /**
  228. * Internal method to resolve the requested source
  229. * and return all other related parameters
  230. *
  231. * @param string $file Filename to get the informations for
  232. * @return array
  233. */
  234. protected function _getFileName($file)
  235. {
  236. $rename = array();
  237. foreach ($this->_files as $value) {
  238. if ($value['source'] == '*') {
  239. if (!isset($rename['source'])) {
  240. $rename = $value;
  241. $rename['source'] = $file;
  242. }
  243. }
  244. if ($value['source'] == $file) {
  245. $rename = $value;
  246. }
  247. }
  248. if (!isset($rename['source'])) {
  249. return $file;
  250. }
  251. if (!isset($rename['target']) or ($rename['target'] == '*')) {
  252. $rename['target'] = $rename['source'];
  253. }
  254. if (is_dir($rename['target'])) {
  255. $name = basename($rename['source']);
  256. $last = $rename['target'][strlen($rename['target']) - 1];
  257. if (($last != '/') and ($last != '\\')) {
  258. $rename['target'] .= DIRECTORY_SEPARATOR;
  259. }
  260. $rename['target'] .= $name;
  261. }
  262. return $rename;
  263. }
  264. }