Magento для PHP MVC розробників – Інсталювання Ресурсу (ч.5/11)

Magento для PHP MVC розробників – Інсталювання Ресурсу (ч.5/11)



Для будь-якого швидко зростаючого проекту розробки програмного забезпечення, завдання зберігати синхронізацію між базами даних на стадії розробки та реалізації стає важливою задачею. Magento пропонує систему для створення версійності скриптів міграції ресурсів, яка може допомогти вашій команді вирішити цю часто суперечливу частину процесу розробки.

 

У попередній статті ми створили модель для публікації веб-блогу. Там ми використовували прямий запит CREATE TABLE безпосередньо в базі даних. А в цьому уроці ми створимо Інсталятор Ресурсу, який створить потрібну нам таблицю через наш модуль. Ми також створимо скрипт оновлення для модуля, який буде оновлювати вже інстальований модуль. Ось короткий перелік кроків, які нам потрібно буде зробити для цього:

 

  • Додати налаштування ресурсу до файлу конфігурації
  • Створити файл класу ресурсів
  • Створити скрипт-інсталятор
  • Створити скрипт для оновлення

 

 

Додавання Інсталятора Ресурсу

Отже, давайте продовжимо розвивати модуль веб-блогу, який ми створили минулого разу. У розділі <global/> конфігурації модуля (config.xml) додайте наступне:

 

<global>
<!-- ... -->
<resources>
  <weblog_setup>
    <setup>
      <module>Alanstormdotcom_Weblog</module>
      <class>Alanstormdotcom_Weblog_Model_Resource_Setup</class>
    </setup>
  </weblog_setup>
</resources>
<!-- ... -->
</global>

 

Тег <weblog_setup> буде використовуватися для унікального визначення цього Інсталятора ресурсу. Бажано, але не обов’язково, використовувати конвенцію іменування типу modelname_setup (НАЗВА-МОДЕЛІ_setup). Блок тегів <module>Alanstormdotcom_Weblog</module> повинен іменуватися у вигляді Packagename_Modulename. Нарешті,

<class>Alanstormdotcom_Weblog_Model_Resource_Setup</class>

має містити ім’я класу, який ми будемо створювати для нашого інсталятора ресурсу. Для початкових скриптів інсталяції не потрібно створювати власний клас, але зробивши це зараз, ви будете мати більшу гнучкість в подальшому.



 

Після додавання вищезазначеного розділу до файлу конфігурації очистіть кеш Magento і спробуйте завантажити будь-яку сторінку свого сайту. Ви побачите виняток типу:

Fatal error: Class 'Alanstormdotcom_Weblog_Model_Resource_Setup' not found in

 

Magento просто намагався створити екземпляр класу, який ми вказали у конфігурації, але не зміг його знайти. Тож нам потрібно створити такий файл із наступним вмістом:

 

Файл: app/code/local/Alanstormdotcom/Weblog/Model/Resource/Setup.php

class Alanstormdotcom_Weblog_Model_Resource_Setup extends Mage_Core_Model_Resource_Setup {

}

 

Тепер перезавантажте будь-яку сторінку свого сайту на Мадженто. Виняток повинен зникнути, а сторінка повинна нормально завантажуватися.

 

 

Створення скрипта Інсталятора

Далі оглянемо процедуру створення скрипту Інсталятора. Це скрипт, який буде містити будь-який CREATE TABLE або інший SQL код, який потрібно запустити для ініціалізації нашого модуля.

 

По-перше, подивіться на файл конфігурації config.xml

 

<modules>
  <Alanstormdotcom_Weblog>
    <version>0.1.0</version>
  </Alanstormdotcom_Weblog>
</modules>

 

Цей розділ повинен бути у всіх файлах config.xml, з його допомогою визначається модуль, а також номер його версії. Назва файлу скрипта інсталятора буде базуватися на даному номері версії. Нижче наведено припущення, що поточна версія вашого модуля – 0.1.0.

 

Створіть наступний файл:

 

Файл: app/code/local/Alanstormdotcom/Weblog/sql/weblog_setup/mysql4-install-0.1.0.php

