Николай Ланец
2 июля 2013 г., 17:41

Автоматическая установка MODX-сайта

Ребята, сегодня я сотворил бомбу :-))) Может кто-то и не оценит, но это реально классная штука!
Кому лень читать много буков, можно просто демку посмотреть.
В чем его суть? Это пакет, устанавливающий другие пакеты. Звучит просто, но не все так просто, как кажется. Скрипты автоустановки 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;

Добавить комментарий