Passed
Push — master ( 2d9553...41ca68 )
by Jesse
01:31
created

Name::for()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 4
nc 1
nop 1
dl 0
loc 5
rs 10
c 0
b 0
f 0
1
<?php
2
declare(strict_types=1);
3
4
namespace Stratadox\EntityState\Internal;
5
6
use function get_class;
7
use function gettype;
8
use function is_object;
9
use function sprintf;
10
use function str_replace;
11
12
/**
13
 * Potentially prefixed property name.
14
 *
15
 * @internal
16
 * @author Stratadox
17
 */
18
final class Name
19
{
20
    private const PROBLEMS = ['\\', '[', ']'];
21
    private const SOLUTIONS = ['\\\\', '\[', '\]'];
22
    private $prefix;
23
    private $name;
24
25
    private function __construct(string $prefix, string $name)
26
    {
27
        $this->prefix = $prefix;
28
        $this->name = $name;
29
    }
30
31
    /**
32
     * Produces a name based on a reflection property.
33
     *
34
     * @param ReflectionProperty $property The reflection property.
35
     * @return Name                        The name for the property.
36
     */
37
    public static function fromReflection(ReflectionProperty $property): Name
38
    {
39
        return new Name('', $property->getName());
40
    }
41
42
    /**
43
     * Produces a name based on a collection entry.
44
     *
45
     * @param object $collection The collection object.
46
     * @param string $key        The position in the collection.
47
     * @return Name              The name for the collection entry.
48
     */
49
    public static function fromCollectionEntry(object $collection, string $key): Name
50
    {
51
        return new Name('', sprintf(
52
            '%s[%s]',
53
            get_class($collection),
54
            self::escape($key)
55
        ));
56
    }
57
58
    /**
59
     * Adds the class of the object to the property name definition.
60
     *
61
     * @param object $object The object whose class to add.
62
     * @return Name          The name with added class.
63
     */
64
    public function for(object $object): Name
65
    {
66
        return new Name(
67
            $this->prefix,
68
            sprintf('%s:%s', get_class($object), $this->name)
69
        );
70
    }
71
72
    /**
73
     * Returns a name for the nested property.
74
     *
75
     * @param ReflectionProperty $property The nested property.
76
     * @return Name                        The prefixed property name.
77
     */
78
    public function forNested(ReflectionProperty $property): Name
79
    {
80
        return new Name(sprintf('%s.', $this), $property->getName());
81
    }
82
83
    /**
84
     * Returns a name for the collection key.
85
     *
86
     * @param iterable $collection The collection where the item is in.
87
     * @param string   $key        The position of the item in the collection.
88
     * @return Name                The array key property name.
89
     */
90
    public function forItem(iterable $collection, string $key): Name
91
    {
92
        return new Name(
93
            $this->prefix,
94
            sprintf(
95
                '%s:%s[%s]',
96
                is_object($collection) ? get_class($collection) : gettype($collection),
97
                $this->name,
98
                self::escape($key)
99
            )
100
        );
101
    }
102
103
    public function toCount(iterable $collection): Name
104
    {
105
        return new Name(
106
            $this->prefix,
107
            sprintf(
108
                'count(%s:%s)',
109
                is_object($collection) ? get_class($collection) : gettype($collection),
110
                $this->name
111
            )
112
        );
113
    }
114
115
    /**
116
     * Returns the string representation of the name.
117
     *
118
     * @return string
119
     */
120
    public function __toString()
121
    {
122
        return $this->prefix . $this->name;
123
    }
124
125
    private static function escape(string $key): string
126
    {
127
        return str_replace(self::PROBLEMS, self::SOLUTIONS, $key);
128
    }
129
}
130