HEX
Server: Apache
System: Linux srv-plesk28.ps.kz 5.14.0-284.18.1.el9_2.x86_64 #1 SMP PREEMPT_DYNAMIC Thu Jun 29 17:06:27 EDT 2023 x86_64
User: greencl1 (10085)
PHP: 8.1.33
Disabled: apache_setenv,dl,eval,exec,openlog,passthru,pcntl_exec,pcntl_fork,popen,posix_getpwuid,posix_kill,posix_mkfifo,posix_setpgid,posix_setsid,posix_setuid,proc_close,proc_get_status,proc_nice,proc_open,proc_terminate,shell_exec,socket_create,socket_create_listen,socket_create_pair,syslog,system,socket_listen,stream_socket_server
Upload Files
File: /var/www/vhosts/greenclinic.kz/test.greenclinic.kz/modules/backend/formwidgets/TagList.php
<?php namespace Backend\FormWidgets;

use Backend\Classes\FormWidgetBase;

/**
 * Tag List Form Widget
 */
class TagList extends FormWidgetBase
{
    use \Backend\Traits\FormModelWidget;

    const MODE_ARRAY = 'array';
    const MODE_STRING = 'string';
    const MODE_RELATION = 'relation';

    //
    // Configurable properties
    //

    /**
     * @var string Tag separator: space, comma.
     */
    public $separator = 'comma';

    /**
     * @var bool Allows custom tags to be entered manually by the user.
     */
    public $customTags = true;

    /**
     * @var mixed Predefined options settings. Set to true to get from model.
     */
    public $options;

    /**
     * @var string Mode for the return value. Values: string, array, relation.
     */
    public $mode = 'string';

    /**
     * @var string If mode is relation, model column to use for the name reference.
     */
    public $nameFrom = 'name';

    /**
     * @var bool Use the key instead of value for saving and reading data.
     */
    public $useKey = false;

    /**
     * @var string Placeholder for empty TagList widget
     */
    public $placeholder = '';

    //
    // Object properties
    //

    /**
     * @inheritDoc
     */
    protected $defaultAlias = 'taglist';

    /**
     * @inheritDoc
     */
    public function init()
    {
        $this->fillFromConfig([
            'separator',
            'customTags',
            'options',
            'mode',
            'nameFrom',
            'useKey',
            'placeholder'
        ]);
    }

    /**
     * @inheritDoc
     */
    public function render()
    {
        $this->prepareVars();

        return $this->makePartial('taglist');
    }

    /**
     * Prepares the form widget view data
     */
    public function prepareVars()
    {
        $this->vars['placeholder'] = $this->placeholder;
        $this->vars['useKey'] = $this->useKey;
        $this->vars['field'] = $this->formField;
        $this->vars['fieldOptions'] = $this->getFieldOptions();
        $this->vars['selectedValues'] = $this->getLoadValue();
        $this->vars['customSeparators'] = $this->getCustomSeparators();
    }

    /**
     * @inheritDoc
     */
    public function getSaveValue($value)
    {
        if ($this->mode === static::MODE_RELATION) {
            return $this->hydrateRelationSaveValue($value);
        }

        if (is_array($value) && $this->mode === static::MODE_STRING) {
            return implode($this->getSeparatorCharacter(), $value);
        }

        return $value;
    }

    /**
     * Returns an array suitable for saving against a relation (array of keys).
     * This method also creates non-existent tags.
     * @return array
     */
    protected function hydrateRelationSaveValue($names)
    {
        if (!$names) {
            return $names;
        }

        $relationModel = $this->getRelationModel();
        $existingTags = $relationModel
            ->whereIn($this->nameFrom, $names)
            ->lists($this->nameFrom, $relationModel->getKeyName())
        ;

        $newTags = $this->customTags ? array_diff($names, $existingTags) : [];

        foreach ($newTags as $newTag) {
            $newModel = $relationModel::create([$this->nameFrom => $newTag]);
            $existingTags[$newModel->getKey()] = $newTag;
        }

        return array_keys($existingTags);
    }

    /**
     * @inheritDoc
     */
    public function getLoadValue()
    {
        $value = parent::getLoadValue();

        if ($this->mode === static::MODE_RELATION) {
            return $this->getRelationObject()->lists($this->nameFrom);
        }

        return $this->mode === static::MODE_STRING
            ? explode($this->getSeparatorCharacter(), $value)
            : $value;
    }

    /**
     * Returns defined field options, or from the relation if available.
     * @return array
     */
    public function getFieldOptions()
    {
        $options = $this->formField->options();

        if (!$options && $this->mode === static::MODE_RELATION) {
            $options = $this->getRelationModel()->lists($this->nameFrom);
        }

        return $options;
    }

    /**
     * Returns character(s) to use for separating keywords.
     * @return mixed
     */
    protected function getCustomSeparators()
    {
        if (!$this->customTags) {
            return false;
        }

        $separators = [];

        $separators[] = $this->getSeparatorCharacter();

        return implode('|', $separators);
    }

    /**
     * Convert the character word to the singular character.
     * @return string
     */
    protected function getSeparatorCharacter()
    {
        switch (strtolower($this->separator)) {
            case 'comma':
                return ',';
            case 'space':
                return ' ';
        }
    }
}