Completed
Push — master ( 67fb5e...175b65 )
by Alex
25s queued 14s
created

CreateNavigationPropertyWithPartner()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 47
Code Lines 25

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 1 Features 0
Metric Value
cc 3
eloc 25
c 2
b 1
f 0
nc 3
nop 10
dl 0
loc 47
rs 9.52

How to fix   Many Parameters   

Many Parameters

Methods with many parameters are not only hard to understand, but their parameters also often become inconsistent when you need more, or different data.

There are several approaches to avoid long parameter lists:

1
<?php
2
3
declare(strict_types=1);
4
5
6
namespace AlgoWeb\ODataMetadata\Library;
7
8
use AlgoWeb\ODataMetadata\CsdlConstants;
9
use AlgoWeb\ODataMetadata\EdmUtil;
10
use AlgoWeb\ODataMetadata\Enums\Multiplicity;
11
use AlgoWeb\ODataMetadata\Enums\OnDeleteAction;
12
use AlgoWeb\ODataMetadata\Enums\PropertyKind;
13
use AlgoWeb\ODataMetadata\Exception\ArgumentException;
14
use AlgoWeb\ODataMetadata\Exception\ArgumentOutOfRangeException;
15
use AlgoWeb\ODataMetadata\Helpers\NavigationPropertyHelpers;
16
use AlgoWeb\ODataMetadata\Interfaces\ICollectionType;
17
use AlgoWeb\ODataMetadata\Interfaces\IEntityType;
18
use AlgoWeb\ODataMetadata\Interfaces\INavigationProperty;
19
use AlgoWeb\ODataMetadata\Interfaces\IStructuralProperty;
20
use AlgoWeb\ODataMetadata\Interfaces\ITypeReference;
21
use AlgoWeb\ODataMetadata\Library\Core\EdmCoreModel;
22
use AlgoWeb\ODataMetadata\StringConst;
23
24
class EdmNavigationProperty extends EdmProperty implements INavigationProperty
25
{
26
    use NavigationPropertyHelpers;
27
    /**
28
     * @var bool
29
     */
30
    private $containsTarget;
31
    /**
32
     * @var OnDeleteAction
33
     */
34
    private $onDelete;
35
    /**
36
     * @var EdmNavigationProperty
37
     */
38
    private $partner;
39
    /**
40
     * @var array<IStructuralProperty>
41
     */
42
    private $dependentProperties;
43
44
    public function __construct(
45
        IEntityType $declaringType,
46
        string $name,
47
        ITypeReference $type,
48
        ?array $dependentProperties,
49
        ?bool $containsTarget,
50
        ?OnDeleteAction $onDelete
51
    ) {
52
        parent::__construct($declaringType, $name, $type);
53
        $this->dependentProperties = $dependentProperties;
54
        $this->containsTarget      = $containsTarget ?? CsdlConstants::Default_ContainsTarget;
55
        $this->onDelete            = $onDelete ?? OnDeleteAction::None();
56
    }
57
58
    /**
59
     * @return INavigationProperty gets the partner of this navigation property
60
     */
61
    public function getPartner(): INavigationProperty
62
    {
63
        return $this->partner;
64
    }
65
66
    /**
67
     * @return OnDeleteAction gets the action to execute on the deletion of this end of a bidirectional association
68
     */
69
    public function getOnDelete(): OnDeleteAction
70
    {
71
        return $this->onDelete;
72
    }
73
74
    /**
75
     * @return bool gets whether this navigation property originates at the principal end of an association
76
     */
77
    public function isPrincipal(): bool
78
    {
79
        return $this->dependentProperties === null && $this->partner !== null &&
80
               $this->partner->dependentProperties !== null;
81
    }
82
83
    /**
84
     * @return IStructuralProperty[]|null gets the dependent properties of this navigation property, returning null if
85
     *                                    this is the principal end or if there is no referential constraint
86
     */
87
    public function getDependentProperties(): ?array
88
    {
89
        return $this->dependentProperties;
90
    }
91
92
    /**
93
     * @return bool gets a value indicating whether the navigation target is contained inside the navigation source
94
     */
95
    public function containsTarget(): bool
96
    {
97
        return $this->containsTarget;
98
    }
99
100
    /**
101
     * @return PropertyKind gets the kind of this property
102
     */
103
    public function getPropertyKind(): PropertyKind
104
    {
105
        return PropertyKind::Navigation();
106
    }
107
108
    /**
109
     * Creates two navigation properties representing an association between two entity types.
110
     *
111
     * @param  EdmNavigationPropertyInfo $propertyInfo information to create the navigation property
112
     * @param  EdmNavigationPropertyInfo $partnerInfo  information to create the partner navigation property
113
     * @return EdmNavigationProperty     created navigation property
114
     */
115
    public static function CreateNavigationPropertyWithPartnerFromInfo(
116
        EdmNavigationPropertyInfo $propertyInfo,
117
        EdmNavigationPropertyInfo $partnerInfo
118
    ): EdmNavigationProperty {
119
        EdmUtil::CheckArgumentNull($propertyInfo->name, 'propertyInfo.Name');
120
        EdmUtil::CheckArgumentNull($propertyInfo->target, 'propertyInfo.Target');
121
        EdmUtil::CheckArgumentNull($partnerInfo->name, 'partnerInfo.Name');
122
        EdmUtil::CheckArgumentNull($partnerInfo->target, 'partnerInfo.Target');
123
124
        $end1 = new EdmNavigationProperty(
125
            $partnerInfo->target,
126
            $propertyInfo->name,
127
            self::createNavigationPropertyType(
128
                $propertyInfo->target,
129
                $propertyInfo->targetMultiplicity
130
            ),
131
            $propertyInfo->dependentProperties,
132
            $propertyInfo->containsTarget,
133
            $propertyInfo->onDelete
134
        );
135
136
        $end2 = new EdmNavigationProperty(
137
            $propertyInfo->target,
138
            $partnerInfo->name,
139
            self::createNavigationPropertyType(
140
                $partnerInfo->target,
141
                $partnerInfo->targetMultiplicity
142
            ),
143
            $partnerInfo->dependentProperties,
144
            $partnerInfo->containsTarget,
145
            $partnerInfo->onDelete
146
        );
147
148
        $end1->partner = $end2;
149
        $end2->partner = $end1;
150
        return $end1;
151
    }
152
153
154
    /**
155
     * Creates two navigation properties representing an association between two entity types.
156
     *
157
     * @param  string                $propertyName               navigation property name
158
     * @param  ITypeReference        $propertyType               type of the navigation property
159
     * @param  IStructuralProperty[] $dependentProperties        dependent properties of the navigation source
160
     * @param  bool                  $containsTarget             a value indicating whether the navigation source logically contains the navigation target
161
     * @param  OnDeleteAction        $onDelete                   action to take upon deletion of an instance of the navigation source
162
     * @param  string                $partnerPropertyName        navigation partner property name
163
     * @param  ITypeReference        $partnerPropertyType        type of the navigation partner property
164
     * @param  IStructuralProperty[] $partnerDependentProperties dependent properties of the navigation target
165
     * @param  bool                  $partnerContainsTarget      a value indicating whether the navigation target logically contains the navigation source
166
     * @param  OnDeleteAction        $partnerOnDelete            action to take upon deletion of an instance of the navigation target
167
     * @return EdmNavigationProperty navigation property
168
     */
169
    public static function CreateNavigationPropertyWithPartner(
170
        string $propertyName,
171
        ITypeReference $propertyType,
172
        array $dependentProperties,
173
        bool $containsTarget,
174
        OnDeleteAction $onDelete,
175
        string $partnerPropertyName,
176
        ITypeReference $partnerPropertyType,
177
        array $partnerDependentProperties,
178
        bool $partnerContainsTarget,
179
        OnDeleteAction $partnerOnDelete
180
    ): EdmNavigationProperty {
181
        $declaringType = self::GetEntityType($partnerPropertyType);
182
        if ($declaringType == null) {
183
            throw new ArgumentException(
184
                StringConst::Constructable_EntityTypeOrCollectionOfEntityTypeExpected('partnerPropertyType')
185
            );
186
        }
187
188
        $partnerDeclaringType = self::GetEntityType($propertyType);
189
        if ($partnerDeclaringType == null) {
190
            throw new ArgumentException(
191
                StringConst::Constructable_EntityTypeOrCollectionOfEntityTypeExpected('propertyType')
192
            );
193
        }
194
195
        $end1 = new EdmNavigationProperty(
196
            $declaringType,
197
            $propertyName,
198
            $propertyType,
199
            $dependentProperties,
200
            $containsTarget,
201
            $onDelete
202
        );
203
204
        $end2 = new EdmNavigationProperty(
205
            $partnerDeclaringType,
206
            $partnerPropertyName,
207
            $partnerPropertyType,
208
            $partnerDependentProperties,
209
            $partnerContainsTarget,
210
            $partnerOnDelete
211
        );
212
213
        $end1->partner = $end2;
214
        $end2->partner = $end1;
215
        return $end1;
216
    }
217
218
    private static function GetEntityType(ITypeReference $type): ?IEntityType
219
    {
220
        $entityType = null;
221
        if ($type->IsEntity()) {
222
            /** @var IEntityType $entityType */
223
            $entityType = $type->getDefinition();
224
        } elseif ($type->IsCollection()) {
225
            $collectionDef = $type->getDefinition();
226
            assert($collectionDef instanceof ICollectionType);
227
            $type = $collectionDef->getElementType();
228
            if ($type->IsEntity()) {
229
                /** @var IEntityType $entityType */
230
                $entityType = $type->getDefinition();
231
                assert($entityType instanceof IEntityType);
232
            }
233
        }
234
235
        return $entityType;
236
    }
237
238
    private static function createNavigationPropertyType(
239
        IEntityType $entityType,
240
        Multiplicity $multiplicity
241
    ): ITypeReference {
242
        switch ($multiplicity) {
243
            case Multiplicity::ZeroOrOne():
244
                return new EdmEntityTypeReference($entityType, true);
245
246
            case Multiplicity::One():
247
                return new EdmEntityTypeReference($entityType, false);
248
249
            case Multiplicity::Many():
250
                return EdmCoreModel::GetCollection(new EdmEntityTypeReference($entityType, false));
251
252
            default:
253
                throw new ArgumentOutOfRangeException(
254
                    StringConst::UnknownEnumVal_Multiplicity($multiplicity->getKey())
255
                );
256
        }
257
    }
258
}
259