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\Control\Vlv; 12 13use FreeDSx\Asn1\Asn1; 14use FreeDSx\Asn1\Type\AbstractType; 15use FreeDSx\Asn1\Type\EnumeratedType; 16use FreeDSx\Asn1\Type\IntegerType; 17use FreeDSx\Asn1\Type\OctetStringType; 18use FreeDSx\Asn1\Type\SequenceType; 19use FreeDSx\Ldap\Control\Control; 20use FreeDSx\Ldap\Exception\ProtocolException; 21 22/** 23 * Represents a VLV Response. draft-ietf-ldapext-ldapv3-vlv-09 24 * 25 * VirtualListViewResponse ::= SEQUENCE { 26 * targetPosition INTEGER (0 .. maxInt), 27 * contentCount INTEGER (0 .. maxInt), 28 * virtualListViewResult ENUMERATED { 29 * success (0), 30 * operationsError (1), 31 * protocolError (3), 32 * unwillingToPerform (53), 33 * insufficientAccessRights (50), 34 * timeLimitExceeded (3), 35 * adminLimitExceeded (11), 36 * innapropriateMatching (18), 37 * sortControlMissing (60), 38 * offsetRangeError (61), 39 * other(80), 40 * ... }, 41 * contextID OCTET STRING OPTIONAL } 42 * 43 * @author Chad Sikorra <Chad.Sikorra@gmail.com> 44 */ 45class VlvResponseControl extends Control 46{ 47 use VlvTrait; 48 49 /** 50 * @var int 51 */ 52 protected $result; 53 54 /** 55 * @param int $offset 56 * @param int $count 57 * @param int $result 58 * @param null|string $contextId 59 */ 60 public function __construct(int $offset, int $count, int $result, ?string $contextId = null) 61 { 62 $this->offset = $offset; 63 $this->count = $count; 64 $this->result = $result; 65 $this->contextId = $contextId; 66 parent::__construct(self::OID_VLV_RESPONSE); 67 } 68 69 /** 70 * @return int 71 */ 72 public function getResult(): int 73 { 74 return $this->result; 75 } 76 77 /** 78 * {@inheritdoc} 79 */ 80 public static function fromAsn1(AbstractType $type) 81 { 82 $vlv = self::decodeEncodedValue($type); 83 84 if (!$vlv instanceof SequenceType) { 85 throw new ProtocolException('The VLV response value contains an unexpected ASN1 type.'); 86 } 87 $offset = $vlv->getChild(0); 88 $count = $vlv->getChild(1); 89 $result = $vlv->getChild(2); 90 $contextId = $vlv->getChild(3); 91 92 if (!$offset instanceof IntegerType) { 93 throw new ProtocolException('The VLV response value contains an unexpected ASN1 type.'); 94 } 95 if (!$count instanceof IntegerType) { 96 throw new ProtocolException('The VLV response value contains an unexpected ASN1 type.'); 97 } 98 if (!$result instanceof EnumeratedType) { 99 throw new ProtocolException('The VLV response value contains an unexpected ASN1 type.'); 100 } 101 if ($contextId !== null && !$contextId instanceof OctetStringType) { 102 throw new ProtocolException('The VLV response value contains an unexpected ASN1 type.'); 103 } 104 105 $response = new self( 106 $offset->getValue(), 107 $count->getValue(), 108 $result->getValue() 109 ); 110 if ($contextId !== null) { 111 $response->contextId = $contextId->getValue(); 112 } 113 114 return parent::mergeControlData($response, $type); 115 } 116 117 /** 118 * {@inheritdoc} 119 */ 120 public function toAsn1(): AbstractType 121 { 122 $this->controlValue = Asn1::sequence( 123 Asn1::integer((int) $this->offset), 124 Asn1::integer((int) $this->count), 125 Asn1::enumerated($this->result) 126 ); 127 if ($this->contextId !== null) { 128 $this->controlValue->addChild(new OctetStringType($this->contextId)); 129 } 130 131 return parent::toAsn1(); 132 } 133} 134