File.php 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241
  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. $rules = $attributes = [];
  54. $requiredIf = null;
  55. $fileLimit = $this->options['fileNumLimit'] ?? 1;
  56. if (!empty($value) && $fileLimit > 1){
  57. $rules[$this->column][] = function($atribute,$value,$fail)use($fileLimit){
  58. $value = array_filter(is_array($value) ? $value : explode(',', $value));
  59. if (count($value) > $fileLimit ) {
  60. $fail(trans('admin.uploader.max_file_limit', ['attribute' => $this->label, 'max' => $fileLimit]));
  61. }
  62. };
  63. return Validator::make($input, $rules, $this->getValidationMessages(), $attributes);
  64. }
  65. if (! $this->hasRule('required') && ! $requiredIf = $this->getRule('required_if*')) {
  66. return false;
  67. }
  68. $rules[$this->column] = $requiredIf ?: 'required';
  69. $attributes[$this->column] = $this->label;
  70. return Validator::make($input, $rules, $this->getValidationMessages(), $attributes);
  71. }
  72. /**
  73. * {@inheritDoc}
  74. */
  75. protected function prepareInputValue($file)
  76. {
  77. if (request()->has(static::FILE_DELETE_FLAG)) {
  78. return $this->destroy();
  79. }
  80. $this->destroyIfChanged($file);
  81. return $file;
  82. }
  83. /**
  84. * {@inheritDoc}
  85. */
  86. public function setRelation(array $options = [])
  87. {
  88. $this->options['formData']['_relation'] = [$options['relation'], $options['key'] ?? null];
  89. return $this;
  90. }
  91. /**
  92. * {@inheritDoc}
  93. */
  94. public function disable(bool $value = true)
  95. {
  96. $this->options['disabled'] = $value;
  97. return $this;
  98. }
  99. protected function formatFieldData($data)
  100. {
  101. return Helper::array($this->getValueFromData($data));
  102. }
  103. /**
  104. * @return array
  105. */
  106. protected function initialPreviewConfig()
  107. {
  108. $previews = [];
  109. foreach (Helper::array($this->value()) as $value) {
  110. $previews[] = [
  111. 'id' => $value,
  112. 'path' => Helper::basename($value),
  113. 'url' => $this->objectUrl($value),
  114. ];
  115. }
  116. return $previews;
  117. }
  118. protected function forceOptions()
  119. {
  120. $this->options['fileNumLimit'] = 1;
  121. }
  122. /**
  123. * {@inheritDoc}
  124. */
  125. public function render()
  126. {
  127. $this->setDefaultServer();
  128. if (! empty($this->value())) {
  129. $this->setupPreviewOptions();
  130. }
  131. $this->forceOptions();
  132. $this->formatValue();
  133. $this->addVariables([
  134. 'fileType' => $this->options['isImage'] ? '' : 'file',
  135. 'showUploadBtn' => ($this->options['autoUpload'] ?? false) ? false : true,
  136. 'options' => JavaScript::format($this->options),
  137. ]);
  138. return parent::render();
  139. }
  140. /**
  141. * @return void
  142. */
  143. protected function formatValue()
  144. {
  145. if ($this->value !== null) {
  146. $this->value = implode(',', Helper::array($this->value));
  147. } elseif (is_array($this->default)) {
  148. $this->default = implode(',', $this->default);
  149. }
  150. }
  151. /**
  152. * Webuploader 事件监听.
  153. *
  154. * @see http://fex.baidu.com/webuploader/doc/index.html#WebUploader_Uploader_events
  155. *
  156. * @param string $event
  157. * @param string $script
  158. * @param bool $once
  159. * @return $this
  160. */
  161. public function on(string $event, string $script, bool $once = false)
  162. {
  163. $script = JavaScript::make($script);
  164. $this->options['events'][] = compact('event', 'script', 'once');
  165. return $this;
  166. }
  167. /**
  168. * Webuploader 事件监听(once).
  169. *
  170. * @see http://fex.baidu.com/webuploader/doc/index.html#WebUploader_Uploader_events
  171. *
  172. * @param string $event
  173. * @param string $script
  174. * @return $this
  175. */
  176. public function once(string $event, string $script)
  177. {
  178. return $this->on($event, $script, true);
  179. }
  180. /**
  181. * @param Field $field
  182. * @param string|array $fieldRules
  183. * @return void
  184. */
  185. public static function deleteRules(Field $field, &$fieldRules)
  186. {
  187. if ($field instanceof self) {
  188. $fieldRules = is_string($fieldRules) ? explode('|', $fieldRules) : $fieldRules;
  189. Helper::deleteContains($fieldRules, ['image', 'file', 'dimensions', 'size', 'max', 'min']);
  190. }
  191. }
  192. public function override(bool $override = true)
  193. {
  194. $this->options['override'] = $override;
  195. return $this;
  196. }
  197. }