PageRenderTime 33ms CodeModel.GetById 12ms RepoModel.GetById 0ms app.codeStats 0ms

/plugins/Field/src/Field/FileField.php

http://github.com/QuickAppsCMS/QuickApps-CMS
PHP | 273 lines | 193 code | 28 blank | 52 comment | 19 complexity | f82f4a66a8e045b75b25c74d0994f5b0 MD5 | raw file
Possible License(s): LGPL-2.1, MPL-2.0-no-copyleft-exception, GPL-3.0
  1. <?php
  2. /**
  3. * Licensed under The GPL-3.0 License
  4. * For full copyright and license information, please see the LICENSE.txt
  5. * Redistributions of files must retain the above copyright notice.
  6. *
  7. * @since 2.0.0
  8. * @author Christopher Castro <chris@quickapps.es>
  9. * @link http://www.quickappscms.org
  10. * @license http://opensource.org/licenses/gpl-3.0.html GPL-3.0 License
  11. */
  12. namespace Field\Field;
  13. use Cake\Filesystem\File;
  14. use Cake\ORM\TableRegistry;
  15. use Cake\Utility\Hash;
  16. use Cake\Validation\Validator;
  17. use CMS\View\View;
  18. use Field\Handler;
  19. use Field\Model\Entity\Field;
  20. use Field\Model\Entity\FieldInstance;
  21. /**
  22. * File Field Handler.
  23. *
  24. * This field allows attach files to entities.
  25. */
  26. class FileField extends Handler
  27. {
  28. /**
  29. * {@inheritDoc}
  30. */
  31. public function info()
  32. {
  33. return [
  34. 'type' => 'text',
  35. 'name' => __d('field', 'Attachment'),
  36. 'description' => __d('field', 'Allows to upload and attach files to contents.'),
  37. 'hidden' => false,
  38. 'maxInstances' => 0,
  39. 'searchable' => false,
  40. ];
  41. }
  42. /**
  43. * {@inheritDoc}
  44. */
  45. public function render(Field $field, View $view)
  46. {
  47. if ($field->metadata->settings['multi'] === 'custom') {
  48. $settings = $field->metadata->settings;
  49. $settings['multi'] = $field->metadata->settings['multi_custom'];
  50. $field->metadata->set('settings', $settings);
  51. }
  52. return $view->element('Field.FileField/display', compact('field'));
  53. }
  54. /**
  55. * {@inheritDoc}
  56. */
  57. public function edit(Field $field, View $view)
  58. {
  59. return $view->element('Field.FileField/edit', compact('field'));
  60. }
  61. /**
  62. * {@inheritDoc}
  63. */
  64. public function fieldAttached(Field $field)
  65. {
  66. $extra = (array)$field->extra;
  67. if (!empty($extra)) {
  68. $newExtra = [];
  69. foreach ($extra as $file) {
  70. $newExtra[] = array_merge([
  71. 'mime_icon' => '',
  72. 'file_name' => '',
  73. 'file_size' => '',
  74. 'description' => '',
  75. ], (array)$file);
  76. }
  77. $field->set('extra', $newExtra);
  78. }
  79. }
  80. /**
  81. * {@inheritDoc}
  82. */
  83. public function validate(Field $field, Validator $validator)
  84. {
  85. if ($field->metadata->required) {
  86. $validator
  87. ->add($field->name, 'isRequired', [
  88. 'rule' => function ($value, $context) use ($field) {
  89. if (isset($context['data'][$field->name])) {
  90. $count = 0;
  91. foreach ($context['data'][$field->name] as $k => $file) {
  92. if (is_integer($k)) {
  93. $count++;
  94. }
  95. }
  96. return $count > 0;
  97. }
  98. return false;
  99. },
  100. 'message' => __d('field', 'You must upload one file at least.')
  101. ]);
  102. }
  103. if ($field->metadata->settings['multi'] !== 'custom') {
  104. $maxFiles = intval($field->metadata->settings['multi']);
  105. } else {
  106. $maxFiles = intval($field->metadata->settings['multi_custom']);
  107. }
  108. $validator
  109. ->add($field->name, 'numberOfFiles', [
  110. 'rule' => function ($value, $context) use ($field, $maxFiles) {
  111. if (isset($context['data'][$field->name])) {
  112. $count = 0;
  113. foreach ($context['data'][$field->name] as $k => $file) {
  114. if (is_integer($k)) {
  115. $count++;
  116. }
  117. }
  118. return $count <= $maxFiles;
  119. }
  120. return false;
  121. },
  122. 'message' => __d('field', 'You can upload {0} files as maximum.', $maxFiles)
  123. ]);
  124. if (!empty($field->metadata->settings['extensions'])) {
  125. $extensions = $field->metadata->settings['extensions'];
  126. $extensions = array_map('strtolower', array_map('trim', explode(',', $extensions)));
  127. $validator
  128. ->add($field->name, 'extensions', [
  129. 'rule' => function ($value, $context) use ($field, $extensions) {
  130. if (isset($context['data'][$field->name])) {
  131. foreach ($context['data'][$field->name] as $k => $file) {
  132. if (is_integer($k)) {
  133. $ext = strtolower(str_replace('.', '', strrchr($file['file_name'], '.')));
  134. if (!in_array($ext, $extensions)) {
  135. return false;
  136. }
  137. }
  138. }
  139. return true;
  140. }
  141. return false;
  142. },
  143. 'message' => __d('field', 'Invalid file extension. Allowed extension are: {0}', $field->metadata->settings['extensions'])
  144. ]);
  145. }
  146. return true;
  147. }
  148. /**
  149. * {@inheritDoc}
  150. *
  151. * - extra: Holds a list (array) of files and their in formation (mime-icon,
  152. * file name, etc).
  153. *
  154. * - value: Holds a text containing all file names separated by space.
  155. */
  156. public function beforeSave(Field $field, $post)
  157. {
  158. // FIX Removes the "dummy" input from extra if exists, the "dummy" input is
  159. // used to force Field Handler to work when empty POST information is sent
  160. $extra = [];
  161. foreach ((array)$field->extra as $k => $v) {
  162. if (is_integer($k)) {
  163. $extra[] = $v;
  164. }
  165. }
  166. $field->set('extra', $extra);
  167. $files = (array)$post;
  168. if (!empty($files)) {
  169. $value = [];
  170. foreach ($files as $k => $file) {
  171. if (!is_integer($k)) {
  172. unset($files[$k]);
  173. continue;
  174. } else {
  175. $file = array_merge([
  176. 'mime_icon' => '',
  177. 'file_name' => '',
  178. 'file_size' => '',
  179. 'description' => '',
  180. ], (array)$file);
  181. }
  182. $value[] = trim("{$file['file_name']} {$file['description']}");
  183. }
  184. $field->set('value', implode(' ', $value));
  185. $field->set('extra', $files);
  186. }
  187. if ($field->metadata->value_id) {
  188. $newFileNames = Hash::extract($files, '{n}.file_name');
  189. try {
  190. $prevFiles = (array)TableRegistry::get('Eav.EavValues')
  191. ->get($field->metadata->value_id)
  192. ->extra;
  193. } catch (\Exception $ex) {
  194. $prevFiles = [];
  195. }
  196. foreach ($prevFiles as $f) {
  197. if (!in_array($f['file_name'], $newFileNames)) {
  198. $file = normalizePath(WWW_ROOT . "/files/{$field->metadata->settings['upload_folder']}/{$f['file_name']}", DS);
  199. $file = new File($file);
  200. $file->delete();
  201. }
  202. }
  203. }
  204. return true;
  205. }
  206. /**
  207. * {@inheritDoc}
  208. */
  209. public function settings(FieldInstance $instance, View $view)
  210. {
  211. return $view->element('Field.FileField/settings_form', compact('instance'));
  212. }
  213. /**
  214. * {@inheritDoc}
  215. */
  216. public function defaultSettings(FieldInstance $instance)
  217. {
  218. return [
  219. 'extensions' => '',
  220. 'multi' => 1,
  221. 'multi_custom' => 1,
  222. 'upload_folder' => '',
  223. 'description' => '',
  224. ];
  225. }
  226. /**
  227. * {@inheritDoc}
  228. */
  229. public function viewModeSettings(FieldInstance $instance, View $view, $viewMode)
  230. {
  231. return $view->element('Field.FileField/view_mode_form', compact('instance', 'viewMode'));
  232. }
  233. /**
  234. * {@inheritDoc}
  235. */
  236. public function defaultViewModeSettings(FieldInstance $instance, $viewMode)
  237. {
  238. return [
  239. 'label_visibility' => 'above',
  240. 'shortcodes' => true,
  241. 'hidden' => false,
  242. 'formatter' => 'link',
  243. ];
  244. }
  245. }