ManifestSerializer.php 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  1. <?php declare(strict_types = 1);
  2. /*
  3. * This file is part of PharIo\Manifest.
  4. *
  5. * (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de>
  6. *
  7. * For the full copyright and license information, please view the LICENSE
  8. * file that was distributed with this source code.
  9. */
  10. namespace PharIo\Manifest;
  11. use PharIo\Version\AnyVersionConstraint;
  12. use PharIo\Version\Version;
  13. use PharIo\Version\VersionConstraint;
  14. use XMLWriter;
  15. /** @psalm-suppress MissingConstructor */
  16. class ManifestSerializer {
  17. /** @var XMLWriter */
  18. private $xmlWriter;
  19. public function serializeToFile(Manifest $manifest, string $filename): void {
  20. \file_put_contents(
  21. $filename,
  22. $this->serializeToString($manifest)
  23. );
  24. }
  25. public function serializeToString(Manifest $manifest): string {
  26. $this->startDocument();
  27. $this->addContains($manifest->getName(), $manifest->getVersion(), $manifest->getType());
  28. $this->addCopyright($manifest->getCopyrightInformation());
  29. $this->addRequirements($manifest->getRequirements());
  30. $this->addBundles($manifest->getBundledComponents());
  31. return $this->finishDocument();
  32. }
  33. private function startDocument(): void {
  34. $xmlWriter = new XMLWriter();
  35. $xmlWriter->openMemory();
  36. $xmlWriter->setIndent(true);
  37. $xmlWriter->setIndentString(\str_repeat(' ', 4));
  38. $xmlWriter->startDocument('1.0', 'UTF-8');
  39. $xmlWriter->startElement('phar');
  40. $xmlWriter->writeAttribute('xmlns', 'https://phar.io/xml/manifest/1.0');
  41. $this->xmlWriter = $xmlWriter;
  42. }
  43. private function finishDocument(): string {
  44. $this->xmlWriter->endElement();
  45. $this->xmlWriter->endDocument();
  46. return $this->xmlWriter->outputMemory();
  47. }
  48. private function addContains(ApplicationName $name, Version $version, Type $type): void {
  49. $this->xmlWriter->startElement('contains');
  50. $this->xmlWriter->writeAttribute('name', $name->asString());
  51. $this->xmlWriter->writeAttribute('version', $version->getVersionString());
  52. switch (true) {
  53. case $type->isApplication(): {
  54. $this->xmlWriter->writeAttribute('type', 'application');
  55. break;
  56. }
  57. case $type->isLibrary(): {
  58. $this->xmlWriter->writeAttribute('type', 'library');
  59. break;
  60. }
  61. case $type->isExtension(): {
  62. $this->xmlWriter->writeAttribute('type', 'extension');
  63. /* @var $type Extension */
  64. $this->addExtension(
  65. $type->getApplicationName(),
  66. $type->getVersionConstraint()
  67. );
  68. break;
  69. }
  70. default: {
  71. $this->xmlWriter->writeAttribute('type', 'custom');
  72. }
  73. }
  74. $this->xmlWriter->endElement();
  75. }
  76. private function addCopyright(CopyrightInformation $copyrightInformation): void {
  77. $this->xmlWriter->startElement('copyright');
  78. foreach ($copyrightInformation->getAuthors() as $author) {
  79. $this->xmlWriter->startElement('author');
  80. $this->xmlWriter->writeAttribute('name', $author->getName());
  81. $this->xmlWriter->writeAttribute('email', $author->getEmail()->asString());
  82. $this->xmlWriter->endElement();
  83. }
  84. $license = $copyrightInformation->getLicense();
  85. $this->xmlWriter->startElement('license');
  86. $this->xmlWriter->writeAttribute('type', $license->getName());
  87. $this->xmlWriter->writeAttribute('url', $license->getUrl()->asString());
  88. $this->xmlWriter->endElement();
  89. $this->xmlWriter->endElement();
  90. }
  91. private function addRequirements(RequirementCollection $requirementCollection): void {
  92. $phpRequirement = new AnyVersionConstraint();
  93. $extensions = [];
  94. foreach ($requirementCollection as $requirement) {
  95. if ($requirement instanceof PhpVersionRequirement) {
  96. $phpRequirement = $requirement->getVersionConstraint();
  97. continue;
  98. }
  99. if ($requirement instanceof PhpExtensionRequirement) {
  100. $extensions[] = $requirement->asString();
  101. }
  102. }
  103. $this->xmlWriter->startElement('requires');
  104. $this->xmlWriter->startElement('php');
  105. $this->xmlWriter->writeAttribute('version', $phpRequirement->asString());
  106. foreach ($extensions as $extension) {
  107. $this->xmlWriter->startElement('ext');
  108. $this->xmlWriter->writeAttribute('name', $extension);
  109. $this->xmlWriter->endElement();
  110. }
  111. $this->xmlWriter->endElement();
  112. $this->xmlWriter->endElement();
  113. }
  114. private function addBundles(BundledComponentCollection $bundledComponentCollection): void {
  115. if (\count($bundledComponentCollection) === 0) {
  116. return;
  117. }
  118. $this->xmlWriter->startElement('bundles');
  119. foreach ($bundledComponentCollection as $bundledComponent) {
  120. $this->xmlWriter->startElement('component');
  121. $this->xmlWriter->writeAttribute('name', $bundledComponent->getName());
  122. $this->xmlWriter->writeAttribute('version', $bundledComponent->getVersion()->getVersionString());
  123. $this->xmlWriter->endElement();
  124. }
  125. $this->xmlWriter->endElement();
  126. }
  127. private function addExtension(ApplicationName $applicationName, VersionConstraint $versionConstraint): void {
  128. $this->xmlWriter->startElement('extension');
  129. $this->xmlWriter->writeAttribute('for', $applicationName->asString());
  130. $this->xmlWriter->writeAttribute('compatible', $versionConstraint->asString());
  131. $this->xmlWriter->endElement();
  132. }
  133. }