Completed
Push — feature/improve-form-definitio... ( 8ffff6...a3c595 )
by Romain
03:04
created

ConditionFactory::instantiateCondition()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 15
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 15
rs 9.4285
c 0
b 0
f 0
cc 2
eloc 7
nc 2
nop 2
1
<?php
2
/*
3
 * 2017 Romain CANON <[email protected]>
4
 *
5
 * This file is part of the TYPO3 FormZ project.
6
 * It is free software; you can redistribute it and/or modify it
7
 * under the terms of the GNU General Public License, either
8
 * version 3 of the License, or any later version.
9
 *
10
 * For the full copyright and license information, see:
11
 * http://www.gnu.org/licenses/gpl-3.0.html
12
 */
13
14
namespace Romm\Formz\Condition;
15
16
use Romm\Formz\Condition\Items\ConditionItemInterface;
17
use Romm\Formz\Condition\Items\FieldHasErrorCondition;
18
use Romm\Formz\Condition\Items\FieldHasValueCondition;
19
use Romm\Formz\Condition\Items\FieldIsEmptyCondition;
20
use Romm\Formz\Condition\Items\FieldIsValidCondition;
21
use Romm\Formz\Core\Core;
22
use Romm\Formz\Exceptions\ClassNotFoundException;
23
use Romm\Formz\Exceptions\EntryNotFoundException;
24
use Romm\Formz\Exceptions\InvalidArgumentTypeException;
25
use Romm\Formz\Service\Traits\SelfInstantiateTrait;
26
use TYPO3\CMS\Core\SingletonInterface;
27
28
/**
29
 * Factory class for working with conditions.
30
 *
31
 * You can register a new condition by using the following code in the file
32
 * `ext_localconf.php` of your extension:
33
 *
34
 *  $conditionFactory = \Romm\Formz\Condition\ConditionFactory::get();
35
 *
36
 *  $conditionFactory->registerCondition(
37
 *      'nameOfMyCondition',
38
 *      \Vendor\Extension\Condition\Items\MyCondition::class
39
 *  );
40
 */
41
class ConditionFactory implements SingletonInterface
42
{
43
    use SelfInstantiateTrait;
44
45
    /**
46
     * @var array
47
     */
48
    private $conditions = [];
49
50
    /**
51
     * @var bool
52
     */
53
    private $defaultConditionsWereRegistered = false;
54
55
    /**
56
     * Use this function to register a new condition type which can then be used
57
     * in the TypoScript configuration. This function should be called from
58
     * `ext_localconf.php`.
59
     *
60
     * The name of the condition must be a valid string, which will be then be
61
     * used as the identifier for the TypoScript conditions. By convention, you
62
     * should use the following syntax: `extension_name.condition_name`.
63
     *
64
     * The condition class must implement the interface
65
     * `ConditionItemInterface`.
66
     *
67
     * @param string $identifier The identifier of the condition, which will then be available for TypoScript conditions.
68
     * @param string $className  Class which will process the condition.
69
     * @return $this
70
     * @throws ClassNotFoundException
71
     * @throws InvalidArgumentTypeException
72
     */
73
    public function registerCondition($identifier, $className)
74
    {
75
        if (false === is_string($identifier)) {
76
            throw InvalidArgumentTypeException::conditionNameNotString($identifier);
77
        }
78
79
        if (false === class_exists($className)) {
80
            throw ClassNotFoundException::conditionClassNameNotFound($identifier, $className);
81
        }
82
83
        if (false === in_array(ConditionItemInterface::class, class_implements($className))) {
84
            throw InvalidArgumentTypeException::conditionClassNameNotValid($className);
85
        }
86
87
        $this->conditions[$identifier] = $className;
88
89
        return $this;
90
    }
91
92
    /**
93
     * @param string $identifier
94
     * @return bool
95
     */
96
    public function hasCondition($identifier)
97
    {
98
        return true === array_key_exists($identifier, $this->conditions);
99
    }
100
101
    /**
102
     * Returns the wanted condition. A check should be done before calling this
103
     * function, with `hasCondition()`.
104
     *
105
     * @param $identifier
106
     * @return mixed
107
     * @throws EntryNotFoundException
108
     */
109
    public function getCondition($identifier)
110
    {
111
        if (false === $this->hasCondition($identifier)) {
112
            throw EntryNotFoundException::conditionNotFound($identifier, $this->conditions);
113
        }
114
115
        return $this->conditions[$identifier];
116
    }
117
118
    /**
119
     * @return array
120
     */
121
    public function getConditions()
122
    {
123
        return $this->conditions;
124
    }
125
126
    /**
127
     * @param string $identifier
128
     * @param array  $arguments
129
     * @return ConditionItemInterface
130
     * @throws EntryNotFoundException
131
     */
132
    public function instantiateCondition($identifier, array $arguments = [])
133
    {
134
        if (false === $this->hasCondition($identifier)) {
135
            throw EntryNotFoundException::instantiateConditionNotFound($identifier, $this->conditions);
136
        }
137
138
        // @todo handle \InvalidArgumentException
139
        /** @var ConditionItemInterface $condition */
140
        $condition = call_user_func_array(
141
            [Core::class, 'instantiate'],
142
            array_merge([$this->conditions[$identifier]], $arguments)
143
        );
144
145
        return $condition;
146
    }
147
148
    /**
149
     * Registers all default conditions from FormZ core.
150
     */
151
    public function registerDefaultConditions()
152
    {
153
        if (false === $this->defaultConditionsWereRegistered) {
154
            $this->defaultConditionsWereRegistered = true;
155
156
            $this->registerCondition(
157
                FieldHasValueCondition::CONDITION_IDENTIFIER,
158
                FieldHasValueCondition::class
159
            )->registerCondition(
160
                FieldHasErrorCondition::CONDITION_IDENTIFIER,
161
                FieldHasErrorCondition::class
162
            )->registerCondition(
163
                FieldIsValidCondition::CONDITION_IDENTIFIER,
164
                FieldIsValidCondition::class
165
            )->registerCondition(
166
                FieldIsEmptyCondition::CONDITION_IDENTIFIER,
167
                FieldIsEmptyCondition::class
168
            );
169
        }
170
    }
171
}
172