Current File : //usr/share/php/Composer/Repository/FilterRepository.php |
<?php declare(strict_types=1);
/*
* This file is part of Composer.
*
* (c) Nils Adermann <naderman@naderman.de>
* Jordi Boggiano <j.boggiano@seld.be>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Composer\Repository;
use Composer\Package\PackageInterface;
use Composer\Package\BasePackage;
use Composer\Pcre\Preg;
/**
* Filters which packages are seen as canonical on this repo by loadPackages
*
* @author Jordi Boggiano <j.boggiano@seld.be>
*/
class FilterRepository implements RepositoryInterface, AdvisoryProviderInterface
{
/** @var ?string */
private $only = null;
/** @var ?non-empty-string */
private $exclude = null;
/** @var bool */
private $canonical = true;
/** @var RepositoryInterface */
private $repo;
/**
* @param array{only?: array<string>, exclude?: array<string>, canonical?: bool} $options
*/
public function __construct(RepositoryInterface $repo, array $options)
{
if (isset($options['only'])) {
if (!is_array($options['only'])) {
throw new \InvalidArgumentException('"only" key for repository '.$repo->getRepoName().' should be an array');
}
$this->only = BasePackage::packageNamesToRegexp($options['only']);
}
if (isset($options['exclude'])) {
if (!is_array($options['exclude'])) {
throw new \InvalidArgumentException('"exclude" key for repository '.$repo->getRepoName().' should be an array');
}
$this->exclude = BasePackage::packageNamesToRegexp($options['exclude']);
}
if ($this->exclude && $this->only) {
throw new \InvalidArgumentException('Only one of "only" and "exclude" can be specified for repository '.$repo->getRepoName());
}
if (isset($options['canonical'])) {
if (!is_bool($options['canonical'])) {
throw new \InvalidArgumentException('"canonical" key for repository '.$repo->getRepoName().' should be a boolean');
}
$this->canonical = $options['canonical'];
}
$this->repo = $repo;
}
public function getRepoName(): string
{
return $this->repo->getRepoName();
}
/**
* Returns the wrapped repositories
*/
public function getRepository(): RepositoryInterface
{
return $this->repo;
}
/**
* @inheritDoc
*/
public function hasPackage(PackageInterface $package): bool
{
return $this->repo->hasPackage($package);
}
/**
* @inheritDoc
*/
public function findPackage($name, $constraint): ?BasePackage
{
if (!$this->isAllowed($name)) {
return null;
}
return $this->repo->findPackage($name, $constraint);
}
/**
* @inheritDoc
*/
public function findPackages($name, $constraint = null): array
{
if (!$this->isAllowed($name)) {
return [];
}
return $this->repo->findPackages($name, $constraint);
}
/**
* @inheritDoc
*/
public function loadPackages(array $packageNameMap, array $acceptableStabilities, array $stabilityFlags, array $alreadyLoaded = []): array
{
foreach ($packageNameMap as $name => $constraint) {
if (!$this->isAllowed($name)) {
unset($packageNameMap[$name]);
}
}
if (!$packageNameMap) {
return ['namesFound' => [], 'packages' => []];
}
$result = $this->repo->loadPackages($packageNameMap, $acceptableStabilities, $stabilityFlags, $alreadyLoaded);
if (!$this->canonical) {
$result['namesFound'] = [];
}
return $result;
}
/**
* @inheritDoc
*/
public function search(string $query, int $mode = 0, ?string $type = null): array
{
$result = [];
foreach ($this->repo->search($query, $mode, $type) as $package) {
if ($this->isAllowed($package['name'])) {
$result[] = $package;
}
}
return $result;
}
/**
* @inheritDoc
*/
public function getPackages(): array
{
$result = [];
foreach ($this->repo->getPackages() as $package) {
if ($this->isAllowed($package->getName())) {
$result[] = $package;
}
}
return $result;
}
/**
* @inheritDoc
*/
public function getProviders($packageName): array
{
$result = [];
foreach ($this->repo->getProviders($packageName) as $name => $provider) {
if ($this->isAllowed($provider['name'])) {
$result[$name] = $provider;
}
}
return $result;
}
/**
* @inheritDoc
*/
public function count(): int
{
if ($this->repo->count() > 0) {
return count($this->getPackages());
}
return 0;
}
public function hasSecurityAdvisories(): bool
{
if (!$this->repo instanceof AdvisoryProviderInterface) {
return false;
}
return $this->repo->hasSecurityAdvisories();
}
/**
* @inheritDoc
*/
public function getSecurityAdvisories(array $packageConstraintMap, bool $allowPartialAdvisories = false): array
{
if (!$this->repo instanceof AdvisoryProviderInterface) {
return ['namesFound' => [], 'advisories' => []];
}
foreach ($packageConstraintMap as $name => $constraint) {
if (!$this->isAllowed($name)) {
unset($packageConstraintMap[$name]);
}
}
return $this->repo->getSecurityAdvisories($packageConstraintMap, $allowPartialAdvisories);
}
private function isAllowed(string $name): bool
{
if (!$this->only && !$this->exclude) {
return true;
}
if ($this->only) {
return Preg::isMatch($this->only, $name);
}
if ($this->exclude === null) {
return true;
}
return !Preg::isMatch($this->exclude, $name);
}
}