Browse Source

修复上传文件表单无法兼容分步表单功能bug

jqh 5 years ago
parent
commit
d8f191c7ab

+ 1 - 1
resources/lang/en/admin.php

@@ -170,7 +170,7 @@ return [
         'interrupt'              => 'Interrupt',
         'upload_failed'          => 'Upload failed! Please try again.',
         'selected_files'         => ':num files selected,size: :size。',
-        'selected_has_failed'    => 'Uploaded: :success, failed: :fail, <a class="retry"  href="javascript:"";">retry</a>or<a class="ignore" href="javascript:"";">ignore</a>',
+        'selected_has_failed'    => 'Uploaded: :success, failed: :fail, <a class="retry"  href="javascript:"";">retry </a>or<a class="ignore" href="javascript:"";"> ignore</a>',
         'selected_success'       => ':num(:size) files selected, Uploaded: :success.',
         'dot'                    => ', ',
         'failed_num'             => 'failed::fail.',

+ 38 - 7
src/Form/Builder.php

@@ -458,21 +458,52 @@ class Builder
     /**
      * Get specify field.
      *
-     * @param string|null $name
+     * @param string $name
      *
-     * @return Field|Collection|Field[]|null
+     * @return Field|null
      */
-    public function field($name = null)
+    public function field($name)
     {
-        if ($name === null) {
-            return $this->fields;
-        }
-
         return $this->fields->first(function (Field $field) use ($name) {
             return $field->column() == $name;
         });
     }
 
+    /**
+     * @param string $name
+     * @return Field|null
+     */
+    public function stepField($name)
+    {
+        if (! $builder = $this->getStepBuilder()) {
+            return;
+        }
+
+        foreach ($builder->all() as $step) {
+            if ($field = $step->field($name)) {
+                return $field;
+            }
+        }
+    }
+
+    /**
+     * @return Field[]|Collection
+     */
+    public function stepFields()
+    {
+        $fields = new Collection();
+
+        if (! $builder = $this->getStepBuilder()) {
+            return $fields;
+        }
+
+        foreach ($builder->all() as $step) {
+            $fields = $fields->merge($step->fields());
+        }
+
+        return $fields;
+    }
+
     /**
      * @param $column
      * @return void

+ 25 - 12
src/Form/Concerns/HasFiles.php

@@ -2,9 +2,13 @@
 
 namespace Dcat\Admin\Form\Concerns;
 
+use Dcat\Admin\Form\Builder;
 use Symfony\Component\HttpFoundation\File\UploadedFile;
 use Dcat\Admin\Form\Field;
 
+/**
+ * @property Builder $builder
+ */
 trait HasFiles
 {
     /**
@@ -14,15 +18,16 @@ trait HasFiles
     {
         $column = $data['upload_column'] ?? null;
         $file   = $data['file'] ?? null;
-        if (!$column && !$file instanceof UploadedFile) {
+        if (! $column && ! $file instanceof UploadedFile) {
             return;
         }
 
-        $field = $this->builder->field($column);
-        if (!$field || !$field instanceof Field\File) {
-            return;
+        $field = $this->builder->field($column) ?: $this->builder->stepField($column);
+
+        if ($field && $field instanceof Field\File) {
+            return $field->upload($file);
         }
-        return $field->upload($file);
+
     }
 
     /**
@@ -41,7 +46,8 @@ trait HasFiles
             return;
         }
 
-        $field = $this->builder->field($column);
+        $field = $this->builder->field($column) ?: $this->builder->stepField($column);
+
         if ($field && in_array(Field\UploadField::class, class_uses($field))) {
             $field->deleteFile($file);
 
@@ -49,15 +55,22 @@ trait HasFiles
         }
     }
 
+    /**
+     * @param array $input
+     * @return void
+     */
     public function deleteFilesWhenCreating(array $input)
     {
-        $this->builder->fields()->filter(function ($field) {
-            return $field instanceof Field\File;
-        })->each(function (Field\File $file) use ($input) {
-            $file->setOriginal($input);
+        $this->builder
+            ->fields()
+            ->filter(function ($field) {
+                return $field instanceof Field\File;
+            })
+            ->each(function (Field\File $file) use ($input) {
+                $file->setOriginal($input);
 
-            $file->destroy();
-        });
+                $file->destroy();
+            });
     }
 
     /**

+ 6 - 2
src/Form/Concerns/HasSteps.php

@@ -3,8 +3,12 @@
 namespace Dcat\Admin\Form\Concerns;
 
 use Closure;
+use Dcat\Admin\Form\Builder;
 use Dcat\Admin\Form\StepBuilder;
 
+/**
+ * @property Builder $builder
+ */
 trait HasSteps
 {
     /**
@@ -41,7 +45,7 @@ trait HasSteps
                 return;
             }
 
-            foreach ($steps[$currentIndex]->field() as $field) {
+            foreach ($steps[$currentIndex]->fields() as $field) {
                 $this->pushField($field);
             }
             return;
@@ -49,7 +53,7 @@ trait HasSteps
 
         if (! empty($data[StepBuilder::ALL_STEPS])) {
             foreach ($steps as $stepForm) {
-                foreach ($stepForm->field() as $field) {
+                foreach ($stepForm->fields() as $field) {
                     $this->pushField($field);
                 }
             }

+ 24 - 7
src/Form/Field/File.php

@@ -161,24 +161,41 @@ class File extends Field
     {
         $this->setDefaultServer();
 
-        if (!empty($this->value())) {
+        if (! empty($this->value())) {
             $this->setupPreviewOptions();
         }
 
         $this->forceOptions();
 
+        $this->formatValue();
+
+        $this->addVariables([
+            'options' => json_encode($this->options),
+            '_files'  => $this->options['isImage'] ? '' : '_files',
+            '_id'     => $this->generateId(),
+        ]);
+
+        return parent::render();
+    }
+
+    /**
+     * @return void
+     */
+    protected function formatValue()
+    {
         if ($this->value !== null) {
             $this->value = join(',', $this->value);
         } elseif (is_array($this->default)) {
             $this->default = join(',', $this->default);
         }
-        $this->addVariables([
-            'options' => json_encode($this->options),
-            '_files' => $this->options['isImage'] ? '' : '_files',
-            '_id' => 'file-'.Str::random(8),
-        ]);
+    }
 
-        return parent::render();
+    /**
+     * @return string
+     */
+    protected function generateId()
+    {
+        return 'file-'.Str::random(8);
     }
 
 }

+ 2 - 2
src/Form/Field/UploadField.php

@@ -31,7 +31,7 @@ trait UploadField
      *
      * @var \Illuminate\Filesystem\Filesystem
      */
-    protected $storage = '';
+    protected $storage;
 
     /**
      * If use unique name to store upload file.
@@ -499,7 +499,7 @@ trait UploadField
      */
     public function destroyIfChanged($file)
     {
-        if (!$file || !$this->original) {
+        if (! $file || ! $this->original) {
             return $this->destroy();
         }
 

+ 21 - 18
src/Form/Field/WebUploader.php

@@ -137,29 +137,32 @@ trait WebUploader
      */
     protected function setupDefaultOptions()
     {
+        $primaryKey = Admin::user() ? Admin::user()->getKey() : null;
+
         $defaultOptions = [
-            'isImage' => false,
-            'disableRemove' => false,
-            'chunked' => true,
-            'fileNumLimit' => 10,
+            'isImage'             => false,
+            'disableRemove'       => false,
+            'chunked'             => true,
+            'fileNumLimit'        => 10,
             // 禁掉全局的拖拽功能。这样不会出现图片拖进页面的时候,把图片打开。
-            'disableGlobalDnd' => true,
-            'fileSizeLimit' => 20971520000, // 20000M
+            'disableGlobalDnd'    => true,
+            'fileSizeLimit'       => 20971520000, // 20000M
             'fileSingleSizeLimit' => 10485760, // 10M
-            'autoUpdateColumn' => true, // 上传完图片后自动保存图片路径
-            'elementName' => $this->getElementName(), // 字段name属性值
+            'autoUpdateColumn'    => true, // 上传完图片后自动保存图片路径
+            'elementName'         => $this->getElementName(), // 字段name属性值
+            'lang'                => trans('admin.uploader'),
+
             'deleteData' => [
                 static::FILE_DELETE_FLAG => '',
-                '_token' => csrf_token(),
-                '_method' => 'PUT',
+                '_token'                 => csrf_token(),
+                '_method'                => 'PUT',
             ],
             'formData' => [
-                '_id' => Admin::user()->getKey(),
+                '_id'           => $primaryKey,
                 'upload_column' => $this->column,
-                '_method' => 'PUT',
-                '_token' => csrf_token(),
+                '_method'       => 'PUT',
+                '_token'        => csrf_token(),
             ],
-            'lang' => trans('admin.uploader'),
         ];
 
         $this->options($defaultOptions);
@@ -167,18 +170,18 @@ trait WebUploader
 
     protected function setDefaultServer()
     {
-        if (!$this->form instanceof Form) {
+        if (! $this->form || ! method_exists($this->form, 'getAction')) {
             return;
         }
 
-        if (!isset($this->options['server'])) {
+        if (empty($this->options['server'])) {
             $this->options['server'] = $this->form->getAction();
         }
-        if (!isset($this->options['deleteUrl'])) {
+        if (empty($this->options['deleteUrl'])) {
             $this->options['deleteUrl'] = $this->form->getAction();
         }
 
-        if ($this->form->builder()->isCreating()) {
+        if ($this->form->builder() && $this->form->builder()->isCreating()) {
             unset(
                 $this->options['formData']['_method'],
                 $this->options['deleteData']['_method'],

+ 3 - 1
src/Form/MultipleForm.php

@@ -22,6 +22,8 @@ class MultipleForm extends WidgetForm
         $this->form    = $form;
         $this->builder = $form->builder();
 
+        $this->initFields();
+
         $this->initFormAttributes();
     }
 
@@ -33,7 +35,7 @@ class MultipleForm extends WidgetForm
      */
     public function pushField(Field &$field)
     {
-        array_push($this->fields, $field);
+        $this->fields->push($field);
 
         $field->setForm($this->form);
 

+ 18 - 0
src/Form/StepBuilder.php

@@ -271,9 +271,27 @@ class StepBuilder
     {
         $this->selectStep();
 
+        $this->setAction();
+
         return $this->renderFields();
     }
 
+    /**
+     * @return void
+     */
+    protected function setAction()
+    {
+        foreach ($this->stepForms as $step) {
+            $step->action($this->form->getAction());
+
+            foreach ($step->fields() as $field) {
+                if ($field instanceof Form\Field\File) {
+                    $field->setForm($this->form);
+                }
+            }
+        }
+    }
+
     /**
      * @return string
      */

+ 3 - 1
src/Form/StepForm.php

@@ -53,7 +53,9 @@ class StepForm extends WidgetForm
     {
         $this->form   = $form;
         $this->parent = $form->builder()->getStepBuilder();
-        $this->index = $index;
+        $this->index  = $index;
+
+        $this->initFields();
 
         $this->title($title);
     }

+ 25 - 10
src/Widgets/Form.php

@@ -9,6 +9,7 @@ use Dcat\Admin\Support\Helper;
 use Dcat\Admin\Traits\HasHtmlAttributes;
 use Illuminate\Contracts\Support\Arrayable;
 use Illuminate\Contracts\Support\Renderable;
+use Illuminate\Support\Collection;
 use Illuminate\Support\Traits\Macroable;
 use Illuminate\Support\Arr;
 use Illuminate\Support\Fluent;
@@ -85,9 +86,9 @@ class Form implements Renderable
     protected $view = 'admin::widgets.form';
 
     /**
-     * @var Field[]
+     * @var Field[]|Collection
      */
-    protected $fields = [];
+    protected $fields;
 
     /**
      * @var bool
@@ -140,7 +141,18 @@ class Form implements Renderable
         $this->data($data);
         $this->key($key);
 
+        $this->initFields();
+
         $this->initFormAttributes();
+
+    }
+
+    /**
+     * Initialize the form fields.
+     */
+    protected function initFields()
+    {
+        $this->fields = new Collection();
     }
 
     /**
@@ -267,14 +279,10 @@ class Form implements Renderable
      * Get specify field.
      *
      * @param string $name
-     * @return Field|null|Field[]
+     * @return Field|null
      */
-    public function field($name = null)
+    public function field($name)
     {
-        if ($name === null) {
-            return $this->fields;
-        }
-
         foreach ($this->fields as $field) {
             if ($field->column() === $name) {
                 return $field;
@@ -282,6 +290,13 @@ class Form implements Renderable
         }
     }
 
+    /**
+     * @return Field[]|Collection
+     */
+    public function fields()
+    {
+        return $this->fields;
+    }
 
     /**
      * Disable Pjax.
@@ -346,7 +361,7 @@ class Form implements Renderable
             'field' => $fieldWidth,
         ];
 
-        collect($this->fields)->each(function ($field) use ($fieldWidth, $labelWidth) {
+        $this->fields->each(function ($field) use ($fieldWidth, $labelWidth) {
             /* @var Field $field  */
             $field->setWidth($fieldWidth, $labelWidth);
         });
@@ -381,7 +396,7 @@ class Form implements Renderable
      */
     public function pushField(Field &$field)
     {
-        array_push($this->fields, $field);
+        $this->fields->push($field);
 
         $field->setForm($this);
         $field->setWidth($this->width['field'], $this->width['label']);