- Вступ Команда Юпі! активно розвиває систему і впроваджує нові можливості, але треба визнати, що...
- Список вимог:
- каркас модуля
- міграції
- Модель
- Відображення списку завдань і фільтрація
- Додати / редагувати / видалення завдань
- Статуси
- Сортування перетягуванням (drag & drop)
- Повідомлення про невиконані завдання в панелі управління
Вступ
Команда Юпі! активно розвиває систему і впроваджує нові можливості, але треба визнати, що ми не всесильні і не можемо задовольнити потреб усіх користувачів. У цьому розділі ми постараємося максимально докладно висвітлити питання створення власних модулів для Юпі !, щоб ви могли самостійно поліпшити свій проект.
Важливо!
Якщо ви не знайомі з фреймворком Yii , То для більш легкого розуміння матеріалу, рекомендую вам ознайомитися з шаблоном проектування MVC , модулями фреймворка, а ще краще - вивчити навчальний посібник з створення блогу .
опис модуля
Оскільки нашим завданням є навчання, а не винахід чогось нового і цікавого, то ми будемо створювати простенький модуль завдань "ToDo". Думаю, для наших цілей цього буде достатньо. Щоб не ускладнювати процес, зробимо припущення, що в системі може бути зареєстрований тільки один користувач. Це дозволить нам не розділяти списки завдань. В якості домашнього завдання ви можете реалізувати цю можливість самостійно.
Всі етапи розробки будуть оформлені в окремі коммітов, які ви зможете подивитися на GitHub . Виниклі питання можна задати на нашому форумі .
Список вимог:
- повинна бути можливість створювати, редагувати і видаляти завдання;
- реалізувати пошук по задачам і фільтрацію по статусу;
- inline-редагування статусів завдань;
- зміна пріоритету завдань перетягуванням мишею (drag & drop);
- на головній сторінці панелі управління відображати повідомлення про кількість невиконаних завдань.
Так, можна зробити все набагато простіше, але нам би хотілося охопити якомога більше різних аспектів створення модуля.
каркас модуля
Спочатку потрібно створити мінімально можливу структуру модуля, для того, щоб можна було включити його в панелі управління і візуально спостерігати зміни в процесі його створення.
Зверніть увагу!
Для більшого розуміння матеріалу, ми не будемо використовувати генератор коду (Gii), а створимо кожен файл і директорію вручну. Звичайно, в майбутньому ви можете використовувати його для спрощення роботи. Прочитати як це зробити, можна тут .
Подальші дії мають на увазі, що у вас встановлена остання стабільна версія Юпі! і відкритий улюблений редактор коду з доданими до проекту файлами системи.
У protected / modules створюємо директорію todo для нашого модуля. Всі подальші дії будуть проводитися всередині цієї категорії.
Створюємо основний файл модуля TodoModule.php з однойменною класом, які розширюють компонент WebModule модуля yupe.
use yupe \ components \ WebModule; class TodoModule extends WebModule {}
І додаємо в нього методи:
getDependencies - повертає масив модулів, від яких буде залежати наш модуль. Припустимо, якби ми хотіли додати коментарі до наших завдань і можливість додавання зображень, то потрібно було б написати так:
return [ 'image', 'comment'];
Наш модуль цілком самостійний, тому ми повернемо порожній масив.
getVersion - повертає версію вашого модуля для відображення в панелі управління.
getCategory - повідомляє системі в якій вкладці меню, панелі управління, відображати меню нашого модуля. Тобто, якщо ми хочемо розмістити його в меню "Контент", то так і напишемо:
return 'Контент';
getName - повертає назву модуля.
getDescription - короткий опис модуля.
getAuthor - ім'я автора або компанії, що створила модуль.
getAuthorEmail - email-адреса.
getUrl - посилання на сайт автора або на демонстраційний сайт.
getIcon - іконка модуля. Вказується в форматі fa fa-fw <назва>. Вибрати відповідну іконку і дізнатися її назву можна на сайті FontAwesome . У цьому модулі використовуємо іконку thumb-tack , Значить метод повинен повернути рядок fa fa-fw fa-thumb-tack.
getAdminPageLink - тут вказується посилання на будь-яку сторінку (частіше головну) модуля. Вона потрібна для відображення кнопки модуля на головній сторінці панелі управління. Будується вона за таким правилом: / <назва модуля> / <назва контролера> / <дію>. Для модуля вона прийме такий вигляд: / todo / todoBackend / index.
getNavigation - повідомляє системі про структуру меню модуля. Він вкрай простий, тому зробимо тільки два пункти: перегляд списку завдань і створення завдання.
return [[ 'icon' => 'fa fa-fw fa-list-alt', 'label' => 'Список завдань', 'url' => [ '/ todo / todoBackend / index']], [ 'icon '=>' fa fa-fw fa-plus-square ',' label '=>' Створити завдання ',' url '=> [' / todo / todoBackend / create ']],];
Ці дані будуть використані для генерації головного меню панелі керування.
Залишилося створити ще один файл і ми зможемо встановити модуль, щоб потім, додаючи функціонал, можна було спостерігати за змінами в панелі управління.
Створюємо директорію install, в якій розміщуємо файл з точно такою ж назвою, як і модуль - todo.php. У ньому буде зберігатися конфігурація модуля, де, для початку, ми просто повідомимо системі про його існування:
return [ 'module' => [ 'class' => 'application.modules.todo.TodoModule',],];
Рядок application.modules.todo.TodoModule - це шлях до головного класу модуля, де application вказує на директорію protected.
От і все! Якщо все зроблено правильно, то в розділі "Модулі", у вкладці "Чи не встановлено!", Ми повинні побачити наш модуль.
Після установки модуля ви повинні побачити пункт "ToDo" в головному меню і кнопку на головній сторінці панелі управління.
І, хоча в ньому ще нічого не відображається, крім назви і меню модуля, а попереду нас чекає ще багато роботи, я думаю, можна вас привітати з цим маленьким, але дуже важливим кроком.
Детально вивчити створені файли ви можете в цьому Ком на GitHub . А якщо виникли питання, то сміливо задавайте їх на нашому форумі . Будемо раді допомогти!
міграції
Тепер прийшов час задуматися над структурою таблиці модуля і створенні міграції. Про те, що таке міграції, для чого вони потрібні і як з ними працювати, ви можете прочитати в офіційному керівництві .
У модулях Юпі! файли міграцій зберігаються в директорії install / migrations. Перед тим як продовжувати, переконайтеся, що ви її створили.
Далі, в консолі, перебуваючи в кореневій папці вашого проекту, виконуємо команду php protected / yiic migrate create todo yupe_todo_table. Цією командою ми створюємо файл міграції yupe_todo_table для модуля todo.
Якщо все пройшло добре, то на даний момент у вас повинна бути наступна структура директорій:
. ├── install │ ├── migrations │ │ └── m151205_141508_yupe_todo_table.php │ └── todo.php ├── LICENSE ├── README.md └── TodoModule.php
Тепер, в створеному файлі, потрібно описати поля таблиці для зберігання завдань. Згідно, описаним вище, вимогам до модуля, у завдання повинно бути опис, статус і сортування.
class m151205_141508_yupe_todo_table extends yupe \ components \ DbMigration {public function safeUp () {$ this-> createTable ( '{{todo}}', [ 'id' => 'pk', 'description' => 'string NOT NULL', 'status' => 'TINYINT (1) NOT NULL DEFAULT 1', 'sort' => 'integer NOT NULL DEFAULT 1',], $ this-> getOptions ()); } Public function safeDown () {$ this-> dropTable ( '{{todo}}'); }}
Зверніть увагу, що назва таблиці укладено в подвійні фігурні дужки {{todo}}. Це зроблено для того, щоб система автоматично підставила префікс для таблиць, який задається на етапі установки. Якщо ви нічого не змінювали, то після застосування міграції в базі даних повинна з'явитися таблиця yupe_todo.
Метод getOptions додає параметри таблиці: ENGINE = InnoDB DEFAULT CHARSET = utf8
Залишилося тільки ввести команду php protected / yiic migrate --module = todo і підтвердити що хочете застосувати міграцію.
Після успішного завершення операції, в базі даних повинна з'явитися таблиця з наступною структурою:
+ ------------- + -------------- + ------ + ----- + ------- - + ---------------- + | Field | Type | Null | Key | Default | Extra | + ------------- + -------------- + ------ + ----- + ------- - + ---------------- + | id | int (11) | NO | PRI | NULL | auto_increment | | description | varchar (255) | NO | | NULL | | | status | tinyint (1) | NO | | 1 | | | sort | int (11) | NO | | 1 | | + ------------- + -------------- + ------ + ----- + ------- - + ---------------- +
результат на GitHub
Модель
З огляду на, що офіційне керівництво по Yii фреймворку надає вичерпну інформацію про моделях , їх створенні і роботі з базою даних , Краще відразу перейти до справи.
У Юпі! є базовий клас YModel, від якого повинні бути успадковані всі моделі. Виходячи з цього, визначаємо клас:
use yupe \ models \ YModel; class Todo extends YModel {}
На цьому етапі знадобиться перевизначити тільки три методи: - tableName - повертає назву таблиці в базі даних. Тут все просто, це буде рядок {{todo}}; - rules - правила валідації даних; - attributeLabels - повертає список міток аттрибутов в форматі 'Атрибут' => 'Опис'.
Все інше будемо дописувати при першій необхідності.
Подивитися на отриманий код ви можете у відповідному Ком на GitHub, посилання на який вказана в кінці цього розділу. А поки опишемо вимоги для правил валідації: - поле description має бути обов'язковим і мати довжину не більше 255 символів; - поля status і sort повинні бути цілочисельними.
[ 'Description', 'required'], [ 'description', 'length', 'max' => 255], [ 'status, sort', 'numerical', 'integerOnly' => true],
Поки це все, що ми можемо написати в моделі. Надалі доведеться додати кілька правил валідації і методів, а поки можна вивчити отриманний результат .
Якщо у вас виникли питання по попередніх кроків керівництва, то можете сміливо ставити їх на форумі . Можливо, це допоможе нам доповнити керівництво і зробити його більш зрозумілим.
На цьому етапі, мабуть, самим логічним буде створення адміністративної частини модуля. Почнемо з контролера.
У методі getNavigation (файл TodoModule.php) посилання на пункти меню мають такий вигляд: [ '/ todo / todoBackend / index']. Як вже говорилося раніше, вони створюються за принципом / назва модуля / назва контролера / дію. З цього випливає, що контролер повинен називатися TodoBackendController і розташовуватися в директорії controllers.
До цього моменту структура директорій модуля повинна мати вигляд:
. ├── controllers │ └── TodoBackendController.php ├── install │ ├── migrations │ │ └── m151205_141508_yupe_todo_table.php │ └── todo.php ├── LICENSE ├── models │ └── Todo.php ├── README.md └── TodoModule.php
Зверніть увагу, що контролер повинен наслідувати BackController. Також створюємо дію index в якому задаємо відображення однойменного уявлення.
use yupe \ components \ controllers \ BackController; class TodoBackendController extends BackController {public function actionIndex () {$ this-> render ( 'index'); }}
Файли уявлень повинні знаходитися в директорії views, всередині якої вони сортуються за тек, що належать до конкретного контролера. В даному випадку це todoBackend. Створюємо файл і залишаємо його поки порожнім.
Для тих, хто не впевнений, що правильно все зрозумів: розміщуємо структуру категорій, яка повинна бути після створення файлу уявлення.
. ├── controllers │ └── TodoBackendController.php ├── install │ ├── migrations │ │ └── m151205_141508_yupe_todo_table.php │ └── todo.php ├── LICENSE ├── models │ └── Todo.php ├── README.md ├── TodoModule.php └── views └── todoBackend └── index.php
Якщо все зроблено правильно, то при кліці на пункті меню Контент - ToDo в панелі управління не повинно з'являтися помилки, як це було раніше. Ви повинні побачити головне меню панелі управління, блок з інформацією про модулі і порожню контентную область.
Відображення списку завдань і фільтрація
Відповідати за відображення списку завдань буде віджет CustomGridView , Якому потрібен джерело даних. Для цього буде використовуватися CActiveDataProvider .
Тепер в моделі (файл models / Todo.php) необхідно створити метод search, який і буде служити джерелом даних для відображення і фільтрації завдань.
public function search () {$ criteria = new CDbCriteria; $ Criteria-> compare ( 'description', $ this-> description, true); $ Criteria-> compare ( 'status', $ this-> status); return new CActiveDataProvider (get_class ($ this), [ 'criteria' => $ criteria, 'sort' => [ 'defaultOrder' => 'sort']]); }
Наведений вище код не повинен викликати труднощів. Варто тільки приділити трохи уваги цим двом рядкам:
$ Criteria-> compare ( 'description', $ this-> description, true); $ Criteria-> compare ( 'status', $ this-> status);
Тут описуються умови для фільтрації даних, з яких можна зрозуміти, що пошук буде здійснюватися тільки по двох полях: description і status. При цьому для поля description третім параметром передається true, що повідомляє системі про можливість пошуку всіх слів фрази.
Для правильної роботи пошуку, в правилах валідації (метод rules) необхідно оголосити ці поля безпечними для сценарію search:
[ 'Description, sort', 'safe', 'on' => 'search']
Тепер потрібно змінити контролер:
public function actionIndex () {// В моделі включаємо сценарій search $ model = new Todo ( 'search'); // Отримуємо дані з запиту. // Якщо в фільтрі нічого не міняли, то в змінній буде null $ query = Yii :: app () -> getRequest () -> getQuery ( 'Todo'); $ Model-> unsetAttributes (); if ($ query) {// Надаємо атрибутам моделі значення із запиту $ model-> setAttributes ($ query); } // Передаємо модель в уявлення $ this-> render ( 'index', [ 'model' => $ model]); }
А в поданні додати віджет:
$ This-> widget ( 'yupe \ widgets \ CustomGridView', [ 'id' => 'todo-grid', 'type' => 'condensed', 'dataProvider' => $ model-> search (), 'filter '=> $ model,' columns '=> [' id ',' description ',' status ', [' class '=>' yupe \ widgets \ CustomButtonColumn ',' template '=>' {update} {delete} '],],]);
Тепер в панелі управління ви повинні побачити наступну картину:
Звертаємо вашу увагу на те, що не весь код розміщується в цьому описі, а тільки найважливіші його частини. Більш детально вивчити код цієї частини можна на GitHub .
Додати / редагувати / видалення завдань
Почнемо роботу з реалізації можливості додавання даних.
Додаємо в TodoBackendController дію actionCreate:
public function actionCreate () {$ model = new Todo (); if ($ data = Yii :: app () -> getRequest () -> getPost ( 'Todo')) {// Якщо форма була відправлена, то присвоюємо атрибути $ model-> setAttributes ($ data); if ($ model-> save ()) {// Показуємо користувачеві повідомлення, якщо дані успішно збережені Yii :: app () -> user-> setFlash (yupe \ widgets \ YFlashMessages :: SUCCESS_MESSAGE, 'Завдання успішно додана'); $ This-> redirect ((array) Yii :: app () -> getRequest () -> getPost ( 'submit-type', [ 'create'])); }} $ This-> render ( 'create', [ 'model' => $ model]); }
Тепер потрібно створити файл уявлення, під назвою create, в якому буде відображатися форма для введення даних.
Оскільки форма буде використовуватися як при створенні завдання, так і при її редагуванні, то, для уникнення дублювання коду, буде логічно винести її в окремий файл.
$ This-> renderPartial ( '_ form', [ 'model' => $ model]);
Для зручності навігації по розділах модуля додамо меню в правий сайдбар:
$ This-> menu = [[ 'icon' => 'fa fa-fw fa-list-alt', 'label' => 'Список завдань', 'url' => [ '/ todo / todoBackend / index'] ], [ 'icon' => 'fa fa-fw fa-plus-square', 'label' => 'Створити завдання', 'url' => [ '/ todo / todoBackend / create']],];
Відображення форми буде здійснюватися виджетом ActiveForm . Валідація даних буде проводитися на клієнтській стороні:
'EnableClientValidation' => true,
Робота зі статусами буде додана пізніше, тому зараз форма містить тільки поле "Опис"
<? = $ Form-> textFieldGroup ($ model, 'description'); ?>
Після додавання потрібних файлів у вас повинна бути наступна структура директорії view
└── views └── todoBackend ├── create.php ├── _form.php └── index.php
Весь доданий код ви можете побачити в цьому Ком .
Якщо ви ніде не помилилися, то можете спробувати додати перше завдання. Після її збереження вона з'явиться в списку завдань.
Зміна завдання по суті нічим не відрізняється від її створення, за винятком того, що потрібно отримати змінювані дані. Створимо метод loadModel, який буде вибирати потрібний рядок з бази даних по первинному ключу, а в разі її відсутності повідомляти про помилку.
private function loadModel ($ id) {$ model = Todo :: model () -> findByPk ($ id); if ($ model === null) {throw new CHttpException (404, 'Запрошення сторінка не знайдена.'); } Return $ model; } Public function actionUpdate ($ id) {// завантажуємо дані $ model = $ this-> loadModel ($ id); if ($ data = Yii :: app () -> getRequest () -> getPost ( 'Todo')) {$ model-> setAttributes ($ data); if ($ model-> update ()) {Yii :: app () -> user-> setFlash (YFlashMessages :: SUCCESS_MESSAGE, 'Завдання успішно оновлена'); $ SubmitType = Yii :: app () -> getRequest () -> getPost ( 'submit-type'); if (isset ($ submitType)) {// Якщо користувач натиснув "Зберегти і закрити", // то відправляємо його на головну сторінку модуля $ this-> redirect ([$ submitType]); } Else {// Інакше залишаємося на сторінці редагування завдання $ this-> redirect ([ 'update', 'id' => $ model-> id]); }}} $ This-> render ( 'update', [ 'model' => $ model]); }
Далі створюємо файл уявлення update, який буде відрізнятися від create тільки назвами заголовків і "хлібними крихтами". Спробуйте самостійно зробити цей файл. Підглянути рішення можна тут .
Для завершення цієї частини робіт залишилося тільки реалізувати обробку видалення завдання.
Слід зазначити, що групове видалення записів реалізовано в контролері BackController, властивості і методи якого успадковує контролер модуля TodoBackendController, так що додаткової реалізації не потрібно.
В першу чергу створюємо фільтр, який заборонятиме звернення до методу actionDelete безпосередньо і вирішувати його тільки через POST запит:
public function filters () {return CMap :: mergeArray (parent :: filters (), [ 'postOnly + delete',]); }
Зверніть увагу на об'єднання двох масивів: батьківського і фільтрів поточного контролера. Про це не варто забувати, тому що в батьківському класі визначається фільтр, що обмежує доступ до адміністративної частини вашого модуля.
Далі реалізуємо видалення:
public function actionDelete ($ id) {if ($ this-> loadModel ($ id) -> delete ()) {Yii :: app () -> user-> setFlash (YFlashMessages :: SUCCESS_MESSAGE, 'Завдання успішно видалена') ; if (! Yii :: app () -> getRequest () -> getParam ( 'ajax')) {$ this-> redirect ((array) Yii :: app () -> getRequest () -> getPost ( 'returnUrl ',' index ')); }}}
Тут все дуже просто і не вимагає додаткових пояснень.
Робота над основними діями закінчена. Тепер ви можете додавати, змінювати і видаляти завдання. Результат, як завжди, можна подивитися у відповідному Ком на GitHub , А якщо виникли питання, то можна задати їх на форумі Юпі! .
Статуси
Напевно ви вже спробували додати завдання і побачили: в списку замість статусу відображається цифра 1, що вкрай не інформативно. Також немає можливості редагувати статус. Пора це виправити.
У кореневій директорії модуля створюємо директорію helpers, в якій буде знаходитися файл TodoStatusHelper, що містить назви статусів і методи для роботи з ними.
Щоб кожен раз не думати про те, яким статусом відповідає та чи інша цифра, дамо їх відповідним константам. Це також спростить редагування значення статусу при необхідності.
class TodoStatusHelper {const STATUS_CANCELLED = 0; const STATUS_DEFAULT = 1; const STATUS_URGENT = 2; const STATUS_DONE = 3; }
Пропонуємо обмежитися чотирма статусами: Скасовано, Звичайна, Термінова, Виконана. При необхідності ви можете самостійно розширити цей список.
Також знадобляться методи для отримання списку статусів і отримання назви статусу за його номером.
public static function getList () {return [self :: STATUS_CANCELLED => 'Скасовано', self :: STATUS_DEFAULT => 'Звичайна', self :: STATUS_URGENT => 'Термінова', self :: STATUS_DONE => 'Виконано',] ; } Public static function getLabel ($ id) {$ list = self :: getList (); return $ list [$ id]; }
Щоб клас хелпера був доступний для подальшого використання, необхідно додати в конфігураційний файл модуля (install / todo.php) такі рядки:
'Import' => [ 'application.modules.todo.helpers. *',],
Після чого потрібно оновити конфігурацію модуля. Це можна зробити в панелі управління, клікнувши на спеціальний значок, який з'явиться на кнопці модуля:
або виконавши консольную команду: php protected / yiic yupe updateConfig
Підготовчі роботи закінчені, тепер пора відобразити назву статусів в списку завдань. Для цього в файлі views / todoBackend / index.php значення status масиву columns замінюємо на нижченаведений код:
[ 'Name' => 'status', 'value' => function (Todo $ data) {return TodoStatusHelper :: getLabel ($ data-> status); }],
Тепер замість незрозумілої цифри у вас повинно відображатися назва статусу
Для зручності фільтрації завдань по статусу зробимо випадає
'Filter' => CHtml :: activeDropDownList ($ model, 'status', TodoStatusHelper :: getList (), [ 'encode' => false, 'empty' => '', 'class' => 'form-control' ,]),
Погодьтеся, стало набагато зручніше!
Далі реалізуємо можливість зміни статусу завдання через форму редагування. Для цього змінимо файл views / todoBackend / _form.php, де замість коду
<Div class = "row"> <div class = "col-sm-12"> <? = $ Form-> textFieldGroup ($ model, 'description'); ?> </ Div> </ div>
поставимо наступний
<Div class = "row"> <div class = "col-sm-8"> <? = $ Form-> textFieldGroup ($ model, 'description'); ?> </ Div> <div class = "col-sm-4"> <? = $ Form-> dropDownListGroup ($ model, 'status', [ 'widgetOptions' => [ 'data' => TodoStatusHelper :: getList (),],]); ?> </ Div> </ div>
Тепер, зайшовши в редагування або додавання завдання, поряд з текстовим полем ви побачите список, що випадає з назвами статусів.
Наберіться терпіння, залишилися останні штрихи і зі статусами буде покінчено. Нам залишилося зробити inline-редагування статусу, тобто дати можливість користувачу змінити статус завдання прямо зі списку, не заходячи в форму редагування.
У Юпі! це зробити не просто, а дуже просто! Реалізуємо в класі TodoBackendController метод actions
public function actions () {return [ 'inline' => [ 'class' => 'yupe \ components \ actions \ YInLineEditAction', 'model' => 'Todo', 'validAttributes' => [ 'status',]] ,]; }
Тут ви повідомляєте системі, що в цьому класі буде ще одна дія (inline), доступне за адресою / todo / todoBackend / inline. Такий підхід дозволяє уникнути непотрібного дублювання коду і спростити його зміна.
Значення ключа class вказує на клас, відповідальний за обробку даного дії. Тобто вам не потрібно кожен раз створювати метод actionInline і копіювати в нього один і той же код. Уявіть наскільки ускладнилася б ваше життя, якщо вам довелося вносити невеликі зміни в роботу цього методу, а їх у вас було б 100. В даному випадку вам потрібно відредагувати тільки один файл.
Значення ключа model містить назву моделі, яка буде відповідати за обробку даних, а в validAttributes зберігаються назви полів, доступних для редагування.
Залишилося замінити код колонки status в файлі views / todoBackend / index.php на наступний:
[ 'Name' => 'status', 'class' => 'yupe \ widgets \ EditableStatusColumn', 'url' => $ this-> createUrl ( '/ todo / todoBackend / inline'), 'source' => TodoStatusHelper :: getList (), 'filter' => CHtml :: activeDropDownList ($ model, 'status', TodoStatusHelper :: getList (), [ 'encode' => false, 'empty' => '', 'class' = > 'form-control',]),],
А тепер можна насолодитися результатом:
Наостанок пропонуємо зробити колірне кодування статусів, щоб їх було простіше розрізняти. Для цього в клас хелпера додаємо новий метод:
public static function getStylesList () {return [self :: STATUS_CANCELLED => [ 'class' => 'label-danger'], self :: STATUS_DEFAULT => [ 'class' => 'label-default'], self :: STATUS_URGENT => [ 'class' => 'label-primary'], self :: STATUS_DONE => [ 'class' => 'label-success'],]; }
У ньому кожному статусу присвоюється своє назва класу мітки. І додаємо рядок 'options' => TodoStatusHelper :: getStylesList (), в опис колонки status в файлі views / todoBackend / index.php
Код цієї частини модуля доступний по засланні . Якщо у вас виникли питання, можете сміливо ставити їх на нашому форумом .
Сортування перетягуванням (drag & drop)
У модулі немає необхідності робити сортування, тому що пріоритети завдань визначаються статусами. Але, оскільки він створюється в навчальних цілях, то пропонуємо реалізувати цю можливість.
У метод actions файлу TodoBackendController додаємо визначення дії sortable:
'Sortable' => [ 'class' => 'yupe \ components \ actions \ SortAction', 'model' => 'Todo', 'attribute' => 'sort']
Поле sort, в якому буде зберігатися порядок сортування записів, ми вже створили в розділі Міграції. Зверніть увагу, що для коректної роботи сортування значення за замовчуванням має бути 1 (NOT NULL DEFAULT 1).
В клас моделі Todo додаємо метод beforeSave, який задає порядок сортування для нових записів:
protected function beforeSave () {if ($ this-> isNewRecord) {$ this-> sort = Yii :: app () -> db-> createCommand () -> select ( 'MAX (sort) + 1') -> from ($ this-> tableName ()) -> queryScalar (); } Return parent :: beforeSave (); }
Наступні рядки додаємо до параметрів віджета CustomGridView в файлі views / todoBackend / index.php:
'SortableRows' => true, 'sortableAjaxSave' => true, 'sortableAttribute' => 'sort', 'sortableAction' => '/ todo / todoBackend / sortable',
Це все! Ось так просто , Ви можете реалізувати drag & drop сортування записів в вашому модулі для CMS Юпі!
Повідомлення про невиконані завдання в панелі управління
Згідно зі списком вимог, в адміністративній частині модуля залишилося реалізувати повідомлення про невиконані завдання.
Реалізацію почнемо з створення методу checkUnfinished в класі Todo:
public function countUnfinished () {return self :: model () -> count ( 'status! =: status', [ ': status' => TodoStatusHelper :: STATUS_DONE]); }
Тут все дуже просто: метод повертає кількість записів в базі, у яких статус не дорівнює "Виконано".
А в клас TodoModule додаємо наступний код:
public function checkSelf () {$ messages = []; $ Count = Todo :: model () -> countUnfinished (); if (! $ count) {return false; } $ Messages [WebModule :: CHECK_NOTICE] [] = [ 'type' => WebModule :: CHECK_NOTICE, 'message' => CHtml :: link ( 'Невиконаних завдань -'. $ Count, [ '/ todo / todoBackend / index ']),]; return $ messages; }
Метод checkSelf буде викликатися щоразу, коли ви будете заходити в панель управління. Повідомлення будуть показуватися на головній сторінці в однойменному блоці.
У цьому методі ми звертаємося до раніше створеного countUnfinished. Якщо значення змінної $ count більше нуля, то метод повертає масив, що містить повідомлення з посиланням на головну сторінку модуля. Згодом масиви повідомлень всіх модулів зливаються в один і виводяться на екран.
Код розділу на GitHub
На цьому роботу над модулем можна вважати завершеною. Викладеного вище матеріалу повинно вистачити для розуміння базових принципів створення модулів для CMS Юпі! Оскільки адміністративна частина модуля відрізняється від клієнтської лише назвою контролерів, то, як практики, ми пропонуємо вам самостійно реалізувати окрему сторінку для відображення відкритих завдань на вашому тестовому сайті. При бажанні ви можете піти далі і розширити функціональність модуля або почати писати свій власний.
В директорії protected / modules міститься безліч готових модулів, в яких ви можете подивитися приклади реалізацій необхідного вам функціоналу.
З питаннями, що виникли чекаємо вас на форумі Юпі! CMS
Form-> textFieldGroup ($ model, 'description'); ?Form-> textFieldGroup ($ model, 'description'); ?
Form-> textFieldGroup ($ model, 'description'); ?
Gt; </ Div> <div class = "col-sm-4"> <?
Form-> dropDownListGroup ($ model, 'status', [ 'widgetOptions' => [ 'data' => TodoStatusHelper :: getList (),],]); ?