Issues (13)

src/Relation/Builder.php (3 issues)

1
<?php
2
/**
3
 *
4
 * This file is part of the Aura project for PHP.
5
 *
6
 * @package Aura.Marshal
7
 *
8
 * @license https://opensource.org/licenses/mit-license.php MIT
9
 *
10
 */
11
namespace Aura\Marshal\Relation;
12
13
use Aura\Marshal\Exception;
14
use Aura\Marshal\Manager;
15
16
/**
17
 *
18
 * A builder to create relationship definition objects.
19
 *
20
 * @package Aura.Marshal
21
 *
22
 */
23
class Builder
24
{
25
    /**
26
     *
27
     * A map of relationships to classes.
28
     *
29
     * @var array<string, class-string<RelationInterface>>
0 ignored issues
show
Documentation Bug introduced by
The doc comment array<string, class-string<RelationInterface>> at position 4 could not be parsed: Unknown type name 'class-string' at position 4 in array<string, class-string<RelationInterface>>.
Loading history...
30
     *
31
     */
32
    protected $relationship_class = [
33
        'belongs_to'       => 'Aura\Marshal\Relation\BelongsTo',
34
        'has_one'          => 'Aura\Marshal\Relation\HasOne',
35
        'has_many'         => 'Aura\Marshal\Relation\HasMany',
36
        'has_many_through' => 'Aura\Marshal\Relation\HasManyThrough',
37
    ];
38
39
    /**
40
     *
41
     * Builds and returns a relation object.
42
     *
43
     * @param string $type The name of the native type in the manager.
44
     *
45
     * @param string $name The name of the native field for the related
46
     * entity or collection.
47
     *
48
     * @param array<string, mixed> $info An array of relationship definition information.
49
     *
50
     * @param Manager $manager A type manager.
51
     *
52
     * @return RelationInterface
53
     *
54
     */
55
    public function newInstance($type, $name, array $info, Manager $manager)
56
    {
57
        $base = [
58
            'relationship'          => null,
59
            'native_field'          => null,
60
            'foreign_type'          => $name,
61
            'foreign_field'         => null,
62
            'through_type'          => null,
63
            'through_native_field'  => null,
64
            'through_foreign_field' => null,
65
        ];
66
67
        $info = array_merge($base, $info);
68
        $info['type'] = $type;
69
        $info['name'] = $name;
70
71
        $this->prepRelationship($info, $manager);
72
        $this->prepNative($info, $manager);
73
        $this->prepForeign($info, $manager);
74
        $this->prepThrough($info, $manager);
75
76
        $relationship = $info['relationship'];
77
        $class = $this->relationship_class[$relationship];
78
79
        return new $class(
80
            $info['native_field'],
81
            $info['foreign'],
82
            $info['foreign_type'],
83
            $info['foreign_field'],
84
            $info['through'],
85
            $info['through_type'],
86
            $info['through_native_field'],
87
            $info['through_foreign_field']
88
        );
89
    }
90
91
    /**
92
     *
93
     * Prepares the type-of-relationship name.
94
     *
95
     * @param array<string, mixed> $info The relationship definition.
96
     *
97
     * @param Manager $manager The type manager.
98
     *
99
     * @return void
100
     *
101
     */
102
    protected function prepRelationship(&$info, Manager $manager)
0 ignored issues
show
The parameter $manager is not used and could be removed. ( Ignorable by Annotation )

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

102
    protected function prepRelationship(&$info, /** @scrutinizer ignore-unused */ Manager $manager)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
103
    {
104
        if (! $info['relationship']) {
105
            throw new Exception("No 'relationship' specified for relation '{$info['name']}' on type '{$info['type']}'.");
106
        }
107
    }
108
109
    /**
110
     *
111
     * Prepares the native field name.
112
     *
113
     * @param array<string, mixed> $info The relationship definition.
114
     *
115
     * @param Manager $manager The type manager.
116
     *
117
     * @return void
118
     *
119
     */
120
    protected function prepNative(&$info, Manager $manager)
0 ignored issues
show
The parameter $manager is not used and could be removed. ( Ignorable by Annotation )

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

120
    protected function prepNative(&$info, /** @scrutinizer ignore-unused */ Manager $manager)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
121
    {
122
        if (! $info['native_field']) {
123
            throw new Exception("No 'native_field' specified for relation '{$info['name']}' on type '{$info['type']}'.");
124
        }
125
    }
126
127
    /**
128
     *
129
     * Prepares the foreign type name, field name, and type object.
130
     *
131
     * @param array<string, mixed> $info The relationship definition.
132
     *
133
     * @param Manager $manager The type manager.
134
     *
135
     * @return void
136
     *
137
     */
138
    protected function prepForeign(&$info, Manager $manager)
139
    {
140
        if (! $info['foreign_type']) {
141
            throw new Exception("No 'foreign_type' specified for relation '{$info['name']}' on type '{$info['type']}'.");
142
        }
143
144
        if (! $info['foreign_field']) {
145
            throw new Exception("No 'foreign_field' specified for relation '{$info['name']}' on type '{$info['type']}'.");
146
        }
147
148
        $info['foreign'] = $manager->__get($info['foreign_type']);
149
    }
150
151
    /**
152
     *
153
     * Prepares the through type name, field names, and type object.
154
     *
155
     * @param array<string, mixed> $info The relationship definition.
156
     *
157
     * @param Manager $manager The type manager.
158
     *
159
     * @return void
160
     *
161
     */
162
    protected function prepThrough(&$info, Manager $manager)
163
    {
164
        if ($info['relationship'] != 'has_many_through') {
165
            $info['through'] = null;
166
            return;
167
        }
168
169
        if (! $info['through_type']) {
170
            throw new Exception("No 'through_type' specified for relation '{$info['name']}' on type '{$info['type']}'.");
171
        }
172
173
        if (! $info['through_native_field']) {
174
            throw new Exception("No 'through_native_field' specified for relation '{$info['name']}' on type '{$info['type']}'.");
175
        }
176
177
        if (! $info['through_foreign_field']) {
178
            throw new Exception("No 'through_foreign_field' specified for relation '{$info['name']}' on type '{$info['type']}'.");
179
        }
180
181
        $info['through'] = $manager->__get($info['through_type']);
182
    }
183
}
184