Skip to content
This repository was archived by the owner on Dec 1, 2023. It is now read-only.
disami115 edited this page Dec 3, 2020 · 9 revisions

Оглавление

С чего начать?

Компонент позволяет создавать формы плагина для Leadvertex. Работа осуществляется с тремя основными компонентами:

  • полями
  • группой полей - в данном компоненте содержится массив полей
  • форма плагина - его можно считать основным, в нем используются остальные компоненты

Рассмотрим каждый компонентам подробнее.

Field - поле

Поле это объект класса, который наследуется от \Leadvertex\Plugin\Components\Form\FieldDefinitions\FieldDefinition.

Список данных классов:

  • BooleanDefinition - чекбокс.
  • FloatDefinition - число с плавающей запятой.
  • IntegerDefinition - целое число.
  • StringDefinition - текст.
  • PasswordDefinition - текстовое поле, которое принимает значение string, которое будет проверено в соответствии с правилами пароля.
  • MarkdownDefinition - текстовое поле, которое поддерживает TUI markdown со всеми плагинами.
  • FileDefinition - URI, по которому можно получить необходимый файл.
  • ListOfEnumDefinition - список значений. Может иметь статический или динамических список. Для статических значений вам необходимо настроить StaticValues. Для динамических значений вам необходимо настроить DynamicValues. Подробнее о классе ListOfEnumDefinition в соответствующем разделе.

Все классы, из списка выше, кроме \Leadvertex\Plugin\Components\Form\FieldDefinitions\ListOfEnumDefinition, принимают в конструктор:

  • title - название поля, тип string
  • description - описание поля, тип string (может быть null)
  • validator - функция для валидации данных, тип callable
  • default - значение по-умолчанию (если не передать, будет null)

Давайте по пробуем написать простое поле:

$field = new \Leadvertex\Plugin\Components\Form\FieldDefinitions\IntegerDefinition(
    'Field_title',
    'Field description',
    function ($value) {
        $errors = [];
        if ($value < 0) {
            $errors[] = 'Value should not be negative';
        }
        return $errors;
    }, 
    10
);

Как видно в примере, для того, что-бы создать поле, достаточно передать в конструктор строки title, description, функцию validator, и при необходимости значение по-умолчанию.

FieldGroup - группа полей

Класс \Leadvertex\Plugin\Components\Form\FieldGroup, используется в Form и с его помощью, можно реализовать группу полей для формы. На форме, группа будет выглядеть, как отдельная вкладка со своим названием, содержащая описание и поля.

Конструктор класса \Leadvertex\Plugin\Components\Form\Form принимает:

  • title - название группы полей, тип string
  • description - описание формы, тип string (может быть null)
  • fields - массив полей

Давайте по пробуем создать простую группу полей, для этого, сначала создадим несколько полей, аналогично примеру выше:

$loginField = new \Leadvertex\Plugin\Components\Form\FieldDefinitions\StringDefinition(
    'Login',
    null,
    function ($value) {
        $errors = [];
         if (!is_scalar($value)) {
             $errors[] = 'Invalid string';
         }
        return $errors;
    }
);
$passField = new \Leadvertex\Plugin\Components\Form\FieldDefinitions\PasswordDefinition(
    'Password',
    'Password description',
    function ($value) {
        $errors = [];
        if (mb_strlen($value) < 6) {
            $errors[] = 'Password too short';
        }
        return $errors;
    }
);

А теперь создадим группу полей:

$title = 'Authorization';
$description = 'Authorization description';
$fields = [
    'login' => $loginField,
    'password' => $passField
];

$authorizationGroup = new \Leadvertex\Plugin\Components\Form\FieldGroup(
    $title,
    $description,
    $fields
);

Как видно в примере, для того, что-бы создать форму, достаточно передать в конструктор строки title, description и button. А так же массив полей.

Form - форма

Форма это объект класса \Leadvertex\Plugin\Components\Form\Form. С его помощью можно создать формы для плагина. Данный класс можно считать основным, в нем используются остальные компоненты.

Конструктор класса \Leadvertex\Plugin\Components\Form\Form принимает:

  • title - название формы, тип string
  • description - описание формы, тип string (может быть null)
  • groups - массив объектов класса \Leadvertex\Plugin\Components\Form\FieldGroup
  • button - название кнопки, тип string

Давайте по пробуем создать простую форму, используя созданную ранее группу полей:

$title = 'Form_title';
$description = 'Form description';
$fieldGroups = [
    'authorization' => $authorizationGroup
];
$button = 'Sing in';

$form = new \Leadvertex\Plugin\Components\Form\Form(
    $title,
    $description,
    $fieldGroups,
    $button
);

Как видно в примере, для того, что-бы создать форму, достаточно передать в конструктор строки title, description и button. А так же объект класса \Leadvertex\Plugin\Components\Form\FieldGroup.

Класс ListOfEnumDefinition

Класс ListOfEnumDefinition реализует поле ListOfEnum.

Конструктор данного класса принимает:

Класс StaticValues

Объект класса StaticValues содержит в себе массив полей, каждое из которых имеет название и группу. Напишем простое поле ListOfEnumDefinition, используя StaticValues:

