/**
  * Get the repository XML as a string that can be returned to the browser or cached for future use.
  *
  * @return string
  */
 private function _getRepoXML()
 {
     $repo = new RepoXML();
     $repo->setDescription(ConfigHandler::Get('/package_repository/description'));
     $dir = Factory::Directory(\ConfigHandler::Get('/package_repository/base_directory'));
     $coredir = $dir->getPath() . 'core/';
     $componentdir = $dir->getPath() . 'components/';
     $themedir = $dir->getPath() . 'themes/';
     $tmpdir = Factory::Directory('tmp/exports/');
     $gpg = new Core\GPG\GPG();
     $keysfound = [];
     $private = ConfigHandler::Get('/package_repository/is_private') || strpos($dir->getPath(), ROOT_PDIR) !== 0;
     $addedpackages = 0;
     $failedpackages = 0;
     $iterator = new \Core\Filestore\DirectoryIterator($dir);
     // Only find signed packages.
     $iterator->findExtensions = ['asc'];
     // Recurse into sub directories
     $iterator->recursive = true;
     // No directories
     $iterator->findDirectories = false;
     // Just files
     $iterator->findFiles = true;
     // And sort them by their filename to make things easy.
     $iterator->sortBy('filename');
     // Ensure that the necessary temp directory exists.
     $tmpdir->mkdir();
     foreach ($iterator as $file) {
         /** @var \Core\Filestore\File $file */
         $fullpath = $file->getFilename();
         // Used in the XML file.
         if ($private) {
             $relpath = \Core\resolve_link('/packagerepository/download?file=' . substr($file->getFilename(), strlen($dir->getPath())));
         } else {
             $relpath = $file->getFilename(ROOT_PDIR);
         }
         // Drop the .asc extension.
         $basename = $file->getBasename(true);
         // Tarball of the temporary package
         $tgz = Factory::File($tmpdir->getPath() . $basename);
         $output = [];
         // I need to 1) retrieve and 2) verify the key for this package.
         try {
             $signature = $gpg->verifyFileSignature($fullpath);
             if (!in_array($signature->keyID, $keysfound)) {
                 $repo->addKey($signature->keyID, null, null);
                 $keysfound[] = $signature->keyID;
             }
         } catch (\Exception $e) {
             trigger_error($fullpath . ' was not able to be verified as authentic, (probably because the GPG public key was not available)');
             $failedpackages++;
             continue;
         }
         // decode and untar it in a temp directory to get the package.xml file.
         exec('gpg --homedir "' . GPG_HOMEDIR . '" -q -d "' . $fullpath . '" > "' . $tgz->getFilename() . '" 2>/dev/null', $output, $ret);
         if ($ret) {
             trigger_error('Decryption of file ' . $fullpath . ' failed!');
             $failedpackages++;
             continue;
         }
         exec('tar -xzf "' . $tgz->getFilename() . '" -C "' . $tmpdir->getPath() . '" ./package.xml', $output, $ret);
         if ($ret) {
             trigger_error('Unable to extract package.xml from' . $tgz->getFilename());
             unlink($tmpdir->getPath() . $basename);
             $failedpackages++;
             continue;
         }
         // Read in that package file and append it to the repo xml.
         $package = new PackageXML($tmpdir->getPath() . 'package.xml');
         $package->getRootDOM()->setAttribute('key', $signature->keyID);
         $package->setFileLocation($relpath);
         $repo->addPackage($package);
         $addedpackages++;
         // But I can still cleanup!
         unlink($tmpdir->getPath() . 'package.xml');
         $tgz->delete();
     }
     return $repo->asPrettyXML();
 }
	public static function _UploadHandler(Form $form) {
		$localfile = \Core\Filestore\Factory::File($form->getElement('upload')->get('value'));
		$localobj = $localfile->getContentsObject();
		if(!$localobj instanceof Core\Filestore\Contents\ContentTGZ){
			$localfile->delete();
			\Core\set_message('Invalid file uploaded', 'error');
			return false;
		}
		
		$tmpdir = $localobj->extract('tmp/installer-' . Core::RandomHex(4));
		
		// There should now be a package.xml metafile inside that temporary directory.
		// Parse it to get the necessary information for this package.
		$metafile = \Core\Filestore\Factory::File($tmpdir->getPath() . 'package.xml');
		if(!$metafile->exists()){
			$localfile->delete();
			$tmpdir->delete();
			\Core\set_message('Invalid package, package does not contain a "package.xml" file.');
			return false;
		}
		
		$pkg     = new PackageXML($metafile->getFilename());
		$key     = str_replace(' ', '-', strtolower($pkg->getName()));
		$name    = $pkg->getName();
		$type    = $pkg->getType();
		$version = $pkg->getVersion();
		
		// Validate the contents of the package.
		if(!(
			$type == 'component' ||
			$type == 'theme' ||
			$type == 'core'
		)){
			$localfile->delete();
			$tmpdir->delete();
			\Core\set_message('Invalid package, package does not appear to be a valid Core package.');
			return false;
		}

		// Now that the data is extracted in a temporary directory, extract every file in the destination.
		/** @var $datadir \Core\Filestore\Directory */
		$datadir = $tmpdir->get('data/');
		if(!$datadir){
			\Core\set_message('Invalid package, package does not contain a "data" directory.');
			return false;
		}
		
		if($type == 'component'){
			$destdir = ROOT_PDIR . 'components/' . $key . '/';
		}
		elseif($type == 'theme'){
			$destdir = ROOT_PDIR . 'themes/' . $key . '/';
		}
		else{
			$destdir = ROOT_PDIR . '/';
		}

		try{
			// Will give me an array of Files in the data directory.
			$files = $datadir->ls(null, true);
			// Used to get the relative path for each contained file.
			$datalen = strlen($datadir->getPath());
			foreach($files as $file){
				if(!$file instanceof \Core\Filestore\Backends\FileLocal) continue;

				// It's a file, copy it over.
				// To do so, resolve the directory path inside the temp data dir.
				$dest = \Core\Filestore\Factory::File($destdir . substr($file->getFilename(), $datalen));
				/** @var $dest \Core\Filestore\Backends\FileLocal */
				$dest->copyFrom($file, true);
			}
		}
		catch(Exception $e){
			// OH NOES!
			$localfile->delete();
			$tmpdir->delete();
			\Core\set_message($e->getMessage(), 'error');
			return false;
		}
		
		
		// Cleanup everything
		$localfile->delete();
		$tmpdir->delete();

		// Clear the cache so the next pageload will pick up on the new components and goodies.
		\Core\Cache::Flush();
		\Core\Templates\Backends\Smarty::FlushCache();
		
		// Print a nice message to the user that it completed.
		\Core\set_message('Successfully installed ' . $name . ' ' . $version, 'success');
		return '/updater';
	}