echo 'Запущено це оновлення: '.get_class($this)."\n <br /> \n";
die("Вийдемо поки що");

 

Частка weblog_setup в шляху повинна збігатися з тегом, який ви створили у файлі config.xml (<weblog_setup/>). Частина назви файлу 0.1.0 повинна відповідати початковій версії вашого модуля. Очистіть кеш Magento та перезавантажте будь-яку сторінку на своєму сайті, і ви повинні побачити щось подібне (при відключених сповіщеннях ви не побачите цього):

 

Запущено це оновлення: Alanstormdotcom_Weblog_Model_Resource_Setup
Вийдемо поки що

 

А це означає, що ваш сценарій оновлення виконано. Згодом ми додамо SQL код до цього скрипта оновлення, але поки зосередимось на самому механізмі встановлення. Видаліть код “die” зі скрипта, щоб виглядало наступним чином:

echo 'Запущено це оновлення: '.get_class($this)."\n <br> \n";

 

Перезавантажте сторінку. Ви повинні побачити повідомлення про оновлення в верхній частині сторінки. Перезавантажте знову і сторінка повинна відображатися без повідомлень.

 

 

Версії ресурсів

Ресурси для встановлення система запускає автоматично і лише потрібні. Це дозволяє зберігати у системі всі скрипти міграції бази даних у відповідному форматі.

 

Виконайте SQL-запит у базі даних для перегляду таблиці core_resource

select * from core_resource;

+-------------------------+------------+--------------+
| code                    | version    | data_version |
+-------------------------+------------+--------------+
| adminnotification_setup | 1.6.0.0    | 1.6.0.0      |
| admin_setup             | 1.6.1.0    | 1.6.1.0      |
| api2_setup              | 1.0.0.0    | 1.0.0.0      |
…………………………………….
| weblog_setup            | 0.1.0      | 0.1.0        |
| weee_setup              | 1.6.0.0    | 1.6.0.0      |
| widget_setup            | 1.6.0.0    | 1.6.0.0      |
| wishlist_setup          | 1.6.0.0    | 1.6.0.0      |
| xmlconnect_setup        | 1.6.0.0    | 1.6.0.0      |
+-------------------------+------------+--------------+
55 rows in set (0.00 sec)

 

 

В отриманій таблиці ви зможете побачити список всіх встановлених модулів та їх номери версій. Наш модуль можна знайти майже в кінці:

 

| weblog_setup            | 0.1.0      | 0.1.0        |

 

Ось як Magento знає, що не потрібно повторно запускати скрипт вдруге, і в подальшому. Ресурс weblog_setup вже встановлено, тому його не буде оновлено. Якщо ви хочете перезапустити сценарій інсталятора (корисно в процесі розробки), просто видаліть рядок для потрібного модуля з цієї таблиці. Давайте зробимо це зараз за допомогою SQL кода:

DELETE from core_resource where code = 'weblog_setup';

 

Також нам потрібно видалити таблицю, яку ми створили вручну в попередньому уроці:

DROP TABLE blog_posts;

 

Потім додайте наступний код до файлу скрипта інсталятора:

 

