1<?php 2 3/* 4 * This file is part of the Fxp Composer Asset Plugin package. 5 * 6 * (c) François Pluchino <francois.pluchino@gmail.com> 7 * 8 * For the full copyright and license information, please view the LICENSE 9 * file that was distributed with this source code. 10 */ 11 12namespace Fxp\Composer\AssetPlugin\Repository; 13 14use Composer\DependencyResolver\Pool; 15use Composer\IO\IOInterface; 16use Composer\Repository\RepositoryInterface; 17use Composer\Repository\RepositoryManager; 18use Fxp\Composer\AssetPlugin\Config\Config; 19 20/** 21 * The asset repository manager. 22 * 23 * @author François Pluchino <francois.pluchino@gmail.com> 24 */ 25class AssetRepositoryManager 26{ 27 /** 28 * @var IOInterface 29 */ 30 protected $io; 31 32 /** 33 * @var RepositoryManager 34 */ 35 protected $rm; 36 37 /** 38 * @var Config 39 */ 40 protected $config; 41 42 /** 43 * @var VcsPackageFilter 44 */ 45 protected $packageFilter; 46 47 /** 48 * @var null|Pool 49 */ 50 protected $pool; 51 52 /** 53 * @var ResolutionManager 54 */ 55 protected $resolutionManager; 56 57 /** 58 * @var RepositoryInterface[] 59 */ 60 protected $repositories = array(); 61 62 /** 63 * @var array 64 */ 65 protected $poolRepositories = array(); 66 67 /** 68 * Constructor. 69 * 70 * @param IOInterface $io The IO 71 * @param RepositoryManager $rm The repository manager 72 * @param Config $config The asset config 73 * @param VcsPackageFilter $packageFilter The package filter 74 */ 75 public function __construct(IOInterface $io, RepositoryManager $rm, Config $config, VcsPackageFilter $packageFilter) 76 { 77 $this->io = $io; 78 $this->rm = $rm; 79 $this->config = $config; 80 $this->packageFilter = $packageFilter; 81 } 82 83 /** 84 * Get the repository manager. 85 * 86 * @return RepositoryManager 87 */ 88 public function getRepositoryManager() 89 { 90 return $this->rm; 91 } 92 93 /** 94 * Get the asset config. 95 * 96 * @return Config 97 */ 98 public function getConfig() 99 { 100 return $this->config; 101 } 102 103 /** 104 * Set the pool. 105 * 106 * @param Pool $pool The pool 107 * 108 * @return self 109 */ 110 public function setPool(Pool $pool) 111 { 112 $this->pool = $pool; 113 114 foreach ($this->poolRepositories as $repo) { 115 $pool->addRepository($repo); 116 } 117 118 $this->poolRepositories = array(); 119 120 return $this; 121 } 122 123 /** 124 * Set the dependency resolution manager. 125 * 126 * @param ResolutionManager $resolutionManager The dependency resolution manager 127 */ 128 public function setResolutionManager(ResolutionManager $resolutionManager) 129 { 130 $this->resolutionManager = $resolutionManager; 131 } 132 133 /** 134 * Solve the dependency resolutions. 135 * 136 * @param array $data 137 * 138 * @return array 139 */ 140 public function solveResolutions(array $data) 141 { 142 return null !== $this->resolutionManager 143 ? $this->resolutionManager->solveResolutions($data) 144 : $data; 145 } 146 147 /** 148 * Adds asset vcs repositories. 149 * 150 * @param array $repositories The repositories 151 * 152 * @throws \UnexpectedValueException When config of repository is not an array 153 * @throws \UnexpectedValueException When the config of repository has not a type defined 154 * @throws \UnexpectedValueException When the config of repository has an invalid type 155 */ 156 public function addRepositories(array $repositories) 157 { 158 foreach ($repositories as $index => $repo) { 159 $this->validateRepositories($index, $repo); 160 161 if ('package' === $repo['type']) { 162 $name = $repo['package']['name']; 163 } else { 164 $name = \is_int($index) ? preg_replace('{^https?://}i', '', $repo['url']) : $index; 165 $name = isset($repo['name']) ? $repo['name'] : $name; 166 $repo['asset-repository-manager'] = $this; 167 $repo['vcs-package-filter'] = $this->packageFilter; 168 } 169 170 $repoInstance = Util::addRepository($this->io, $this->rm, $this->repositories, $name, $repo, $this->pool); 171 172 if (null === $this->pool && $repoInstance instanceof RepositoryInterface) { 173 $this->poolRepositories[] = $repoInstance; 174 } 175 } 176 } 177 178 /** 179 * Validates the config of repositories. 180 * 181 * @param int|string $index The index 182 * @param array|mixed $repo The config repo 183 * 184 * @throws \UnexpectedValueException 185 */ 186 protected function validateRepositories($index, $repo) 187 { 188 if (!\is_array($repo)) { 189 throw new \UnexpectedValueException('Repository '.$index.' ('.json_encode($repo).') should be an array, '.\gettype($repo).' given'); 190 } 191 if (!isset($repo['type'])) { 192 throw new \UnexpectedValueException('Repository '.$index.' ('.json_encode($repo).') must have a type defined'); 193 } 194 195 $this->validatePackageRepositories($index, $repo); 196 $this->validateVcsRepositories($index, $repo); 197 } 198 199 /** 200 * Validates the config of package repositories. 201 * 202 * @param int|string $index The index 203 * @param array|mixed $repo The config repo 204 * 205 * @throws \UnexpectedValueException 206 */ 207 protected function validatePackageRepositories($index, $repo) 208 { 209 if ('package' !== $repo['type']) { 210 return; 211 } 212 213 if (!isset($repo['package'])) { 214 throw new \UnexpectedValueException('Repository '.$index.' ('.json_encode($repo).') must have a package definition"'); 215 } 216 217 foreach (array('name', 'type', 'version', 'dist') as $key) { 218 if (!isset($repo['package'][$key])) { 219 throw new \UnexpectedValueException('Repository '.$index.' ('.json_encode($repo).') must have the "'.$key.'" key in the package definition"'); 220 } 221 } 222 } 223 224 /** 225 * Validates the config of vcs repositories. 226 * 227 * @param int|string $index The index 228 * @param array|mixed $repo The config repo 229 * 230 * @throws \UnexpectedValueException 231 */ 232 protected function validateVcsRepositories($index, $repo) 233 { 234 if ('package' === $repo['type']) { 235 return; 236 } 237 238 if (false === strpos($repo['type'], '-')) { 239 throw new \UnexpectedValueException('Repository '.$index.' ('.json_encode($repo).') must have a type defined in this way: "%asset-type%-%type%"'); 240 } 241 if (!isset($repo['url'])) { 242 throw new \UnexpectedValueException('Repository '.$index.' ('.json_encode($repo).') must have a url defined'); 243 } 244 } 245} 246