Ребята, сегодня я сотворил бомбу :-)))
Может кто-то и не оценит, но это реально классная штука!
Кому лень читать много буков, можно просто демку посмотреть.
В чем его суть? Это пакет, устанавливающий другие пакеты. Звучит просто, но не все так просто, как кажется.
Скрипты автоустановки MODX всплывали и раньше. У безумкина это серверные скрипты, выполняющие установку, обновление или удаление MODX. Здесь Илья про свою сборку пишет. Мой пакет работает по другому принципу: он устанавливается как и обычный пакет. Но в него зашита дополнительная логика. В частности сейчас прописана только малая часть того, что я хочу получить в конечном итоге, а именно установка пакетов из списка. Все работает на уровне API MODX, то есть через $modx я и проверяю уже имеющиеся пакеты, установлены они или нет, качаю их, устанавливаю, проверяю ошибки и т.п. К слову, и в этот раз понадобилась вот эта информация, чтобы не обламывался вывод логов.
Так вот, преимущество данного способа в том, что во-первых, не надо вообще доступа к серверу иметь, а во-вторых, ставить можно как на чистый MODX, так и уже на работающий с уже установленными пакетами. В перспективе из скрипта будут сразу выполняться всякие настройки системы, создание типовых разделов и т.п.
Забегая немного вперед, скажу, что все это я делаю в рамках своей идеи создания готовых сборок сайтов. Немного разверну мысль: с WordPress я познакомился ровно тогда же, когда и с MODX, а именно в январе-феврале 2009-го. Так как я люблю больше программировать, я уцепился за MODX. Мой же товарищ, не умеющий программировать вообще, но любитель блогосферы, подсел на WP. И хотя я сам ничего не делал с WP, я видел как он легко создает на нем новые сайты и что у него есть реальные посещения и т.п. К чему я это все? К тому, что Да, MODX — это Сила, это практически безграничные возможности, Но: 1) все-таки не так много готовых решений, как хотелось бы, 2) нет вообще стандартов по оформлению сайтов и норм шаблонизации, 3) как следствие — нет готовых сайтов-заготовок вообще.
Сайтов на WP создается 100 000 в день. На Livestreet (который гораздо ближе к WP, нежели к MODX) тоже не мало сайтов. При этом на этих сайтах в порядке вещей используются дизайны-клоны. И это нормально. Заходишь на сайт, сразу видишь, что это WP или LS, но если там информация, которая тебя интересует, эти мелочи не берешь во внимание. А главное — простота в установке и обслуживании для тех, кто вообще не умеет программировать. Готовых и понятных решений масса. При чем в MODX тоже пакеты устанавливаются просто, но извините, тот же Wayfinder скачать — это мелочь, его еще воткнуть надо куда положено, и параметры всякие прописать. На тот же LS ставятся плагины, которые как правило не требуют никаких действий от владельца сайта. Скачал плагин, становил его, и тут же на сайте новый функционал, новые кнопочки и т.п. И это классно! Другое дело что дорабатывать это все сложнее, чем в MODX, но эти стандарты позволяют всем, и дизайнерам, и программистам, и конечным сайтовладельцам работать как одна команда.
Как раз только вчера читал вот эту статью: www.noupe.com/wordpress/wordpress-or-modx-the-winner-is-73407.html (она на англ. Кто переведет и выложит перевод, респект и уважуха!). Человек пишет сравнительный обзор MODX и WP. И говорит о том же: там есть те плюсы и минусы, а там другие. И нам надо смотреть на сторонние решения и высматривать в них плюсы, и портировать их на MODX.
Что я хочу сделать? Я пока не доработал еще все, но скоро представлю комплексный пакет, который будет создавать правильную структуру сайта с запилом под шаблонизацию. Дело в том, что сейчас модель MODX не оконченная. В частности MODX-шаблоны, это на самом деле не шаблоны, а больше контроллеры, так как несколько шаблонов мы как правило создает для того, чтобы задать связи TV с документами и распределить логику (с этим шаблоном мы ленту новостей заложим, с этим у нас карточка товара формироваться будет, и т.д.). Но это не комплексная шаблонизация сайта. Попробуйте разом сменить дизайн сайта, а лучше попереключать несколько вариантов оформления… В модели, которую я закладываю, как я и сказал, MODX-шаблоны будут выполнять только роль контроллеров. Сама же шаблонизация будет выполняться с использованием различных систем-шаблонизаторов. Пакет modxSmarty я уже собрал (но выложу, когда окончательно его обкатаю и дополню). Он не устанавливает Smarty (так как Smarty уже есть в MODX), но он создает плагин, который подключает Smarty для фронтэнда, а так же прописывает настройки пути до папки шаблонов (скинов), используемого шаблона для сайта и т.п., очищает Smarty-кеш, когда очищается кеш всего сайт. А главное — устанавливает дополнительные функции-плагины для Smarty, которые позволяют работать с MODX-элементами. К примеру, чтобы вызвать тот же Wayfinder, можно будет на уровне Smarty-шаблона прописать {snippet name=«Wayfinder»}.
В дальнейшем появятся и другие шаблонизаторы. Первый на очереди — Twig.
Все это не только откроет дорогу для тех программистов, которые не работали раньше с MODX только потому что им не хотелось связываться с парсером MODX, но и позволит привлечь дизайнеров для разработки готовых копируемых тем для MODX-сайтов. И быть может MODX все-таки войдет и в блогосферу…
UPD: Исходники пакета выложу позже, а пока самое интересное из него — резолвер, который и устанавливает пакеты.
<?php
if ($object->xpdo) {
$modx =& $object->xpdo;
// $modelPath = $modx->getOption($pkgName.'.core_path',null,$modx->getOption('core_path').'components/
'.$pkgName.'/').'model/';
switch ($options[xPDOTransport::PACKAGE_ACTION]) {
case xPDOTransport::ACTION_INSTALL:
case xPDOTransport::ACTION_UPGRADE:
if ($modx instanceof modX) {
if(!$modx->loadClass('transport.modTransportPackage')){
return $modx->log(modX::LOG_LEVEL_ERROR, "Could not load
modTransportPackage class");
}
/*
* Packages need to install
*/
$packages = array(
'Wayfinder',
'getResources',
'getPage',
'Ace',
'TinyMCE',
'phpTemplates',
'GoogleSiteMap',
);
$modx->log(modX::LOG_LEVEL_INFO, "Trying to install packages: ".
implode(", ", $packages). "<br />\n
Be patient. it`s take a several moments.");
$modx->setLogLevel(modX::LOG_LEVEL_INFO);
$LogTarget = $modx->getLogTarget();
$LogTopic = $LogTarget->subscriptions[0];
$messages = array();
foreach($packages as $packageName){
if(!$packageName) continue;
if($packageExists = $modx->getObject('modTransportPackage',
array(
'package_name' => $packageName,
))){
$messages[] = array(
'level' => modX::LOG_LEVEL_INFO,
'msg' => "Package '{$packageName}' allready exists" ,
);
/*
* Check is installed
*/
if(!$packageExists->get('installed')){
$messages[] = array(
'level' => modX::LOG_LEVEL_ERROR,
'msg' => "Package '{$packageName}' exists, but not
installed. Please, install it manually" ,
);
}
continue;
}
// $modx->log(modX::LOG_LEVEL_INFO, "Try to get '{$packageName}' package.");
$response = $modx->runProcessor('workspace/packages/rest/getlist', array(
'provider' => 1,
'query' => $packageName,
));
if($response->isError()){
$messages[] = array(
'level' => modX::LOG_LEVEL_ERROR,
'msg' => $response->getMessage(),
);
continue;
}
if(!$result = json_decode($response->getResponse())){
$messages[] = array(
'level' => modX::LOG_LEVEL_ERROR,
'msg' => "Error while reading results" ,
);
continue;
}
/*
* Try to find package info
*/
foreach($result->results as $r){
$package = (array)$r;
if($package['name'] == $packageName){
goto downloadPackage;
}
}
/*
* Info was not found
*/
$messages[] = array(
'level' => modX::LOG_LEVEL_ERROR,
'msg' => "Package '{$packageName}' was not found. Please try
to install it manually" ,
);
continue;
/*
* Download Package
*/
downloadPackage:
$messages[] = array(
'level' => modX::LOG_LEVEL_INFO,
'msg' => "Trying to download '{$packageName}' package" ,
);
$response = $modx->runProcessor('workspace/packages/rest/download', array(
'provider' => 1,
'info' => "{$package['location']}::{$package['signature']}",
));
if($response->isError()){
$messages[] = array(
'level' => modX::LOG_LEVEL_ERROR,
'msg' => "Failed download '{$packageName}'. ".$response->getMessage(),
);
continue;
}
$result = $response->getResponse();
if($result['success'] == 1){
$messages[] = array(
'level' => modX::LOG_LEVEL_INFO,
'msg' => "Package '{$packageName}' downloaded success" ,
);
goto installPackage;
}
$messages[] = array(
'level' => modX::LOG_LEVEL_ERROR,
'msg' => "Failed download '{$packageName}'.",
);
/*
* Installing Package
*/
installPackage:
$messages[] = array(
'level' => modX::LOG_LEVEL_INFO,
'msg' => "Trying to install '{$packageName}' package" ,
);
$response = $modx->runProcessor('workspace/packages/install', array(
'signature' => $package['signature'],
));
if($response->isError()){
$messages[] = array(
'level' => modX::LOG_LEVEL_ERROR,
'msg' => "Failed install '{$packageName}'. ". $response->getMessage(),
);
continue;
}
$messages[] = array(
'level' => modX::LOG_LEVEL_INFO,
'msg' => $response->getMessage() ,
);
}
$modx->registry->setLogging($LogTarget, $LogTopic);
// $modx->log(xPDO::LOG_LEVEL_ERROR, '$err');
// print_r($messages);
$modx->setLogLevel(modX::LOG_LEVEL_INFO);
foreach($messages as $msg){
$modx->log($msg['level'], $msg['msg']);
}
}
break;
}
}
return true;