/src/N98/Magento/Command/MagentoConnect/AbstractConnectCommand.php

https://github.com/shandyDev/n98-magerun · PHP · 148 lines · 95 code · 15 blank · 38 comment · 16 complexity · b078770873a9b3f15d9205e718ccd30a MD5 · raw file

  1. <?php
  2. namespace N98\Magento\Command\MagentoConnect;
  3. use N98\Magento\Command\AbstractMagentoCommand;
  4. use N98\Util\OperatingSystem;
  5. use Symfony\Component\Console\Input\InputInterface;
  6. use Symfony\Component\Console\Output\OutputInterface;
  7. abstract class AbstractConnectCommand extends AbstractMagentoCommand
  8. {
  9. /**
  10. * @var string
  11. */
  12. protected $mageScript = null;
  13. /**
  14. * @param \Symfony\Component\Console\Input\InputInterface $input
  15. * @param \Symfony\Component\Console\Output\OutputInterface $output
  16. * @throws \Exception
  17. */
  18. private function findMageScript(InputInterface $input, OutputInterface $output)
  19. {
  20. if ($this->mageScript === null) {
  21. $this->detectMagento($output);
  22. @chdir($this->_magentoRootFolder);
  23. $this->mageScript = './mage';
  24. if (!is_file($this->mageScript)) {
  25. throw new \Exception('Could not find "mage" shell script in current installation');
  26. }
  27. if (!is_executable($this->mageScript)) {
  28. if (!@chmod($this->mageScript, 0755)) {
  29. throw new \Exception('Cannot make "mage" shell script executable. Please chmod the file manually.');
  30. }
  31. }
  32. if (!strstr(shell_exec($this->mageScript . ' list-channels'), 'community')) {
  33. // no channels available -> try to setup
  34. shell_exec($this->mageScript . ' mage-setup');
  35. }
  36. }
  37. }
  38. /**
  39. * @return bool
  40. */
  41. public function isEnabled()
  42. {
  43. return function_exists('shell_exec') && !OperatingSystem::isWindows();
  44. }
  45. /**
  46. * @param string $line
  47. * @return array
  48. */
  49. protected function matchConnectLine($line)
  50. {
  51. $matches = array();
  52. preg_match('/([a-zA-Z0-9-_]+):\s([0-9.]+)\s([a-z]+)/', $line, $matches);
  53. return $matches;
  54. }
  55. /**
  56. * @param \Symfony\Component\Console\Input\InputInterface $input
  57. * @param \Symfony\Component\Console\Output\OutputInterface $output
  58. * @param string $mageScriptParams
  59. * @return string
  60. */
  61. protected function callMageScript(InputInterface $input, OutputInterface $output, $mageScriptParams)
  62. {
  63. $this->findMageScript($input, $output);
  64. return shell_exec($this->mageScript . ' ' . $mageScriptParams);
  65. }
  66. /**
  67. * @param string $packageName
  68. * @param string $searchPackageName
  69. * @return bool
  70. */
  71. protected function isAlternative($packageName, $searchPackageName)
  72. {
  73. $lev = levenshtein($packageName, $searchPackageName);
  74. return $lev <= strlen($searchPackageName) / 3 || false !== strpos($searchPackageName, $packageName);
  75. }
  76. /**
  77. * @param array $alternatives
  78. * @param \Symfony\Component\Console\Input\InputInterface $input
  79. * @param \Symfony\Component\Console\Output\OutputInterface $output
  80. * @return string
  81. */
  82. protected function askForAlternativePackage($alternatives, InputInterface $input, OutputInterface $output)
  83. {
  84. foreach ($alternatives as $key => $package) {
  85. $question[] = '<comment>[' . ($key+1) . ']</comment> ' . $package . "\n";
  86. }
  87. $question[] = "<question>Use alternative package? :</question> ";
  88. $packageNumber = $this->getHelper('dialog')->askAndValidate($output, $question, function($typeInput) use ($alternatives) {
  89. if (!in_array($typeInput, range(1, count($alternatives)))) {
  90. throw new \InvalidArgumentException('Invalid type');
  91. }
  92. return $typeInput;
  93. });
  94. return $alternatives[$packageNumber - 1];
  95. }
  96. /**
  97. * @param \Symfony\Component\Console\Input\InputInterface $input
  98. * @param \Symfony\Component\Console\Output\OutputInterface $output
  99. * @return int|void
  100. */
  101. protected function execute(InputInterface $input, OutputInterface $output)
  102. {
  103. $found = false;
  104. $alternatives = array();
  105. $extensions = $this->callMageScript($input, $output, 'list-available');
  106. $searchPackage = $input->getArgument('package');
  107. foreach (preg_split('/' . PHP_EOL . '/', $extensions) as $line) {
  108. $matches = $this->matchConnectLine($line);
  109. if (!empty($matches)) {
  110. if ($matches[1] == $searchPackage) {
  111. $found = true;
  112. break 1;
  113. } else {
  114. if ($this->isAlternative($matches[1], $searchPackage)) {
  115. $alternatives[] = $matches[1];
  116. }
  117. }
  118. }
  119. }
  120. if ($found) {
  121. $this->doAction($input, $output, $searchPackage);
  122. } else {
  123. $output->writeln('<comment>Could not found package.</comment>');
  124. if (count($alternatives) > 0) {
  125. $this->doAction(
  126. $input,
  127. $output,
  128. $this->askForAlternativePackage($alternatives, $input, $output)
  129. );
  130. }
  131. }
  132. }
  133. }