Issues (23)

src/Definition/ObjectDefinition.php (2 issues)

Labels
Severity
1
<?php
2
3
/**
4
 * This file is part of slick/di package
5
 *
6
 * For the full copyright and license information, please view the LICENSE.md
7
 * file that was distributed with this source code.
8
 */
9
10
namespace Slick\Di\Definition;
11
12
use ReflectionException;
13
use Slick\Di\Definition\Object\DefinitionData;
14
use Slick\Di\Definition\Object\Resolver;
15
use Slick\Di\Definition\Object\ResolverAwareInterface;
16
use Slick\Di\Definition\Object\ResolverInterface;
17
use Slick\Di\Exception\ClassNotFoundException;
18
use Slick\Di\Exception\MethodNotFoundException;
19
use Slick\Di\Exception\PropertyNotFoundException;
20
21
/**
22
 * Object
23
 *
24
 * @package Slick\Di\Definition
25
 * @author  Filipe Silva <[email protected]>
26
 */
27
class ObjectDefinition extends AbstractDefinition implements
0 ignored issues
show
The type Slick\Di\Definition\AbstractDefinition was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
28 8
    FluentObjectDefinitionInterface,
29
    ResolverAwareInterface,
30 8
    BackwardCompatibleDefinitionInterface
31
{
32
    /**
33
     * @var DefinitionData
34
     */
35
    protected $definitionData;
36
37
    /**
38
     * @var ResolverInterface
39
     */
40
    protected $resolver;
41
42
    /**
43
     * @var \ReflectionClass
44
     */
45
    private $reflectionClass;
46
47
    /**
48
     * @var mixed
49
     */
50
    private $lastValue;
51
52
    /**
53
     * Old methods that should be removed in next major version
54
     */
55
    use BackwardCompatibleMethodsTrait;
56
57
    /**
58
     * Creates an object definition
59
     *
60
     * @param string $className
61
     *
62
     * @throws ClassNotFoundException if the provided class name is from an
63
     *         undefined or inaccessible class.
64
     */
65
    public function __construct($className)
66
    {
67
        if (!class_exists($className)) {
68
            throw new ClassNotFoundException(
69
                "The class '{$className}' does not exists or it cannot be ".
70
                "loaded. Object definition therefore cannot be ".
71
                "created."
72
            );
73
        }
74
75
        $this->definitionData = new DefinitionData($className);
76
    }
77
78
    /**
79
     * Creates an object definition
80
     *
81
     * @param string $className
82
     *
83
     * @return FluentObjectDefinitionInterface
84
     *
85
     * @throws ClassNotFoundException if the provided class name is from an
86
     *         undefined or inaccessible class.
87
     */
88
    public static function create($className)
89
    {
90
        return new static($className);
91
    }
92
93
    /**
94
     * Resolves the definition into a scalar or object
95
     *
96
     * @return mixed
97
     */
98
    public function resolve(): mixed
99
    {
100
        return $this->getResolver()
101
            ->setContainer($this->getContainer())
102
            ->resolve($this->definitionData);
0 ignored issues
show
The method resolve() does not exist on Slick\Di\ContainerAwareInterface. It seems like you code against a sub-type of Slick\Di\ContainerAwareInterface such as Slick\Di\Definition\Object\ResolverInterface. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

102
            ->/** @scrutinizer ignore-call */ resolve($this->definitionData);
Loading history...
103
    }
104
105
    /**
106
     * Set the arguments for the last defined method call
107
     *
108
     * If there are no defined method calls it will set the constructor argument list
109
     *
110
     * @param array|mixed ...$arguments Arguments passed to object constructor
111
     *
112
     * @return ObjectDefinition
113
     * @throws ReflectionException
114
     */
115
    public function with(...$arguments)
116
    {
117
118
        if (empty($this->definitionData->calls())) {
119
            $this->getReflectionClass()
120
                ->getMethod('withConstructorArgument')
121
                ->invokeArgs($this, $arguments);
122
            return $this;
123
        }
124
125
        $this->definitionData->updateLastMethod($arguments);
126
        return $this;
127
    }
128
129
    /**
130
     * Set the arguments used to create the object
131
     *
132
     * @param array ...$arguments
133
     *
134
     * @return ObjectDefinition
135
     */
136
    public function withConstructorArgument(...$arguments)
137
    {
138
        $this->definitionData->withArguments($arguments);
139
        return $this;
140
    }
141
142
    /**
143
     * Get the object resolver
144
     *
145
     * @return ResolverInterface
146
     */
147
    public function getResolver()
148
    {
149
        if (!$this->resolver) {
150
            $this->setResolver(new Resolver());
151
        }
152
        return $this->resolver;
153
    }
154
155
    /**
156
     * Set the object resolver
157
     *
158
     * @param ResolverInterface $resolver
159
     *
160
     * @return self|$this
161
     */
162
    public function setResolver(ResolverInterface $resolver)
163
    {
164
        $this->resolver = $resolver;
165
        return $this;
166
    }
167
168
    /**
169
     * Get the definition data
170
     *
171
     * @return DefinitionData
172
     */
173
    public function getDefinitionData()
174
    {
175
        return $this->definitionData;
176
    }
177
178
    /**
179
     * Define a method call in the freshly created object
180
     *
181
     * @param string $methodName The method name to call
182
     *
183
     * @return FluentObjectDefinitionInterface|self
184
     *
185
     * @throws MethodNotFoundException
186
     */
187
    public function call($methodName)
188
    {
189
        $this->getReflectionClass()
190
            ->getMethod('callMethod')
191
            ->invokeArgs($this, [$methodName]);
192
        return $this;
193
    }
194
195
    /**
196
     * Define a method call with provide call
197
     *
198
     * @param string $methodName
199
     * @param array ...$arguments
200
     *
201
     * @return self|ObjectDefinitionInterface
202
     *
203
     * @throws MethodNotFoundException
204
     */
205
    public function callMethod($methodName, ...$arguments)
206
    {
207
208
        if (!method_exists($this->definitionData->className(), $methodName)) {
209
            throw new MethodNotFoundException(
210
                "The method '{$methodName}' is not defined in the class ".
211
                "{$this->definitionData->className()}"
212
            );
213
        }
214
215
        $this->definitionData->addCall(
216
            DefinitionData::METHOD,
217
            $methodName,
218
            $arguments
219
        );
220
        return $this;
221
    }
222
223
    /**
224
     * Set the value that will be assigned to a property
225
     *
226
     * @param mixed $value
227
     *
228
     * @return ObjectDefinition
229
     */
230
    public function assign($value)
231
    {
232
        $this->lastValue = $value;
233
        return $this;
234
    }
235
236
    /**
237
     * Assign the last defined value to the provided property
238
     *
239
     * The value will be reset after its assigned.
240
     *
241
     * @param string $property
242
     *
243
     * @return ObjectDefinition
244
     */
245
    public function to($property)
246
    {
247
        if (!property_exists($this->definitionData->className(), $property)) {
248
            throw new PropertyNotFoundException(
249
                "The class '{$this->definitionData->className()}' has no ".
250
                "property called '{$property}'."
251
            );
252
        }
253
        $this->getReflectionClass()
254
            ->getMethod('assignProperty')
255
            ->invokeArgs($this, [$property, $this->lastValue]);
256
257
        $this->lastValue = null;
258
        return $this;
259
    }
260
261
    /**
262
     * Assigns a value to the property with provided name
263
     *
264
     * @param string $name
265
     * @param mixed  $value
266
     *
267
     * @return ObjectDefinition
268
     */
269
    public function assignProperty($name, $value)
270
    {
271
        $this->definitionData->addCall(
272
            DefinitionData::PROPERTY,
273
            $name,
274
            $value
275
        );
276
        return $this;
277
    }
278
279
    /**
280
     * Get the self reflection
281
     *
282
     * @return \ReflectionClass
283
     */
284
    protected function getReflectionClass()
285
    {
286
        if (!$this->reflectionClass) {
287
            $this->reflectionClass = new \ReflectionClass($this);
288
        }
289
        return $this->reflectionClass;
290
    }
291
}
292