Дисклеймер

Данная статья не в коем разе не создана ради холивара, а преследует строго противоположную цель: показать разработчикам MODX Revolution, что ее старший/младший (смотря с какой стороны посмотреть) брат evolutionCMS не так и далеко от вас и содержит ответы на вопросы, которые я часто получал от ревистов. И да, данную статью меня побудило написать увеличение таких вопросов. Поэтому если вы ревист и вам необходимо иногда работать с Эво (подчеркиваю, что я не в коем разе не агитирую за ту или иную ветку) рекомендую пробежаться глазками по этой статье, возможно она вам поможет избежать ненужной траты времени.
Данная статья не является научным трудом. А также разбита на две части для лучшего восприятия.

Работа с базой (а не объектами)

В Revolution принято оперировать объектами. В evolution, по-сути, кроме объекта $modx ничего и нет)
Не, можно вызывать их через подключение библиотек, как я написал выше, но из коробки, как правило, используются прямые запросы в базу.
Выполняются они через класс db. Ниже список основных методов, которые я использую ежедневно при разработке.

<?php
/* Пример ниже абсолютно бессмысленный, просто для понимания работы */

$sc = $modx->getFulltableName('site_content'); // Возвращает полное название таблицы с префиксом (раньше чаще всего использовался префикс modx_, в данный момент он ставится рандомно)
$tv = $modx->getFulltableName('site_tmplvar_contentvalues'); // Аналогично. таблица ТВшек
foreach($_POST as $key => $val) $_POST[$key] = $modx->db->escape($val); // escape()- экранирование от всяких ненужностей
$res = $modx->db->query('Select * from '.$sc.' where id<50'); // Прямой запрос в базу. $modx->prepare() и $modx->execute() - не требуется. Результат выполнения аналогчен функции mysql_row, но позволяет работать с различными типами баз данных
while ($row = $modx->db->getRow($res)) // getRow() - функция перебора результата mysql и приведение к ассоциативному массиву. Аналогично mysql_fetch_row();
{
	$tv = $modx->db->getValue('Select `value` from '.$tv.' where `contentid`='.$row['id'].' and tmplvarid=10'); //getValue() - возвращает первое значение из первой колонки в результате запроса. В данном случае мы получаем значение ТВ с id=10 для документа $row['id'];
	if ($tv==1) 
	{
		$modx->db->update(array('pagetitle'=>'Измененный заголовок '.$row['id'],'alias'=>$row[id]),$sc,'id='.$row[id]); 
		/*
		Здесь мы изменяем таблицу site_content, сам вызов приводится к 
		'Update '.$sc.' set `pagetitle`="Измененный заголовок '.$row['id'].'",`alias`="'.$row['id'].'" where `id`='.$row['id']; 
		Более подробный синтаксис тут - http://docs.evo.im/03_develop/04_dbapi/update.html
		*/
	}
	else
	{
		$modx->db->insert(array('value'=>1,'contentid'=>$row['id'],'tmplvarid'=>10),$tv); 
		/*
		Здесь мы добавляем запись в site_tmplvar_contentvalues, сам вызов приводится к 
		'INSERT INTO '.$tv.' (`value`,`contentid`,`tplvarid`) VALUES ("1","'.$row[id]'","10")';
		Более подробный синтаксис тут - http://docs.evo.im/03_develop/04_dbapi/insert.html
		*/
	}
}


Более подрбный список методов тут — http://docs.evo.im/03_develop/04_dbapi.html

Помимо dbapi есть и просто api. Многие методы аналогичны методом в Рево, полный список можно глянуть тут: http://docs.evo.im/03_develop/03_api.html

Настройка форм в админке


Админка evolutionCMS давно уже не содержит фреймов и работает на Ajax, плюс к этому не использует никаких сторонних фреймворков, кроме разве что jQuery и bootsrap. И с одной стороны это осложняет разработку каких-либо станартных форм, таблиц и прочего, с другой стороны полностью развязывает руки. Вы можете исполтзовать webix для дополнительных параметров, extJs для картинок, нативный js для построения графиков и все это одновременно! (Пример бредовый, но сама возможность подкупает). А это, в свою очередь, позволяет кроить админку как угодно и множество разработчиков предлагает свои решения по тем или иным вопросам.
В конфигурации внешнего видо добавлено множество полезных функций, есть удобное управление категориями путем drop&down, в extrats есть множество различных дополнений, но несомненным лидером по коичеству решений является студия Диван.Дизайн (http://code.divandesign.ru/modx) их решение ManagerManager и различные дополнения к нему.

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

Например такой код:

mm_createTab('SEO', 'seo', '', '', '', '');
mm_moveFieldsToTab('titl,keyw,desc,seoOverride,noIndex,sitemap_changefreq,sitemap_priority,sitemap_exclude', 'seo', '', '');
mm_widget_tags('keyw',',');


создаст вкладку SEO для всех шаблонов и перенесет туда ТВ-параметры перечисленные в mm_moveFieldsToTab, а также добавит виджет tags, который под полем покажет ранее используемые значения для этого ТВ-параметра.
(Группировка параметров и перенос их на отдельную вкладку можно реализовать и через системную настройку «Группировать ТВ параметры» в разделе «интерфейс и представление»).

Помимо этого у них есть множество других интересных дополнений: скрывать системные поля, ограничивать количество сиволов, выбор документа из древа, создание секций, подключение карт, задание дефолтных значений и многое другое. Напоминаю ссылку для того, чтобы ознакомиться с полным перечнем их решений — http://code.divandesign.ru/modx

И да, вероятно все это похоже на настройку форм в Рево, но как мне кажется тут возможностей все же по-более, но спорить не буду, ибо давно не смотрел эту реализацию в Рево, плюс к этому — тут я все же рассказываю про то, как работать в Эво)

