Содержание

Проект caravantex.ru

Август, 2015

Август, 2015 г. Завершен.

Цели проекта

Работы по фронту сайта.

Особенности

CMS Symfony, XHTML, JavaScript, PHP, AJAX.

Описание

Проект caravantex.ru

Очередная задачка от «Лидер Поиска». Предыстория у задачки очень интересная.

Проект стартовал еще в 2013, но то ли разработчик был криворук (я так и не понял работал он в штате или был подрядчиком) или еще по какой причине, но проект был забыт. Сейчас заказчик вроде как зашевелился, соответственно проект подняли из архива и понеслось…

Для меня подготовили ТЗ, попросили скидку так как бюджет проекта - ноль (деньги уже получены были еще в 2013). Я посчитал отправил ответ. В этот момент на связь вышел первоначальный разработчик. Естественно ТЗ перекинули ему, но он отказался (о причинах могу лишь догадываться). Доработка опять вернулась ко мне :-).

Сайт оказался построен на фреймворке Symfony, причем старой версии (1.4), причем с каким-то надругательством над ней. Ну или система позволяет использовать методы принципиально отличающиеся от документации. Дополнительно ко всему верстка просто ужасна - множество ошибок вложенности тегов, какие-то монструозные и неявные решения. О кодстайлинге вообще молчу. А еще видели бы вы ПА.

По криворукости первоначального разработчика этот проект выходит на первое место в моем личном рейтинге.

Что же касается задачи, то тут все решилось очень просто. Т. к. сайт не предполагает личного кабинета, то вся корзина храниться в сессии (если потребуется сохранение корзины между сессиями, можно будет задействовать куки). Управление корзиной реализовано полностью через AJAX запросы.

Для всего этого я написал два новых модуля - ajax (обработка асинхронных запросов) и checkout (управление заказами), благо адекватная документация есть. При разработке этих модулей я столкнулся с одним неудобством фреймворка. Так он оказался крайне не дружелюбен в отношении подключения файлов JS и CSS, а также в отношении настройки маршрутизации. Во-первых приходится изучать новый «язык разметки» для описания конфигураций(от чего, по идее, должны избавлять фреймворки). Во-вторых, если добавить лишний таб или пробел перед директивой, то система сразу падает с 500 ошибкой. Я что-то дико сомневаюсь, что это все оправданно с точки зрения удобства разработки. К тому же такой подход к DBO (через описание таблиц) не самый удобный. Могли бы посмотреть на тот же prestaShop.


Сентябрь, 2015

Сентябрь, 2015 г. Завершен.

Цели проекта

Работы по фронту сайта.

Особенности

CMS Symfony, XHTML, JavaScript, PHP, AJAX.

Описание

Проект caravantex.ru

Эти работы вскрыли очередные неудобства и косяки в предложенном решении и/или в идеологии фреймворка.

Еще в первом прочтении документации по Symfony я обратил внимание на то, что идет слишком много настроек фреймфорка через командную строку (shell) на сервере. В тот раз я не обратил на это особого внимания…

В Symfony есть возможность через shell запускать php скрипт symfony с передачей дополнительных параметров через командную строку. Основная суть скрипта состоит в запуске фреймворка, обработке параметров из командной строки и совершение определенных действий, зависящих от этих параметров. В частности, через этот способ реализован механизм выполнения заданий (task в терминологии системы).

Возможное еще что-то реализовано через запуск из shell, но я пока с этим не столкнулся.

Я думаю, уже многие напряглись - вызов php_shell() огромная дыра в безопасности, причем гораздо шире чем всем любимый eval().

Когда я дошел до реанимации и расширения импорта данных из XLSX, то долго не мог понять, почему он собственно не работает. Предварительные раскопки и доработки скрипта заставили читать и парсить файл экселя. Парсинг заключался в создании ну очень странного массива данных и сохранение его в файл. Классическое решение разбора xlsx это либо читать его построчно и обрабатывать данные (в большинстве случаем это очень ресурсоемкое решение). Либо создать массив данных, где каждую строку записывают как отдельный элемент массива, а потом поэлементно обрабатывают его. Есть еще третий подход, когда формирует несколько массивов или специальный массив, где данные сгруппированные по их типу. Делается это крайне редки и только в тех случаях где явно, что затраты на более сложную структуру в последствии окупятся их разбором и/или импортом в систему.

Так вот в данном случаи была попытка реализовать именно третий способ. Но при этом структура массива вышла крайне не удачной. Так артикулы товарах (именно по ним происходит связка импортируемых товаров и базы данных) в одних случая выступают в виде ключей массива, что очень логично. В других же случаях ключи массива - значения параметров, а значения массива - массив артикулов. Вроде данные сгруппированы и вроде сокращается число элементов в массиве, но при разборе это требует перебора параметров в цикле, с целью выяснить принадлежит ли этот параметр конкретному товару или нет. Сами понимаете, что производительность страдает.

Удивил меня следующий шаг после разбора файла импорта - запуск через php_shell задачи по импорту данных в систему. Стало ясно, что на локалке протестировать решение я не смогу в силу особенностей локального сервера. У меня ограниченные знания в области системного администрирования и тратить время на настройку локального сервера я не планировал. В последствии это оказалось правильным решением.

Доработав остальные задачи, я выгрузил все обновления на боевой сервер и начал тестировать импорт данных. И он опять не работал. Опечалившись, я сделал логирование хода выполнения скрипта и удивился, что он помирает на попытке запустить команду в shell. Судя по всему и боевой сервер не настроен…

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

Я описал проблему заказчику и предложил ему два решения - найти сисадмина и настроить сервер или увеличить бюджет на выполнение задачи и переписать скрипты импорта, чтобы обойти запуск команды через shell. Причем нужно было перерабатывать всю работу скрипта с учетом итеративного разбора данных - иначе толком не отследишь ход выполнения разбора (на больших файла пользователь может подумать, что система повисла), да и по тайм ауту скрипт будет отваливаться (практику использования set_time_limit(0) на каждой итерации я считаю порочной).

Помним, что для компании Лидер Поиска это убыточный проект и любое расширение бюджета вгоняет проект в еще большие минуса. Поэтому они решили, найти системного администратора и настроить сервер. Собственно на этом моя история с текущим блоком должна была закончится. Но нет…

Было привлечено два системных администратора, которые по очереди пытались настроить сервер. Я специально для них написал php скрипт, который при запуске из командной строки выводил «Hello world». Через неделю их мучений и переписки с техподдержкой хостера, выяснилось, что «На сервере, с целью обеспечения безопасности, заблокировано выполнение php_shell() и ни за какие деньги мы вам его не включим» :-). Почему это сразу не выяснилось - не понятно.