1<?php 2 3/** 4 * This file is part of the FreeDSx LDAP package. 5 * 6 * (c) Chad Sikorra <Chad.Sikorra@gmail.com> 7 * 8 * For the full copyright and license information, please view the LICENSE 9 * file that was distributed with this source code. 10 */ 11 12namespace FreeDSx\Ldap\Protocol\Factory; 13 14use FreeDSx\Asn1\Type\AbstractType; 15use FreeDSx\Ldap\Exception\InvalidArgumentException; 16use FreeDSx\Ldap\Exception\ProtocolException; 17use FreeDSx\Ldap\Exception\RuntimeException; 18use FreeDSx\Ldap\Operation\Request\ExtendedRequest; 19use FreeDSx\Ldap\Operation\Response\ExtendedResponse; 20use FreeDSx\Ldap\Operation\Response\PasswordModifyResponse; 21 22/** 23 * Used to instantiate specific extended response OIDs. 24 * 25 * @author Chad Sikorra <Chad.Sikorra@gmail.com> 26 */ 27class ExtendedResponseFactory 28{ 29 /** 30 * @var string[] 31 */ 32 protected static $map = [ 33 ExtendedRequest::OID_PWD_MODIFY => PasswordModifyResponse::class, 34 ]; 35 36 /** 37 * Retrieve the Request Response/Request class given a protocol number and the ASN1. 38 * 39 * @param AbstractType $asn1 40 * @param string $oid 41 * @return ExtendedResponse 42 * @throws ProtocolException 43 * @throws RuntimeException 44 */ 45 public function get(AbstractType $asn1, string $oid): ExtendedResponse 46 { 47 if (!self::has($oid)) { 48 throw new ProtocolException(sprintf( 49 'There is no extended response mapped for %s.', 50 $oid 51 )); 52 } 53 $responseConstruct = self::$map[$oid] . '::fromAsn1'; 54 if (!is_callable($responseConstruct)) { 55 throw new RuntimeException(sprintf( 56 'The extended response construct is not callable: %s', 57 $responseConstruct 58 )); 59 } 60 61 return call_user_func($responseConstruct, $asn1); 62 } 63 64 /** 65 * Check whether a specific control OID is mapped to a class. 66 * 67 * @param string $oid 68 * @return bool 69 */ 70 public function has(string $oid) 71 { 72 return isset(self::$map[$oid]); 73 } 74 75 /** 76 * Set a specific class for an operation. It must implement ProtocolElementInterface. 77 * 78 * @throws InvalidArgumentException 79 */ 80 public static function set(string $oid, string $className): void 81 { 82 if (!class_exists($className)) { 83 throw new InvalidArgumentException(sprintf( 84 'The class for the extended response %s does not exist: %s', 85 $oid, 86 $className 87 )); 88 } 89 if (!is_subclass_of($className, ExtendedResponse::class)) { 90 throw new InvalidArgumentException(sprintf( 91 'The class must extend the ExtendedResponse, but it does not: %s', 92 $className 93 )); 94 } 95 self::$map[$oid] = $className; 96 } 97} 98