Создание модуля

  1. Структура модуля
  2. Создание модуля
  1. Установка модуля
  2. Декорация модуля
  3. Методы контроллера 
  4. Создание файлов шаблона карточки сохранения мероприятия
  5. Подключение шаблона сохранения мероприятия
  6. Добавление ссылки на создание мероприятия
  7. Добавление ссылки на список мероприятий из карточки сохранения
  8. Проектирование базы данных
  9. Создание объекта Modules\Activity\Panel\Models\Saver()
  10. Создание объекта Modules\Activity\Panel\Models\Reader()
  11. Обработка свойств для Reader
  12. Создание интерфейса карточки редактирования сущности
  13. Сохранение сущности
  14. Подставляем сохраненные значения в базу
  15. Удаляем сущность
  16. Оптимизация CRUD
  17. Создание динамических разделов
  18. Разработка App API

Разработку модуля будем проводить на примере модуля Мероприятия.

В простой версии модуля должно быть реализовано следующее:

В админ-панели должна быть возможность:

  1. Добавление мероприятия
  2. Получение списка мероприятий
  3. Редактирование мероприятия
  4. Синхронизация мероприятий с модулем Страницы

1. Установка модуля

Авторизуйтесь в админ-панели и перейдите в Расширения.

Перейдите по ссылке, скопируйте установочный код и введите его в менеджер расширений.

После нажатия на кнопку Установить, модуль установиться в платформу.

2. Декорация модуля

Для примера будем создавать модуль Мероприятия

Для модуля необходим символьный код, для мероприятий, будем использовать Activity

Так же нам необходима группа для нашего компонента, группа нужна для классификации компонента в списках. 

Группу для нашего модуля будем использовать: Публикации

В итоге, нам нужен компонент:

Название Мероприятия
Символьный код Activity
Группа Публикации

Перейдите в папку: /extensions/Modules/ и переименуйте Sample в Activity

Теперь наш модуль называется Activity

Откройте файл в редакторе: /extensions/Modules/Activity/manifest.php и настройте метаданные


<?php

return [
    'version' => '1.0',
    'publicLink' => 'https://dev.prologue-uni.ru/d/modules/',
    'sort' => 1,
    'titles' => [
        'ru' => [
            'group' => 'Публикации',
            'name' => 'Мероприятия',
        ]
    ]
];

 

version Версия модуля
publicLink Ссылка на описание модуля
sort Порядковый номер
titles

Подписи

group Группа компонента
name Название компонента

 

Файл /extensions/Modules/Activity/Panel/Language/ru/messages.php - отвечает за локализацию модуля, укажите корректное название модуля.


<?php

return [
    'title' => 'Мероприятия',
    'list' => [
        'tabList' => 'Список',
        'add' => 'Добавить мероприятие',
    ],
];

Откройте файл в редакторе: /extensions/Modules/Activity/Panel/Module.php и укажите верный Namespace


namespace Modules\Activity\Panel;

 

3. Ознакомьтесь с методами контроллера 

Для того, чтобы продолжить разработку, необходимо ознакомится с методами Module.php

4. Создаем файлы шаблона карточки сохранения мероприятия

В папке /extensions/Modules/Activity/Panel/Views/ создаем папку saveActivity

Создаем файл /extensions/Modules/Activity/Panel/Views/saveActivity/template.php с содержимым


<?php
defined('PROLOGUE_CORE') or die;

/** @var array $data */

$arTabs = [
    [
        'title' => $this->messages['saveActivity']['tabGeneral'],
        'template' => 'tabs/general.php'
    ],
];

?>
<ul class="tabs">
    <?php foreach ($arTabs as $k => $tab) { ?>
        <li class="tab col">
            <a href="#tab_<?= $k ?>" class="active"><?= $tab['title'] ?></a>
        </li>
    <? } ?>
</ul>
<?php foreach ($arTabs as $k => $tab) { ?>
    <div id="tab_<?= $k ?>" class="panel__moduleContent-tab active">
        <?php include $tab['template']; ?>
    </div>
<? } ?>

В языковый файл /extensions/Modules/Activity/Panel/Language/ru/messages.php добавляем:


    'saveActivity' => [
        'tabGeneral' => 'Основная информация',
    ]

Создаем папку /extensions/Modules/Activity/Panel/Views/saveActivity/tabs/ - в этой папке будут хранится табы карточки

Создаем файл /extensions/Modules/Activity/Panel/Views/saveActivity/tabs/general.php - в этом файле будет интерфейс таба tabs/general с содержимым:


