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\Operation\Request\ExtendedRequest; 18use FreeDSx\Ldap\Operation\Response\ExtendedResponse; 19use FreeDSx\Ldap\Operation\Response\PasswordModifyResponse; 20 21/** 22 * Used to instantiate specific extended response OIDs. 23 * 24 * @author Chad Sikorra <Chad.Sikorra@gmail.com> 25 */ 26class ExtendedResponseFactory 27{ 28 /** 29 * @var string[] 30 */ 31 protected static $map = [ 32 ExtendedRequest::OID_PWD_MODIFY => PasswordModifyResponse::class, 33 ]; 34 35 /** 36 * Retrieve the Request Response/Request class given a protocol number and the ASN1. 37 * 38 * @param AbstractType $asn1 39 * @param string $oid 40 * @return ExtendedResponse 41 * @throws ProtocolException 42 */ 43 public function get(AbstractType $asn1, string $oid): ExtendedResponse 44 { 45 if (!self::has($oid)) { 46 throw new ProtocolException(sprintf( 47 'There is no extended response mapped for %s.', 48 $oid 49 )); 50 } 51 $responseConstruct = self::$map[$oid] . '::fromAsn1'; 52 if (!is_callable($responseConstruct)) { 53 throw new RuntimeException(sprintf( 54 'The extended response construct is not callable: %s', 55 $responseConstruct 56 )); 57 } 58 59 return call_user_func($responseConstruct, $asn1); 60 } 61 62 /** 63 * Check whether a specific control OID is mapped to a class. 64 * 65 * @param string $oid 66 * @return bool 67 */ 68 public function has(string $oid) 69 { 70 return isset(self::$map[$oid]); 71 } 72 73 /** 74 * Set a specific class for an operation. It must implement ProtocolElementInterface. 75 */ 76 public static function set(string $oid, string $className): void 77 { 78 if (!class_exists($className)) { 79 throw new InvalidArgumentException(sprintf( 80 'The class for the extended response %s does not exist: %s', 81 $oid, 82 $className 83 )); 84 } 85 if (!is_subclass_of($className, ExtendedResponse::class)) { 86 throw new InvalidArgumentException(sprintf( 87 'The class must extend the ExtendedResponse, but it does not: %s', 88 $className 89 )); 90 } 91 self::$map[$oid] = $className; 92 } 93} 94