/** * Create/De-cache a provider and return it * * @param string $providerId * @param array|ProviderConfigLike $config * @param bool $createIfNotFound If false and provider not already created, NULL is returned * * @throws \InvalidArgumentException * @return BaseProvider */ protected static function _createProvider($providerId, $config = null, $createIfNotFound = true) { list($_providerId, $_type, $_mapKey, $_generic) = static::_normalizeProviderId($providerId); $_cacheKey = $_mapKey . ($_generic ?: null); if (null === ($_provider = Option::get(static::$_providerCache, $_cacheKey))) { $_config = empty($config) ? array() : $config; // Get the class mapping... if (null === ($_map = Option::get(static::$_classMap, $_mapKey))) { if (null === ($_map = Option::get(static::$_classMap, $_providerId))) { throw new \InvalidArgumentException('The provider "' . $providerId . '" has no associated mapping. Cannot create.'); } } if (true !== $createIfNotFound && array() == $_config) { return null; } if (!empty($_config) && !$_config instanceof ProviderConfigLike && !is_array($_config) && !is_object($_config)) { throw new \InvalidArgumentException('The "$config" value specified must be null, an object, an array, or an instance of ProviderConfigLike.'); } // Get the base template and merge it into the configuration $_template = BaseProviderConfig::getTemplate($_providerId); // Check the endpoint maps... $_endpoints = Option::get($_config, 'endpoint_map', array()); Option::set($_config, 'endpoint_map', array_merge(Option::get($_template, 'endpoint_map', array()), $_endpoints)); /** @noinspection PhpIncludeInspection */ require $_map['path']; if (empty($_config)) { $_config = array(); } $_className = $_map['namespace'] . '\\' . $_map['class_name']; $_mirror = new \ReflectionClass($_className); // Fill the config with the store values if any if (null !== $_type) { Option::sins($_config, 'type', $_type); } // Load any stored configuration $_config = static::_mergeConfigFromStore($_providerId, $_config); // Instantiate! $_provider = $_mirror->newInstanceArgs(array($_providerId, $_config)); // Cache the current version... Option::set(static::$_providerCache, $_cacheKey, $_provider); } return $_provider; }