XmlCatalogGenerateCommand.php 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  1. <?php
  2. /**
  3. * Copyright © Magento, Inc. All rights reserved.
  4. * See COPYING.txt for license details.
  5. */
  6. namespace Magento\Developer\Console\Command;
  7. use Magento\Framework\Exception\InputException;
  8. use Symfony\Component\Console\Command\Command;
  9. use Symfony\Component\Console\Input\InputArgument;
  10. use Symfony\Component\Console\Input\InputOption;
  11. use Symfony\Component\Console\Input\InputInterface;
  12. use Symfony\Component\Console\Output\OutputInterface;
  13. /**
  14. * Class XmlCatalogGenerateCommand Generates dictionary of URNs for the IDE
  15. *
  16. * @SuppressWarnings(PMD.CouplingBetweenObjects)
  17. *
  18. * @api
  19. * @since 100.0.2
  20. */
  21. class XmlCatalogGenerateCommand extends Command
  22. {
  23. /**
  24. * Option for the type of IDE
  25. */
  26. const IDE_OPTION = 'ide';
  27. /**
  28. * Argument for the path to IDE config file
  29. */
  30. const IDE_FILE_PATH_ARGUMENT = 'path';
  31. /**
  32. * @var \Magento\Framework\App\Utility\Files
  33. */
  34. private $filesUtility;
  35. /**
  36. * @var \Magento\Framework\Config\Dom\UrnResolver
  37. */
  38. private $urnResolver;
  39. /**
  40. * @var \Magento\Framework\Filesystem\Directory\ReadFactory
  41. */
  42. private $readFactory;
  43. /**
  44. * Supported formats
  45. *
  46. * @var \Magento\Developer\Model\XmlCatalog\Format\FormatInterface[]
  47. */
  48. private $formats;
  49. /**
  50. * @param \Magento\Framework\App\Utility\Files $filesUtility
  51. * @param \Magento\Framework\Config\Dom\UrnResolver $urnResolver
  52. * @param \Magento\Framework\Filesystem\Directory\ReadFactory $readFactory
  53. * @param \Magento\Developer\Model\XmlCatalog\Format\FormatInterface[] $formats
  54. */
  55. public function __construct(
  56. \Magento\Framework\App\Utility\Files $filesUtility,
  57. \Magento\Framework\Config\Dom\UrnResolver $urnResolver,
  58. \Magento\Framework\Filesystem\Directory\ReadFactory $readFactory,
  59. array $formats = []
  60. ) {
  61. $this->filesUtility = $filesUtility;
  62. $this->urnResolver = $urnResolver;
  63. $this->formats = $formats;
  64. $this->readFactory = $readFactory;
  65. parent::__construct();
  66. }
  67. /**
  68. * {@inheritdoc}
  69. */
  70. protected function configure()
  71. {
  72. $this->setName('dev:urn-catalog:generate')
  73. ->setDescription('Generates the catalog of URNs to *.xsd mappings for the IDE to highlight xml.')
  74. ->setDefinition([
  75. new InputOption(
  76. self::IDE_OPTION,
  77. null,
  78. InputOption::VALUE_REQUIRED,
  79. 'Format in which catalog will be generated. Supported: ['.
  80. implode(', ', $this->getSupportedFormats()) . ']',
  81. 'phpstorm'
  82. ),
  83. new InputArgument(
  84. self::IDE_FILE_PATH_ARGUMENT,
  85. InputArgument::REQUIRED,
  86. 'Path to file to output the catalog. For PhpStorm use .idea/misc.xml'
  87. )
  88. ]);
  89. parent::configure();
  90. }
  91. /**
  92. * Get an array of URNs
  93. *
  94. * @param OutputInterface $output
  95. * @return array
  96. */
  97. private function getUrnDictionary(OutputInterface $output)
  98. {
  99. $files = $this->filesUtility->getXmlCatalogFiles('*.xml');
  100. $files = array_merge($files, $this->filesUtility->getXmlCatalogFiles('*.xsd'));
  101. $urns = [];
  102. foreach ($files as $file) {
  103. $fileDir = dirname($file[0]);
  104. $fileName = basename($file[0]);
  105. $read = $this->readFactory->create($fileDir);
  106. $content = $read->readFile($fileName);
  107. $matches = [];
  108. preg_match_all('/schemaLocation="(urn\:magento\:[^"]*)"/i', $content, $matches);
  109. if (isset($matches[1])) {
  110. $urns = array_merge($urns, $matches[1]);
  111. }
  112. }
  113. $urns = array_unique($urns);
  114. $paths = [];
  115. foreach ($urns as $urn) {
  116. try {
  117. $paths[$urn] = $this->urnResolver->getRealPath($urn);
  118. } catch (\Exception $e) {
  119. // don't add unsupported element to array
  120. if ($output->getVerbosity() >= OutputInterface::VERBOSITY_VERBOSE) {
  121. $output->writeln($e->getMessage());
  122. }
  123. }
  124. }
  125. return $paths;
  126. }
  127. /**
  128. * {@inheritdoc}
  129. * @throws \InvalidArgumentException
  130. */
  131. protected function execute(InputInterface $input, OutputInterface $output)
  132. {
  133. $ideName = $input->getOption(self::IDE_OPTION);
  134. $ideFilePath = $input->getArgument(self::IDE_FILE_PATH_ARGUMENT);
  135. $urnDictionary = $this->getUrnDictionary($output);
  136. if ($formatter = $this->getFormatters($ideName)) {
  137. $formatter->generateCatalog($urnDictionary, $ideFilePath);
  138. } else {
  139. throw new InputException(__("Format for IDE '%1' is not supported", $ideName));
  140. }
  141. }
  142. /**
  143. * Get formatter based on format
  144. *
  145. * @param string $format
  146. * @return \Magento\Developer\Model\XmlCatalog\Format\FormatInterface|false
  147. */
  148. private function getFormatters($format)
  149. {
  150. $format = strtolower($format);
  151. if (!isset($this->formats[$format])) {
  152. return false;
  153. }
  154. return $this->formats[$format];
  155. }
  156. /**
  157. * Get registered formatter aliases
  158. *
  159. * @return string[]
  160. */
  161. public function getSupportedFormats()
  162. {
  163. return array_keys($this->formats);
  164. }
  165. }