jeyroik / extas-foundation
Extas foundation package
Installs: 3 980
Dependents: 58
Suggesters: 0
Security: 0
Stars: 1
Watchers: 1
Forks: 0
Open Issues: 1
Requires
- ext-json: *
- jeyroik/extas-base: 2.*
- jeyroik/extas-exceptions: 0.*
- jeyroik/extas-id: 0.*
- league/container: 4.*
- symfony/console: 6.*
- symfony/finder: 6.*
Requires (Dev)
- jeyroik/extas-snuffbox: 1.*
- phpunit/phpunit: ^9
- vlucas/phpdotenv: ^5.5
- dev-master
- v6.x-dev
- 6.22.1
- 6.22.0
- 6.21.3
- 6.21.2
- 6.21.1
- 6.21.0
- 6.20.0
- 6.19.0
- 6.18.4
- 6.18.3
- 6.18.2
- 6.18.1
- 6.18.0
- 6.17.0
- 6.16.1
- 6.16.0
- 6.15.1
- 6.15.0
- 6.14.0
- 6.13.0
- 6.12.0
- 6.11.2
- 6.11.1
- 6.11.0
- 6.10.0
- 6.9.1
- 6.9.0
- 6.8.1
- 6.8.0
- 6.7.0
- 6.6.0
- 6.5.3
- 6.5.2
- 6.5.1
- 6.5.0
- 6.4.1
- 6.4.0
- 6.3.0
- 6.2.0
- 6.1.2
- 6.1.1
- 6.1.0
- 6.0.0
- v5.x-dev
- 5.15.0
- 5.14.1
- 5.14.0
- 5.13.0
- 5.12.2
- 5.12.1
- 5.12.0
- 5.11.0
- 5.10.0
- 5.9.0
- 5.8.1
- 5.8.0
- 5.7.2
- 5.7.1
- 5.7.0
- 5.6.0
- 5.5.0
- 5.4.0
- 5.3.0
- 5.2.0
- 5.1.0
- 5.0.1
- 5.0.0
- 4.1.0
- 4.0.0
- 3.1.0
- 2.1.0
- 2.0.0
- 1.2.0
- 1.0.0
- 0.7.1
- 0.7.0
- 0.6.2
- 0.5.1
- dev-development
This package is auto-updated.
Last update: 2024-10-16 15:59:23 UTC
README
Описание
Данный пакет содержит базовые сущности для Extas`a:
extas\components\Item
Базовый объект, позволяющий использовать из коробки плагины и расширения (см. ниже)extas\components\plugins\Plugin
Плагин. Позволяет реализовывать плагины (подробности см. ниже).extas\components\extensions\Extension
Расширение. Позволяет реализовывать расширения (декораторы) для классов, унаследованных отItem
.
Требования
- PHP 7.4+
- Какое-либо хранилище (для тестов по-умолчанию используется JSON-файл).
Установка пакета
# composer require jeyroik/extas-foundation:6.*
Установка extas-совместимого приложения
# vendor/bin/extas install -t "repo/template/path" -s "repo/classes/save/path"
Для сущностей доступна стадия extas\\interfaces\\stages\\IStageBeforeInstallEntity
, подключившись к которой можно проводить дополнительные манипуляции с данными сущности.
Сушности приложения устанавливаются раньше сущностей библиотек.
# vendor/bin/extas-extra e
Подробнее про команду extra
читайте ниже.
Установка прочих сущностей
Для установки прочих сущностей, доступна команда extra
.
С помощью плагинов есть возможность подключиться к данной команде и через единый интерфейс этой команды устаналивать любые сущности и вообще выполнять любые действия, которые требуется.
Чтобы посмотреть список доступных опций, используйте помощь по команде:
# vendor/bin/extas extra -h
Конфигурация приложения
- Для настройки конфигурации вашего приложения, необходимо создать два файла
extas.app.storage.json
для кофигурации хранилища, плагинов и расширений;extas.app.json
для конфигурации сущностей.- Минимальную конфигурацию можно найти в
extas.app.storage.dist.json
, а также в текущей документации ниже по тексту.extas.app.dist.json
, а также в текущей документации ниже по тексту.
- Если вы разрабатываете бибилиотеку, то настройки для неё необходимо складывать в
extas.storage.json
- конфигурация хранилища, плагинов и расширений.extas.json
- конфигурация сущностей.- Минимальную конфигурацию можно найти в
extas.storage.dist.json
, а также в текущей документации ниже по тексту.extas.dist.json
, а также в текущей документации ниже по тексту.
Запуск тестов
# composer test
Использование
Item
Базовую сущность следует использовать как родителя для ваших сущностей (моделей и т.п.).
class My extends extas\components\Item
В этом случае вы сразу же получаете:
- поддержку динамических свойств:
$my = new My(); $my->some = 'thing';
- поддержку интерфейса массива:
$my = new My(); $my['fieldName'] = 5; $val = $my['fieldName']; echo $val;// 5 isset($my['fieldName']); // true unset($my['fieldName']); isset($my['fieldName']); // false
- поддержку итератора:
foreach($my as $field => $value)
- поддержку декораторов:
$my->notExistingMethod($arg1, $arg2)
- поддержку быстрого доступа к хранилищу:
$my->myTable()->one(...)
- поддержку плагинов (событий): внутри метода класса
My
- создание сущности
<сущность>.created
, срабатывает при сохранении нового экземпляра сущности в хранилище; - инициализация сущности
<сущность>.init
, срабатывает при инициализации объекта сущности; - удаление объекта сущности
<сущность>.after
, срабатывает при удалении объекта сущности - конвертация в массив, строку и целочисленное значение соответственно
<сущность>.to.array
,<сущность>.to.string
,<сущность>.to.int
- создание сущности
- поддержку целого ряда вспомогательных методов (каждый из которых предоставляет соответствующее событие для плагинов) вида
- __toArray()
- __toJson()
- __toInt()
- __equal(IItem $other) - сравнение с другой сущностью.
- __has('attr1', 'attr2', ...) - проверка наличия необходимых атрибутов.
- __select('attr1', 'attr2', ...) - получение сущности с ограниченным набором полей.
- поддержку создания новых событий для плагинов:
foreach($this->getPluginsByStage('event.name') as $plugin) { $plugin($arg1, $arg2); }
Ниже, после рассмотрения каждой базовой сущности, представлен рабочий пример использования всех сущностей вместе и по отдельности.
Плагин
Плагин следует использовать как родителя для ваших плагинов.
class MyPlugin extends extas\components\plugins\Plugin {}
Чтобы реализовать плагин, вам необходимо перегрузить метод __invoke()
.
Аргументы метода зависят от конкретной стадии (события).
Пример реализации плагина можно увидеть ниже.
Предустановка плагинов
В extas.app.storage.json
для приложения и в extas.storage.json
для библиотек:
{ "plugins": [ { "class": "class\\Name", "stage": "stage.name", "priority": 10 } ] }
priority
- чем выше приоритет, тем раньше (относительно других плагинов на этой стадии) выполнится плагин. Параметр является необязательным.
Расширение
Расширение следует использовать как родителя для ваших расширений (декораторов). Расширение позволяет динамически прозрачно добавлять методы сущностям, не трогая их код.
class MyExtension extends extas\components\Extension implements IMyExtension{}
Предустановка расширений
В extas.app.storage.json
для приложения и в extas.storage.json
для библиотек:
{ "extensions": [ { "class": "extension\\Class", "interface": "extension\\Interface", "subject": ["subject.name.1", "subject.name.2", "*"], "methods": ["method1", "method2"] } ] }
Пример использования каждой сущности по отдельности и вместе
Item
namespace my\extas; use extas\components\Item; class My extends Item { public function getName() { return $this->config['name'] ?? ''; } public function setName($name) { $this->name = $name; return $this; } protected function getSubjectForExtension(): string { return 'my'; } } $my = new my\extas\My(['name' => 'on init']); echo $my['name']; // 'on init' echo $my->getName(); // 'on init' echo $my->name; // 'on init' $my['description'] = 'Using Item example'; foreach($my as $field => $value) { echo $field . ' = ' . $value; } /** * Will output: * name = on init * description = Using Item example */
Плагин
namespace my\extas; use extas\components\Item; class My extends Item { public function getName() { $name = $this->config['name'] ?? ''; foreach($this->getPluginsByStage('my.name.get') as $plugin) { $plugin($name); } return $name; } public function setName($name) { $this->config['name'] = $name; return $this; } protected function getSubjectForExtension(): string { return 'my'; } } use extas\components\Plugin; class PluginEmptyName extends Plugin { public function __invoke(&$name) { $name = $name ?: 'Missed "name"'; } } // extas.storage.json/extas.app.storage.json { "plugins": [ { "class": "my\\extas\\PluginEmptyName", "stage": "my.name.get" } ] } // somewhere in a code $my = new My(); echo $my->getName(); // 'Missed "name"'
Внимание! Чтобы вышеуказанный пример сработал, плагин должен быть установлен в системе.
Детали см. в разделе Установка
.
Расширение
namespace my\extas; use extas\components\Item; class My extends Item { public function getName() { $name = $this->config['name'] ?? ''; foreach($this->getPluginsByStage('my.name.get') as $plugin) { $plugin($name); } return $name; } public function setName($name) { $this->config['name'] = $name; return $this; } protected function getSubjectForExtension(): string { return 'my'; } } /** * Для расширений рекомендуется всегда подготавливать интерфейсы. * Это помогает при разработке (подсказки) и позволяет удобнее контролировать расширения. */ interface IGetMutatedName { /** * @return string */ public function getMutatedName(): string; } use extas\components\Extension; class MyGetMutatedName extends Extension implements IGetMutatedName { public string $subject = 'my'; /** * Последним аргументом любого метода, который является расширением, * передаётся экземпляр сущности, которая расширяется * * @param null|My $my * * @return string */ public function getMutatedName(My $my = null) { $name = $my->getName(); return str_replace('.', '\\', $name); } } // extas.storage.json/extas.app.storage.json { "extensions": [ { "class": "my\\extas\\MyGetMutatedName", "interface": "my\\extas\\IGetMutatedName", "subject": ["my"], "methods": ["getMutatedName"] } ] } // somewhere in a code $my = new My(['name' => 'extas.extensions.extension.example']); echo $my->getMutatedName(); // extas\\extensions\\extension\\example
Внимание! Чтобы вышеуказанный пример сработал, расширение должно быть установлено в системе.
Детали см. в разделе Установка
.
extas.app.storage.json
{ "name": "vendor/package", "drivers": [ { "driver": "\\driver\\Class", "options": { "dsn": "{username}:{userpassword}@{host}:{port}/{db} | {path/to/db}", "username": "", "password": "", "host": "", "port": "", "db": "" }, "tables": ["t1", ...] } ], "tables": { "some_entities": { "item_class": "", "pk": "", "aliases": ["alias1", ...], "hooks": { "create-before": true, "update-before": true, "update-after": true, ... }, "code": { "create-before": "echo 'any code you want'; \\extas\\components\\repositories\\RepoItem::throwIfExist($this, $item, ['name'])", ... } }, ... }, "plugins": [ { ... }, ... ], "extensions": [ { ... }, ... ], "envs": [ "name1": "description" ] }
extas.app.json
Сушности приложения устанавливаются раньше сущностей библиотек.
{ "some_entities": [ { ... }, ... ] }
extas.storage.json
Внимание
: не размещайте в данной конфигурации секцию с настройкой драйверов - она будет игнорироваться.
Драйвера настраиваются в extas.app.storage.json
.
{ "name": "vendor/package", "tables": { "some_entities": { "item_class": "", "pk": "", "aliases": ["alias1", ...], "hooks": { "create-before": true, "update-before": true, "update-after": true, ... }, "code": { "create-before": "echo 'any code you want';", ... } }, ... }, "plugins": [ { ... }, ... ], "extensions": [ { ... }, ... ], "envs": { "name1": "description 1" } }
extas.json
{ "some_entities": [ { ... }, ... ] }
ENV
Чтобы узнать какие требуются переменные окружения, выполните команду env
:
# vendor/bin/extas env
Чтобы добавить свои переменные окружения в данный список, добавьте в конфигурации хранилища extas.app.storage.json
(для библиотек в extas.storage.json
) раздел envs
и опишите свои переменные как это показано в примерах соответствующих конфигураций выше.