<?php
defined('PROLOGUE_CORE') or die;

/** @var array $data */

?>

<? formLinkInList(
    [
        'title' => $this->messages['inList'],
        'link' => $data['linkInList'],
    ]
) ?>

В языковый файл /extensions/Modules/Activity/Panel/Language/ru/messages.php добавляем:


'inList' => 'Вернуться в список',

5. Подключение шаблона сохранения мероприятия

В методе loadView() нужно написать код:


        if (Router::isRoute('saveActivity')) {
            include 'Views/saveActivity/template.php';
        }

6. Добавим ссылку на создание мероприятия

Нужно чтобы в маршруте /panel/?module=Activity&route=main в шаблоне появилась ссылка $data['saveActivityLink']

Для этого, модернизируем метод getPageData()


    public function getPageData()
    {

        if (Router::isRoute('main')) {
            return [
                'saveActivityLink' => Router::routeToModule(
                    [
                        'module' => $this->moduleName,
                        'routeName' => 'saveActivity',
                    ]
                )
            ];
        }

    }

Затем, откройте в редакторе /extensions/Modules/Activity/Panel/Views/list/tabs/list.php и кнопке в href="" вставьте

<?= $data['saveActivityLink'] ?>

7. Добавим ссылку на список мероприятий из карточки сохранения

Нужно чтобы в маршруте /panel/?module=Activity&route=saveActivity в шаблоне /extensions/Modules/Activity/Panel/Views/saveActivity/tabs/general.php появилась ссылка $data['inList']

Для этого, модернизируем метод getPageData()


    public function getPageData()
    {

        if (Router::isRoute('main')) {
            return [
                'saveActivityLink' => Router::routeToModule(
                    [
                        'module' => $this->moduleName,
                        'routeName' => 'saveActivity',
                    ]
                )
            ];
        }

        if (Router::isRoute('saveActivity')) {
            return [
                'linkInList' => Router::routeToModule(
                    [
                        'module' => $this->moduleName,
                        'routeName' => 'main',
                    ]
                )
            ];
        }

    }

Готово! Теперь у нас работает линковка между разделами модуля.

8. Проектируем базу данных

Нам нужно создать таблицу app_activity_items

id Id мероприятия int(11) AUTO_INCREMENT
name Название мероприятия varchar(255)
date_create Дата создания мероприятия datetime
activity_date Дата проведения мероприятия datetime
image Изображение мероприятия text
preview_text Краткое описание text
full_text Полное описание text
active Мероприятие активно varchar(1)
is_tmp Является временной записью varchar(1)

9. Создание объекта Modules\Activity\Panel\Models\Saver()

Создадим файл: /extensions/Modules/Activity/Panel/Models/Saver.php

Опишем класс:


<?php

namespace Modules\Activity\Panel\Models;

use Prologue\Framework\Database\Database;
use Prologue\Framework\Tests\TDD;


Class Saver
{

  const entity = 'app_activity_items';

}

const entity = 'app_activity_items'; - сущность которую будем сохранять

Используйте готовые методы для данного объекта: https://dev.prologue-uni.ru/d/saver.html

Создаем тест

Подробнее о тестах: https://tdd.prologue-framework.ru/

Создаем файл: /extensions/Modules/Activity/Tests/Panel/Models/Saver/save.php


<?php
include $_SERVER['DOCUMENT_ROOT'] . '/app/configuration/init.php';

use  Modules\Activity\Panel\Models\Saver;

\Prologue\Framework\Tests\TDD::start(function () {

    Saver::save(
        [
            'id' => 0,
            'fields' => [
                'name' => 'Тестовое мероприятие',
                'activity_date' => '2020-01-22 14:00',
                'image' => '',
                'preview_text' => 'Краткое описание',
                'full_text' => 'Полное описание',
                'active' => 1,
            ]
        ]
    );

});

После запуска теста в браузере, будет создана запись в БД

Для того, чтобы протестировать редактирование записи, укажите id и измените name


<?php
include $_SERVER['DOCUMENT_ROOT'] . '/app/configuration/init.php';

use  Modules\Activity\Panel\Models\Saver;

\Prologue\Framework\Tests\TDD::start(function () {

    Saver::save(
        [
            'id' => 1,
            'fields' => [
                'name' => 'Тестовое мероприятие (ред)',
                'activity_date' => '2020-01-22 14:00',
                'image' => '',
                'preview_text' => 'Краткое описание',
                'full_text' => 'Полное описание',
                'active' => 1,
            ]
        ]
    );

});

