3 namespace Composer\Installers;
6 use Composer\Installer\BinaryInstaller;
7 use Composer\Installer\LibraryInstaller;
8 use Composer\IO\IOInterface;
9 use Composer\Package\PackageInterface;
10 use Composer\Repository\InstalledRepositoryInterface;
11 use Composer\Util\Filesystem;
13 class Installer extends LibraryInstaller
17 * Package types to installer class map
21 private $supportedTypes = array(
22 'aimeos' => 'AimeosInstaller',
23 'asgard' => 'AsgardInstaller',
24 'attogram' => 'AttogramInstaller',
25 'agl' => 'AglInstaller',
26 'annotatecms' => 'AnnotateCmsInstaller',
27 'bitrix' => 'BitrixInstaller',
28 'bonefish' => 'BonefishInstaller',
29 'cakephp' => 'CakePHPInstaller',
30 'chef' => 'ChefInstaller',
31 'civicrm' => 'CiviCrmInstaller',
32 'ccframework' => 'ClanCatsFrameworkInstaller',
33 'cockpit' => 'CockpitInstaller',
34 'codeigniter' => 'CodeIgniterInstaller',
35 'concrete5' => 'Concrete5Installer',
36 'craft' => 'CraftInstaller',
37 'croogo' => 'CroogoInstaller',
38 'dokuwiki' => 'DokuWikiInstaller',
39 'dolibarr' => 'DolibarrInstaller',
40 'decibel' => 'DecibelInstaller',
41 'drupal' => 'DrupalInstaller',
42 'elgg' => 'ElggInstaller',
43 'eliasis' => 'EliasisInstaller',
44 'ee3' => 'ExpressionEngineInstaller',
45 'ee2' => 'ExpressionEngineInstaller',
46 'ezplatform' => 'EzPlatformInstaller',
47 'fuel' => 'FuelInstaller',
48 'fuelphp' => 'FuelphpInstaller',
49 'grav' => 'GravInstaller',
50 'hurad' => 'HuradInstaller',
51 'imagecms' => 'ImageCMSInstaller',
52 'itop' => 'ItopInstaller',
53 'joomla' => 'JoomlaInstaller',
54 'kanboard' => 'KanboardInstaller',
55 'kirby' => 'KirbyInstaller',
56 'kodicms' => 'KodiCMSInstaller',
57 'kohana' => 'KohanaInstaller',
58 'lms' => 'LanManagementSystemInstaller',
59 'laravel' => 'LaravelInstaller',
60 'lavalite' => 'LavaLiteInstaller',
61 'lithium' => 'LithiumInstaller',
62 'magento' => 'MagentoInstaller',
63 'majima' => 'MajimaInstaller',
64 'mako' => 'MakoInstaller',
65 'maya' => 'MayaInstaller',
66 'mautic' => 'MauticInstaller',
67 'mediawiki' => 'MediaWikiInstaller',
68 'microweber' => 'MicroweberInstaller',
69 'modulework' => 'MODULEWorkInstaller',
70 'modx' => 'ModxInstaller',
71 'modxevo' => 'MODXEvoInstaller',
72 'moodle' => 'MoodleInstaller',
73 'october' => 'OctoberInstaller',
74 'ontowiki' => 'OntoWikiInstaller',
75 'oxid' => 'OxidInstaller',
76 'osclass' => 'OsclassInstaller',
77 'pxcms' => 'PxcmsInstaller',
78 'phpbb' => 'PhpBBInstaller',
79 'pimcore' => 'PimcoreInstaller',
80 'piwik' => 'PiwikInstaller',
81 'plentymarkets'=> 'PlentymarketsInstaller',
82 'ppi' => 'PPIInstaller',
83 'puppet' => 'PuppetInstaller',
84 'radphp' => 'RadPHPInstaller',
85 'phifty' => 'PhiftyInstaller',
86 'porto' => 'PortoInstaller',
87 'redaxo' => 'RedaxoInstaller',
88 'reindex' => 'ReIndexInstaller',
89 'roundcube' => 'RoundcubeInstaller',
90 'shopware' => 'ShopwareInstaller',
91 'sitedirect' => 'SiteDirectInstaller',
92 'silverstripe' => 'SilverStripeInstaller',
93 'smf' => 'SMFInstaller',
94 'sydes' => 'SyDESInstaller',
95 'symfony1' => 'Symfony1Installer',
96 'thelia' => 'TheliaInstaller',
97 'tusk' => 'TuskInstaller',
98 'typo3-cms' => 'TYPO3CmsInstaller',
99 'typo3-flow' => 'TYPO3FlowInstaller',
100 'userfrosting' => 'UserFrostingInstaller',
101 'vanilla' => 'VanillaInstaller',
102 'whmcs' => 'WHMCSInstaller',
103 'wolfcms' => 'WolfCMSInstaller',
104 'wordpress' => 'WordPressInstaller',
105 'yawik' => 'YawikInstaller',
106 'zend' => 'ZendInstaller',
107 'zikula' => 'ZikulaInstaller',
108 'prestashop' => 'PrestashopInstaller'
112 * Installer constructor.
114 * Disables installers specified in main composer extra installer-disable
117 * @param IOInterface $io
118 * @param Composer $composer
119 * @param string $type
120 * @param Filesystem|null $filesystem
121 * @param BinaryInstaller|null $binaryInstaller
123 public function __construct(
127 Filesystem $filesystem = null,
128 BinaryInstaller $binaryInstaller = null
130 parent::__construct($io, $composer, $type, $filesystem,
132 $this->removeDisabledInstallers();
138 public function getInstallPath(PackageInterface $package)
140 $type = $package->getType();
141 $frameworkType = $this->findFrameworkType($type);
143 if ($frameworkType === false) {
144 throw new \InvalidArgumentException(
145 'Sorry the package type of this package is not yet supported.'
149 $class = 'Composer\\Installers\\' . $this->supportedTypes[$frameworkType];
150 $installer = new $class($package, $this->composer, $this->getIO());
152 return $installer->getInstallPath($package, $frameworkType);
155 public function uninstall(InstalledRepositoryInterface $repo, PackageInterface $package)
157 parent::uninstall($repo, $package);
158 $installPath = $this->getPackageBasePath($package);
159 $this->io->write(sprintf('Deleting %s - %s', $installPath, !file_exists($installPath) ? '<comment>deleted</comment>' : '<error>not deleted</error>'));
165 public function supports($packageType)
167 $frameworkType = $this->findFrameworkType($packageType);
169 if ($frameworkType === false) {
173 $locationPattern = $this->getLocationPattern($frameworkType);
175 return preg_match('#' . $frameworkType . '-' . $locationPattern . '#', $packageType, $matches) === 1;
179 * Finds a supported framework type if it exists and returns it
181 * @param string $type
184 protected function findFrameworkType($type)
186 $frameworkType = false;
188 krsort($this->supportedTypes);
190 foreach ($this->supportedTypes as $key => $val) {
191 if ($key === substr($type, 0, strlen($key))) {
192 $frameworkType = substr($type, 0, strlen($key));
197 return $frameworkType;
201 * Get the second part of the regular expression to check for support of a
204 * @param string $frameworkType
207 protected function getLocationPattern($frameworkType)
210 if (!empty($this->supportedTypes[$frameworkType])) {
211 $frameworkClass = 'Composer\\Installers\\' . $this->supportedTypes[$frameworkType];
212 /** @var BaseInstaller $framework */
213 $framework = new $frameworkClass(null, $this->composer, $this->getIO());
214 $locations = array_keys($framework->getLocations());
215 $pattern = $locations ? '(' . implode('|', $locations) . ')' : false;
218 return $pattern ? : '(\w+)';
224 * @return IOInterface
226 private function getIO()
232 * Look for installers set to be disabled in composer's extra config and
233 * remove them from the list of supported installers.
236 * - true, "all", and "*" - disable all installers.
237 * - false - enable all installers (useful with
238 * wikimedia/composer-merge-plugin or similar)
242 protected function removeDisabledInstallers()
244 $extra = $this->composer->getPackage()->getExtra();
246 if (!isset($extra['installer-disable']) || $extra['installer-disable'] === false) {
247 // No installers are disabled
251 // Get installers to disable
252 $disable = $extra['installer-disable'];
254 // Ensure $disabled is an array
255 if (!is_array($disable)) {
256 $disable = array($disable);
259 // Check which installers should be disabled
260 $all = array(true, "all", "*");
261 $intersect = array_intersect($all, $disable);
262 if (!empty($intersect)) {
263 // Disable all installers
264 $this->supportedTypes = array();
266 // Disable specified installers
267 foreach ($disable as $key => $installer) {
268 if (is_string($installer) && key_exists($installer, $this->supportedTypes)) {
269 unset($this->supportedTypes[$installer]);