$staticValues = new StaticValues([
    "static_1" => [ 
        'title' => 'Value1',
        'group' => 'Group1'
    ],
    "static_2" => [ 
        'title' => 'Value2',
        'group' => 'Group1'
    ],
    "static_3" => [ 
        'title' => 'Value3',
        'group' => 'Group2'
    ],
]);

Класс DynamicValues

Объект класса DynamicValues содержит в себе массив полей, каждое из которых имеет название и группу. Напишем простое поле ListOfEnumDefinition, используя DynamicValues:

$dynamicValues = new DynamicValues('http://example.com/autocomplete/example');

По ссылке должен возвращаться список значений, каждое из которых имеет название и группу. Для этого, вы можете написать свой класс, который должен реализовывать интерфейс AutocompleteInterface, подробнее о реализации подобного класса в соответствующем разделе.

Класс Limit

Объект класса \Leadvertex\Plugin\Components\Form\FieldDefinitions\ListOfEnum\Limit необходим для добавления ограничений в ListOfEnumDefinition. Конструктор принимает:

  • min - минимальное число значений из списка, тип int (может быть null)
  • max - максимальное число значений из списка, тип int (может быть null)

Создадим простой объект класса Limit:

$limit = new Limit(1, 5);

В классе реализованы методы:

  • public function getMin(): ?int - геттер поля min
  • public function getMax(): ?int - геттер поля max
  • public function jsonSerialize() - сериализует объект в значение, которое изначально может быть сериализовано функцией json_encode()

Реализация поля ListOfEnum

Реализация поля ListOfEnum выглядит одинаково для StaticValues и DynamicValues:

$title = 'Field_title';
$description = 'Field description';
$validator = function ($values, ListOfEnumDefinition $definition) 
{
   $limit = $definition->getLimit();

   $errors = [];

   if (!is_null($values) && !is_array($values))
   {
      $errors[] = "Ошибка валидации";
      return $errors;
   }

   if (is_null($values))
   {
      $values = [];
   }

   if ($limit)
   {
      if ($limit->getMin() && (count($values) < $limit->getMin())) {
         $errors[] = 'Выбрано меньше, чем минимальное {$limit->getMin()]}';
      }

      if ($limit->getMax() && count($values) > $limit->getMax()) {
         $errors[] = 'Выбрано больше, чем максимальное {$limit->getMax()]}';
      }
   }

   return $errors;
};
$valuesList = new StaticValues([
    "static_1" => [ 
        'title' => 'Value1',
        'group' => 'Group1'
    ],
    "static_2" => [ 
        'title' => 'Value2',
        'group' => 'Group1'
    ],
    "static_3" => [ 
        'title' => 'Value3',
        'group' => 'Group2'
    ],
]);
$limit = new Limit(1, 2);
$default = [static_1];

$field = new ListOfEnumDefinition(
    $title,
    $description,
    $validator, 
    $valuesList,
    $limit,
    $default
);

Класс реализующий AutocompleteInterface

Данный класс, реализуя AutocompleteInterface, позволяет формировать и возвращать по ссылке на него, массив полей для ListOfEnumDefinition.

Должны быть реализованы:

  • public function query(string $query): array; принимает на вход значение параметров, переданных в ссылке и возвращает и формирует список для ListOfEnumDefinition.
  • public function values(array $values): array; принимает на вход значение параметров, переданных в ссылке в виде массива и формирует список для ListOfEnumDefinition.
  • public function validate(array $values): bool; валидатор, для проверки корректности сформированного списка.

Напишем наш класс и созПример реализации:

namespace Leadvertex\Plugin\Instance\Macros\Autocomplete;

class Example implements AutocompleteInterface
{

    public function query(?string $query): array
    {
        if (trim($query) === '') {
            $query = 1;
        }

        $values = [];
        if (preg_match('~^\d+$~', $query)) {
            for ($i = 1; $i <= (int)$query; $i++) {
                $values["dynami_{$i}"] = [
                    'title' => "Строка #{$i}",
                    'group' => "Группа #{$i}"
                ];
            }
        }
        return $values;
    }

    public function values(array $values): array
    {
        $result = [];

        sort($values);
        array_filter($values, function ($value) {
            return preg_match('~^dynamic_\d+$~', $value);
        });

        foreach ($values as $value) {
            $result[$value] = [
                'title' => "Строка #{$value}",
                'group' => "Группа #{$value}"
            ];
        }
        return $result;
    }

    public function validate(array $values): bool
    {
        foreach ($values as $value) {
            if (is_null($value)) {
                return false;
            }
        }
        return true;
    }

}

Давайте по пробуем запросить список:

GET http://example.com/autocomplete/example

В ответ получим:

{
  "dynami_1": {
    "title": "Строка #1",
    "group": "От 1 до 10"
  }
}

Запросим:

GET http://example.com/autocomplete/example?query=3
{
  "dynami_1": {
    "title": "Строка #1",
    "group": "Группа #1"
  },
  "dynami_2": {
    "title": "Строка #2",
    "group": "Группа #2"
  },
  "dynami_3": {
    "title": "Строка #3",
    "group": "Группа #3"
  }
}

Запросим:

GET http://example.com/autocomplete/example?query[]=9&query[]=10
{
  "9": {
    "title": "Строка #9",
    "group": "Группа #9"
  },
  "10": {
    "title": "Строка #10",
    "group": "Группа #10"
  }
}