Ejemplo n.º 1
0
	CLI::PrintActionStart('No repositories installed');
	CLI::PrintActionStatus('skip');
}
foreach($updatesites as $site){
	CLI::PrintActionStart('Scanning repository ' . $site->get('url'));
	/** @var UpdateSiteModel $site */
	if(!$site->isValid()){
		CLI::PrintActionStatus('failed');
		continue;
	}

	++$sitecount;
	$file = $site->getFile();

	$repoxml = new RepoXML();
	$repoxml->loadFromFile($file);
	$rootpath = dirname($file->getFilename()) . '/';

	CLI::PrintActionStatus('ok');

	foreach($repoxml->getPackages() as $pkg){
		/** @var PackageXML $pkg */

		$n = str_replace(' ', '-', strtolower($pkg->getName()));
		$type = $pkg->getType();
		$location = $pkg->getFileLocation();
		if(strpos($location, '://') === false){
			// The remote location may or may not be fully resolved.
			$location = $rootpath . $location;
		}
	/**
	 * Add a repository to the site.
	 * This will also handle the embedded keys, (as of 2.4.5).
	 *
	 * This contains the first step and second steps.
	 */
	public function repos_add() {
		$request = $this->getPageRequest();
		$view    = $this->getView();

		$site = new UpdateSiteModel();

		$form = Form::BuildFromModel($site);
		$form->set('action', \Core\resolve_link('/updater/repos/add'));
		$form->addElement('submit', array('value' => 'Next'));

		$view->title = 'Add Repo';
		// Needed because dynamic pages do not record navigation.
		$view->addBreadcrumb('Repositories', 'updater/repos');

		$view->assign('form', $form);

		if(!is_dir(GPG_HOMEDIR)){
			// Try to create it?
			if(is_writable(dirname(GPG_HOMEDIR))){
				// w00t
				mkdir(GPG_HOMEDIR);
			}
			else{
				\Core\set_message(GPG_HOMEDIR . ' does not exist and could not be created!  Please fix this before proceeding!', 'error');
				$form = null;
			}
		}
		elseif(!is_writable(GPG_HOMEDIR)){
			\Core\set_message(GPG_HOMEDIR . ' is not writable!  Please fix this before proceeding!', 'error');
			$form = null;
		}


		// This is the logic for step 2 (confirmation).
		// This is after all the template logic from step 1 because it will fallback to that form if necessary.
		if($request->isPost()){
			$url      = $request->getPost('model[url]');
			$username = $request->getPost('model[username]');
			$password = $request->getPost('model[password]');

			// Validate and standardize this repo url.
			// This is because most people will simply type repo.corepl.us.
			if(strpos($url, '://') === false){
				$url = 'http://' . $url;
			}

			// Lookup that URL first!
			if(UpdateSiteModel::Count(array('url' => $url)) > 0){
				\Core\set_message($url . ' is already used!', 'error');
				return;
			}

			// Load up a new Model, that's the easiest way to pull the repo data.
			$model = new UpdateSiteModel();
			$model->setFromArray([
				'url' => $url,
				'username' => $username,
				'password' => $password,
			]);

			// From here on out, populate the previous form with this new model.
			$form = Form::BuildFromModel($model);
			$form->set('action', \Core\resolve_link('/updater/repos/add'));
			$form->addElement('submit', array('value' => 'Next'));
			$view->assign('form', $form);

			/** @var \Core\Filestore\Backends\FileRemote $remote */
			$remote = $model->getFile();

			if($remote->requiresAuthentication()){
				if(!$username){
					\Core\set_message($url . ' requires authentication!', 'error');
					return;
				}
				else{
					\Core\set_message('Invalid credentials for ' . $url, 'error');
					return;
				}
			}

			if(!$model->isValid()){
				\Core\set_message($url . ' does not appear to be a valid repository!', 'error');
				return;
			}

			$repo = new RepoXML();
			$repo->loadFromFile($remote);

			// Make sure the keys are good
			if(!$repo->validateKeys()){
				\Core\set_message('There were invalid/unpublished keys in the repo!  Refusing to import.', 'error');
				return;
			}

			// The very final bit of this logic is to look and see if there's a "confirm" present.
			// If there is, the user clicked accept on the second page and I need to go ahead and import the data.
			if($request->getPost('confirm')){
				$model->set('description', $repo->getDescription());
				$model->save();
				$keysimported = 0;
				$keycount     = sizeof($repo->getKeys());
				$gpg          = new \Core\GPG\GPG();

				foreach($repo->getKeys() as $keyData){
					try{
						$gpg->importKey($keyData['key']);
						++$keysimported;
					}
					catch(Exception $e){
						\Core\set_message('Unable to import key [' . $keyData['key'] . '] from keyserver!', 'error');
					}
				}

				if(!$keycount){
					\Core\set_message('Added repository site successfully!', 'success');
				}
				elseif($keycount != $keysimported){
					\Core\set_message('Added repository site, but unable to import ' . ($keycount-$keysimported) . ' key(s).', 'info');
				}
				else{
					\Core\set_message('Added repository site and imported ' . $keysimported . ' key(s) successfully!', 'success');
				}

				\core\redirect('/updater/repos');
			}

			$view->templatename = 'pages/updater/repos_add2.tpl';
			$view->assign('description', $repo->getDescription());
			$view->assign('keys', $repo->getKeys());
			$view->assign('url', $url);
			$view->assign('username', $username);
			$view->assign('password', $password);
		}
	}
Ejemplo n.º 3
0
	/**
	 * Perform a lookup on any repository sites installed and get a list of provided pacakges.
	 *
	 * @return array
	 */
	public static function GetUpdates(){
		// Allow this to be cached for x amount of time.  This will save the number of remote requests.
		//if(false && isset($_SESSION['updaterhelper_getupdates']) && $_SESSION['updaterhelper_getupdates']['expire'] <= time()){
		//	return $_SESSION['updaterhelper_getupdates']['data'];
		//}

		// Build a list of components currently installed, this will act as a base.
		$components = array();
		$core       = array();
		$themes     = array();
		$sitecount  = 0;
		$pkgcount   = 0;
		$current    = Core::GetComponents();
		$froze      = \ConfigHandler::Get('/core/updater/versionfreeze');

		// If Core isn't installed yet, GetComponents will yield null.
		if($current === null) $current = array();

		/** @var string $backportVersion Add support for "~bpoXYZ" version strings for backported packages. */
		$coreVersion      = Core::GetVersion();
		$coreVersionParts = Core::VersionSplit($coreVersion);
		$backportVersion  = '~bpo' . $coreVersionParts['major'] . $coreVersionParts['minor'] . $coreVersionParts['point'];

		foreach($current as $c){
			/** @var $c Component_2_1 */
			$n = $c->getKeyName();

			$parts = Core::VersionSplit($c->getVersion());

			if($n == 'core'){
				$core = array(
					'name' => $n,
					'title' => $c->getName(),
					'version' => $c->getVersion(),
					'feature' => $parts['major'] . '.' . $parts['minor'],
					'source' => 'installed',
					'description' => $c->getDescription(),
					'provides' => $c->getProvides(),
					'requires' => $c->getRequires(),
					'location' => null,
					'status' => 'installed',
					'type' => 'core',
					'typetitle' => 'Core',
					'key' => null,
					'destdir' => $c->getBaseDir(),
				);
			}
			else{
				$components[$n] = array(
					'name' => $n,
					'title' => $c->getName(),
					'version' => $c->getVersion(),
					'feature' => $parts['major'] . '.' . $parts['minor'],
					'source' => 'installed',
					'description' => $c->getDescription(),
					'provides' => $c->getProvides(),
					'requires' => $c->getRequires(),
					'location' => null,
					'status' => 'installed',
					'type' => 'components',
					'typetitle' => 'Component ' . $c->getName(),
					'key' => null,
					'destdir' => $c->getBaseDir(),
				);
			}
		}

		foreach(Core::GetDisabledComponents() as $c){
			/** @var $c Component_2_1 */
			$n = $c->getKeyName();

			$parts = Core::VersionSplit($c->getVersion());

			$components[$n] = array(
				'name' => $n,
				'title' => $c->getName(),
				'version' => $c->getVersion(),
				'feature' => $parts['major'] . '.' . $parts['minor'],
				'source' => 'installed',
				'description' => $c->getDescription(),
				'provides' => $c->getProvides(),
				'requires' => $c->getRequires(),
				'location' => null,
				'status' => 'disabled',
				'type' => 'components',
				'typetitle' => 'Component ' . $c->getName(),
				'key' => null,
				'destdir' => $c->getBaseDir(),
			);
		}

		// And repeat for the themes.
		// I need to do a check if they exist because if called from the installer, it may not.
		if(class_exists('ThemeHandler')){
			$currentthemes = ThemeHandler::GetAllThemes();
			if($currentthemes === null) $currentthemes = array();
		}
		else{
			$currentthemes = array();
		}

		foreach($currentthemes as $t){
			/** @var $t Theme */
			$n = $t->getKeyName();

			$parts = Core::VersionSplit($t->getVersion());

			$themes[$n] = array(
				'name' => $n,
				'title' => $t->getName(),
				'version' => $t->getVersion(),
				'feature' => $parts['major'] . '.' . $parts['minor'],
				'source' => 'installed',
				'description' => $t->getDescription(),
				'location' => null,
				'status' => 'installed',
				'type' => 'themes',
				'typetitle' => 'Theme ' . $t->getName(),
				'key' => null,
				'destdir' => $t->getBaseDir(),
			);
		}

		// Now, look up components from all the updates sites.
		// If the system isn't installed yet, then this will not be found.  Just use a blank array.
		if(class_exists('UpdateSiteModel')){
			$updatesites = UpdateSiteModel::Find();
		}
		else{
			$updatesites = array();
		}


		foreach($updatesites as $site){

			if(!$site->isValid()) continue;

			++$sitecount;
			$file = $site->getFile();

			$repoxml = new RepoXML();
			$repoxml->loadFromFile($file);
			$rootpath = dirname($file->getFilename()) . '/';

			foreach($repoxml->getPackages() as $pkg){
				/** @var $pkg PackageXML */
				// Already installed and is up to date, don't do anything.
				//if($pkg->isCurrent()) continue;

				$n = str_replace(' ', '-', strtolower($pkg->getName()));
				$type = $pkg->getType();
				if($n == 'core') $type = 'core'; // Override the core, even though it is a component...
				++$pkgcount;

				switch($type){
					case 'core':
						$vers = $pkg->getVersion();

						// Only display the newest version available.
						if(!Core::VersionCompare($vers, $core['version'], 'gt')) continue;

						// Only display new feature versions if it's not frozen.
						$parts = Core::VersionSplit($pkg->getVersion());
						if($froze && $core['feature'] != $parts['major'] . '.' . $parts['minor']) continue;

						$core = array(
							'name' => $n,
							'title' => $pkg->getName(),
							'version' => $vers,
							'feature' => $parts['major'] . '.' . $parts['minor'],
							'source' => 'repo-' . $site->get('id'),
							'sourceurl' => $site->get('url'),
							'description' => $pkg->getDescription(),
							'provides' => $pkg->getProvides(),
							'requires' => $pkg->getRequires(),
							'location' => $pkg->getFileLocation(),
							'status' =>'update',
							'type' => 'core',
							'typetitle' => 'Core ',
							'key' => $pkg->getKey(),
							'destdir' => ROOT_PDIR,
						);
						break;
					case 'component':
						$vers  = $pkg->getVersion();
						$parts = Core::VersionSplit($pkg->getVersion());
						$packagedWithVersion = $pkg->getRootDOM()->getAttribute('packager');

						if($packagedWithVersion && Core::VersionCompare($packagedWithVersion, $coreVersion, '>')){
							// Skip any package created with a newer version of Core than what is currently installed!
							continue;
						}

						// Is it already loaded in the list?
						if(isset($components[$n])){

							if(strpos($vers, '~bpo') !== false && strpos($vers, $backportVersion) === false){
								// Skip back ported versions not specifically for this version of Core.
								// This will check and see if the string ~bpo is present,
								// and when it is, enforce that it matches exactly this version of Core.
								continue;
							}

							// I only want the newest version.
							if(!Core::VersionCompare($vers, $components[$n]['version'], 'gt')){
								continue;
							}

							// Only display new feature versions if it's not frozen.
							if(
								$froze &&
								$components[$n]['status'] == 'installed' &&
								$components[$n]['feature'] != $parts['major'] . '.' . $parts['minor']
							){
								continue;
							}
						}

						// If it's available in the core, it's an update... otherwise it's new.
						$status = Core::GetComponent($n) ? 'update' : 'new';

						$components[$n] = array(
							'name' => $n,
							'title' => $pkg->getName(),
							'version' => $vers,
							'feature' => $parts['major'] . '.' . $parts['minor'],
							'source' => 'repo-' . $site->get('id'),
							'sourceurl' => $site->get('url'),
							'description' => $pkg->getDescription(),
							'provides' => $pkg->getProvides(),
							'requires' => $pkg->getRequires(),
							'location' => $pkg->getFileLocation(),
							'status' => $status,
							'type' => 'components',
							'typetitle' => 'Component ' . $pkg->getName(),
							'key' => $pkg->getKey(),
							'destdir' => ROOT_PDIR . 'components/' . $n . '/',
						);
						break;
					case 'theme':
						$vers = $pkg->getVersion();
						$parts = Core::VersionSplit($pkg->getVersion());

						// Is it already loaded in the list?
						if(isset($themes[$n])){
							// I only want the newest version.
							if(!Core::VersionCompare($vers, $themes[$n]['version'], 'gt')) continue;

							// Only display new feature versions if it's not frozen.
							if(
								$froze &&
								$themes[$n]['status'] == 'installed' &&
								$themes[$n]['feature'] != $parts['major'] . '.' . $parts['minor']
							){
								continue;
							}
						}

						$status = ThemeHandler::GetTheme($n) ? 'update' : 'new';

						$themes[$n] = array(
							'name' => $n,
							'title' => $pkg->getName(),
							'version' => $vers,
							'feature' => $parts['major'] . '.' . $parts['minor'],
							'source' => 'repo-' . $site->get('id'),
							'sourceurl' => $site->get('url'),
							'description' => $pkg->getDescription(),
							'location' => $pkg->getFileLocation(),
							'status' => $status,
							'type' => 'themes',
							'typetitle' => 'Theme ' . $pkg->getName(),
							'key' => $pkg->getKey(),
							'destdir' => ROOT_PDIR . 'themes/' . $n . '/',
						);
				}

				//var_dump($pkg->asPrettyXML()); die();
			}
		}

		// Give me the components in alphabetical order.
		ksort($components);
		ksort($themes);

		// Cache this for next pass.
		//$_SESSION['updaterhelper_getupdates'] = array();
		//$_SESSION['updaterhelper_getupdates']['data'] = array('core' => $core, 'components' => $components, 'themes' => $themes);
		//$_SESSION['updaterhelper_getupdates']['expire'] = time() + 60;

		return [
			'core'       => $core,
			'components' => $components,
			'themes'     => $themes,
			'sitecount'  => $sitecount,
			'pkgcount'   => $pkgcount,
		];
	}