Completed
Push — feature/improve-form-definitio... ( 5df9ba...6ebf3c )
by Romain
02:15
created

AbstractFormDefinitionComponent   A

Complexity

Total Complexity 19

Size/Duplication

Total Lines 128
Duplicated Lines 0 %

Coupling/Cohesion

Components 2
Dependencies 6

Importance

Changes 0
Metric Value
wmc 19
lcom 2
cbo 6
dl 0
loc 128
rs 10
c 0
b 0
f 0

7 Methods

Rating   Name   Duplication   Size   Complexity  
A checkDefinitionFreezeState() 0 8 2
A isDefinitionFrozen() 0 5 2
A getDefinitionState() 0 13 2
A attachParents() 0 7 2
A attachParent() 0 6 2
B handlePropertyMagicMethod() 0 13 5
A forceNameForProperty() 0 10 4
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\Form\Definition;
15
16
use Romm\ConfigurationObject\ConfigurationObjectFactory;
17
use Romm\ConfigurationObject\Service\Items\Parents\ParentsTrait;
18
use Romm\ConfigurationObject\Traits\ConfigurationObject\MagicMethodsTrait;
19
use Romm\Formz\Exceptions\PropertyNotAccessibleException;
20
21
class AbstractFormDefinitionComponent
22
{
23
    use MagicMethodsTrait {
24
        handlePropertyMagicMethod as handlePropertyMagicMethodInternal;
25
    }
26
    use ParentsTrait {
27
        attachParent as private attachParentInternal;
28
        attachParents as private attachParentsInternal;
29
    }
30
31
    /**
32
     * @var bool
33
     */
34
    private $parentsAttached = false;
35
36
    /**
37
     * This method is used by setter methods, and other methods which goal is to
38
     * modify a property value.
39
     *
40
     * It checks that the definition is not frozen, and if it is actually frozen
41
     * an exception is thrown.
42
     *
43
     * @throws PropertyNotAccessibleException
44
     */
45
    protected function checkDefinitionFreezeState()
46
    {
47
        if ($this->isDefinitionFrozen()) {
48
            $methodName = debug_backtrace()[1]['function'];
49
50
            throw PropertyNotAccessibleException::formDefinitionFrozenMethod(get_class($this), $methodName);
51
        }
52
    }
53
54
    /**
55
     * @return bool
56
     */
57
    protected function isDefinitionFrozen()
58
    {
59
        return $this->getDefinitionState()
60
            && $this->getDefinitionState()->isDefinitionFrozen();
61
    }
62
63
    /**
64
     * @return FormDefinitionState
65
     */
66
    protected function getDefinitionState()
67
    {
68
        if ($this instanceof FormDefinition) {
69
            return $this->getState();
0 ignored issues
show
Documentation Bug introduced by
The method getState does not exist on object<Romm\Formz\Form\D...ormDefinitionComponent>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
70
        } else {
71
            return $this->withFirstParent(
72
                FormDefinition::class,
73
                function (FormDefinition $formDefinition) {
74
                    return $formDefinition->getState();
75
                }
76
            );
77
        }
78
    }
79
80
    /**
81
     * Overrides the magic methods handling from the Configuration Object API.
82
     *
83
     * Blocks the parents feature once it has been used.
84
     *
85
     * @param object[] $parents
86
     */
87
    public function attachParents(array $parents)
88
    {
89
        if (false === $this->parentsAttached) {
90
            $this->attachParentsInternal($parents);
91
            $this->parentsAttached = true;
92
        }
93
    }
94
95
    /**
96
     * @see attachParents()
97
     *
98
     * @param object $parent
99
     * @param bool   $direct
100
     */
101
    public function attachParent($parent, $direct = true)
102
    {
103
        if (false === $this->parentsAttached) {
104
            $this->attachParentInternal($parent, $direct);
105
        }
106
    }
107
108
    /**
109
     * Overrides the magic methods handling from the Configuration Object API.
110
     *
111
     * A new check is added: if the definition is frozen, and a setter method is
112
     * called, an exception must be thrown.
113
     *
114
     * @param string $property
115
     * @param string $type
116
     * @param array  $arguments
117
     * @return mixed
118
     * @throws PropertyNotAccessibleException
119
     */
120
    protected function handlePropertyMagicMethod($property, $type, array $arguments)
121
    {
122
        if ($type === 'set'
123
            && $this->isPropertyAccessible($property)
124
            && ($this->isDefinitionFrozen()
125
                || false === ConfigurationObjectFactory::getInstance()->isRunning()
0 ignored issues
show
Bug introduced by
The method isRunning() does not seem to exist on object<Romm\Configuratio...igurationObjectFactory>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
126
            )
127
        ) {
128
            throw PropertyNotAccessibleException::formDefinitionFrozenProperty(get_class($this), $property);
129
        }
130
131
        return $this->handlePropertyMagicMethodInternal($property, $type, $arguments);
132
    }
133
134
    /**
135
     * @param array $data
136
     * @param string $property
137
     */
138
    protected static function forceNameForProperty(&$data, $property)
139
    {
140
        if (isset($data[$property])
141
            && is_array($data[$property])
142
        ) {
143
            foreach ($data[$property] as $key => $entry) {
144
                $data[$property][$key]['name'] = $key;
145
            }
146
        }
147
    }
148
}
149