$installer = $this;
$installer->startSetup();
$installer->run("
  CREATE TABLE `{$installer->getTable('weblog/blogpost')}` (
    `blogpost_id` int(11) NOT NULL auto_increment,
    `title` text,
    `post` text,
    `date` datetime default NULL,
    `timestamp` timestamp NOT NULL default CURRENT_TIMESTAMP,
    PRIMARY KEY  (`blogpost_id`)
  ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
  INSERT INTO `{$installer->getTable('weblog/blogpost')}` VALUES (1,'My New Title','This is a blog post', '2017-09-01 00:00:00','2017-09-02 23:10:00');
");
$installer->endSetup();

 

 

Очистіть кеш Magento та перезавантажте будь-яку сторінку в системі. Після цього повинна з’явитися нова таблиця blog_posts з одним записом.

 

 

Анатомія скрипта Інсталятора

Отже, давайте розглянемо скрипт по черзі. По-перше, є $this.

$installer = $this;

 

Кожен сценарій інсталятора запускається з контексту класу ресурсу Інсталяції, який ми створили раніше. Це означає, що будь-яке посилання на $this зі скрипта буде посиланням на екземпляр об’єкту з цього класу. Хоча це не є обов’язковим, більшість сценаріїв інсталятора в core модулях мають псевдонім $this для змінної, яка називається installer, і це ми тут зробили. Незважаючи на те, що це не є необхідним, це є конвенцією, тому найкраще завжди слідувати конвенції, якщо у вас немає вагомих причин для іншого.

 

Далі в коді йдуть запити, що обрамлені викликом двох методів:

$installer->startSetup();
//...
$installer->endSetup();

 

Якщо ви поглянете на клас Mage_Core_Model_Resource_Setup у app/code/core/Mage/Core/Model/Resource/Setup.php (цей клас успадковує скрипт), ви побачите, що ці методи виконують базові SQL налаштування:

 

public function startSetup() {
  $this->getConnection()->startSetup()
  return $this;
}

public function endSetup() {
  $this->getConnection()->endSetup();
  return $this;
}

 

Подивіться на клас Varien_Db_Adapter_Pdo_Mysql, щоб знайти справжнє SQL налаштування, що виконується для MySQL підключень методами startSetup() і endSetup().

 

І, нарешті, виклик методу run:

$installer->run(...);

 

який в якості параметру містить рядок з SQL кодом, необхідним для налаштування таблиці(ь) вашої бази даних. Ви можете вказати будь-яку кількість запитів, розділених двокрапкою. Ви також, напевно, помітили наступне

$installer->getTable('weblog/blogpost')

 

Метод getTable дозволяє передавати URI Моделі та отримувати назву таблиці. Використання цього методу гарантує, що ваш скрипт продовжуватиме працювати, навіть якщо хтось змінить назву цієї таблиці у файлі конфігурації. Клас Mage_Core_Model_Resource_Setup містить багато корисних допоміжних методів, таких як цей. Найкращий спосіб ознайомитися з усім можливим є вивчення сценаріїв Інсталятора, які використовуються core модулями Magento.

 

 

Агностичні сценарії RDBMS

Починаючи з версії 1.6 Magento (теоретично) підтримує більшу кількість баз даних, тобто не лише MySQL. Оскільки наш набір сценаріїв містить сирі SQL запити, він може некоректно працювати в іншій системі баз даних, скажімо, MSSQL. З цієї причини назва файлу скрипта інсталятора починається з mysql4-.

 

Для того, щоб зробити скрипти інсталювання сумісними з іншими базами даних, Magento пропонує об’єкт таблиці DDL (Data Definition Language). Ось альтернативна версія нашого сценарію інсталювання, яка працюватиме на будь-яких підтримуваних СУБД:

 

Файл: app/code/local/Alanstormdotcom/Weblog/sql/weblog_setup/mysql4-install-0.1.0.php

$installer = $this;
$installer->startSetup();
$table = $installer->getConnection()->newTable($installer->getTable('weblog/blogpost'))
->addColumn('blogpost_id', Varien_Db_Ddl_Table::TYPE_INTEGER, null, array(
  'unsigned' => true,
  'nullable' => false,
  'primary' => true,
  'identity' => true,
), 'Blogpost ID')
->addColumn('title', Varien_Db_Ddl_Table::TYPE_TEXT, null, array(
  'nullable' => false,
), 'Blogpost Title')
->addColumn('post', Varien_Db_Ddl_Table::TYPE_TEXT, null, array(
  'nullable' => true,
), 'Blogpost Body')
->addColumn('date', Varien_Db_Ddl_Table::TYPE_DATETIME, null, array(
), 'Blogpost Date')
->addColumn('timestamp', Varien_Db_Ddl_Table::TYPE_TIMESTAMP, null, array(
), 'Timestamp')
->setComment('Alanstormdotcom weblog/blogpost entity table');
$installer->getConnection()->createTable($table);

$installer->endSetup();

 

Як видно з коду, у цій версії скрипта не використовуються сирі SQL запити. Тож яку версію ви повинні використовувати? Якщо вам потрібно, щоб ваші модулі працювали на будь-якому базовому сервері RDBMS, скористайтеся новими сценаріями оновлення в стилі DDL. Якщо ви турбуєтеся про зворотну сумісність, скористайтеся стилем сирих SQL запитів, який підтримується Magento 1.6 і 1.7 (і, можливо, буде підтримуватися всіма Magento 1.x версіями).

 

 

Оновлення Модуля

Отже, ми створили скрипт, який буде налаштовувати початкові таблиці бази даних, але що робити, якщо потрібно змінити структуру існуючого модуля? Ресурси для Інсталювання Magento підтримують просту схему версій, яка дозволить вам автоматично запускати скрипти для оновлення ваших модулів.

 

Коли Magento запускає сценарій встановлення для модуля, він більше ніколи не запустить інший installer для цього модуля (за винятком ручного видалення посилання в таблиці core_resource). Замість цього вам потрібно створити сценарій оновлення. Сценарії оновлення дуже схожі на сценарії інсталятора з кількома ключовими відмінностями.

 

Щоб протестувати це, ми створимо скрипт у наступному місці з таким вмістом:

 

Файл: app/code/local/Alanstormdotcom/Weblog/sql/weblog_setup/upgrade-0.1.0-0.2.0.php:

echo 'Тестування нашого сценарію оновлення (upgrade-0.1.0-0.2.0.php) та зупинення виконання скрипта перед тим як оновиться номер версії системи';
die();

 

Сценарії оновлення містяться у тій самій папці, що й сценарій Інсталяції, але називається трохи по-іншому. По-перше, і найбільш очевидно, що ім’я файлу містить слово upgrade (тобто, оновлення). По-друге, ви помітите, що є два номери версій, розділених символом ““. Перший (0.1.0) – це версія модуля, з якої ми оновлюємось. Другий (0.2.0) – це версія модуля, до якої ми оновлюємося.

 

Якщо ми очистимо кеш і перезавантажимо сторінку, наш скрипт не буде працювати. Щоб викликати оновлення, нам потрібно оновити номер версії у файлі config.xml нашого модуля:

 

<modules>
  <Alanstormdotcom_Weblog>
    <version>0.2.0</version>
  </Alanstormdotcom_Weblog>
</modules>

 

За наявності нового номера версії, ми повинні очистити кеш Magento та завантажити будь-яку сторінку на сайті. Так сценарій оновлення запрацює.

До речі, ми також могли б назвати наш скрипт оновлення mysql4-upgrade-0.1.0-0.2.0.php. Це означатиме, що наше оновлення міститиме MySQL-специфічний SQL код.

 

Перш ніж ми продовжуватимемо та фактично реалізуємо сценарій оновлення, є одна важлива частина поведінки, яку вам потрібно знати. Створіть інший файл оновлення в наступному місці з таким вмістом:

 

Файл: app/code/local/Alanstormdotcom/Weblog/sql/weblog_setup/upgrade-0.1.0-0.1.5.php:

echo 'Тестування нашого сценарію оновлення (upgrade-0.1.0-0.1.5.php), і не припинення виконання <br>';

 

Якщо ви перезавантажите сторінку, ви помітите, що показуються обидва повідомлення. Коли Magento помічає, що номер версії модуля змінився, він буде працювати з усіма скриптами інсталяції, необхідними для оновлення цієї версії. Хоча ми ніколи не створювали версію 0.1.5 для модуля Weblog, Magento бачить сценарій оновлення та спробує запустити його. Скрипти будуть працювати в порядку від найнижчого до найвищого. Якщо ви подивитесь на таблицю core_resource,

 

select * from core_resource where code = 'weblog_setup';

+--------------+---------+--------------+
| code         | version | data_version |
+--------------+---------+--------------+
| weblog_setup | 0.1.5   | 0.1.5        |
+--------------+---------+--------------+
1 row in set (0.00 sec)

 

ви помітите, що Magento вважає номером версії модуля 1.5. Це тому, що ми завершили виконання оновлення від 1.0 до 1.5, але не завершили виконання оновлення з 1.0 до 2.0.

 

Отже, з усього цього, написання нашого фактичного сценарію оновлення є ідентичним написанню сценарію інсталювання. Давайте змінимо скрипт версії 0.1.0-0.2.0:

 

$installer = $this;
$installer->startSetup();
$installer->getConnection()
->changeColumn($installer->getTable('weblog/blogpost'), 'post', 'post', array(
  'type' => Varien_Db_Ddl_Table::TYPE_TEXT,
  'nullable' => false,
  'comment' => 'Blogpost Body'
)
);
$installer->endSetup();
die("Ви побачите, чому це тут через секунду");

 

Спробуйте оновити сторінку на своєму сайті і… нічого. Сценарій оновлення не запустився. Поле post в нашій таблиці все ще повертає нульові значення, а що ще важливіше, виклик die() не зупинив виконання. Ось чому так сталося:

 

  1. Ресурс weblog_setup був у версії 0.1.0
  2. Ми оновили наш модуль до версії 0.2.0
  3. Magento побачив оновлений модуль і побачив, що для запуску було два сценарії оновлення; від 0.1.0 до 0.1.5 та від 0.1.0 до 0.2.0
  4. Magento поставив до черги обидва скрипти для запуску
  5. Magento запустив скрипт з 0.1.0 до 0.1.5
  6. Ресурс weblog_setup тепер має версію 0.1.5
  7. Magento запустив скрипт з 0.1.0 до 0.2.0, виконання було припинено
  8. На наступному завантаженні сторінки Magento побачив weblog_setup у версії 0.1.5 і не побачив жодних сценаріїв оновлення для запуску, оскільки обидва скрипти вказали, що їх слід запустити з версії 0.1.0

 

Правильний спосіб досягти того, що ми хочемо, полягає в іменуванні наших скриптів наступним чином:

 

upgrade-0.1.0-0.1.5.php #Цей оновлює з 0.1.0 до 0.1.5
upgrade-0.1.5-0.2.0.php #А цей оновлює з 0.1.5 до 0.2.0

 

Magento досить розумний, щоб запускати обидва скрипти при завантаженні однієї сторінки. Ви можете повернутися в часі і спробувати це, оновивши таблицю core_resource

 

UPDATE core_resource SET version = '0.1.0', data_version = '0.1.0' WHERE code = 'weblog_setup';

 

Одна з дивних примх Magento системи в тому, що оновлення будуть запускатись так, як це було раніше налаштовано. Це означає, що вам потрібно бути обережними, коли декілька розробників додають до системи свої сценарії оновлення.

 

 

 

Підведення підсумків

Тепер ви повинні знати основи використання ресурсів Інсталювання Magento для створення версій скриптів міграції бази даних, а також зрозуміти скрипти, що містяться в core модулях. Окрім створення стандартного способу написання сценаріїв міграції для розробників, ресурси Інсталювання стають набагато важливішими при створенні та модифікації моделей Entity Attribute Value.

 

 

Автор: Alan Storm (http://alanstorm.com/magento_setup_resources/)

Переклад українською: SebWeo

 

 

Всі статті даної серії:

  1. Magento для PHP MVC розробників (Alan Storm) – ч.1/11
  2. Magento для PHP MVC розробників – розбір Контролера (ч.2/11)
  3. Magento для PHP MVC розробників – Макети, Блоки та Шаблони (ч.3/11)
  4. Magento для PHP MVC розробників – Моделі та основи ORM (ч.4/11)
  5. Magento для PHP MVC розробників – Інсталювання Ресурсу (ч.5/11)
  6. Magento для PHP MVC розробників – Розширений ORM – EAV (ч.6/11)
  7. Magento для PHP MVC розробників – Особлива конфігурація системи (ч.7/11)
  8. Magento для PHP MVC розробників – Поглиблене налаштування системи (ч.8/11)
  9. Magento для PHP MVC розробників – Колекції Varien Data (ч.9/11)
  10. Magento для PHP MVC розробників – Перевизначення і оновлюваність системи (ч.10/11)
  11. Magento для PHP MVC розробників – Конфігурація системи за замовчуванням (ч.11/11)

 



Напишіть тут свою думку/питання

Ваша пошта не публікуватиметься. Обов’язкові поля позначені *