PageRenderTime 38ms CodeModel.GetById 13ms RepoModel.GetById 1ms app.codeStats 0ms

/application/libraries/Uploader.php

http://github.com/tcm-project/tangocms
PHP | 254 lines | 116 code | 24 blank | 114 comment | 15 complexity | 7b1d204746f9c0bfea5a3486e8055d10 MD5 | raw file
Possible License(s): LGPL-2.1
  1. <?php
  2. /**
  3. * Zula Framework Uploader
  4. * --- A simple upload handler class to assist with uploading of files
  5. * Any file uploaded will be stored using a random file name by default
  6. *
  7. * @patches submit all patches to patches@tangocms.org
  8. *
  9. * @author Alex Cartwright
  10. * @copyright Copyright (C) 2007, 2008, 2009, 2010 Alex Cartwright
  11. * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html GNU/LGPL 2.1
  12. * @package Zula_Uploader
  13. */
  14. class Uploader extends Zula_LibraryBase implements Iterator {
  15. /**
  16. * Upload name/key to be used
  17. * @var string
  18. */
  19. protected $uploadName = null;
  20. /**
  21. * Holds details for all of the files
  22. * @var array
  23. */
  24. protected $files = array();
  25. /**
  26. * Main configuration array that will be used for
  27. * all of the uploaded files.
  28. * @var array
  29. */
  30. protected $config = array(
  31. 'allowedMime' => array(),
  32. 'uploadDir' => '',
  33. 'maxFileSize' => 0,
  34. 'subDir' => true,
  35. 'subDirName' => null,
  36. 'overwrite' => false,
  37. 'extractArchives' => false,
  38. );
  39. /**
  40. * Holds which index/iteration we are on for the files
  41. * @var int
  42. */
  43. private $filePosition = 0;
  44. /**
  45. * Constructor
  46. * Sets the file key/name to be used for uploading
  47. *
  48. * @param string $uploadName
  49. * @param string $uploadDir
  50. * @return object
  51. */
  52. public function __construct( $uploadName, $uploadDir=null ) {
  53. if ( ini_get( 'file_uploads' ) == false ) {
  54. throw new Uploader_NotEnabled( 'file uploads are currently disabled with the PHP configuration' );
  55. } else if ( isset( $_FILES[ $uploadName ] ) ) {
  56. $this->uploadName = $uploadName;
  57. if ( is_array( $_FILES[ $uploadName ]['tmp_name'] ) ) {
  58. $fileCount = count( $_FILES[ $uploadName ]['tmp_name'] );
  59. for( $i = 0; $i < $fileCount; $i++ ) {
  60. $this->files[] = array(
  61. 'name' => str_replace( "\0", '', $_FILES[ $uploadName ]['name'][ $i ] ),
  62. 'tmp_name' => $_FILES[ $uploadName ]['tmp_name'][ $i ],
  63. 'size' => $_FILES[ $uploadName ]['size'][ $i ],
  64. 'error' => $_FILES[ $uploadName ]['error'][ $i ],
  65. 'mime' => null,
  66. );
  67. }
  68. } else {
  69. $this->files[] = $_FILES[ $uploadName ];
  70. $this->files[0]['name'] = str_replace( "\0", '', $this->files[0]['name'] );
  71. $this->files[0]['mime'] = null;
  72. unset( $this->files[0]['type'] ); # This is re-genereated with a more reliable method
  73. }
  74. $this->uploadDir( $uploadDir );
  75. // Set max file size to that of the current php.ini default
  76. $this->maxFileSize( ini_get( 'upload_max_filesize' ) );
  77. } else {
  78. throw new Uploader_NoExist( 'Upload file name "'.$uploadName.'" does not exist' );
  79. }
  80. }
  81. /**
  82. * Get details about the uploader configuration
  83. *
  84. * @param string $name
  85. * @return mixed
  86. */
  87. public function __get( $name ) {
  88. return isset($this->config[ $name ]) ? $this->config[ $name ] : parent::__get( $name );
  89. }
  90. /**
  91. * Sets the directory to where files will be uploaded
  92. * to. If left blank, then it will revert to the
  93. * default sets within Zula.
  94. *
  95. * @param string $dir
  96. * @return bool|object
  97. */
  98. public function uploadDir( $dir=null ) {
  99. if ( !trim( $dir ) ) {
  100. $dir = $this->_zula->getDir( 'uploads' );
  101. }
  102. $this->config['uploadDir'] = rtrim( $dir, '/\ ' );
  103. return $this;
  104. }
  105. /**
  106. * Set maximum file size for uploaded files. Also
  107. * accepts PHP short-hand byte value, ie '9m' or
  108. * '5k', or '4g'
  109. *
  110. * @param int $fileSize
  111. * @return bool|object
  112. */
  113. public function maxFileSize( $fileSize ) {
  114. $this->config['maxFileSize'] = zula_byte_value( $fileSize );
  115. return $this;
  116. }
  117. /**
  118. * Sets the allowed mime types
  119. *
  120. * @param array|string $mime
  121. * @return object
  122. */
  123. public function allowedMime( $mime=null ) {
  124. $this->config['allowedMime'] = array_map( 'strtolower', (array) $mime );
  125. return $this;
  126. }
  127. /**
  128. * Quick method to easily add in allowed mime types for
  129. * common images. Note, this *appends* to the allowed mimes
  130. *
  131. * @return object
  132. */
  133. public function allowImages() {
  134. $this->config['allowedMime'] = array_merge(
  135. $this->config['allowedMime'],
  136. array('image/gif', 'image/jpeg', 'image/png')
  137. );
  138. return $this;
  139. }
  140. /**
  141. * Sets if sub-directories should be made
  142. *
  143. * @param bool $subdir
  144. * @return object
  145. */
  146. public function subDirectories( $subdir=true ) {
  147. $this->config['subDir'] = (bool) $subdir;
  148. return $this;
  149. }
  150. /**
  151. * Sets the name of the sub directory to use, if not provided
  152. * then a random one will be generated for you and used for all
  153. * multiple file uploads.
  154. *
  155. * @param string $name
  156. * @return object
  157. */
  158. public function subDirectoryName( $name ) {
  159. $this->config['subDirName'] = (string) $name;
  160. return $this;
  161. }
  162. /**
  163. * Sets if a file can be overwritten, when providing a custom
  164. * name for the file when uploading (instead of random)
  165. *
  166. * @param bool $allow
  167. * @return object
  168. */
  169. public function allowOverwrite( $allow=true ) {
  170. $this->config['overwrite'] = (bool) $allow;
  171. return $this;
  172. }
  173. /**
  174. * Allow archives (currently only .zip) to be uploaded and the contents
  175. * extracted. Each file in the archive must match the allowed mime
  176. * types and file size, if they don't they will not be kept.
  177. *
  178. * bool false will be returned if there is no method for extracting the
  179. * supported archive types.
  180. *
  181. * @param bool $extract
  182. * @return object|bool
  183. */
  184. public function extractArchives( $extract=true ) {
  185. if ( $extract && zula_supports( 'zipExtraction' ) ) {
  186. $this->config['extractArchives'] = true;
  187. $this->config['allowedMime'][] = 'application/zip';
  188. return $this;
  189. } else {
  190. $this->config['extractArchives'] = false;
  191. return $this;
  192. }
  193. }
  194. /**
  195. * Returns instance of Uploader_File for the current file
  196. * index/iterator, or false on failure.
  197. *
  198. * @param int $key
  199. * @return object|false
  200. */
  201. public function getFile( $key=null ) {
  202. if ( $key === null ) {
  203. $key = $this->filePosition;
  204. }
  205. if ( isset( $this->files[ $key ] ) ) {
  206. return new Uploader_File( $this->files[ $key ], $this );
  207. } else {
  208. return false;
  209. }
  210. }
  211. /**
  212. * PHP Iterator Methods
  213. */
  214. public function rewind() {
  215. $this->filePosition = 0;
  216. }
  217. public function current() {
  218. return $this->getFile();
  219. }
  220. public function key() {
  221. return $this->filePosition;
  222. }
  223. public function next() {
  224. ++$this->filePosition;
  225. }
  226. public function valid() {
  227. return isset( $this->files[ $this->filePosition ] );
  228. }
  229. }
  230. ?>