Completed
Push — middleware-wip ( 7414b2...785812 )
by Romain
02:52
created

FormObjectFactory::getProxy()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 10
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 10
rs 9.4285
c 0
b 0
f 0
cc 2
eloc 5
nc 2
nop 1
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\FormObject;
15
16
use Romm\Formz\Core\Core;
17
use Romm\Formz\Exceptions\ClassNotFoundException;
18
use Romm\Formz\Exceptions\InvalidArgumentTypeException;
19
use Romm\Formz\Form\FormInterface;
20
use Romm\Formz\Service\CacheService;
21
use Romm\Formz\Service\StringService;
22
use Romm\Formz\Service\Traits\ExtendedSelfInstantiateTrait;
23
use Romm\Formz\Service\TypoScriptService;
24
use TYPO3\CMS\Core\SingletonInterface;
25
26
/**
27
 * Factory class that will manage form object instances.
28
 *
29
 * You can fetch a new instance by calling one of the following methods:
30
 * `getInstanceFromFormInstance()` or `getInstanceFromClassName()`
31
 *
32
 * @see \Romm\Formz\Form\FormObject\FormObject
33
 */
34
class FormObjectFactory implements SingletonInterface
35
{
36
    use ExtendedSelfInstantiateTrait;
37
38
    /**
39
     * @var TypoScriptService
40
     */
41
    protected $typoScriptService;
42
43
    /**
44
     * @var FormObject[]
45
     */
46
    protected $instances = [];
47
48
    /**
49
     * @var FormObjectStatic[]
50
     */
51
    protected $static = [];
52
53
    /**
54
     * @var FormObjectProxy[]
55
     */
56
    protected $proxy = [];
57
58
    /**
59
     * @param FormInterface $form
60
     * @param string        $name
61
     * @return FormObject
62
     */
63
    public function getInstanceWithFormInstance(FormInterface $form, $name = 'defaultName')
64
    {
65
        $hash = $name . '-' . spl_object_hash($form);
66
67
        if (false === isset($this->instances[$hash])) {
68
            $formObject = $this->getInstanceWithClassName(get_class($form), $name);
69
            $formObject->setForm($form);
70
71
            $this->instances[$hash] = $formObject;
72
        }
73
74
        return $this->instances[$hash];
75
    }
76
77
    /**
78
     * Will create an instance of `FormObject` based on a class that implements
79
     * the interface `FormInterface`.
80
     *
81
     * @param string $className
82
     * @param string $name
83
     * @return FormObject
84
     */
85
    public function getInstanceWithClassName($className, $name)
86
    {
87
        /** @var FormObject $formObject */
88
        $formObject = Core::instantiate(FormObject::class, $name, $this->getStaticInstance($className));
89
90
        return $formObject;
91
    }
92
93
    /**
94
     * Returns the proxy object for the given form object and form instance.
95
     *
96
     * Please use with caution, as this is a very low level function!
97
     *
98
     * @param FormInterface $form
99
     * @return FormObjectProxy
100
     */
101
    public function getProxy(FormInterface $form)
102
    {
103
        $hash = spl_object_hash($form);
104
105
        if (false === isset($this->proxy[$hash])) {
106
            $this->proxy[$hash] = $this->getNewProxyInstance($form);
107
        }
108
109
        return $this->proxy[$hash];
110
    }
111
112
    /**
113
     * @param string $className
114
     * @return FormObjectStatic
115
     * @throws ClassNotFoundException
116
     * @throws InvalidArgumentTypeException
117
     */
118
    protected function getStaticInstance($className)
119
    {
120
        if (false === class_exists($className)) {
121
            throw ClassNotFoundException::wrongFormClassName($className);
122
        }
123
124
        if (false === in_array(FormInterface::class, class_implements($className))) {
125
            throw InvalidArgumentTypeException::wrongFormType($className);
126
        }
127
128
        $cacheIdentifier = $this->getCacheIdentifier($className);
129
130
        if (false === isset($this->static[$cacheIdentifier])) {
131
            $cacheInstance = CacheService::get()->getCacheInstance();
132
133
            if ($cacheInstance->has($cacheIdentifier)) {
134
                $instance = $cacheInstance->get($cacheIdentifier);
135
            } else {
136
                $instance = $this->getNewStaticInstance($className);
137
                $instance->getObjectHash();
138
139
                $cacheInstance->set($cacheIdentifier, $instance);
140
            }
141
142
            $instance->injectInFormConfiguration();
143
144
            $this->static[$cacheIdentifier] = $instance;
145
        }
146
147
        return $this->static[$cacheIdentifier];
148
    }
149
150
    /**
151
     * @param string $className
152
     * @return string
153
     */
154
    protected function getCacheIdentifier($className)
155
    {
156
        $sanitizedClassName = StringService::get()->sanitizeString(str_replace('\\', '-', $className));
157
158
        return 'form-object-' . $sanitizedClassName;
159
    }
160
161
    /**
162
     * Wrapper for unit tests.
163
     *
164
     * @param string $className
165
     * @return FormObjectStatic
166
     */
167
    protected function getNewStaticInstance($className)
168
    {
169
        /** @var FormObjectStatic $formObjectStatic */
170
        $formObjectStatic = Core::instantiate(FormObjectStatic::class, $className);
171
172
        return $formObjectStatic;
173
    }
174
175
    /**
176
     * Wrapper for unit tests.
177
     *
178
     * @param FormInterface $form
179
     * @return FormObjectProxy
180
     */
181
    protected function getNewProxyInstance(FormInterface $form)
182
    {
183
        /** @var FormObjectProxy $formObjectProxy */
184
        $formObjectProxy = Core::instantiate(FormObjectProxy::class, $form);
185
186
        return $formObjectProxy;
187
    }
188
}
189