/**
  * Creates a new source file entry.
  * 
  * @param	integer		$sourceID
  * @param	string		$location
  * @param	string		$type
  * @param	integer		$fileDate
  * @return	SourceFile
  */
 public static function create($sourceID, $location, $type, $profileName = '', $fileDate = TIME_NOW)
 {
     $fileVersion = $packageName = '';
     // get filename
     $filename = basename($location);
     // set file version based upon type
     if ($type != 'wcfsetup') {
         require_once PB_DIR . 'lib/system/package/PackageReader.class.php';
         $pr = new PackageReader($sourceID, $location, true);
         $data = $pr->getPackageData();
         $fileVersion = $data['version'];
         $packageName = $data['name'];
         $type = 'package';
     }
     $sql = "INSERT INTO\tpb" . PB_N . "_source_file\n\t\t\t\t\t(sourceID, hash, filename, fileType, fileVersion, fileDate, packageName, profileName)\n\t\t\tVALUES\t\t(" . $sourceID . ",\n\t\t\t\t\t'" . escapeString(StringUtil::getRandomID()) . "',\n\t\t\t\t\t'" . escapeString($filename) . "',\n\t\t\t\t\t'" . $type . "',\n\t\t\t\t\t'" . escapeString($fileVersion) . "',\n\t\t\t\t\t" . $fileDate . ",\n\t\t\t\t\t'" . escapeString($packageName) . "',\n\t\t\t\t\t'" . escapeString($profileName) . "')";
     WCF::getDB()->sendQuery($sql);
     $fileID = WCF::getDB()->getInsertID('pb' . PB_N . '_source_file', 'fileID');
     $sourceFile = new SourceFile($fileID);
     // move file
     if (!copy($location, PB_DIR . 'packages/' . $sourceFile->fileID . '-' . $sourceFile->hash)) {
         $sql = "DELETE FROM\tpb" . PB_N . "_source_file\n\t\t\t\tWHERE\t\tfileID = " . $sourceFile->fileID;
         WCF::getDB()->sendQuery($sql);
         throw new SystemException("Could not move source file, resource missing or insufficient permissions.");
     }
     @unlink($location);
     return $sourceFile;
 }
 /**
  * Builds a package
  *
  * @param	integer		$source			id or instance of a source
  * @param	PackageReader	$package		required and optional packages
  * @param	string		$directory		source directory
  * @param	string		$filename		the filename
  * @param	mixed		$excludeFiles		files to exclude while packing archive
  * @param	boolean		$ignoreDotFiles		should files beginning with a dot be ignored
  * @param	boolean		$removeAfter		should temporary files be removed afterwards
  */
 public function __construct($source, PackageReader $package, $directory, $filename, $excludeFiles = array(), $ignoreDotFiles = true, $removeAfter = false, $allowedDotFiles = array())
 {
     // read source
     $this->source = $source instanceof Source ? $source : new Source($source);
     // read package
     $this->package = $package->getPackageData();
     if (!isset($this->package['name'])) {
         throw new SystemException('Missing package name in "' . $directory . '", package.xml is not valid');
     }
     $this->ignoreDotFiles = $ignoreDotFiles;
     // add additional files whitch should be allowed
     if (!empty($allowedDotFiles)) {
         if (!is_array($allowedDotFiles)) {
             $allowedDotFiles = array($allowedDotFiles);
         }
         $this->allowedDotFiles = array_merge($this->allowedDotFiles, $allowedDotFiles);
     }
     // add additional files whitch should be excluded
     if (!empty($excludeFiles)) {
         if (!is_array($excludeFiles)) {
             $excludeFiles = array($excludeFiles);
         }
         $this->excludeFiles = array_merge($this->excludeFiles, $excludeFiles);
     }
     // get data for filename
     $data = array('pn' => $this->package['name'], 'pv' => $this->package['version'], 'pr' => 'r' . $this->source->revision, 't' => DateUtil::formatTime('%Y-%m-%d %H:%M:%S', TIME_NOW, false));
     // set archive name
     $this->filename = PackageHelper::getArchiveName($filename, $data);
     // mark package as built
     $buildDirectory = FileUtil::addTrailingSlash($this->source->buildDirectory);
     $location = $buildDirectory . $this->filename;
     PackageHelper::addPackageData($this->package['name'], $location);
     // check requirements
     $this->verifyPackages('requiredpackage', $directory);
     $this->verifyPackages('optionalpackage', $directory);
     // intialize archive
     $location = $this->createArchive($directory, $this->filename, $removeAfter);
     // do not move files created on-the-fly
     if (PackageHelper::isTemporaryFile($location)) {
         $this->location = $location;
         return;
     }
     // register file
     require_once PB_DIR . 'lib/data/source/file/SourceFileEditor.class.php';
     $sourceFile = SourceFileEditor::create($this->source->sourceID, $location, 'package');
     $this->location = $sourceFile->getPath();
 }
 public function readPackages()
 {
     WCF::getCache()->addResource('packages-' . $this->source->sourceID, PB_DIR . 'cache/cache.packages-' . $this->source->sourceID . '.php', PB_DIR . 'lib/system/cache/CacheBuilderPackages.class.php');
     $packages = WCF::getCache()->get('packages-' . $this->source->sourceID);
     // read current builds
     $files = DirectoryUtil::getInstance($this->source->buildDirectory, false)->getFiles();
     foreach ($files as $file) {
         if (strrpos($file, '.tar.gz') !== false) {
             $package = new PackageReader($this->source->sourceID, $this->source->buildDirectory . $file, true);
             $data = $package->getPackageData();
             $this->packages[$data['name']][$data['version']] = array('file' => $file, 'xml' => $package->getXML());
         }
     }
 }
 /**
  * Searching inside directory and sub directories for package.xml
  *
  * @param	integer		$maxDimension
  */
 protected static function readDirectories($directory, $maxDimension = 3)
 {
     // scan current dir for package.xml
     if (file_exists($directory . 'package.xml')) {
         $relativeDirectory = str_replace(self::$source->sourceDirectory, '', $directory);
         $pr = new PackageReader(self::$source, $relativeDirectory);
         $packageData = $pr->getPackageData();
         // remove optional or required packages shipped within the package
         // source, preventing dependency issues if using build profiles
         foreach ($packageData as $type => $data) {
             if ($type == 'optionalpackage' || $type == 'requiredpackage') {
                 if (!is_array($data)) {
                     continue;
                 }
                 foreach ($data as $packageName => $packageAttributes) {
                     if (empty($packageAttributes['file'])) {
                         continue;
                     }
                     $path = $directory . $packageAttributes['file'];
                     if (file_exists($path)) {
                         unset($packageData[$type][$packageName]);
                     }
                 }
             }
         }
         self::$packages[$relativeDirectory] = $packageData;
     } else {
         // look for WCFSetup resources
         $pathinfo = pathinfo(FileUtil::getRealPath($directory));
         $path = explode('/', $pathinfo['basename']);
         if (array_pop($path) == 'wcfsetup') {
             self::addWcfResource($directory);
         } else {
             if ($maxDimension) {
                 if (is_dir($directory)) {
                     if ($dh = opendir($directory)) {
                         $maxDimension--;
                         while (($file = readdir($dh)) !== false) {
                             if (!in_array($file, array('.', '..', '.svn'))) {
                                 self::readDirectories($directory . $file . '/', $maxDimension);
                             }
                         }
                         closedir($dh);
                     }
                 }
             }
         }
     }
 }