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