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\ClientProtocolHandler; 13 14use FreeDSx\Asn1\Exception\EncoderException; 15use FreeDSx\Ldap\Entry\Entries; 16use FreeDSx\Ldap\Exception\BindException; 17use FreeDSx\Ldap\Exception\OperationException; 18use FreeDSx\Ldap\Exception\ProtocolException; 19use FreeDSx\Ldap\Exception\UnsolicitedNotificationException; 20use FreeDSx\Ldap\Operation\LdapResult; 21use FreeDSx\Ldap\Operation\Request\SearchRequest; 22use FreeDSx\Ldap\Operation\Response\SearchResponse; 23use FreeDSx\Ldap\Operation\Response\SearchResultDone; 24use FreeDSx\Ldap\Operation\Response\SearchResultEntry; 25use FreeDSx\Ldap\Protocol\LdapMessageRequest; 26use FreeDSx\Ldap\Protocol\LdapMessageResponse; 27use FreeDSx\Ldap\Protocol\Queue\ClientQueue; 28use FreeDSx\Socket\Exception\ConnectionException; 29 30/** 31 * Logic for handling search operations. 32 * 33 * @author Chad Sikorra <Chad.Sikorra@gmail.com> 34 */ 35class ClientSearchHandler extends ClientBasicHandler 36{ 37 /** 38 * @param ClientProtocolContext $context 39 * @return LdapMessageResponse|null 40 * @throws EncoderException 41 * @throws ProtocolException 42 * @throws UnsolicitedNotificationException 43 * @throws ConnectionException 44 */ 45 public function handleRequest(ClientProtocolContext $context): ?LdapMessageResponse 46 { 47 /** @var SearchRequest $request */ 48 $request = $context->getRequest(); 49 if ($request->getBaseDn() === null) { 50 $request->setBaseDn($context->getOptions()['base_dn'] ?? null); 51 } 52 53 return parent::handleRequest($context); 54 } 55 56 /** 57 * @param LdapMessageRequest $messageTo 58 * @param LdapMessageResponse $messageFrom 59 * @param ClientQueue $queue 60 * @param array $options 61 * @return LdapMessageResponse|null 62 * @throws OperationException 63 * @throws BindException 64 * @throws ProtocolException 65 * @throws UnsolicitedNotificationException 66 * @throws ConnectionException 67 */ 68 public function handleResponse(LdapMessageRequest $messageTo, LdapMessageResponse $messageFrom, ClientQueue $queue, array $options): ?LdapMessageResponse 69 { 70 $entries = []; 71 72 while (!($messageFrom->getResponse() instanceof SearchResultDone)) { 73 $response = $messageFrom->getResponse(); 74 if ($response instanceof SearchResultEntry) { 75 $entry = $response->getEntry(); 76 $entries[] = $entry; 77 } 78 $messageFrom = $queue->getMessage($messageTo->getMessageId()); 79 } 80 81 $ldapResult = $messageFrom->getResponse(); 82 if (!$ldapResult instanceof LdapResult) { 83 throw new OperationException('The final search result is malformed.'); 84 } 85 86 $finalResponse = new LdapMessageResponse( 87 $messageFrom->getMessageId(), 88 new SearchResponse($ldapResult, new Entries(...$entries)), 89 ...$messageFrom->controls()->toArray() 90 ); 91 92 return parent::handleResponse($messageTo, $finalResponse, $queue, $options); 93 } 94} 95