Skip to content

Instantly share code, notes, and snippets.

@gvozdb
Last active April 4, 2023 08:28
Show Gist options
  • Star 7 You must be signed in to star a gist
  • Fork 9 You must be signed in to fork a gist
  • Save gvozdb/84671636d763007bcc78 to your computer and use it in GitHub Desktop.
Save gvozdb/84671636d763007bcc78 to your computer and use it in GitHub Desktop.
Скрипт автоустановки компонентов в MODX. Работает как из консоли, так и из веба. Скрипт из консоли работает корректно на сервере, настроенном по этой инструкции - https://modx.pro/hosting/678-the-right-hosting-for-modx-revolution-2/
<?php
/*
Скрипт надо запускать от юзера - владельца сайта, чтобы созданные файлы пакетов не принадлежали юзеру root
$ sudo -u USERNAME php /var/www/USERNAME/packages.php /var/www/USERNAME/www/
Или от root, а после выставить владельца:
$ php /root/scripts/modx/packages.php /var/www/USERNAME/www/ && /var/www/USERNAME/chmod
Чтобы запустить из веба, просто положите скрипт в корень или куда-нибудь глубже и вызовите по HTTP
*/
// >> Список репозиториев с компонентами для установки
$providers = array(
array(
'name' => 'modx.com',
'service_url' => 'http://rest.modx.com/extras/',
'username' => '',
'api_key' => '',
'packages' => array( // true - инсталлировать
'babel' => true,
'collections' => true,
'console' => true,
'formit' => true,
),
),
array(
'name' => 'MS',
'service_url' => 'https://modstore.pro/extras/',
'username' => '',
'api_key' => '',
'packages' => array( // false - просто скачать
'ace' => true,
'ajaxform' => true,
'controlerrorlog' => true,
'dateago' => true,
'jevix' => true,
'minifyx' => true,
// 'minishop2' => false,
'phpthumbon' => true,
'pdotools' => true,
'theme.bootstrap' => true,
'tickets' => false,
'typomce' => false,
'videogallery' => true,
'ytranslit' => true,
),
),
// локальная папка с транспортниками
array(
'type' => 'transport',
'path' => '/root/daemons/py/hostpanel_daemon/script/php/packages/', // путь до локальных пакетов
'packages' => array(
'ms2gallery' => array(
'version' => '1.5.3-pl',
'install' => true,
),
'msearch2' => array(
// 'path' => '/root/daemons/py/hostpanel_daemon/script/php/packages/', // можно указать путь здесь, переопределив тот, который выше
'version' => '1.5.5-pl',
'install' => true,
),
),
),
);
// << Список репозиториев с компонентами для установки
$countSaved = 0;
$countInstalled = 0;
$console = !empty($argv) ? true : false; // Узнаём откуда запустили из консоли или из веба
if($console)
{
if( !empty($argv[1]) && file_exists( $argv[1] .'index.php' ) )
{
$current_dir = $argv[1];
}
}
// >> Подключаем
define('MODX_API_MODE', true);
$current_dir = !empty($current_dir) ? $current_dir : dirname(__FILE__) .'/';
$index_php = $current_dir .'index.php';
$i=0;
while( !file_exists( $index_php ) && $i < 9 )
{
$current_dir = dirname(dirname($index_php)) .'/';
$index_php = $current_dir .'index.php';
$i++;
}
if(file_exists($index_php))
{
require_once $index_php;
}
if(!is_object($modx))
{
_print('ERROR: Не удалось подгрузить MODX');
die;
}
// << Подключаем
// >> Включаем обработку ошибок
$modx->getService('error','error.modError');
$modx->setLogLevel(modX::LOG_LEVEL_ERROR);
$modx->setLogTarget(XPDO_CLI_MODE ? 'ECHO' : 'HTML');
// << Включаем обработку ошибок
$modx->switchContext('mgr');
$modx->addPackage('modx.transport', MODX_CORE_PATH .'model/');
$modx->getVersionData();
$productVersion = $modx->version['code_name'] .'-'. $modx->version['full_version'];
foreach( $providers as $prov )
{
$transport = (!empty($prov['type']) && $prov['type'] == 'transport') ? true : false;
if(!$transport && !$provider = $modx->getObject('transport.modTransportProvider', array('service_url' => $prov['service_url'])))
{
$provider = $modx->newObject('transport.modTransportProvider');
$provider->fromArray($prov);
$provider->save();
}
if(!$transport) {
$provider->getClient();
}
foreach( $prov['packages'] as $packageName => $data )
{
$install = $transport
? $data['install']
: $data;
$params = array();
if(!$transport)
{
$response = $provider->request('package', 'GET',
array(
'query' => $packageName
));
if(!empty($response))
{
$foundPackages = simplexml_load_string($response->response);
if($foundPackages['total'] > 0)
{
foreach($foundPackages as $foundPackage)
{
if(strtolower((string)$foundPackage->name) == strtolower($packageName))
{
$params = array(
'package_name' => (string)$foundPackage->name,
'signature' => (string)$foundPackage->signature,
'location' => $foundPackage->location,
);
}
}
}
else {
_print('Not found: "'. $packageName .'"');
}
}
}
else if($transport)
{
$path = !empty($data['path'])
? $data['path']
: $prov['path'];
$signature = $packageName .'-'. $data['version'];
$location = $path . $signature .'.transport.zip';
if(file_exists($location))
{
$params = array(
'package_name' => $packageName,
'signature' => $signature,
'location' => $location,
);
}
}
if(!empty($params))
{
packageSaveInstall(array_merge(
$params,
array(
'provider' => is_object($provider) ? $provider->id : '0',
'install' => $install ? $install : 0,
)
));
}
}
}
if($countSaved > 0) {
_print('Done!');
}
/*
* Функция сохраняет и инсталлирует пакет
*/
function packageSaveInstall($params)
{
global $modx, $countSaved, $countInstalled;
$package_name = !empty($params['package_name']) ? $params['package_name'] : '';
$signature = !empty($params['signature']) ? $params['signature'] : '';
$location = !empty($params['location']) ? $params['location'] : '';
$provider = !empty($params['provider']) ? $params['provider'] : 0;
$install = !empty($params['install']) ? $params['install'] : 0;
if(empty($signature) || empty($location) || empty($package_name)) {return;}
if( !$modx->getCount('transport.modTransportPackage', array('signature' => $signature)) )
{
$sig = explode('-', $signature);
$ver = getVersionExplode($sig[1] . (!empty($sig[2]) ? '-'. $sig[2] : ''));
file_put_contents( MODX_CORE_PATH .'packages/'. $signature .'.transport.zip', file_get_contents($location) );
$package = $modx->newObject('transport.modTransportPackage');
$package->set('signature', $signature);
$package->fromArray(array(
'created' => date('Y-m-d h:i:s'),
'updated' => null,
'state' => 1,
'workspace' => 1,
'provider' => $provider,
'source' => $signature .'.transport.zip',
'package_name' => $package_name,
'version_major' => $ver['version_major'],
'version_minor' => $ver['version_minor'],
'version_patch' => $ver['version_patch'],
'release' => $ver['release'],
'release_index' => $ver['release_index'],
));
if($success = $package->save())
{
_print('Saved: "'. $package_name .'"');
$countSaved++;
if($install)
{
$package->install();
_print('Installed: "'. $package_name .'"');
$countInstalled++;
}
}
else {
_print('Could not save: "'. $package_name .'"');
}
}
else {
_print('Already exists: "'. $package_name .'"');
}
}
/*
* Функция выводит массив с данными версии $v
*/
function getVersionExplode($v)
{
if(empty($v)) {return;}
$ver = explode('-', $v);
$sig = explode('.', $ver[0]);
$rel = isset($ver[1])
? preg_split('/([0-9]+)/', $ver[1], -1, PREG_SPLIT_DELIM_CAPTURE)
: array();
$r['version'] = $ver[0];
$r['version_major'] = !empty($sig[0])
? $sig[0]
: 0;
$r['version_minor'] = !empty($sig[1])
? $sig[1]
: 0;
$r['version_patch'] = !empty($sig[2])
? $sig[2]
: 0;
$r['release'] = isset($rel[0])
? $rel[0]
: (isset($ver[1])
? $ver[1]
: ''
);
$r['release_index'] = isset($rel[1])
? $rel[1]
: '0';
return $r;
}
/*
* Функция принтит в консоль или веб
*/
function _print($str='', $br=true)
{
global $console;
if(empty($str)) {return;}
if($console)
{
fwrite(STDOUT, $str . ($br ? "\n" : ""));
}
else {
print $str . ($br ? "<br />" : "");
}
}
exit;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment