1<?php 2/** 3 * This file is part of the FreeDSx LDAP package. 4 * 5 * (c) Chad Sikorra <Chad.Sikorra@gmail.com> 6 * 7 * For the full copyright and license information, please view the LICENSE 8 * file that was distributed with this source code. 9 */ 10 11namespace FreeDSx\Ldap\Protocol\Factory; 12 13use FreeDSx\Asn1\Type\AbstractType; 14use FreeDSx\Ldap\Exception\InvalidArgumentException; 15use FreeDSx\Ldap\Exception\ProtocolException; 16use FreeDSx\Ldap\Exception\RuntimeException; 17use FreeDSx\Ldap\Search\Filter\AndFilter; 18use FreeDSx\Ldap\Search\Filter\ApproximateFilter; 19use FreeDSx\Ldap\Search\Filter\EqualityFilter; 20use FreeDSx\Ldap\Search\Filter\FilterInterface; 21use FreeDSx\Ldap\Search\Filter\GreaterThanOrEqualFilter; 22use FreeDSx\Ldap\Search\Filter\LessThanOrEqualFilter; 23use FreeDSx\Ldap\Search\Filter\MatchingRuleFilter; 24use FreeDSx\Ldap\Search\Filter\NotFilter; 25use FreeDSx\Ldap\Search\Filter\OrFilter; 26use FreeDSx\Ldap\Search\Filter\PresentFilter; 27use FreeDSx\Ldap\Search\Filter\SubstringFilter; 28 29/** 30 * Get the filter object from a specific ASN1 tag type. 31 * 32 * @author Chad Sikorra <Chad.Sikorra@gmail.com> 33 */ 34class FilterFactory 35{ 36 /** 37 * @var array 38 */ 39 protected static $map = [ 40 0 => AndFilter::class, 41 1 => OrFilter::class, 42 2 => NotFilter::class, 43 3 => EqualityFilter::class, 44 4 => SubstringFilter::class, 45 5 => GreaterThanOrEqualFilter::class, 46 6 => LessThanOrEqualFilter::class, 47 7 => PresentFilter::class, 48 8 => ApproximateFilter::class, 49 9 => MatchingRuleFilter::class, 50 ]; 51 52 /** 53 * @throws ProtocolException 54 */ 55 public static function get(AbstractType $type): FilterInterface 56 { 57 $filterClass = self::$map[$type->getTagNumber()] ?? null; 58 if ($filterClass === null) { 59 throw new ProtocolException(sprintf( 60 'The received filter "%s" is not recognized.', 61 $type->getTagNumber() 62 )); 63 } 64 $filterConstruct = $filterClass . '::fromAsn1'; 65 if (!is_callable($filterConstruct)) { 66 throw new RuntimeException(sprintf( 67 'The filter construct is not callable: %s', 68 $filterConstruct 69 )); 70 } 71 72 return call_user_func($filterConstruct, $type); 73 } 74 75 /** 76 * @param int $filterType 77 * @return bool 78 */ 79 public static function has(int $filterType): bool 80 { 81 return isset(self::$map[$filterType]); 82 } 83 84 /** 85 * @param int $filterType 86 * @param string $filterClass 87 */ 88 public static function set(int $filterType, string $filterClass): void 89 { 90 if (!class_exists($filterClass)) { 91 throw new InvalidArgumentException(sprintf('The filter class does not exist: %s', $filterClass)); 92 } 93 if (!is_subclass_of($filterClass, FilterInterface::class)) { 94 throw new InvalidArgumentException(sprintf('The filter class must implement FilterInterface: %s', $filterClass)); 95 } 96 97 self::$map[$filterType] = $filterClass; 98 } 99} 100