File.php 5.4 KB

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