Кто знаком с
symfony, тот наверняка слышал о такой штуке как
diem. Это замечательная надстройка над первой версией symfony, которая прикручивает к нему возможности CMS.
Diem, как и symfony, облегчает жизнь программисту, предоставляя возможность автоматической генерации кода. Но генерит он его, естественно, в symfony-style. А что, если он нам не подходит?
В проекте на diem концепция работы со view несколько отличается от стандартной. Если в стандартном symfony всё идёт от темплитов, которые представляют собой целые страницы (слой отображения), и экшенов - слой контроллера для темплита, то в diem сделали упор на удобство работы контенщика, а именно на возможность построения страницы "по кирпичикам". Это значит, что теперь менеджер создаёт страницу и накидывает на неё "виджеты" (widgets). Прямая аналогия с компонентами битрикса. А widget по своей сути есть не что иное, как partial с соответствующей логикой, помещённой в компонент.
Таким образом, в diem слой Controller/View несколько сместился от action/template к component/partial (хотя, конечно action/template никто не отменял). Косвенный намёк на это можно найти в описании релиза 5й версии:
The keyword "actions" has been replaced with "components".
"actions" keyword is now deprecated but still supported for backward compatibility.
Теперь, собственно, про генерацию кода. Для примера - конкретная (и, я думаю, распространённая) задача. Научить diem следующим правилам:
- В качестве отступов использовать "\t" вместо четырёх пробелов.
- Фигурная скобка должна открываться и закрываться на той же строке как у класса, так и у методов.
Здесь рассматривается генерация кода и правка кодестайла для модулей в diem. Для "голого" symfony всё выглядит иначе (об этом, быть может напишу позже).
Итак, чтобы сгенерить новый модуль в diem, описываем его в modules.yml:
testmodule:
name: Демо-стенд
components:
createOrder: {name: 'Создание заказа'}
changeService: {name: 'Изменени услуги'}
По такому описанию, diem в состоянии сгенерить файлы модуля, если набрать в CLI:
./symfony dmFront:generate
После вызова этой команды, управление по цепочке передаётся до метода dmFrontGenerateTask::execute(). Этот метод делает 3 вещи:
- Генерит скелет класса action'ов:
$actionGenerator = new dmFrontActionGenerator($module, $this->dispatcher, $this->get('filesystem'), $moduleDir);
- Компонентов
$componentGenerator = new dmFrontComponentGenerator($module, $this->dispatcher, $this->get('filesystem'), $moduleDir);
- И шаблоны
$actionTemplateGenerator = new dmFrontActionTemplateGenerator($module, $this->dispatcher, $this->get('filesystem'), $moduleDir);
Diem в качестве инструмента для генерации кода использует Zend CodeGenerator (lib/vendor/diem/dmCorePlugin/lib/vendor/Zend/CodeGenerator). Кроме того, они добавили своих французских плющек и назвали их dmZend CodeGenerator(lib/vendor/diem/dmCorePlugin/lib/vendor/dmZend). Всё это вызывается из классов генерации кода lib/vendor/diem/dmFrontPlugin/lib/generator.
Вот три места где заключены все правила кодестайла для генератора кода diem.
Чтобы решить задачу, поставленную выше, делаем следующие изменения:
- lib/vendor/diem/dmCorePlugin/lib/vendor/Zend/CodeGenerator/Php/Class.php метод generate()
$implemented = $this->getImplementedInterfaces();
if (!empty($implemented)) {
$output .= ' implements ' . implode(', ', $implemented);
}
// $output .= self::LINE_FEED . '{' . self::LINE_FEED . self::LINE_FEED;
$output .= ' {' . self::LINE_FEED . self::LINE_FEED; // Our codestyle
- lib/vendor/diem/dmCorePlugin/lib/vendor/dmZend/CodeGenerator/Php/Method.php метод generate()
if (!empty($parameters)) {
foreach ($parameters as $parameter) {
$parameterOuput[] = $parameter->generate();
}
$output .= implode(', ', $parameterOuput);
}
// $output .= ')' . self::LINE_FEED . $indent . '{' . self::LINE_FEED;
$output .= ') {' . self::LINE_FEED; //Our codestyle
- lib/vendor/diem/dmFrontPlugin/lib/generator/dmFrontActionGenerator.php
class dmFrontActionGenerator extends dmFrontModuleGenerator
{
protected
$class,
// $indentation = ' ';
$indentation = "\t"; // Our codestyle
- lib/vendor/diem/dmFrontPlugin/lib/generator/dmFrontComponentGenerator.php
class dmFrontComponentGenerator extends dmFrontModuleGenerator
{
protected
$class,
// $indentation = ' ';
$indentation = "\t"; // Our codestyle
В итоге, получаем код, соответствующий нашему кодестайлу:
/**
* Демо-стенд components
*
* No redirection nor database manipulation ( insert, update, delete ) here
*/
class testmoduleComponents extends myFrontModuleComponents {
public function executeCreateOrder() {
// Your code here
}
public function executeChangeService() {
// Your code here
}
}
У обычной правки файлов либы есть минус - они слетят при обновлении. Тут есть 2 выхода - поместить либу под систему контроля версий, либо добавить свой task для CLI. Второй, конечно, правильнее, но, как оно обычно бывает, сложнее :)
Читать дальше......