Реализация мультиполей


В Revolution есть мегаудобная штука как MIGx. Что это и зачем это, думаю, рассказывать. Не нужно)) В Evolution есть целых ТРИ подобных решения!)
Да простит меня 64j (ярый противник данного решения), это дополнение от студии ДиванДизайн и звучит оно как mm_ddMultipleFields (http://code.divandesign.ru/modx/mm_ddmultiplefields) настраивается оно в чанке mm_rules. Для вывода есть готовый скрипт ddGetMultipleField (http://code.divandesign.ru/modx/ddgetmultiplefield) либо самопис. В целом очень удобная и интересная штука, кроме одного: все данные хранятся в строковом виде, типа param1::param2||param3::param4… Данное хранение данных весьма забавно и очень хорошо экплойдится, но с учетом уже полной поддержки типа поля json в MySQL8, мягко говоря, использовать оное не разумно). Но на старых проектах такое часто можно увидеть)

Второе решение multiFields — https://github.com/64j/multiFields/ Отличнейшая реализация мультиполей, крутить вертеть можно что угодно и как угодно, множество настроек и возможностей, но по признанием даже самого создателя, оно «малость» замороченное. Поглядеть можете, но встречается оно крайне редко. Чаще все же используется номер три (они очень похожи).

multiTV. Устанавливается из Extrats. По нему есть терабайты информации в сети, поэтому особо останавливаться не буду, скажу только что он оооочень сильно напоминает MIGx, также умеет работать с кастомными таблицами, имеет на борту кучу виджетов, используется повсеместно, данные хранит в JSON.
И помимо плагина для админки есть и сниппет, который позволяет выводить все в нужном виде.
Более подробную информацию можете посмотреть на странице документации — http://docs.evo.im/04_extras/multitv.html

Модификаторы


Данную часть меня также попросила написать Мисс MODX REVO :).
Скажу честно: я ими практически не пользуюсь. Если они нужны в вызове DocLister, я данные обрабатываю в prepare. Если мне нужен условный оператор, то я использую либо такую конструкцию: https://github.com/modxcms/evolution/wiki/@IF-@ELSEIF-@ELSE-@ENDIF, или сниппет if (http://docs.evo.im/04_extras/if.html). Или пишу свой сниппет.
Тем не менее, вроде, pHX никто не отменял, и конструкция вида [*pagetitle:notags*] у меня спокойно прошла… На официальной страницы документации информации пока нет… Нужно будет добавить))

Вызов эво из внешнего файла


Для вызова движка из внешнего файла достаточно простой инструкции:

<?php
	define('MODX_API_MODE', true);
	define('IN_MANAGER_MODE', false);	//true/false в зависимости от того, нужно вам выполнять что-то от имени админа или нет
	include_once("index.php");	
	$modx->db->connect();	
	if (empty ($modx->config)) {
		$modx->getSettings();
	}


и все, можете использовать все возможности evolutionCMS

Перенос на новый хост


В отличие от Revolution при переносе сайта достаточно изменить только параметры подключения в файле MGR_DIR/includes/cofig.inc.php, сбросить пути в конфигурации на вкладках файл-менеджер и файл-браузер и скинуть кэш. Если, вдруг админка начнет кричать про CSFR просто удалите файл /assets/cache/siteCache.idx.php
И да, я дважды использовал глобальную переменную MGR_DIR в связи с тем, что для того, чтобы изменить папку админки ее достаточно просто переименовать и скинуть кэш. И все. Нигде ничего более прописывать не нужно)

Заключение


Ну и закончу тем, с чего начал. Данная статья не несет в себе цели создать дополнительный холивар! Это просто небольшие ньюансы при работе с evolution написанные прежде всего для Ревистов которым по тем или иным причинам нужно (реже хочется) работать с Эво.
Очень многое осталось за скобками. Прежде всего магазин. Но тут, откровенно, пока самое больное место. Почему пока? Потому что Dmi3yy обещался-таки выпустить evoShop в сентябре, которого мы ждем то ли 1,5 то ли 2,5 года)))
По остальным моментам — пишите в комментариях чтобы вы хотели услышать, прочитать. Если вопросов будет много — напишу следующую часть. Если не будет — ну и ладно!)

Всем добра, интересных задач и адекватных клиентов!)

Предыдущая часть статьи.