BaseInstaller.php 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  1. <?php
  2. namespace Composer\Installers;
  3. use Composer\IO\IOInterface;
  4. use Composer\Composer;
  5. use Composer\Package\PackageInterface;
  6. abstract class BaseInstaller
  7. {
  8. protected $locations = array();
  9. protected $composer;
  10. protected $package;
  11. protected $io;
  12. /**
  13. * Initializes base installer.
  14. *
  15. * @param PackageInterface $package
  16. * @param Composer $composer
  17. * @param IOInterface $io
  18. */
  19. public function __construct(PackageInterface $package = null, Composer $composer = null, IOInterface $io = null)
  20. {
  21. $this->composer = $composer;
  22. $this->package = $package;
  23. $this->io = $io;
  24. }
  25. /**
  26. * Return the install path based on package type.
  27. *
  28. * @param PackageInterface $package
  29. * @param string $frameworkType
  30. * @return string
  31. */
  32. public function getInstallPath(PackageInterface $package, $frameworkType = '')
  33. {
  34. $type = $this->package->getType();
  35. $prettyName = $this->package->getPrettyName();
  36. if (strpos($prettyName, '/') !== false) {
  37. list($vendor, $name) = explode('/', $prettyName);
  38. } else {
  39. $vendor = '';
  40. $name = $prettyName;
  41. }
  42. $availableVars = $this->inflectPackageVars(compact('name', 'vendor', 'type'));
  43. $extra = $package->getExtra();
  44. if (!empty($extra['installer-name'])) {
  45. $availableVars['name'] = $extra['installer-name'];
  46. }
  47. if ($this->composer->getPackage()) {
  48. $extra = $this->composer->getPackage()->getExtra();
  49. if (!empty($extra['installer-paths'])) {
  50. $customPath = $this->mapCustomInstallPaths($extra['installer-paths'], $prettyName, $type, $vendor);
  51. if ($customPath !== false) {
  52. return $this->templatePath($customPath, $availableVars);
  53. }
  54. }
  55. }
  56. $packageType = substr($type, strlen($frameworkType) + 1);
  57. $locations = $this->getLocations();
  58. if (!isset($locations[$packageType])) {
  59. throw new \InvalidArgumentException(sprintf('Package type "%s" is not supported', $type));
  60. }
  61. return $this->templatePath($locations[$packageType], $availableVars);
  62. }
  63. /**
  64. * For an installer to override to modify the vars per installer.
  65. *
  66. * @param array $vars
  67. * @return array
  68. */
  69. public function inflectPackageVars($vars)
  70. {
  71. return $vars;
  72. }
  73. /**
  74. * Gets the installer's locations
  75. *
  76. * @return array
  77. */
  78. public function getLocations()
  79. {
  80. return $this->locations;
  81. }
  82. /**
  83. * Replace vars in a path
  84. *
  85. * @param string $path
  86. * @param array $vars
  87. * @return string
  88. */
  89. protected function templatePath($path, array $vars = array())
  90. {
  91. if (strpos($path, '{') !== false) {
  92. extract($vars);
  93. preg_match_all('@\{\$([A-Za-z0-9_]*)\}@i', $path, $matches);
  94. if (!empty($matches[1])) {
  95. foreach ($matches[1] as $var) {
  96. $path = str_replace('{$' . $var . '}', $$var, $path);
  97. }
  98. }
  99. }
  100. return $path;
  101. }
  102. /**
  103. * Search through a passed paths array for a custom install path.
  104. *
  105. * @param array $paths
  106. * @param string $name
  107. * @param string $type
  108. * @param string $vendor = NULL
  109. * @return string
  110. */
  111. protected function mapCustomInstallPaths(array $paths, $name, $type, $vendor = NULL)
  112. {
  113. foreach ($paths as $path => $names) {
  114. if (in_array($name, $names) || in_array('type:' . $type, $names) || in_array('vendor:' . $vendor, $names)) {
  115. return $path;
  116. }
  117. }
  118. return false;
  119. }
  120. }