Установка компонентов через MODX API

Предлагаю всем желающим готовую функцию для установки компонентов через Api.

Можно делать из консоли, можно из сниппета — не важно. Собственно загрузка файла выделена в отдельную функцию, которая пытается работать через file_get_contents(), если это не запрещено. Иначе использует cUrl.

Параметров всего 2: имя компонента и id провайдера пакетов (по умолчанию — 1, то есть, modx.com).

// Установка пакета из указанного репозитория MODX
function installPackage($packageName, $provider = 1) {
	global $modx;

	/* @var modTransportProvider $provider */
	$provider = $modx->getObject('transport.modTransportProvider', $provider);

	$provider->getClient();
	$modx->getVersionData();
	$productVersion = $modx->version['code_name'].'-'.$modx->version['full_version'];

	$response = $provider->request('package','GET',array(
		'supports' => $productVersion,
		'query' => $packageName
	));

	if(!empty($response)) {
		$foundPackages = simplexml_load_string($response->response);
		foreach($foundPackages as $foundPackage) {
			/* @var modTransportPackage $foundPackage */
			if($foundPackage->name == $packageName) {
				$sig = explode('-',$foundPackage->signature);
				$versionSignature = explode('.',$sig[1]);
				$url = $foundPackage->location;

				if (!download($url, $modx->getOption('core_path').'packages/'.$foundPackage->signature.'.transport.zip')) {
					return array(
						'success' => 0,
						'message' => 'Could not download package <b>'.$packageName.'</b>.',
					);
				}

				/* add in the package as an object so it can be upgraded */
				/** @var modTransportPackage $package */
				$package = $modx->newObject('transport.modTransportPackage');
				$package->set('signature',$foundPackage->signature);
				$package->fromArray(array(
					'created' => date('Y-m-d h:i:s'),
					'updated' => null,
					'state' => 1,
					'workspace' => 1,
					'provider' => $provider->id,
					'source' => $foundPackage->signature.'.transport.zip',
					'package_name' => $sig[0],
					'version_major' => $versionSignature[0],
					'version_minor' => !empty($versionSignature[1]) ? $versionSignature[1] : 0,
					'version_patch' => !empty($versionSignature[2]) ? $versionSignature[2] : 0,
				));

				if (!empty($sig[2])) {
					$r = preg_split('/([0-9]+)/',$sig[2],-1,PREG_SPLIT_DELIM_CAPTURE);
					if (is_array($r) && !empty($r)) {
						$package->set('release',$r[0]);
						$package->set('release_index',(isset($r[1]) ? $r[1] : '0'));
					} else {
						$package->set('release',$sig[2]);
					}
				}

				if($package->save() && $package->install()) {
					return array(
						'success' => 1,
						'message' => '<b>'.$packageName.'</b> was successfully installed',
					);
				}
				else {
					return array(
						'success' => 0,
						'message' => 'Could not save package <b>'.$packageName.'</b>',
					);
				}
				break;
			}
		}
	}
	else {
		return array(
			'success' => 0,
			'message' => 'Could not find <b>'.$packageName.'</b> in MODX repository',
		);
	}
	return true;
}


// Функция закачки файла обычным способом или через cUrl
function download($src, $dst) {
	if (ini_get('allow_url_fopen')) {
		$file = @file_get_contents($src);
	}
	else if (function_exists('curl_init')) {
		$ch = curl_init();
		curl_setopt($ch, CURLOPT_URL, $src);
		curl_setopt($ch, CURLOPT_HEADER, 0);
		curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
		curl_setopt($ch, CURLOPT_TIMEOUT,180);
		$safeMode = @ini_get('safe_mode');
		$openBasedir = @ini_get('open_basedir');
		if (empty($safeMode) && empty($openBasedir)) {
			curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
		}

		$file = curl_exec($ch);
		curl_close($ch);
	}
	else {
		return false;
	}
	file_put_contents($dst, $file);

	return file_exists($dst);
}
Василий Наумкин
21 марта 2013, 07:57
7
2 650
0

Комментарии: 4

Alex Vakhitov
21 марта 2013, 13:00
0
Первые шаги к платному репозиторию? (:
    Василий Наумкин
    21 марта 2013, 13:02
    0
    Нет, разбирался, отчего глючит автоустановка pdoTools в MS2.

    Этот скрипт не на стороне репозитория запускается, а у клиента.
      Alex Vakhitov
      21 марта 2013, 13:37
      0
      Понятно, а просто когда думал о платно репозитории пришел к выводу что проще сделать компонент который будет по API общаться с репозиторием и ставить дополнения
Svoy
15 января 2014, 16:32
0
я не волшебник..(с)
но мне проще:
— скопировать на хостинг подготовленный образ modx с уже установленным пакетами
— создать базу и залить в нее дамп с образа
— подкорректировать конфиг файлы modx (абсолютные пути и параметры доступа к БД)

а вообще, огромный респект за огромный вклад в modx.