Запись обновится:

Тест пройден.

10. Создание объекта Modules\Activity\Panel\Models\Reader()

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

/panel/?module=Activity&route=main

Создадим файл: /extensions/Modules/PriceTypes/Panel/Models/Reader.php

Опишем класс:


<?php

namespace Modules\Activity\Panel\Models;

use Prologue\Framework\Database\Database;
use Prologue\Framework\Tests\TDD;


Class Reader
{

    const entity = 'app_activity_items';

}

const entity = 'app_activity_items'; - сущность которую будем читать

 

Используйте готовые методы для данного объекта: https://dev.prologue-uni.ru/d/reader.html

Создаем тест

Создаем файл: /extensions/Modules/Activity/Tests/Panel/Models/Reader/getAllRecords.php


<?php
include $_SERVER['DOCUMENT_ROOT'] . '/app/configuration/init.php';

use Modules\Activity\Panel\Models\Reader;

\Prologue\Framework\Tests\TDD::start(function () {

    Reader::getAllRecords(
        [

        ]
    );

});

Тест должен вернуть список сущьностей из базы.

Откройте файл в редакторе: /extensions/Modules/Activity/Panel/Module.php

Нужно подключить:

use Modules\Activity\Panel\Models\Reader as ActivityItemsReader;

В метод getPageData() добавьте код:


'activityItems' => ActivityItemsReader::getAllRecords([])

Перейдите в файл: /extensions/Modules/Activity/Panel/Views/list/tabs/list.php

Нужно написать код, который выведет таблицу с мероприятиями.

Код доступен по этой ссылке https://dev.prologue-uni.ru/d/spisok-suschnostey.html 

Так же, нужно добавить языковые строки в файл: /extensions/Modules/Activity/Panel/Language/ru/messages.php


    'list' => [
        'tabList' => 'Список',
        'add' => 'Добавить мероприятие',
        'activityId' => 'Id мероприятия',
        'activityName' => 'Мероприятие',
        'activityNotItems' => 'Мероприятия отсутствуют.',
    ],

Готово. Теперь у нас есть список мероприятий.

11. Обработка свойств для Reader

Откройте файл в редакторе: /extensions/Modules/Activity/Panel/Models/Reader.php

Нам необходимо работать с методом handle() для того, чтобы модифицировать свойства сущности.

Нам необходимо добавить свойство saveLink - для того, чтобы у сущности появилась ссылка на карточку редактирования.

Используем метод routeToModule()


    private static function handle($record)
    {

        $record['saveLink'] = Router::routeToModule(
            [
                'module' => 'Activity',
                'routeName' => 'saveActivity',
                'params' => [
                    'activityId' => $record['id']
                ]
            ]
        );

        return $record;
    }

Таким образом можно добавлять и модифицировать любые свойства для сущности.

Теперь из списка можно перейти в карточку конкретной сущности по маршруту вида: 

/panel/?module=Activity&route=saveActivity&activityId=1

12. Создание интерфейса карточки редактирования сущности

Откройте файл в редакторе: /extensions/Modules/Activity/Panel/Views/saveActivity/template.php

И добавьте обертку: 


<form class="module_saveItemFields js_saveActivityItemForm">

</form>

Чтобы получилось так:


<?php
defined('PROLOGUE_CORE') or die;

/** @var array $data */

$arTabs = [
    [
        'title' => $this->messages['saveActivity']['tabGeneral'],
        'template' => 'tabs/general.php'
    ],
];

?>
<ul class="tabs">
    <?php foreach ($arTabs as $k => $tab) { ?>
        <li class="tab col">
            <a href="#tab_<?= $k ?>" class="active"><?= $tab['title'] ?></a>
        </li>
    <? } ?>
</ul>
<form class="module_saveItemFields js_saveActivityItemForm">
    <?php foreach ($arTabs as $k => $tab) { ?>
        <div id="tab_<?= $k ?>" class="panel__moduleContent-tab active">
            <?php include $tab['template']; ?>
        </div>
    <? } ?>
</form>

Использование типовых полей

Типовые поля описаны в этом разделе: https://dev.prologue-uni.ru/d/tipovye-polya/

Откройте файл в редакторе: /extensions/Modules/Activity/Panel/Views/saveActivity/tabs/general.php и разместите код:


<?php
defined('PROLOGUE_CORE') or die;

/** @var array $data */

?>

<? formLinkInList(
    [
        'title' => $this->messages['inList'],
        'link' => $data['linkInList'],
    ]
) ?>

<? formInput(
    [
        'code' => 'name',
        'value' => $data['activity']['name'],
        'title' => $this->messages['saveActivity']['name'],
        'required' => true
    ]
); ?>

<? formDateTime(
    [
        'code' => 'activity_date',
        'value' => $data['activity']['activity_date'],
        'title' => $this->messages['saveActivity']['activity_date'],
    ]
); ?>

<? formImage(
    [
        'title' => $this->messages['saveActivity']['image'],
        'code' => 'image',
        'value' => $data['activity']['image'],
        'folderCode' => 'activity',
        'subFolderCode' => 'st-1',
        'entityId' => \Prologue\Framework\Http\Request::get('activityId'),
    ]
); ?>

<? formText(
    [
        'title' => $this->messages['saveActivity']['preview_text'],
        'code' => 'preview_text',
        'value' => $data['activity']['preview_text'],
        'required' => false,
    ]
); ?>

<? if (!$data['activity']['name']) {
    $data['activity']['active'] = 1;
} ?>

<? formCheckBox(
    [
        'title' => $this->messages['saveActivity']['active'],
        'code' => 'active',
        'value' => $data['activity']['active'],
        'required' => false,
    ]
); ?>

<? formButton(
    [
        'title' => $this->messages['saveActivity']['save'],
        'cssClass' => 'orange',
    ]
) ?>

Откройте файл: /extensions/Modules/Activity/Panel/Language/ru/messages.php и разместите языковые строки:


    'saveActivity' => [
        'tabGeneral' => 'Основная информация',
        'name' => 'Название мероприятия',
        'activity_date' => 'Дата мероприятия',
        'image' => 'Изображение',
        'preview_text' => 'Краткое описание',
        'save' => 'Сохранить',
        'active' => 'Мероприятие активно',
    ],

Откройте файл в редакторе: /extensions/Modules/Activity/Panel/Views/saveActivity/template.php и добавьте новый таб:


    [
        'title' => $this->messages['saveActivity']['tabDescription'],
        'template' => 'tabs/description.php'
    ],


Добавьте языковую строку:


'tabDescription' => 'Описание мероприятия',

 

Создайте файл: /extensions/Modules/Activity/Panel/Views/saveActivity/tabs/description.php

Разместите код:


<?php
defined('PROLOGUE_CORE') or die;

/** @var array $data */

?>

<? formLinkInList(
    [
        'title' => $this->messages['inList'],
        'link' => $data['linkInList'],
    ]
) ?>

<? formTextEditor(
    [
        'title' => $this->messages['saveActivity']['full_text'],
        'code' => 'full_text',
        'value' => $data['activity']['full_text'],
        'required' => false,
    ]
); ?>

<? formButton(
    [
        'title' => $this->messages['saveActivity']['save'],
        'cssClass' => 'orange',
    ]
) ?>

Добавьте языковую строку:

'saveActivity' :

'full_text' => 'Описание',

13. Сохранение сущности

Откройте файл в редакторе: /extensions/Modules/Activity/Panel/Static/script.js

  1. Переименуйте метод saveItem(); в saveActivityItem();
  2. Переименуйте класс js_saveItemForm на js_saveActivityItemForm
  3. Измените action на saveActivityItem

Получится вот такой код:


function ModuleClass() {

    function index() {

        saveActivityItem();

    }

    function saveActivityItem() {
        $(document).on('submit', '.js_saveActivityItemForm', function () {
            save($(this));
            return false;
        });

        function save(obj) {
            var data = new FormData;
            $.each(obj.serializeArray(), function (index, value) {
                data.append(value.name, value.value);
            });
            data.append('action', 'saveActivityItem');
            modulePreload();
            $.ajax({
                url: '',
                data: data,
                processData: false,
                contentType: false,
                type: 'POST',
                success: function (data) {
                    M.toast({html: data.message});
                    setTimeout(function () {
                        window.location.href = data.link;
                    }, 700);
                }
            });
        }
    }


    index();
}

Откройте файл: /extensions/Modules/Activity/Panel/Module.php и создайте метод:


    public function saveActivityItem()
    {
        
    }

Инициализируйте в методе ajax()


    public function ajax()
    {
        $this->saveActivityItem();
    }

Подключите:


use  Modules\Activity\Panel\Models\Saver as ActivityItemSaver;

