Form.php 10.1 KB
<?php
/**
+-----------------------------------------------------------------------------------------------------------------------
 * 重写 laravel-admin Form 类
+-----------------------------------------------------------------------------------------------------------------------
 * PHP version 7
 *
 * @category  App\Admin\Rewrite
 * @package   App\Admin\Rewrite
 * @author    Richer <yangzi1028@163.com>
 * @date      2020年3月24日,10:02:24
 * @copyright 2021-2022 Richer (http://www.Richer.com/)
 * @license   http://www.Richer.com/ License
 * @link      http://www.Richer.com/
 */
namespace App\Admin\Rewrite;

use App\Admin\Rewrite\Form\Builder;
use Closure;
use Encore\Admin\Form as EncoreForm;
use Encore\Admin\Form\Field;
use Encore\WangEditor\Editor;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Support\Arr;

/**
 * Class Form.
 *
 * @method Field\Text           text($column, $label = '')
 * @method Field\Checkbox       checkbox($column, $label = '')
 * @method Field\Radio          radio($column, $label = '')
 * @method Field\Select         select($column, $label = '')
 * @method Field\MultipleSelect multipleSelect($column, $label = '')
 * @method Field\Textarea       textarea($column, $label = '')
 * @method Field\Hidden         hidden($column, $label = '')
 * @method Field\Id             id($column, $label = '')
 * @method Field\Ip             ip($column, $label = '')
 * @method Field\Url            url($column, $label = '')
 * @method Field\Color          color($column, $label = '')
 * @method Field\Email          email($column, $label = '')
 * @method Field\Mobile         mobile($column, $label = '')
 * @method Field\Slider         slider($column, $label = '')
 * @method Field\File           file($column, $label = '')
 * @method Field\Image          image($column, $label = '')
 * @method Field\Date           date($column, $label = '')
 * @method Field\Datetime       datetime($column, $label = '')
 * @method Field\Time           time($column, $label = '')
 * @method Field\Year           year($column, $label = '')
 * @method Field\Month          month($column, $label = '')
 * @method Field\DateRange      dateRange($start, $end, $label = '')
 * @method Field\DateTimeRange  datetimeRange($start, $end, $label = '')
 * @method Field\TimeRange      timeRange($start, $end, $label = '')
 * @method Field\Number         number($column, $label = '')
 * @method Field\Currency       currency($column, $label = '')
 * @method Field\HasMany        hasMany($relationName, $label = '', $callback)
 * @method Field\SwitchField    switch($column, $label = '')
 * @method Field\Display        display($column, $label = '')
 * @method Field\Rate           rate($column, $label = '')
 * @method Field\Divider        divider($title = '')
 * @method Field\Password       password($column, $label = '')
 * @method Field\Decimal        decimal($column, $label = '')
 * @method Field\Html           html($html, $label = '')
 * @method Field\Tags           tags($column, $label = '')
 * @method Field\Icon           icon($column, $label = '')
 * @method Field\Embeds         embeds($column, $label = '', $callback)
 * @method Field\MultipleImage  multipleImage($column, $label = '')
 * @method Field\MultipleFile   multipleFile($column, $label = '')
 * @method Field\Captcha        captcha($column, $label = '')
 * @method Field\Listbox        listbox($column, $label = '')
 * @method Field\Table          table($column, $label, $builder)
 * @method Field\Timezone       timezone($column, $label = '')
 * @method Field\KeyValue       keyValue($column, $label = '')
 * @method Field\ListField      list($column, $label = '')
 */
class Form extends EncoreForm
{
    /**
     * @var bool
     */
    protected $isSoftDeletes = true;

