BootstrapFile.php 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195
  1. <?php
  2. namespace Dcat\Admin\Form\Field;
  3. use Dcat\Admin\Form\Field;
  4. use Illuminate\Support\Arr;
  5. use Illuminate\Support\Facades\Validator;
  6. use Symfony\Component\HttpFoundation\File\UploadedFile;
  7. class BootstrapFile extends Field
  8. {
  9. use BootstrapUploadField;
  10. /**
  11. * Css.
  12. *
  13. * @var array
  14. */
  15. protected static $css = [
  16. '/vendor/dcat-admin/bootstrap-fileinput/css/fileinput.min.css?v=4.5.2',
  17. ];
  18. /**
  19. * Js.
  20. *
  21. * @var array
  22. */
  23. protected static $js = [
  24. '/vendor/dcat-admin/bootstrap-fileinput/js/plugins/canvas-to-blob.min.js',
  25. '/vendor/dcat-admin/bootstrap-fileinput/js/fileinput.min.js?v=4.5.2',
  26. ];
  27. /**
  28. * Create a new File instance.
  29. *
  30. * @param string $column
  31. * @param array $arguments
  32. */
  33. public function __construct($column, $arguments = [])
  34. {
  35. $this->initStorage();
  36. parent::__construct($column, $arguments);
  37. }
  38. /**
  39. * Default directory for file to upload.
  40. *
  41. * @return mixed
  42. */
  43. public function defaultDirectory()
  44. {
  45. return config('admin.upload.directory.file');
  46. }
  47. /**
  48. * {@inheritdoc}
  49. */
  50. public function getValidator(array $input)
  51. {
  52. if (request()->has(static::FILE_DELETE_FLAG)) {
  53. return false;
  54. }
  55. if ($this->validator) {
  56. return $this->validator->call($this, $input);
  57. }
  58. /*
  59. * If has original value, means the form is in edit mode,
  60. * then remove required rule from rules.
  61. */
  62. if ($this->original()) {
  63. $this->removeRule('required');
  64. }
  65. /*
  66. * Make input data validatable if the column data is `null`.
  67. */
  68. if (Arr::has($input, $this->column) && is_null(Arr::get($input, $this->column))) {
  69. $input[$this->column] = '';
  70. }
  71. $rules = $attributes = [];
  72. if (!$fieldRules = $this->getRules()) {
  73. return false;
  74. }
  75. $rules[$this->column] = $fieldRules;
  76. $attributes[$this->column] = $this->label;
  77. return Validator::make($input, $rules, $this->getValidationMessages(), $attributes);
  78. }
  79. /**
  80. * Prepare for saving.
  81. *
  82. * @param UploadedFile|array $file
  83. *
  84. * @return mixed|string
  85. */
  86. protected function prepareToSave($file)
  87. {
  88. if (request()->has(static::FILE_DELETE_FLAG)) {
  89. return $this->destroy();
  90. }
  91. $this->name = $this->getStoreName($file);
  92. return $this->uploadAndDeleteOriginal($file);
  93. }
  94. /**
  95. * Upload file and delete original file.
  96. *
  97. * @param UploadedFile $file
  98. *
  99. * @return mixed
  100. */
  101. protected function uploadAndDeleteOriginal(UploadedFile $file)
  102. {
  103. $this->renameIfExists($file);
  104. $path = null;
  105. if (!is_null($this->storagePermission)) {
  106. $path = $this->storage->putFileAs($this->getDirectory(), $file, $this->name, $this->storagePermission);
  107. } else {
  108. $path = $this->storage->putFileAs($this->getDirectory(), $file, $this->name);
  109. }
  110. $this->destroy();
  111. return $path;
  112. }
  113. /**
  114. * Preview html for file-upload plugin.
  115. *
  116. * @return string
  117. */
  118. protected function preview()
  119. {
  120. return $this->objectUrl($this->value());
  121. }
  122. /**
  123. * Initialize the caption.
  124. *
  125. * @param string $caption
  126. *
  127. * @return string
  128. */
  129. protected function initialCaption($caption)
  130. {
  131. return basename($caption);
  132. }
  133. /**
  134. * @return array
  135. */
  136. protected function initialPreviewConfig()
  137. {
  138. return [
  139. ['caption' => basename($this->value()), 'key' => 0],
  140. ];
  141. }
  142. /**
  143. * Render file upload field.
  144. *
  145. * @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
  146. */
  147. public function render()
  148. {
  149. $this->options(['overwriteInitial' => true]);
  150. $this->setupDefaultOptions();
  151. if (!empty($this->value)) {
  152. $this->attribute('data-initial-preview', $this->preview());
  153. $this->attribute('data-initial-caption', $this->initialCaption($this->value));
  154. $this->setupPreviewOptions();
  155. }
  156. $options = json_encode($this->options);
  157. $this->script = <<<JS
  158. $("{$this->getElementClassSelector()}").fileinput({$options});
  159. JS;
  160. return parent::render();
  161. }
  162. }