strategies[$name])) { return $this->strategies[$name]; } if ( $this->hasNamingStrategy() && ($hydrated = $this->getNamingStrategy()->hydrate($name)) && isset($this->strategies[$hydrated]) ) { return $this->strategies[$hydrated]; } if (! isset($this->strategies['*'])) { throw new Exception\InvalidArgumentException(sprintf( '%s: no strategy by name of "%s", and no wildcard strategy present', __METHOD__, $name )); } return $this->strategies['*']; } /** * Checks if the strategy with the given name exists. * * @param string $name The name of the strategy to check for. */ public function hasStrategy(string $name): bool { if (isset($this->strategies[$name])) { return true; } if ( $this->hasNamingStrategy() && isset($this->strategies[$this->getNamingStrategy()->hydrate($name)]) ) { return true; } return isset($this->strategies['*']); } /** * Adds the given strategy under the given name. * * @param string $name The name of the strategy to register. * @param Strategy\StrategyInterface $strategy The strategy to register. */ public function addStrategy(string $name, Strategy\StrategyInterface $strategy): void { $this->strategies[$name] = $strategy; } /** * Removes the strategy with the given name. * * @param string $name The name of the strategy to remove. */ public function removeStrategy(string $name): void { unset($this->strategies[$name]); } /** * Converts a value for extraction. If no strategy exists the plain value is returned. * * @param string $name The name of the strategy to use. * @param mixed $value The value that should be converted. * @param null|object $object The object is optionally provided as context. * @return mixed */ public function extractValue(string $name, mixed $value, ?object $object = null) { return $this->hasStrategy($name) ? $this->getStrategy($name)->extract($value, $object) : $value; } /** * Converts a value for hydration. If no strategy exists the plain value is returned. * * @param string $name The name of the strategy to use. * @param mixed $value The value that should be converted. * @param null|array $data The whole data is optionally provided as context. * @return mixed */ public function hydrateValue(string $name, mixed $value, ?array $data = null) { return $this->hasStrategy($name) ? $this->getStrategy($name)->hydrate($value, $data) : $value; } /** * Convert a name for extraction. If no naming strategy exists, the plain value is returned. * * @param string $name The name to convert. * @param null|object $object The object is optionally provided as context. * @return string */ public function extractName(string $name, ?object $object = null) { return $this->hasNamingStrategy() ? $this->getNamingStrategy()->extract($name, $object) : $name; } /** * Converts a value for hydration. If no naming strategy exists, the plain value is returned. * * @param string $name The name to convert. * @param null|mixed[] $data The whole data is optionally provided as context. */ public function hydrateName(string $name, ?array $data = null): string { return $this->hasNamingStrategy() ? $this->getNamingStrategy()->hydrate($name, $data) : $name; } /** * Get the filter instance */ public function getFilter(): Filter\FilterInterface { return $this->getCompositeFilter(); } /** * Add a new filter to take care of what needs to be hydrated. * To exclude e.g. the method getServiceLocator: * * * $composite->addFilter("servicelocator", * function ($property) { * list($class, $method) = explode('::', $property); * if ($method === 'getServiceLocator') { * return false; * } * return true; * }, FilterComposite::CONDITION_AND * ); * * * @param string $name Index in the composite * @param callable|Filter\FilterInterface $filter */ public function addFilter(string $name, $filter, int $condition = Filter\FilterComposite::CONDITION_OR): void { $this->getCompositeFilter()->addFilter($name, $filter, $condition); } /** * Check whether a specific filter exists at key $name or not * * @param string $name Index/name in the composite */ public function hasFilter(string $name): bool { return $this->getCompositeFilter()->hasFilter($name); } /** * Remove a filter from the composition. * * To not extract "has" methods, unregister the filter. * * * $filterComposite->removeFilter('has'); * */ public function removeFilter(string $name): void { $this->getCompositeFilter()->removeFilter($name); } /** * Adds the given naming strategy * * @param NamingStrategy\NamingStrategyInterface $strategy The naming to register. */ public function setNamingStrategy(NamingStrategy\NamingStrategyInterface $strategy): void { $this->namingStrategy = $strategy; } /** * Gets the naming strategy. * * If no naming strategy is registered, registers the * `IdentityNamingStrategy`, which acts essentially as a no-op. * * {@inheritDoc} */ public function getNamingStrategy(): NamingStrategy\NamingStrategyInterface { if (null === $this->namingStrategy) { $this->namingStrategy = new NamingStrategy\IdentityNamingStrategy(); } return $this->namingStrategy; } /** * Checks if a naming strategy exists. */ public function hasNamingStrategy(): bool { return isset($this->namingStrategy); } /** * Removes the naming strategy */ public function removeNamingStrategy(): void { $this->namingStrategy = null; } /** * Lazy-load the composite filter instance. * * If no instance is yet registerd for the $filterComposite property, this * method will lazy load one. * * @throws Exception\DomainException If composed $filterComposite is not a * Filter\FilterComposite instance, nor null. */ protected function getCompositeFilter(): Filter\FilterComposite { if (! $this->filterComposite) { $this->filterComposite = new Filter\FilterComposite(); } return $this->filterComposite; } }