File.php 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254
  1. <?php
  2. namespace Dcat\Admin\Form\Field;
  3. use Dcat\Admin\Contracts\UploadField as UploadFieldInterface;
  4. use Dcat\Admin\Form\Field;
  5. use Dcat\Admin\Support\Helper;
  6. use Dcat\Admin\Support\JavaScript;
  7. use Illuminate\Support\Arr;
  8. use Illuminate\Support\Facades\Validator;
  9. class File extends Field implements UploadFieldInterface
  10. {
  11. use WebUploader;
  12. use UploadField;
  13. /**
  14. * @var array
  15. */
  16. protected $options = [
  17. 'events' => [],
  18. 'override' => false,
  19. ];
  20. public function __construct($column, $arguments = [])
  21. {
  22. parent::__construct($column, $arguments);
  23. $this->setUpDefaultOptions();
  24. }
  25. public function setElementName($name)
  26. {
  27. $this->mergeOptions(['elementName' => $name]);
  28. return parent::setElementName($name);
  29. }
  30. /**
  31. * @return mixed
  32. */
  33. public function defaultDirectory()
  34. {
  35. return config('admin.upload.directory.file');
  36. }
  37. /**
  38. * {@inheritdoc}
  39. */
  40. public function getValidator(array $input)
  41. {
  42. if (request()->has(static::FILE_DELETE_FLAG)) {
  43. return false;
  44. }
  45. if ($this->validator) {
  46. return $this->validator->call($this, $input);
  47. }
  48. if (! Arr::has($input, $this->column)) {
  49. return false;
  50. }
  51. $value = Arr::get($input, $this->column);
  52. $value = array_filter(is_array($value) ? $value : explode(',', $value));
  53. $fileLimit = $this->options['fileNumLimit'] ?? 1;
  54. if ($fileLimit < count($value)) {
  55. $this->form->responseValidationMessages(
  56. $this->column,
  57. trans('admin.uploader.max_file_limit', ['attribute' => $this->label, 'max' => $fileLimit])
  58. );
  59. return false;
  60. }
  61. $rules = $attributes = [];
  62. $requiredIf = null;
  63. if (! $this->hasRule('required') && ! $requiredIf = $this->getRule('required_if*')) {
  64. return false;
  65. }
  66. $rules[$this->column] = $requiredIf ?: 'required';
  67. $attributes[$this->column] = $this->label;
  68. return Validator::make($input, $rules, $this->getValidationMessages(), $attributes);
  69. }
  70. /**
  71. * {@inheritDoc}
  72. */
  73. protected function prepareInputValue($file)
  74. {
  75. if (request()->has(static::FILE_DELETE_FLAG)) {
  76. return $this->destroy();
  77. }
  78. $this->destroyIfChanged($file);
  79. return $file;
  80. }
  81. /**
  82. * {@inheritDoc}
  83. */
  84. public function setRelation(array $options = [])
  85. {
  86. $this->options['formData']['_relation'] = [$options['relation'], $options['key']];
  87. return $this;
  88. }
  89. /**
  90. * {@inheritDoc}
  91. */
  92. public function disable(bool $value = true)
  93. {
  94. $this->options['disabled'] = $value;
  95. return $this;
  96. }
  97. protected function formatFieldData($data)
  98. {
  99. return Helper::array($this->getValueFromData($data));
  100. }
  101. /**
  102. * @return array
  103. */
  104. protected function initialPreviewConfig()
  105. {
  106. $previews = [];
  107. foreach (Helper::array($this->value()) as $value) {
  108. $previews[] = [
  109. 'id' => $value,
  110. 'path' => Helper::basename($value),
  111. 'url' => $this->objectUrl($value),
  112. ];
  113. }
  114. return $previews;
  115. }
  116. protected function forceOptions()
  117. {
  118. $this->options['fileNumLimit'] = 1;
  119. }
  120. /**
  121. * {@inheritDoc}
  122. */
  123. public function render()
  124. {
  125. $this->setDefaultServer();
  126. if (! empty($this->value())) {
  127. $this->setupPreviewOptions();
  128. }
  129. $this->forceOptions();
  130. $this->formatValue();
  131. $this->addVariables([
  132. 'fileType' => $this->options['isImage'] ? '' : 'file',
  133. 'showUploadBtn' => ($this->options['autoUpload'] ?? false) ? false : true,
  134. 'options' => JavaScript::format($this->options),
  135. ]);
  136. return parent::render();
  137. }
  138. /**
  139. * @return void
  140. */
  141. protected function formatValue()
  142. {
  143. if ($this->value !== null) {
  144. $this->value = implode(',', Helper::array($this->value));
  145. } elseif (is_array($this->default)) {
  146. $this->default = implode(',', $this->default);
  147. }
  148. }
  149. /**
  150. * Webuploader 事件监听.
  151. *
  152. * @see http://fex.baidu.com/webuploader/doc/index.html#WebUploader_Uploader_events
  153. *
  154. * @param string $event
  155. * @param string $script
  156. * @param bool $once
  157. * @return $this
  158. */
  159. public function on(string $event, string $script, bool $once = false)
  160. {
  161. $script = JavaScript::make($script);
  162. $this->options['events'][] = compact('event', 'script', 'once');
  163. return $this;
  164. }
  165. /**
  166. * Webuploader 事件监听(once).
  167. *
  168. * @see http://fex.baidu.com/webuploader/doc/index.html#WebUploader_Uploader_events
  169. *
  170. * @param string $event
  171. * @param string $script
  172. * @return $this
  173. */
  174. public function once(string $event, string $script)
  175. {
  176. return $this->on($event, $script, true);
  177. }
  178. /**
  179. * @param Field $field
  180. * @param string|array $fieldRules
  181. * @return void
  182. */
  183. public static function deleteRules(Field $field, &$fieldRules)
  184. {
  185. if ($field instanceof self) {
  186. $fieldRules = is_string($fieldRules) ? explode('|', $fieldRules) : $fieldRules;
  187. Helper::deleteContains($fieldRules, ['image', 'file', 'dimensions', 'size', 'max', 'min']);
  188. }
  189. }
  190. public function override(bool $override = true)
  191. {
  192. $this->options['override'] = $override;
  193. return $this;
  194. }
  195. /**
  196. * Set key for error message.
  197. *
  198. * @param string|array $key
  199. * @return $this
  200. */
  201. public function setErrorKey($key)
  202. {
  203. parent::setErrorKey($key);
  204. $this->options['formData']['upload_column'] = $key;
  205. return $this;
  206. }
  207. }