PageRenderTime 22ms CodeModel.GetById 27ms RepoModel.GetById 1ms app.codeStats 0ms

/vendors/olc_baker/skels/default/Model/Behavior/UploadBehavior.php

https://github.com/kiang/olc_baker
PHP | 243 lines | 209 code | 23 blank | 11 comment | 31 complexity | bd38b36f5d27db58d78374a35f2e4421 MD5 | raw file
  1. <?php
  2. /**
  3. * This file is a part of UploadPack - a set of classes that makes file uploads in CakePHP as easy as possible.
  4. *
  5. * UploadBehavior
  6. *
  7. * UploadBehavior does all the job of saving files to disk while saving records to database. For more info read UploadPack documentation.
  8. *
  9. * @author MichaƂ Szajbe (michal.szajbe@gmail.com) and netguru.pl
  10. * @link http://github.com/netguru/uploadpack
  11. * @version 0.1
  12. */
  13. App::import('Core', 'String');
  14. class UploadBehavior extends ModelBehavior
  15. {
  16. public static $__settings = array();
  17. public $toWrite = array();
  18. public $toDelete = array();
  19. public function setup(&$model, $settings = array())
  20. {
  21. $defaults = array(
  22. 'path' => ':webroot/upload/:model/:id/:basename_:style.:extension',
  23. 'styles' => array()
  24. );
  25. foreach ($settings as $field => $array) {
  26. self::$__settings[$model->name][$field] = array_merge($defaults, $array);
  27. }
  28. }
  29. public function beforeSave(&$model)
  30. {
  31. $this->_reset();
  32. foreach (self::$__settings[$model->name] as $field => $settings) {
  33. if (!empty($model->data[$model->name][$field]) && is_array($model->data[$model->name][$field]) && is_uploaded_file($model->data[$model->name][$field]['tmp_name'])) {
  34. $pathInfo = pathinfo($model->data[$model->name][$field]['name']);
  35. $model->data[$model->name][$field]['name'] = String::uuid() . '.' . $pathInfo['extension'];
  36. if (!empty($model->id)) {
  37. $this->_prepareToDeleteFiles($model, $field, true);
  38. }
  39. $this->_prepareToWriteFiles($model, $field);
  40. unset($model->data[$model->name][$field]);
  41. $model->data[$model->name][$field] = $this->toWrite[$field]['name'];
  42. } else {
  43. unset($model->data[$model->name][$field]);
  44. }
  45. }
  46. return true;
  47. }
  48. public function afterSave(&$model, $create)
  49. {
  50. if (!$create) {
  51. $this->_deleteFiles($model);
  52. }
  53. $this->_writeFiles($model);
  54. }
  55. public function beforeDelete(&$model)
  56. {
  57. $this->_reset();
  58. $this->_prepareToDeleteFiles($model);
  59. return true;
  60. }
  61. public function afterDelete(&$model)
  62. {
  63. $this->_deleteFiles($model);
  64. }
  65. public function _reset()
  66. {
  67. $this->_toWrite = null;
  68. $this->_toDelete = null;
  69. }
  70. public function _prepareToWriteFiles(&$model, $field)
  71. {
  72. $this->toWrite[$field] = $model->data[$model->name][$field];
  73. }
  74. public function _writeFiles(&$model)
  75. {
  76. if (!empty($this->toWrite)) {
  77. foreach ($this->toWrite as $field => $toWrite) {
  78. $settings = $this->_interpolate($model, $field, $toWrite['name'], 'original');
  79. $destDir = dirname($settings['path']);
  80. if (!file_exists($destDir)) {
  81. @mkdir($destDir, 0777, true);
  82. @chmod($destDir, 0777);
  83. }
  84. if (is_dir($destDir) && is_writable($destDir)) {
  85. if (@move_uploaded_file($toWrite['tmp_name'], $settings['path'])) {
  86. foreach ($settings['styles'] as $style => $geometry) {
  87. $newSettings = $this->_interpolate($model, $field, $toWrite['name'], $style);
  88. $this->_resize($settings['path'], $newSettings['path'], $geometry);
  89. }
  90. }
  91. }
  92. }
  93. }
  94. }
  95. public function _prepareToDeleteFiles(&$model, $field = null, $forceRead = false)
  96. {
  97. $needToRead = true;
  98. if ($field === null) {
  99. $fields = array_keys(self::$__settings[$model->name]);
  100. } else {
  101. $fields = array($field);
  102. }
  103. if (!$forceRead && !empty($model->data[$model->alias])) {
  104. $needToRead = false;
  105. foreach ($fields as $field) {
  106. if (!array_key_exists($field, $model->data[$model->alias])) {
  107. $needToRead = true;
  108. break;
  109. }
  110. }
  111. }
  112. if ($needToRead) {
  113. $data = $model->find('first', array('conditions' => array($model->alias.'.'.$model->primaryKey => $model->id), 'fields' => $fields));
  114. } else {
  115. $data = $model->data;
  116. }
  117. if (is_array($this->toDelete)) {
  118. $this->toDelete = array_merge($this->toDelete, $data[$model->alias]);
  119. } else {
  120. $this->toDelete = $data[$model->alias];
  121. }
  122. $this->toDelete['id'] = $model->id;
  123. }
  124. public function _deleteFiles(&$model)
  125. {
  126. foreach (self::$__settings[$model->name] as $field => $settings) {
  127. if (!empty($this->toDelete[$field])) {
  128. $styles = array_keys($settings['styles']);
  129. $styles[] = 'original';
  130. foreach ($styles as $style) {
  131. $settings = $this->_interpolate($model, $field, $this->toDelete[$field], $style);
  132. if (file_exists($settings['path'])) {
  133. @unlink($settings['path']);
  134. }
  135. }
  136. }
  137. }
  138. }
  139. public function _interpolate(&$model, $field, $filename, $style)
  140. {
  141. return self::interpolate($model->name, $model->id, $field, $filename, $style);
  142. }
  143. public static function interpolate($modelName, $modelId, $field, $filename, $style, $defaults = array())
  144. {
  145. $pathinfo = pathinfo($filename);
  146. $interpolations = array_merge(array(
  147. 'webroot' => preg_replace('/\/$/', '', WWW_ROOT),
  148. 'model' => Inflector::tableize($modelName),
  149. 'basename' => !empty($filename) ? $pathinfo['filename'] : null,
  150. 'extension' => !empty($filename) ? $pathinfo['extension'] : null,
  151. 'id' => $modelId,
  152. 'style' => $style
  153. ), $defaults);
  154. $settings = self::$__settings[$modelName][$field];
  155. $keys = array('path', 'url', 'default_url');
  156. foreach ($interpolations as $k => $v) {
  157. foreach ($keys as $key) {
  158. if (isset($settings[$key])) {
  159. $settings[$key] = preg_replace('/\/{2,}/', '/', str_replace(":$k", $v, $settings[$key]));
  160. }
  161. }
  162. }
  163. return $settings;
  164. }
  165. public function _resize($srcFile, $destFile, $geometry)
  166. {
  167. copy($srcFile, $destFile);
  168. $pathinfo = pathinfo($srcFile);
  169. $src = null;
  170. $createHandler = null;
  171. $outputHandler = null;
  172. switch (low($pathinfo['extension'])) {
  173. case 'gif':
  174. $createHandler = 'imagecreatefromgif';
  175. $outputHandler = 'imagegif';
  176. break;
  177. case 'jpg':
  178. case 'jpeg':
  179. $createHandler = 'imagecreatefromjpeg';
  180. $outputHandler = 'imagejpeg';
  181. break;
  182. case 'png':
  183. $createHandler = 'imagecreatefrompng';
  184. $outputHandler = 'imagepng';
  185. break;
  186. default:
  187. return false;
  188. }
  189. if ($src = $createHandler($destFile)) {
  190. $srcW = imagesx($src);
  191. $srcH = imagesy($src);
  192. list($width, $height) = explode('x', $geometry);
  193. $destW = $width;
  194. $destH = $height;
  195. if ($srcW > $width || $srcH > $height) {
  196. $ratio = $width / $srcW;
  197. if ($srcH * $ratio <= $height) {
  198. $destH = $srcH * $ratio;
  199. } else {
  200. $ratio = $height / $srcH;
  201. $destW = $srcW * $ratio;
  202. }
  203. }
  204. $destX = 0;
  205. $destY = 0;
  206. if ($destW < $width) {
  207. $destX = floor(($width - $destW) / 2);
  208. }
  209. if ($destY < $height) {
  210. $destY = floor(($height - $destH) / 2);
  211. }
  212. $img = imagecreatetruecolor($width, $height);
  213. imagefill($img, 0, 0, imagecolorallocate($img, 255, 255, 255));
  214. imagecopyresampled($img, $src, $destX, $destY, 0, 0, $destW, $destH, $srcW, $srcH);
  215. $outputHandler($img, $destFile);
  216. return true;
  217. }
  218. return false;
  219. }
  220. }