Нове життя legacy проекту

На хабре є багато статей, як зробити добре. Є багато статей, як робити не варто.
Але що, якщо у вас є проект, який працює, приносить бізнесу гроші, але з програмістів, що в ньому зрозуміти, не може майже ніхто. Кожна зміна робиться на страх і ризик зіграти в російську рулетку.

Добре, коли у вас є рік або два для підготовки нового проекту з нуля (був у мене такий досвід). Але якщо власник не готовий вкладатися в те, що ви будете щось робити паралельно з нуля, поки старий движок на всю загинається. Спроби навіть заговорити, про те, щоб написати все по новій, зустрічають моментальний відмову. Але можна спробувати маленькими кроками, робити новий движок, який поступово почав забирати на себе всю більшу і більшу роль в роботі проекту. Власне про досвід здійснити таку заміну, я б хотів вам розповісти.

Дано
Сайт з продажу квитків на концерти, пхп плюс мускуль, код старий, має невелике логічне поділ (на мій смак, трохи краще битрикса), шаблони, бізнес логіка і прямі запити в бд прямо в одному методі. Найбільш використовувані класи на 2.000+ рядків. Вообщем все як ми любимо.

Куди переїжджаємо? Симфонія, так як це найбільш популярний фреймворк в нашому оточенні, є багато людей, які провели не один рік, у створенні проектів на ньому. Також симфонія зараз використовується в багатьох проектах, має хорошу документацію і використовує багато нові фішки пхп. Вообщем оди цього фреймворку співають у багатьох статтях, але на практикте це зводитися до більш легкої підтримки і можливості пошуку фахівців.

Створення моделей
Дані це найголовніше, що у вас є, особливо якщо ви хочете «викинути» движок. Тому починати розробку нового движка логічно з того, щоб підчепити дані з поточної бази. У випадку з symfony ми будемо створювати моделі. Насправді тут все досить просто, базові поля ви можете створити з допомогою команди doctrine:mapping:import (детальніше можна почитати тут). Для того, щоб не обробляти відразу всі таблиці, команду запускали на урезаной базі, де залишилися тільки основні таблиці (замовлення, квитки, заходи і користувачі, плюс пара таблиць зв'язків і розширених даних)

Тут ви можете зустріти перші проблеми. В нашій базі виявилися enum, які доктрина ніяк не хоче перетравлювати, але за пару годин роботи вийшло скласти міграцію (тут мається на увазі просто sql файл, а не міграція доктрини) на наш невеликий десяток цих полів, яка замінила enum на рядка/числа.

Трохи попрацювавши з колонками ми без проблем отримай та зв'язку в наших об'єктах. Якщо звичайно старі розробники дбали про вас і використовували primary key якості зв'язку або якісь колонки, з допомогою яких ви могли б описати зв'язку one/many. Так що тут нам трохи пощастило.

Майже пощастило. Друга проблема виявилася з замовленнями, слово order є зарезервованими, в одній з таблиць є колонка яка містить в це поле id замовлення (спасибі автору, що в інших таблицях він несподівано став використовувати ord_id а не слово order). Тут з швидких рішень виявився тільки хак з завантаженням.

public function postLoad(LifecycleEventArgs $event)
{
$entity = $event->getEntity();

if ($entity instanceof Ticket) {
// getOrderNumber видає номер який міститься в колонці order
$id = $entity->getOrderNumber();

if ($id) {
$order = $event->getEntityManager()->getRepository('AppBundle:Orders')->find($id);

if (!$order) {
throw new \Exception(sprintf("Order %d not found in base", $id));
}

// setOrder/getOrder насправді працюють з прихованим полем orderObject який містить в собі об'єкт замовлення
$entity->setOrder($order);
}
}
}

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

/**
* @ORM\Column(type="integer", options={"default" = 0})
*/
public $type = 0;

Заміна крона
З чого почати впроваджувати новий движок? Що не страшно зламати без втрати клієнтів, якщо ваш проект не покритий тестами? Де відбувається «брудна» робота, яка особливо не цікава власникам бізнесу? Де можна реалізувати логіку, але при цьому не потрібно інтегрувати шаблони старого сайту? Так що у нас вибір на бойове хрещення нового движка випав на крон завдання. Як мінімум ще одна причина по який його хотілося замінити, це те, що в старому движку виклики йшли через wget.

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

Перші кроки (окремий віджет)
Другий блок який був реалізований на новому движку, це несподівано підвернувся віджет для партнерів. З себе він представляв невелику сторінку, яка через iframe вбудовується на партнерський сайт. А також ця сторінка вимагала окремого управління в адмінці. Чесно кажучи, коли я читав вимоги і усвідомлював, що новий движок тільки що пройшов бойове хрещення, я думав, що краще просто бути не може.

З самим iframe проблем немає, верстка окремо, шаблон окремо, навіть окрема таблиця, для управління тим, що потрібно показувати. Але це все було потрібно редагувати через адмінку, і найголовніше, щоб користувач не відчув різниці (або відчув тільки в кращу сторону). Тому треба було вирішити дві проблеми: авторизація і зовнішній вигляд форм.

Перше вирішилося через механізм guard'ів. Знадобився лише перенести логіку зі старого коду методи getCredentials і getUser. Для нашого проекту вся логіка зайняла менше 10 рядків. За мої 5 років на симфонії, у мене ніколи не було більш швидкого налаштування авторизації і всього лише одним класом. Питання з зовнішнім виглядом легко зважився за допомогою стилізації форм.

Налаштування nginx
Тепер треба запустити все це диво. На старому проекті використовувалася зв'язка nginx+apache, і тут є деякі проблеми, що конфіги апача мало хто толком зараз вміє налаштовувати з розподілом по шляхах, тому був організований другий бекенда з php-fpm. Нові шляхи відправлялися на app.php а він вже в свою чергу вирушав на fpm з коренем у папці нового проекту. Власне в конфіг був доданий приблизно такий код.

location ~ ^/admin/parnter {
root /path-to-new-engine/web;
try_files $uri /app.php$is_args$args;
}

location ~ ^/app\.php(/|$) {
root /path-to-new-engine/web;
Internal;
...fast_cgi config...
}

Що в підсумку?
На даний момент, можна сказати, що ми зробили крок від концепції до вже працюючих речей. В цілому було отримано позитивний досвід, і проблеми, які виникли на цьому етапі навряд чи можна назвати проблемами, скоріше це программистские будні. Так само не варто забувати про психологічний ефект, тепер це не якийсь легасі проект, якому немає кінця і краю, тут вже є перспективи для впровадження нових розробок, що безперечно манить розробників. Так само позитивний ефект виявився і для замовника, так як на його проекті ми почали використовувати більш відомий і передбачуваний інструмент, то за деякими його хотінням ми почали скорочувати терміни виконання, що вплинуло і на зниження вартості розробки нових фішок. Не всіх звичайно, але з чогось треба було почати.
Джерело: Хабрахабр

0 коментарів

Тільки зареєстровані та авторизовані користувачі можуть залишати коментарі.