    /**
     * Available fields.
     *
     * @var array
     */
    public static $availableFields = [
        'button'         => Field\Button::class,
        'checkbox'       => Field\Checkbox::class,
        'checkboxButton' => Field\CheckboxButton::class,
        'checkboxCard'   => Field\CheckboxCard::class,
        'color'          => Field\Color::class,
        'currency'       => Field\Currency::class,
        'date'           => Field\Date::class,
        'dateRange'      => Field\DateRange::class,
        'datetime'       => Field\Datetime::class,
        'dateTimeRange'  => Field\DatetimeRange::class,
        'datetimeRange'  => Field\DatetimeRange::class,
        'decimal'        => Field\Decimal::class,
        'display'        => Field\Display::class,
        'divider'        => Field\Divider::class,
        'embeds'         => Field\Embeds::class,
        'email'          => Field\Email::class,
       // 'file'           => \App\Admin\Rewrite\Form\Field\File::class,
        'file'           => Field\File::class,
        'hasMany'        => Field\HasMany::class,
        'hidden'         => Field\Hidden::class,
        'id'             => Field\Id::class,
        'image'          => \App\Admin\Rewrite\Form\Field\Image::class,
//        'image'          => Field\Image::class,
        'ip'             => Field\Ip::class,
        'mobile'         => Field\Mobile::class,
        'month'          => Field\Month::class,
        'multipleSelect' => Field\MultipleSelect::class,
        'number'         => Field\Number::class,
        'password'       => Field\Password::class,
        'radio'          => Field\Radio::class,
        'radioButton'    => Field\RadioButton::class,
        'radioCard'    => Field\RadioCard::class,
        'rate'           => Field\Rate::class,
        'select'         => Field\Select::class,
        'slider'         => Field\Slider::class,
        'switch'         => Field\SwitchField::class,
        'text'           => Field\Text::class,
        'textarea'       => Field\Textarea::class,
        'time'           => Field\Time::class,
        'timeRange'      => Field\TimeRange::class,
        'url'            => Field\Url::class,
        'year'           => Field\Year::class,
        'html'           => Field\Html::class,
        'tags'           => Field\Tags::class,
        'icon'           => Field\Icon::class,
        'multipleFile'   => \App\Admin\Rewrite\Form\Field\MultipleFile::class,
        'multipleImage'  => \App\Admin\Rewrite\Form\Field\MultipleImage::class,
//        'multipleImage'  => Field\MultipleImage::class,
        'captcha'        => Field\Captcha::class,
        'listbox'        => Field\Listbox::class,
        'table'          => Field\Table::class,
        'timezone'       => Field\Timezone::class,
        'keyValue'       => Field\KeyValue::class,
        'list'           => Field\ListField::class,

        // 自定义控件
        'editor'         => Editor::class,
        'chunk_file'     => \App\Admin\Rewrite\ChunkFileUpload\ChunkFileField::class,
        'belongsToMany'     => Field\BelongsToMany::class,
    ];

    /**
     * Create a new form instance.
     *
     * @param $model
     * @param \Closure $callback
     */
    public function __construct($model, Closure $callback = null)
    {
        $this->model = $model;

        $this->builder = new Builder($this);

        $this->initLayout();

        if ($callback instanceof Closure) {
            $callback($this);
        }

        $this->isSoftDeletes = in_array(SoftDeletes::class, class_uses_deep($this->model), true);

        $this->callInitCallbacks();
    }

    /**
     * Prepare input data for update.
     *
     * @param array $updates
     * @param bool $oneToOneRelation If column is one-to-one relation.
     *
     * @return array
     */
    protected function prepareUpdate(array $updates, $oneToOneRelation = false): array
    {
        $prepared = [];

        // update By Richer 于 2019年8月12日12:03:13 由于使用了StepForm 导致无法获取到 fields
        $fields = $this->builder->fields();
        if ($fields->isEmpty()) {
            $values = $this->model->toArray();
            if ($values) {
                // 获取keys
                $fields = array_keys($values);

                foreach ($values as $field => $value) {
                    $columns = $field;

                    // If column not in input array data, then continue.
                    if (!Arr::has($updates, $columns)) {
                        continue;
                    }

                    // dump($updates);
                    //     dump($columns);

                    // if ($this->isInvalidColumn($columns, $oneToOneRelation || $field->isJsonType)) {
                    //     continue;
                    // }

                    // $value = $this->getDataByColumn($updates, $columns);

                    // $value = $field->prepare($value);


                    if (is_array($columns)) {
                        foreach ($columns as $name => $column) {
                            Arr::set($prepared, $column, $value[$name]);
                        }
                    } elseif (is_string($columns)) {
                        // 移除选中的值
                        Arr::forget($value, Arr::get($updates, Field::FILE_DELETE_FLAG));
                        Arr::set($prepared, $columns, $value);
                    }
                }
            }
        } else {
            foreach ($fields as $field) {
                $columns = $field->column();

                // If column not in input array data, then continue.
                if (!Arr::has($updates, $columns)) {
                    continue;
                }

                if ($this->isInvalidColumn($columns, $oneToOneRelation || $field->isJsonType)) {
                    continue;
                }

                $value = $this->getDataByColumn($updates, $columns);

                $value = $field->prepare($value);

                if (is_array($columns)) {
                    foreach ($columns as $name => $column) {
                        Arr::set($prepared, $column, $value[$name]);
                    }
                } elseif (is_string($columns)) {
                    Arr::set($prepared, $columns, $value);
                }
            }
        }

        //dump($fields);
        /* @var Model $this ->model */
        //$builder = $this->model();
        // dump($values);
        // dump($this->builder->fields());
        /** @var Field $field */

        return $prepared;
    }
}