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\Exception\OperationException;
16use FreeDSx\Ldap\Exception\ProtocolException;
17use FreeDSx\Ldap\Exception\RuntimeException;
18use FreeDSx\Ldap\Exception\UnsolicitedNotificationException;
19use FreeDSx\Ldap\Operation\Request\ExtendedRequest;
20use FreeDSx\Ldap\Protocol\Factory\ExtendedResponseFactory;
21use FreeDSx\Ldap\Protocol\LdapMessageResponse;
22use FreeDSx\Socket\Exception\ConnectionException;
23use ReflectionClass;
24use ReflectionException;
25
26/**
27 * Logic for handling extended operations.
28 *
29 * @author Chad Sikorra <Chad.Sikorra@gmail.com>
30 */
31class ClientExtendedOperationHandler extends ClientBasicHandler
32{
33    /**
34     * @var ExtendedResponseFactory
35     */
36    protected $extendedResponseFactory;
37
38    public function __construct(ExtendedResponseFactory $extendedResponseFactory = null)
39    {
40        $this->extendedResponseFactory = $extendedResponseFactory ?? new ExtendedResponseFactory();
41    }
42
43    /**
44     * @param ClientProtocolContext $context
45     * @return LdapMessageResponse|null
46     * @throws OperationException
47     * @throws EncoderException
48     * @throws ProtocolException
49     * @throws UnsolicitedNotificationException
50     * @throws ConnectionException
51     * @throws ReflectionException
52     * @throws RuntimeException
53     */
54    public function handleRequest(ClientProtocolContext $context): ?LdapMessageResponse
55    {
56        $messageFrom = parent::handleRequest($context);
57
58        /** @var ExtendedRequest $request */
59        $request = $context->getRequest();
60        if (!$this->extendedResponseFactory->has($request->getName())) {
61            return $messageFrom;
62        }
63        if ($messageFrom === null) {
64            throw new OperationException('Expected an LDAP message response, but none was received.');
65        }
66
67        $response = $this->extendedResponseFactory->get(
68            $messageFrom->getResponse()->toAsn1(),
69            $request->getName()
70        );
71        $prop = (new ReflectionClass(LdapMessageResponse::class))->getProperty('response');
72        $prop->setAccessible(true);
73        $prop->setValue($messageFrom, $response);
74
75        return $messageFrom;
76    }
77}
78