Example #3
0
	public function getPackages() {
		$pkgs = array();
		foreach ($this->getElements('core/package|components/package|themes/package') as $p) {
			$pkg = new PackageXML(null);
			$pkg->loadFromNode($p);
			$pkgs[] = $pkg;
		}
		return $pkgs;
	}
Example #4
0
                continue;
            }
            if ($fileInfo->isDir()) {
                $node = new DOMElement('dir');
                $return->appendChild($node);
                $node->setAttribute('name', $fileInfo->getBasename());
                $this->getDirectoryListing($fileInfo->getPathname(), $node);
            } else {
                $node = new DOMElement('file');
                $return->appendChild($node);
                $node->setAttribute('name', $fileInfo->getBasename());
                $node->setAttribute('role', 'php');
            }
        }
    }
    public function usage()
    {
        echo <<<STDOUT
    Usage: package --version= --source=

STDOUT;
        exit(1);
    }
}
$a = $argc;
$b = $argv;
$c = realpath(__FILE__);
if (realpath($argv[0]) == realpath(__FILE__)) {
    $pxml = new PackageXML();
    $pxml->run();
}
 public static function RebuildPackages()
 {
     $dir = \Core\Filestore\Factory::Directory(\ConfigHandler::Get('/package_repository/base_directory'));
     $coredir = $dir->getPath() . 'core/';
     $componentdir = $dir->getPath() . 'components/';
     $themedir = $dir->getPath() . 'themes/';
     $tmpdir = \Core\Filestore\Factory::Directory('tmp/exports/');
     $gpg = new Core\GPG\GPG();
     $keysfound = [];
     $addedpackages = 0;
     $failedpackages = 0;
     $skippedpackages = 0;
     $ls = $dir->ls('asc', true);
     \Core\CLI\CLI::PrintProgressBar(0);
     $totalPackages = sizeof($ls);
     $percentEach = 100 / $totalPackages;
     $currentPercent = 0;
     // Ensure that the necessary temp directory exists.
     $tmpdir->mkdir();
     foreach ($ls as $file) {
         /** @var \Core\Filestore\File $file */
         $fullpath = $file->getFilename();
         $relpath = substr($file->getFilename(), strlen($dir->getPath()));
         $tmpdirpath = $tmpdir->getPath();
         // Drop the .asc extension.
         $basename = $file->getBasename(true);
         // Tarball of the temporary package
         $tgz = \Core\Filestore\Factory::File($tmpdirpath . $basename);
         $output = [];
         // I need to 1) retrieve and 2) verify the key for this package.
         try {
             $signature = $gpg->verifyFileSignature($fullpath);
         } catch (\Exception $e) {
             trigger_error($fullpath . ' was not able to be verified as authentic, (probably because the GPG public key was not available)');
             $failedpackages++;
             continue;
         }
         // decode and untar it in a temp directory to get the package.xml file.
         exec('gpg --homedir "' . GPG_HOMEDIR . '" -q -d "' . $fullpath . '" > "' . $tgz->getFilename() . '" 2>/dev/null', $output, $ret);
         if ($ret) {
             trigger_error('Decryption of file ' . $fullpath . ' failed!');
             $failedpackages++;
             continue;
         }
         // Extract the package.xml metafile, this is critical!
         exec('tar -xzf "' . $tgz->getFilename() . '" -C "' . $tmpdirpath . '" ./package.xml', $output, $ret);
         if ($ret) {
             trigger_error('Unable to extract package.xml from' . $tgz->getFilename());
             unlink($tmpdirpath . $basename);
             $failedpackages++;
             continue;
         }
         // Read in that package file and append it to the repo xml.
         $package = new PackageXML($tmpdirpath . 'package.xml');
         $package->getRootDOM()->setAttribute('key', $signature->keyID);
         $package->setFileLocation($relpath);
         // Core has a few differences than most components.
         if ($package->getKeyName() == 'core') {
             $pkgName = 'Core Plus';
             $chngName = 'Core Plus';
             $type = 'core';
             $chngDepth = 3;
             $chngFile = './data/core/CHANGELOG';
             $xmlFile = './data/core/component.xml';
         } else {
             $pkgName = $package->getName();
             $chngName = ($package->getType() == 'theme' ? 'Theme/' : '') . $package->getName();
             $type = $package->getType();
             $chngDepth = 2;
             $chngFile = './data/CHANGELOG';
             $xmlFile = './data/' . ($package->getType() == 'theme' ? 'theme.xml' : 'component.xml');
         }
         // Lookup this package in the database or create if it doesn't exist.
         $model = PackageRepositoryPackageModel::Find(['type = ' . $package->getType(), 'key = ' . $package->getKeyName(), 'version = ' . $package->getVersion()], 1);
         if (!$model) {
             $model = new PackageRepositoryPackageModel();
             $model->set('type', $type);
             $model->set('key', $package->getKeyName());
             $model->set('version', $package->getVersion());
         }
         // Set the data provided by the package.xml file.
         $model->set('name', $pkgName);
         $model->set('gpg_key', $package->getKey());
         $model->set('packager', $package->getPackager());
         $model->set('file', $relpath);
         $model->set('description', $package->getDescription());
         $model->set('requires', $package->getRequires());
         $model->set('provides', $package->getProvides());
         $model->set('upgrades', $package->getUpgrades());
         unlink($tmpdirpath . 'package.xml');
         // Extract out the CHANGELOG file, this is not so critical.
         // I need strip-components=2 to drop off the "." and "data" prefixes.
         exec('tar -xzf "' . $tgz->getFilename() . '" -C "' . $tmpdirpath . '" --strip-components=' . $chngDepth . ' ' . $chngFile, $output, $ret);
         // If there is a CHANGELOG, parse that too!
         if (file_exists($tmpdirpath . 'CHANGELOG')) {
             try {
                 $ch = new Core\Utilities\Changelog\Parser($chngName, $tmpdirpath . 'CHANGELOG');
                 $ch->parse();
                 // Get the version for this iteration.
                 $chsec = $ch->getSection($model->get('version'));
                 $model->set('packager_name', $chsec->getPackagerName());
                 $model->set('packager_email', $chsec->getPackagerEmail());
                 $model->set('datetime_released', $chsec->getReleasedDateUTC());
                 $model->set('changelog', $chsec->fetchAsHTML(null));
             } catch (Exception $e) {
                 // meh, we just won't have a changelog.
             } finally {
                 if (file_exists($tmpdirpath . 'CHANGELOG')) {
                     // Cleanup
                     unlink($tmpdirpath . 'CHANGELOG');
                 }
             }
         }
         // Retrieve out the screenshots from this component.
         exec('tar -xzf "' . $tgz->getFilename() . '" -O ' . $xmlFile . ' > "' . $tmpdirpath . 'comp.xml"', $output, $ret);
         if (file_exists($tmpdirpath . 'comp.xml')) {
             try {
                 $images = [];
                 $c = new Component_2_1($tmpdirpath . 'comp.xml');
                 $screens = $c->getScreenshots();
                 if (sizeof($screens)) {
                     foreach ($screens as $s) {
                         // Extract out this screen and save it to the filesystem.
                         $archivedFile = dirname($xmlFile) . '/' . $s;
                         $localFile = \Core\Filestore\Factory::File('public/packagerepo-screens/' . $model->get('type') . '-' . $model->get('key') . '-' . $model->get('version') . '/' . basename($s));
                         // Write something into the file so that it exists on the filesystem.
                         $localFile->putContents('');
                         // And now tar can extract directly to that destination!
                         exec('tar -xzf "' . $tgz->getFilename() . '" -O ' . $archivedFile . ' > "' . $localFile->getFilename() . '"', $output, $ret);
                         if (!$ret) {
                             // Return code should be 0 on a successful write.
                             $images[] = $localFile->getFilename(false);
                         }
                     }
                 }
                 $model->set('screenshots', $images);
             } catch (Exception $e) {
                 // meh, we just won't have images..
             } finally {
                 if (file_exists($tmpdirpath . 'comp.xml')) {
                     // Cleanup
                     unlink($tmpdirpath . 'comp.xml');
                 }
             }
         }
         if ($model->changed()) {
             $model->save(true);
             $addedpackages++;
         } else {
             $skippedpackages++;
         }
         // But I can still cleanup!
         $tgz->delete();
         $currentPercent += $percentEach;
         \Core\CLI\CLI::PrintProgressBar($currentPercent);
     }
     // Commit everything!
     PackageRepositoryPackageModel::CommitSaves();
     return ['updated' => $addedpackages, 'skipped' => $skippedpackages, 'failed' => $failedpackages];
 }
