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