ValueGenerator::__construct()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 1
c 1
b 0
f 0
dl 0
loc 4
ccs 2
cts 2
cp 1
rs 10
cc 1
nc 1
nop 1
crap 1
1
<?php
2
3
namespace Bdf\Form\Aggregate\Value;
4
5
use Bdf\Form\ElementInterface;
6
7
/**
8
 * The base value generator implementation
9
 *
10
 * <code>
11
 * (new ValueGenerator())->generate($form); // Will generate an empty array
12
 * (new ValueGenerator(MyEntity::class))->generate($form); // Will call the default constructor of MyEntity
13
 * (new ValueGenerator($entity))->generate($form); // Will clone the instance of $entity
14
 * (new ValueGenerator(function (FormInterface $form) { return new MyEntity(...); }))->generate($form); // Custom generator
15
 * </code>
16
 *
17
 * @template T
18
 * @implements ValueGeneratorInterface<T>
19
 */
20
final class ValueGenerator implements ValueGeneratorInterface
21
{
22
    /**
23
     * @var callable():T|T|class-string<T>
24
     */
25
    private $value;
26
27
    /**
28
     * @var callable():T|T|class-string<T>|null
29
     */
30
    private $attachment;
31
32
    /**
33
     * ValueGenerator constructor.
34
     *
35
     * @param callable():T|T|class-string<T> $value
36
     */
37 257
    public function __construct($value = [])
38
    {
39
        /** @psalm-suppress PropertyTypeCoercion */
40 257
        $this->value = $value;
41 257
    }
42
43
    /**
44
     * {@inheritdoc}
45
     */
46 25
    public function attach($entity): void
47
    {
48
        /** @psalm-suppress PropertyTypeCoercion */
49 25
        $this->attachment = $entity;
50 25
    }
51
52
    /**
53
     * {@inheritdoc}
54
     */
55 44
    public function generate(ElementInterface $element)
56
    {
57 44
        $value = $this->attachment ?? $this->value;
58
59 44
        if (is_string($value)) {
60
            /** @var T */
61 9
            return new $value;
62
        }
63
64 37
        if (is_callable($value)) {
65 3
            return ($value)($element);
66
        }
67
68
        // Only clone value if it's not attached
69 34
        if (!$this->attachment && is_object($value)) {
70 1
            return clone $value;
71
        }
72
73 33
        return $value;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $value returns the type callable which is incompatible with the return type mandated by Bdf\Form\Aggregate\Value...orInterface::generate() of Bdf\Form\Aggregate\Value\T.

In the issue above, the returned value is violating the contract defined by the mentioned interface.

Let's take a look at an example:

interface HasName {
    /** @return string */
    public function getName();
}

class Name {
    public $name;
}

class User implements HasName {
    /** @return string|Name */
    public function getName() {
        return new Name('foo'); // This is a violation of the ``HasName`` interface
                                // which only allows a string value to be returned.
    }
}
Loading history...
74
    }
75
}
76