<?php
/*
* This file is part of PharIo\Manifest.
*
* (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace PharIo\Manifest;
use PharIo\Version\AnyVersionConstraint;
use PharIo\Version\Version;
use PharIo\Version\VersionConstraint;
use XMLWriter;
class ManifestSerializer {
/**
* @var XMLWriter
*/
private $xmlWriter;
public function serializeToFile(Manifest $manifest, $filename) {
file_put_contents(
$filename,
$this->serializeToString($manifest)
);
}
public function serializeToString(Manifest $manifest) {
$this->startDocument();
$this->addContains($manifest->getName(), $manifest->getVersion(), $manifest->getType());
$this->addCopyright($manifest->getCopyrightInformation());
$this->addRequirements($manifest->getRequirements());
$this->addBundles($manifest->getBundledComponents());
return $this->finishDocument();
}
private function startDocument() {
$xmlWriter = new XMLWriter();
$xmlWriter->openMemory();
$xmlWriter->setIndent(true);
$xmlWriter->setIndentString(str_repeat(' ', 4));
$xmlWriter->startDocument('1.0', 'UTF-8');
$xmlWriter->startElement('phar');
$xmlWriter->writeAttribute('xmlns', 'https://phar.io/xml/manifest/1.0');
$this->xmlWriter = $xmlWriter;
}
private function finishDocument() {
$this->xmlWriter->endElement();
$this->xmlWriter->endDocument();
return $this->xmlWriter->outputMemory();
}
private function addContains($name, Version $version, Type $type) {
$this->xmlWriter->startElement('contains');
$this->xmlWriter->writeAttribute('name', $name);
$this->xmlWriter->writeAttribute('version', $version->getVersionString());
switch (true) {
case $type->isApplication(): {
$this->xmlWriter->writeAttribute('type', 'application');
break;
}
case $type->isLibrary(): {
$this->xmlWriter->writeAttribute('type', 'library');
break;
}
case $type->isExtension(): {
/* @var $type Extension */
$this->xmlWriter->writeAttribute('type', 'extension');
$this->addExtension($type->getApplicationName(), $type->getVersionConstraint());
break;
}
default: {
$this->xmlWriter->writeAttribute('type', 'custom');
}
}
$this->xmlWriter->endElement();
}
private function addCopyright(CopyrightInformation $copyrightInformation) {
$this->xmlWriter->startElement('copyright');
foreach($copyrightInformation->getAuthors() as $author) {
$this->xmlWriter->startElement('author');
$this->xmlWriter->writeAttribute('name', $author->getName());
$this->xmlWriter->writeAttribute('email', (string) $author->getEmail());
$this->xmlWriter->endElement();
}
$license = $copyrightInformation->getLicense();
$this->xmlWriter->startElement('license');
$this->xmlWriter->writeAttribute('type', $license->getName());
$this->xmlWriter->writeAttribute('url', $license->getUrl());
$this->xmlWriter->endElement();
$this->xmlWriter->endElement();
}
private function addRequirements(RequirementCollection $requirementCollection) {
$phpRequirement = new AnyVersionConstraint();
$extensions = [];
foreach($requirementCollection as $requirement) {
if ($requirement instanceof PhpVersionRequirement) {
$phpRequirement = $requirement->getVersionConstraint();
continue;
}
if ($requirement instanceof PhpExtensionRequirement) {
$extensions[] = (string) $requirement;
}
}
$this->xmlWriter->startElement('requires');
$this->xmlWriter->startElement('php');
$this->xmlWriter->writeAttribute('version', $phpRequirement->asString());
foreach($extensions as $extension) {
$this->xmlWriter->startElement('ext');
$this->xmlWriter->writeAttribute('name', $extension);
$this->xmlWriter->endElement();
}
$this->xmlWriter->endElement();
$this->xmlWriter->endElement();
}
private function addBundles(BundledComponentCollection $bundledComponentCollection) {
if (count($bundledComponentCollection) === 0) {
return;
}
$this->xmlWriter->startElement('bundles');
foreach($bundledComponentCollection as $bundledComponent) {
$this->xmlWriter->startElement('component');
$this->xmlWriter->writeAttribute('name', $bundledComponent->getName());
$this->xmlWriter->writeAttribute('version', $bundledComponent->getVersion()->getVersionString());
$this->xmlWriter->endElement();
}
$this->xmlWriter->endElement();
}
private function addExtension($application, VersionConstraint $versionConstraint) {
$this->xmlWriter->startElement('extension');
$this->xmlWriter->writeAttribute('for', $application);
$this->xmlWriter->writeAttribute('compatible', $versionConstraint->asString());
$this->xmlWriter->endElement();
}
}