Example #6
0
			exec('tar -xzf "' . $tmpdir . $basename . '" -C "' . $tmpdir . '" ./package.xml', $output, $ret);
			if($ret){
				echo 'FAILED!' . NL . 'Unable to extract package.xml from the tarball!' . NL;
				unlink($tmpdir . $basename);
				$failedpackages++;
				continue;
			}

			$output = array();
			// I also need the GPG key for this specific package.
			exec('gpg --verify "' . $fullpath . '" 2>&1 | grep "key ID" | sed \'s:.*key ID \([A-Z0-9]*\)$:\1:\'', $output, $result);
			$key = $output[0];

			// Read in that package file and append it to the repo xml.
			$package = new PackageXML($tmpdir . 'package.xml');
			$package->getRootDOM()->setAttribute('key', $key);
			$package->setFileLocation($relpath);
			$repo->addPackage($package);
			$addedpackages++;

			// But I can still cleanup!
			unlink($tmpdir . 'package.xml');
			unlink($tmpdir . $basename);

			echo "OK!" . NL;
		}


	}
	else{
Example #7
0
	/**
	 * Save or get the package XML for this component.  This is useful for the
	 * packager
	 *
	 * @param boolean     $minified
	 * @param bool|string $filename
	 *
	 * @return string|null
	 */
	public function savePackageXML($minified = true, $filename = false) {

		$packagexml = new PackageXML();
		$packagexml->setFromComponent($this);

		$out = ($minified) ? $packagexml->asMinifiedXML() : $packagexml->asPrettyXML();

		if ($filename) {
			file_put_contents($filename, $out);
		}
		else {
			return $out;
		}
	}