/wire/core/Pagefile.php

https://github.com/Cahya/P21 · PHP · 284 lines · 111 code · 40 blank · 133 comment · 21 complexity · ad6b3613987afaec871e2455dc2eb198 MD5 · raw file

  1. <?php
  2. /**
  3. * ProcessWire Pagefile
  4. *
  5. * Represents a single file item attached to a page, typically via a FieldtypeFile field.
  6. *
  7. * ProcessWire 2.x
  8. * Copyright (C) 2010 by Ryan Cramer
  9. * Licensed under GNU/GPL v2, see LICENSE.TXT
  10. *
  11. * http://www.processwire.com
  12. * http://www.ryancramer.com
  13. *
  14. */
  15. class Pagefile extends WireData {
  16. /**
  17. * Reference to the owning collection of Pagefiles
  18. *
  19. */
  20. protected $pagefiles;
  21. /**
  22. * Construct a new Pagefile
  23. *
  24. * @param Pagefiles $pagefiles
  25. * @param string $filename Full path and filename to this pagefile
  26. *
  27. */
  28. public function __construct(Pagefiles $pagefiles, $filename) {
  29. $this->pagefiles = $pagefiles;
  30. if(strlen($filename)) $this->setFilename($filename);
  31. $this->set('description', '');
  32. }
  33. /**
  34. * Set the filename associated with this Pagefile
  35. *
  36. * No need to call this as it's already called from the constructor.
  37. * This exists so that Pagefile/Pageimage descendents can create cloned variations, if applicable.
  38. *
  39. * @param string $filename
  40. *
  41. */
  42. public function setFilename($filename) {
  43. $basename = basename($filename);
  44. if($basename != $filename && strpos($filename, $this->pagefiles->path()) !== 0) {
  45. $this->install($filename);
  46. } else {
  47. $this->set('basename', $basename);
  48. }
  49. }
  50. /**
  51. * Install this Pagefile
  52. *
  53. * Implies copying the file to the correct location (if not already there), and populating it's name
  54. *
  55. * @param string $filename Full path and filename of file to install
  56. *
  57. */
  58. protected function ___install($filename) {
  59. $basename = $this->pagefiles->cleanBasename($filename, true);
  60. $pathInfo = pathinfo($basename);
  61. $basename = basename($basename, ".$pathInfo[extension]");
  62. // remove any extra dots in the filename
  63. $basename = str_replace(".", "_", $basename);
  64. $basenameNoExt = $basename;
  65. $basename .= ".$pathInfo[extension]";
  66. // ensure filename is unique
  67. $cnt = 0;
  68. while(file_exists($this->pagefiles->path() . $basename)) {
  69. $cnt++;
  70. $basename = "$basenameNoExt-$cnt.$pathInfo[extension]";
  71. }
  72. $destination = $this->pagefiles->path() . $basename;
  73. if(!@copy($filename, $destination)) throw new WireException("Unable to copy: $filename => $destination");
  74. if($this->config->chmodFile) chmod($this->pagefiles->path() . $basename, octdec($this->config->chmodFile));
  75. parent::set('basename', $basename);
  76. }
  77. /**
  78. * Sets a value in this Pagefile
  79. *
  80. * Externally, this would be used to set the file's basename or description
  81. *
  82. * @param string $key
  83. * @param mixed $value
  84. * @return this
  85. *
  86. */
  87. public function set($key, $value) {
  88. if($key == 'basename') $value = $this->pagefiles->cleanBasename($value, false);
  89. if($key == 'description') $value = $this->fuel('sanitizer')->textarea($value);
  90. return parent::set($key, $value);
  91. }
  92. /**
  93. * Get a value from this Pagefile
  94. *
  95. * @param string $key
  96. * @return mixed Returns null if value does not exist
  97. *
  98. */
  99. public function get($key) {
  100. $value = null;
  101. if($key == 'name') $key = 'basename';
  102. if($key == 'pathname') $key == 'filename';
  103. switch($key) {
  104. case 'url':
  105. case 'filename':
  106. case 'description':
  107. case 'ext':
  108. case 'hash':
  109. case 'filesize':
  110. case 'filesizeStr':
  111. // 'basename' property intentionally excluded
  112. $value = $this->$key();
  113. break;
  114. }
  115. if(is_null($value)) return parent::get($key);
  116. return $value;
  117. }
  118. /**
  119. * Return the next Pagefile in the Pagefiles, or NULL if at the end
  120. *
  121. * @return Pagefile|null
  122. *
  123. */
  124. public function getNext() {
  125. return $this->pagefiles->getNext($this);
  126. }
  127. /**
  128. * Return the previous Pagefile in the Pagefiles, or NULL if at the beginning
  129. *
  130. * @return Pagefile|null
  131. *
  132. */
  133. public function getPrev() {
  134. return $this->pagefiles->getPrev($this);
  135. }
  136. /**
  137. * Return the web accessible URL to this Pagefile
  138. *
  139. */
  140. public function url() {
  141. return $this->pagefiles->url . $this->basename;
  142. }
  143. /**
  144. * Returns the disk path to the Pagefile
  145. *
  146. */
  147. public function filename() {
  148. return $this->pagefiles->path . $this->basename;
  149. }
  150. /**
  151. * Returns the basename of this Pagefile
  152. *
  153. */
  154. public function basename() {
  155. return parent::get('basename');
  156. }
  157. /**
  158. * Returns the value of the description field
  159. *
  160. * @return string
  161. *
  162. */
  163. public function description() {
  164. return parent::get("description");
  165. }
  166. /**
  167. * Returns the filesize in number of bytes
  168. *
  169. * @return int
  170. *
  171. */
  172. public function filesize() {
  173. return @filesize($this->filename());
  174. }
  175. /**
  176. * Returns the filesize in a formatted, output-ready string
  177. *
  178. * @return int
  179. *
  180. */
  181. public function filesizeStr() {
  182. $size = $this->filesize();
  183. if($size < 1024) return number_format($size) . " bytes";
  184. $kb = round($size / 1024);
  185. return number_format($kb) . " kb";
  186. }
  187. /**
  188. * Returns the Pagefile's extension
  189. *
  190. */
  191. public function ext() {
  192. return substr($this->basename(), strrpos($this->basename(), '.')+1);
  193. }
  194. /**
  195. * When dereferenced as a string, a Pagefile returns it's basename
  196. *
  197. */
  198. public function __toString() {
  199. return $this->basename;
  200. }
  201. /**
  202. * Return a unique MD5 hash representing this Pagefile
  203. *
  204. */
  205. public function hash() {
  206. if($hash = parent::get('hash')) return $hash;
  207. $this->set('hash', md5($this->basename()));
  208. return parent::get('hash');
  209. }
  210. /**
  211. * Delete the physical file on disk, associated with this Pagefile
  212. *
  213. */
  214. public function unlink() {
  215. return unlink($this->filename);
  216. }
  217. /**
  218. * Rename this file to $basename
  219. *
  220. * @param string $basename
  221. * @return string|false Returns basename on success, or boolean false if rename failed
  222. *
  223. */
  224. public function rename($basename) {
  225. $basename = $this->pagefiles->cleanBasename($basename, true);
  226. if(rename($this->filename, $this->pagefiles->path . $basename)) {
  227. $this->set('basename', $basename);
  228. return $basename;
  229. }
  230. return false;
  231. }
  232. /**
  233. * Copy this file to the new specified path
  234. *
  235. * @param string $path Path (not including basename)
  236. * @return mixed result of copy() function
  237. *
  238. */
  239. public function copyToPath($path) {
  240. $result = copy($this->filename, $path . $this->basename());
  241. if($this->config->chmodFile) chmod($path . $this->basename(), octdec($this->config->chmodFile));
  242. return $result;
  243. }
  244. }