Chris@2: , Sebastian Heuer , Sebastian Bergmann Chris@2: * Chris@2: * For the full copyright and license information, please view the LICENSE Chris@2: * file that was distributed with this source code. Chris@2: */ Chris@2: Chris@2: namespace PharIo\Manifest; Chris@2: Chris@2: use DOMDocument; Chris@2: use DOMElement; Chris@2: Chris@2: class ManifestDocument { Chris@2: const XMLNS = 'https://phar.io/xml/manifest/1.0'; Chris@2: Chris@2: /** Chris@2: * @var DOMDocument Chris@2: */ Chris@2: private $dom; Chris@2: Chris@2: /** Chris@2: * ManifestDocument constructor. Chris@2: * Chris@2: * @param DOMDocument $dom Chris@2: */ Chris@2: private function __construct(DOMDocument $dom) { Chris@2: $this->ensureCorrectDocumentType($dom); Chris@2: Chris@2: $this->dom = $dom; Chris@2: } Chris@2: Chris@2: public static function fromFile($filename) { Chris@2: if (!file_exists($filename)) { Chris@2: throw new ManifestDocumentException( Chris@2: sprintf('File "%s" not found', $filename) Chris@2: ); Chris@2: } Chris@2: Chris@2: return self::fromString( Chris@2: file_get_contents($filename) Chris@2: ); Chris@2: } Chris@2: Chris@2: public static function fromString($xmlString) { Chris@2: $prev = libxml_use_internal_errors(true); Chris@2: libxml_clear_errors(); Chris@2: Chris@2: $dom = new DOMDocument(); Chris@2: $dom->loadXML($xmlString); Chris@2: Chris@2: $errors = libxml_get_errors(); Chris@2: libxml_use_internal_errors($prev); Chris@2: Chris@2: if (count($errors) !== 0) { Chris@2: throw new ManifestDocumentLoadingException($errors); Chris@2: } Chris@2: Chris@2: return new self($dom); Chris@2: } Chris@2: Chris@2: public function getContainsElement() { Chris@2: return new ContainsElement( Chris@2: $this->fetchElementByName('contains') Chris@2: ); Chris@2: } Chris@2: Chris@2: public function getCopyrightElement() { Chris@2: return new CopyrightElement( Chris@2: $this->fetchElementByName('copyright') Chris@2: ); Chris@2: } Chris@2: Chris@2: public function getRequiresElement() { Chris@2: return new RequiresElement( Chris@2: $this->fetchElementByName('requires') Chris@2: ); Chris@2: } Chris@2: Chris@2: public function hasBundlesElement() { Chris@2: return $this->dom->getElementsByTagNameNS(self::XMLNS, 'bundles')->length === 1; Chris@2: } Chris@2: Chris@2: public function getBundlesElement() { Chris@2: return new BundlesElement( Chris@2: $this->fetchElementByName('bundles') Chris@2: ); Chris@2: } Chris@2: Chris@2: private function ensureCorrectDocumentType(DOMDocument $dom) { Chris@2: $root = $dom->documentElement; Chris@2: Chris@2: if ($root->localName !== 'phar' || $root->namespaceURI !== self::XMLNS) { Chris@2: throw new ManifestDocumentException('Not a phar.io manifest document'); Chris@2: } Chris@2: } Chris@2: Chris@2: /** Chris@2: * @param $elementName Chris@2: * Chris@2: * @return DOMElement Chris@2: * Chris@2: * @throws ManifestDocumentException Chris@2: */ Chris@2: private function fetchElementByName($elementName) { Chris@2: $element = $this->dom->getElementsByTagNameNS(self::XMLNS, $elementName)->item(0); Chris@2: Chris@2: if (!$element instanceof DOMElement) { Chris@2: throw new ManifestDocumentException( Chris@2: sprintf('Element %s missing', $elementName) Chris@2: ); Chris@2: } Chris@2: Chris@2: return $element; Chris@2: } Chris@2: }