3 namespace Drupal\migrate\Plugin\Discovery;
5 use Drupal\Component\Plugin\Discovery\DiscoveryInterface;
6 use Drupal\Component\Plugin\Discovery\DiscoveryTrait;
9 * Remove plugin definitions with non-existing providers.
12 * This is a temporary solution to the fact that migration source plugins have
13 * more than one provider. This functionality will be moved to core in
14 * https://www.drupal.org/node/2786355.
16 class ProviderFilterDecorator implements DiscoveryInterface {
21 * The Discovery object being decorated.
23 * @var \Drupal\Component\Plugin\Discovery\DiscoveryInterface
28 * A callable for testing if a provider exists.
32 protected $providerExists;
35 * Constructs a InheritProviderDecorator object.
37 * @param \Drupal\Component\Plugin\Discovery\DiscoveryInterface $decorated
38 * The object implementing DiscoveryInterface that is being decorated.
39 * @param callable $provider_exists
40 * A callable, gets passed a provider name, should return TRUE if the
41 * provider exists and FALSE if not.
43 public function __construct(DiscoveryInterface $decorated, callable $provider_exists) {
44 $this->decorated = $decorated;
45 $this->providerExists = $provider_exists;
49 * Removes plugin definitions with non-existing providers.
51 * @param mixed[] $definitions
52 * An array of plugin definitions (empty array if no definitions were
53 * found). Keys are plugin IDs.
54 * @param callable $provider_exists
55 * A callable, gets passed a provider name, should return TRUE if the
56 * provider exists and FALSE if not.
58 * @return array|\mixed[]
59 * An array of plugin definitions. If a definition is an array and has a
60 * provider key that provider is guaranteed to exist.
62 public static function filterDefinitions(array $definitions, callable $provider_exists) {
63 // Besides what the caller accepts, we also accept core or component.
64 $provider_exists = function ($provider) use ($provider_exists) {
65 return in_array($provider, ['core', 'component']) || $provider_exists($provider);
67 return array_filter($definitions, function ($definition) use ($provider_exists) {
68 // Plugin definitions can be objects (for example, Typed Data) those will
69 // become empty array here and cause no problems.
70 $definition = (array) $definition + ['provider' => []];
71 // There can be one or many providers, handle them as multiple always.
72 $providers = (array) $definition['provider'];
73 return count($providers) == count(array_filter($providers, $provider_exists));
80 public function getDefinitions() {
81 return static::filterDefinitions($this->decorated->getDefinitions(), $this->providerExists);
85 * Passes through all unknown calls onto the decorated object.
87 * @param string $method
88 * The method to call on the decorated object.
93 * The return value from the method on the decorated object.
95 public function __call($method, array $args) {
96 return call_user_func_array([$this->decorated, $method], $args);