Реализуем отклик и вызовем метод save()


    public function saveActivityItem()
    {
        if (Request::multi('action') != 'saveActivityItem') {
            return false;
        }

        $response['status'] = 'ok';

        $id = ActivityItemSaver::save(
            [
                'id' => (int)Request::get('activityId'),
                'fields' => [
                    'name' => Request::post('name'),
                    'activity_date' => Request::post('activity_date'),
                    'image' => Request::post('image'),
                    'preview_text' => Request::post('preview_text'),
                    'full_text' => Request::post('full_text'),
                    'active' => Request::post('active'),
                ]
            ]
        );

        $response['link'] = Router::routeToModule(
            [
                'module' => 'Activity',
                'routeName' => 'saveActivity',
                'params' => [
                    'activityId' => $id
                ]
            ]
        );

        $response['message'] = $this -> messages['messageSuccessSave'];

        Rest::response($response);
    }

Добавьте языковую строку:


'messageSuccessSave' => 'Успешно сохранено!',

Готово. Записи сохраняются в базу.

14. Подставляем сохраненные значения в базу

Откройте файл в редакторе: /extensions/Modules/Activity/Panel/Module.php

В методе getPageData() допишите следующий код:


        if (Router::isRoute('saveActivity')) {
            return [
                'linkInList' => Router::routeToModule(
                    [
                        'module' => $this->moduleName,
                        'routeName' => 'main',
                    ]
                ),
                'activity' => ActivityItemsReader::getOneRecord(
                    [
                        'id' => Request::get('activityId')
                    ]
                )
            ];
        }

Теперь в шаблонах доступен массив $data['activity'] - с данными сущности.

15. Удаляем сущность

Создайте файл: /extensions/Modules/Activity/Panel/Models/Remover.php

И опишите класс объекта Remover()

Создайте тест: /extensions/Modules/Activity/Tests/Panel/Models/Remover/remove.php


<?php
include $_SERVER['DOCUMENT_ROOT'] . '/app/configuration/init.php';

use  Modules\Activity\Panel\Models\Remover;

\Prologue\Framework\Tests\TDD::start(function () {

    Remover::remove(
        [
            'id' => 5
        ]
    );

});

Передайте id сущности и протестируйте удаление. 

Откройте файл в редакторе: /extensions/Modules/Activity/Panel/Models/Reader.php

В метод handle() нужно добавить ссылку на удаление: 


        $record['removeLink'] = Router::routeToModule(
            [
                'module' => 'Activity',
                'routeName' => 'removeActivity',
                'params' => [
                    'activityId' => $record['id']
                ]
            ]
        );

Отктройте файл в редакторе:  /extensions/Modules/Activity/Panel/Views/list/tabs/list.php

В таблицу нужно добавить еще один столбец для выпадающего списка и в каждую строку, нужно вставить контрол dropdown()


<?php
defined('PROLOGUE_CORE') or die;
?>
<div class="row controlPanel">
    <div class="col s6 controlPanel__left">

    </div>
    <div class="col s6 controlPanel__right">
        <a href="<?= $data['saveActivityLink'] ?>" class="btn orange waves-effect waves-light">
            <?= $this->messages['list']['add'] ?>
        </a>
    </div>
</div>

<div class="row" style="height: calc(100vh - 225px); overflow: auto;">
    <div class="col s12">
        <? if ($data['activityItems']) { ?>
            <table>
                <thead>
                <tr>
                    <th><?= $this->messages['list']['activityId'] ?></th>
                    <th><?= $this->messages['list']['activityName'] ?></th>
                    <th></th>
                </tr>
                </thead>
                <tbody>
                <? foreach ($data['activityItems'] as $item) { ?>
                    <tr>
                        <td><?= $item['id'] ?></td>
                        <td>
                            <a href="<?= $item['saveLink'] ?>"><?= $item['name'] ?></a>
                        </td>
                        <td>
                            <? dropdown(
                                [
                                    'list' => [
                                        [
                                            'title' => $this->messages['list']['remove'],
                                            'link' => $item['removeLink'],
                                            'confirm' => true,
                                        ]
                                    ]
                                ]
                            ) ?>
                        </td>
                    </tr>
                <? } ?>
                </tbody>
            </table>
        <? } else { ?>
            <p>
                <?= $this->messages['list']['activityNotItems'] ?>
            </p>
        <? } ?>
    </div>
</div>

Добавьте языковую строку: 

list:


'remove' => 'Удалить мероприятие',

 

