/** * Adds a module to the repository * @param zibo\library\filesystem\File $pharFile Path to the phar file of the module * @return array Array with Module instances of the installed modules */ public function addModule(File $pharFile) { $moduleIO = new XmlModuleIO(); $modules = $moduleIO->readModules($pharFile); $zibo = Zibo::getInstance(); foreach ($modules as $module) { $namespace = $module->getNamespace(); $name = $module->getName(); $version = $module->getVersion(); $ziboVersion = $module->getZiboVersion(); $zibo->runEvent(Zibo::EVENT_LOG, $namespace . '.' . $name . ' ' . $version, '', 0, RepositoryModule::LOG_NAME); $query = $this->createQuery(); $xpath = new DOMXPath($this->indexDom); $modulesElement = $xpath->query($query)->item(0); $query = $this->createModuleQuery($namespace, $name); $moduleElement = $xpath->query($query, $modulesElement)->item(0); $zibo->runEvent(Zibo::EVENT_LOG, 'module element found?', is_object($moduleElement) ? $moduleElement->ownerDocument->saveXML($moduleElement) : $moduleElement); if (!$moduleElement) { $moduleElement = $this->indexDom->createElement(RepositoryModule::TAG_MODULE); $moduleElement->setAttribute(RepositoryModule::ATTRIBUTE_NAMESPACE, $namespace); $moduleElement->setAttribute(RepositoryModule::ATTRIBUTE_NAME, $name); $modulesElement->appendChild($moduleElement); } else { $query = $this->createVersionQuery($version); $versionElement = $xpath->query($query, $moduleElement)->item(0); if ($versionElement) { $zibo->runEvent(Zibo::EVENT_LOG, 'version element found?', is_object($versionElement) ? $versionElement->ownerDocument->saveXML($versionElement) : $versionElement); throw new ModuleVersionAlreadyExistsException("Version {$version} of module {$namespace}/{$name} already exists in the repository", $namespace, $name, $version); } } $versionElement = $this->indexDom->createElement(RepositoryModule::TAG_VERSION); $versionElement->setAttribute(RepositoryModule::ATTRIBUTE_VERSION, $version); $versionElement->setAttribute(RepositoryModule::ATTRIBUTE_ZIBO_VERSION, $ziboVersion); $dependencies = $module->getDependencies(); foreach ($dependencies as $dependency) { $dependencyElement = $this->indexDom->createElement(RepositoryModule::TAG_DEPENDENCY); $dependencyElement->setAttribute(RepositoryModule::ATTRIBUTE_NAMESPACE, $dependency->getNamespace()); $dependencyElement->setAttribute(RepositoryModule::ATTRIBUTE_NAME, $dependency->getName()); $dependencyElement->setAttribute(RepositoryModule::ATTRIBUTE_VERSION, $dependency->getVersion()); $versionElement->appendChild($dependencyElement); // should we also check if the dependencies are met in the repository, otherwise fail and show why ??? // dependency version acts as a minimal version AFAIK } // search the first existing version that has a version number lower than the one we want to insert // we will insert the new version before that existing version, to keep the version with the highest version number at the top $firstLowerVersionElement = null; foreach ($moduleElement->childNodes as $existingVersionElement) { if (version_compare($existingVersionElement->getAttribute(RepositoryModule::ATTRIBUTE_VERSION), $version) === -1) { $firstLowerVersionElement = $existingVersionElement; break; } } if ($firstLowerVersionElement) { $moduleElement->insertBefore($versionElement, $firstLowerVersionElement); } else { $moduleElement->appendChild($versionElement); } $moduleFile = $this->getModuleFile($namespace, $name, $version); $pharFile->copy($moduleFile); } $this->isIndexDirty = true; return $modules; }
/** * Gets the index element for the provided index * @param zibo\library\xml\dom\Document $dom * @param zibo\library\database\definition\Index $index Index to get the element from * @return DOMElement */ protected function getElementFromIndex(Document $dom, Index $index) { $indexName = $index->getName(); $indexElement = $dom->createElement(self::TAG_INDEX); $indexElement->setAttribute(self::ATTRIBUTE_NAME, $indexName); $fields = $index->getFields(); foreach ($fields as $field) { $fieldElement = $dom->createElement(self::TAG_INDEX_FIELD); $fieldElement->setAttribute(self::ATTRIBUTE_NAME, $field->getName()); $indexElement->appendChild($fieldElement); } return $indexElement; }
/** * Reads the index of this repository * @return null */ private function readIndexFile() { $indexFile = new File($this->directory, self::INDEX_FILE); $dom = new Document('1.0', 'utf-8'); $dom->formatOutput = true; $dom->preserveWhiteSpace = false; if (!$indexFile->exists()) { Zibo::getInstance()->runEvent(Zibo::EVENT_LOG, 'Initializing new index file', $indexFile, 0, RepositoryModule::LOG_NAME); $modulesElement = $dom->createElement(RepositoryModule::TAG_MODULES); $repositoryElement = $dom->createElement(RepositoryModule::TAG_REPOSITORY); $repositoryElement->appendChild($modulesElement); $dom->appendChild($repositoryElement); } else { $dom->setRelaxNGFileFromConfig(self::CONFIG_REPOSITORY_RNG); $success = @$dom->load($indexFile); if (!$success) { $error = error_get_last(); throw new ZiboException("Failed loading {$indexFile} into a DOM tree: " . $error['message']); } } $this->indexDom = $dom; }