ManifestSerializer.php 5.9 KB

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