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