Откройте файл в редакторе: /extensions/Modules/Activity/Panel/Module.php

В методе init() инициализируйте метод: removeActivity()


    public function init()
    {

        $this->moduleName = Request::get('module');

        $this->messages = Language::message('/extensions/Modules/#MODULE#/Panel/Language/messages.php');

        $this -> removeActivity();

        return [
            'data' => [
                'title' => $this->messages['title'],
                'static' => [
                    'css' => [
                        'style.css'
                    ],
                    'js' => [
                        'script.js'
                    ]
                ]
            ],
        ];
    }

Подключите: 


use  Modules\Activity\Panel\Models\Remover as ActivityRemover;

И опишите метод:


    private function removeActivity()
    {
        if (!Router::isRoute('removeActivity')) {
            return false;
        }

        ActivityRemover::remove(
            [
                'id' => Request::get('activityId')
            ]
        );

        Router::redirect(
            Router::routeToModule(
                [
                    'module' => $this->moduleName,
                    'routeName' => 'main',
                ]
            )
        );

    }

Готово. Теперь записи удаляются.

16. Оптимизация CRUD

После CRUD операций, нужно использовать метод платформы Prologue\Panel\Platform\Platform::CRUDEpilogue()

Открываем объект в редакторе: /extensions/Modules/Activity/Panel/Models/Saver.php

Подключаем:

use Prologue\Panel\Platform\Platform;

В методе save(), перед return вызываем:


 Platform::CRUDEpilogue();

Должно получится вот так:


    public static function save($params)
    {
        TDD::debug($params, 'params', 'Инициализируем параметры');

        if (!$params['id']) {
            $params['id'] = self::createTmpEntity();
        }

        self::save__updateDatabaseRecord($params);

        self::removeTmpEntity();

        Platform::CRUDEpilogue();

        return $params['id'];
    }

 

Подключение метода CRUDEpilogue() необходимо для очистки кеша и оптимизации производительности.

Открываем файл в редакторе: /extensions/Modules/Activity/Panel/Models/Remover.php

Подключаем:

use Prologue\Panel\Platform\Platform;

В методе remove(), в самом конце делаем вызов CRUDEpilogue()


    public static function remove($params)
    {

        TDD::debug($params, 'params', 'Инициализация параметров');

        $database = new Database;

        $pdo = $database->init();

        $sql = 'DELETE FROM ' . self::entity . ' WHERE id=:id LIMIT 1';

        $stmt = $pdo->prepare($sql);

        $stmt->execute(
            [
                'id' => $params['id']
            ]
        );

        Platform::CRUDEpilogue();

    }

CRUD операции модуля готовы.

17. Создание динамических разделов

Нам необходимо чтобы для использования нашего модуля создавалось 2 функциональных раздела.

  1. Раздел со списком мероприятий
  2. Раздел с мероприятием детально

Для этого, нужно создать функционал синхронизации с модулем Страницы.

Создайте Раздел со списком мероприятий по данной инструкции: https://dev.prologue-uni.ru/d/stranica-spiska-suschnostey.html

Создайте раздел с мероприятием детально по данной инструкции: https://dev.prologue-uni.ru/d/stranica-detal-noy-suschnosti.html

18. Разработка App API

Модуль сохраняет сущности в базу, выполняет CRUD операции.

Теперь нам нужно создать API модуля, для того, чтобы с ним можно было работать из вне. К примеру, для того, чтобы компоненты получали из него данные.

Для этого, разработаем Modules\Activity\App\Models\Reader()

Описание объекта доступно по этой ссылке: https://dev.prologue-uni.ru/d/app-reader.html

Создадим тесты и убедимся что все работает.

 

/extensions/Modules/Activity/Tests/App/Models/Reader/getAllRecords.php

 


<?php
include $_SERVER['DOCUMENT_ROOT'] . '/app/configuration/init.php';

use Modules\Activity\App\Models\Reader;

\Prologue\Framework\Tests\TDD::start(function () {

    Reader::getAllRecords(
        [

        ]
    );

});

 

/extensions/Modules/Activity/Tests/App/Models/Reader/getOneRecord.php

 


<?php
include $_SERVER['DOCUMENT_ROOT'] . '/app/configuration/init.php';

use Modules\Activity\App\Models\Reader;

\Prologue\Framework\Tests\TDD::start(function () {

    Reader::getOneRecord(
        [
            'id' => 1
        ]
    );

});

 

  1. Структура модуля
  2. Создание модуля