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\Search\Filter;
12
13use FreeDSx\Asn1\Asn1;
14use FreeDSx\Asn1\Type\AbstractType;
15use FreeDSx\Asn1\Type\IncompleteType;
16use FreeDSx\Asn1\Type\SequenceType;
17use FreeDSx\Ldap\Exception\ProtocolException;
18use FreeDSx\Ldap\Protocol\Factory\FilterFactory;
19use FreeDSx\Ldap\Protocol\LdapEncoder;
20
21/**
22 * Represents the negation of a filter. RFC 4511, 4.5.1
23 *
24 * @author Chad Sikorra <Chad.Sikorra@gmail.com>
25 */
26class NotFilter implements FilterInterface
27{
28    protected const CHOICE_TAG = 2;
29
30    /**
31     * @var FilterInterface
32     */
33    protected $filter;
34
35    /**
36     * @param FilterInterface $filter
37     */
38    public function __construct(FilterInterface $filter)
39    {
40        $this->filter = $filter;
41    }
42
43    /**
44     * @return FilterInterface
45     */
46    public function get(): FilterInterface
47    {
48        return $this->filter;
49    }
50
51    /**
52     * @param FilterInterface $filter
53     * @return $this
54     */
55    public function set(FilterInterface $filter)
56    {
57        $this->filter = $filter;
58
59        return $this;
60    }
61
62    /**
63     * {@inheritdoc}
64     */
65    public function toAsn1(): AbstractType
66    {
67        return Asn1::context(self::CHOICE_TAG, Asn1::sequence($this->filter->toAsn1()));
68    }
69
70    /**
71     * {@inheritdoc}
72     */
73    public function toString(): string
74    {
75        return self::PAREN_LEFT
76            . self::OPERATOR_NOT
77            . $this->filter->toString()
78            . self::PAREN_RIGHT;
79    }
80
81    /**
82     * @return string
83     */
84    public function __toString()
85    {
86        return $this->toString();
87    }
88
89    /**
90     * {@inheritdoc}
91     */
92    public static function fromAsn1(AbstractType $type)
93    {
94        $type = $type instanceof IncompleteType ? (new LdapEncoder())->complete($type, AbstractType::TAG_TYPE_SEQUENCE) : $type;
95        if (!($type instanceof SequenceType && count($type) === 1)) {
96            throw new ProtocolException('The not filter is malformed');
97        }
98        $child = $type->getChild(0);
99        if ($child === null) {
100            throw new ProtocolException('The "not" filter is malformed.');
101        }
102
103        return new self(FilterFactory::get($child));
104    }
105}
106