Completed
Push — master ( e54666...fb0960 )
by Christopher
10:55 queued 05:18
created

createAssocationSetForAssocation()   B

Complexity

Conditions 2
Paths 2

Size

Total Lines 28
Code Lines 24

Duplication

Lines 5
Ratio 17.86 %

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 5
loc 28
rs 8.8571
cc 2
eloc 24
nc 2
nop 5
1
<?php
2
3
namespace AlgoWeb\ODataMetadata;
4
5
use AlgoWeb\ODataMetadata\MetadataV3\edm\EntityContainer\AssociationSetAnonymousType;
6
use AlgoWeb\ODataMetadata\MetadataV3\edm\EntityContainer\AssociationSetAnonymousType\EndAnonymousType;
7
use AlgoWeb\ODataMetadata\MetadataV3\edm\EntityContainer\EntitySetAnonymousType;
8
use AlgoWeb\ODataMetadata\MetadataV3\edm\TAssociationEndType;
9
use AlgoWeb\ODataMetadata\MetadataV3\edm\TAssociationType;
10
use AlgoWeb\ODataMetadata\MetadataV3\edm\TConstraintType;
11
use AlgoWeb\ODataMetadata\MetadataV3\edm\TDocumentationType;
12
use AlgoWeb\ODataMetadata\MetadataV3\edm\TEntityPropertyType;
13
use AlgoWeb\ODataMetadata\MetadataV3\edm\TEntityTypeType;
14
use AlgoWeb\ODataMetadata\MetadataV3\edm\TPropertyRefType;
15
use AlgoWeb\ODataMetadata\MetadataV3\edm\TReferentialConstraintRoleElementType;
16
use AlgoWeb\ODataMetadata\MetadataV3\edmx\Edmx;
17
use JMS\Serializer\SerializerBuilder;
18
19
class MetadataManager
20
{
21
    private $V3Edmx = null;
22
    private $oldEdmx = null;
23
    private $lastError = null;
24
    private $serializer = null;
25
26
    public function __construct($namespaceName = "Data", $containerName = "DefaultContainer")
27
    {
28
        $this->V3Edmx = new Edmx($namespaceName, $containerName);
29
        if (!$this->V3Edmx->isOK($msg)) {
30
            throw new \Exception($msg);
31
        }
32
        $ymlDir = __DIR__ . DIRECTORY_SEPARATOR . "MetadataV3" . DIRECTORY_SEPARATOR . "JMSmetadata";
33
        $this->serializer =
34
            SerializerBuilder::create()
35
                ->addMetadataDir($ymlDir)
36
                ->build();
37
    }
38
39
    public function getEdmx()
40
    {
41
        return $this->V3Edmx;
42
    }
43
44
    public function getEdmxXML()
45
    {
46
        return $this->serializer->serialize($this->V3Edmx, "xml");
47
    }
48
49
    public function addEntityType($name, $accessType = "Public", $summary = null, $longDescription = null)
50
    {
51
        $this->startEdmxTransaction();
52
        $NewEntity = new TEntityTypeType();
53
        $NewEntity->setName($name);
54 View Code Duplication
        if (null != $summary || null != $longDescription) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
55
            $documentation = new TDocumentationType();
56
            $documentation->setSummary($summary);
57
            $documentation->setLongDescription($longDescription);
58
            $NewEntity->setDocumentation($documentation);
59
        }
60
61
        $entitySet = new EntitySetAnonymousType();
62
        $entitySet->setName($this->pluralize(2, $NewEntity->getName()));
63
        $namespace = $this->V3Edmx->getDataServices()[0]->getNamespace();
64 View Code Duplication
        if (0 == strlen(trim($namespace))) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
65
            $entityTypeName = $NewEntity->getName();
66
        } else {
67
            $entityTypeName = $namespace . "." . $NewEntity->getName();
68
        }
69
        $entitySet->setEntityType($entityTypeName);
70
        $entitySet->setGetterAccess($accessType);
71
72
        $this->V3Edmx->getDataServices()[0]->addToEntityType($NewEntity);
73
        $this->V3Edmx->getDataServices()[0]->getEntityContainer()[0]->addToEntitySet($entitySet);
74
        if (!$this->V3Edmx->isok($this->lastError)) {
75
            $this->revertEdmxTransaction();
76
            return false;
77
        }
78
        $this->commitEdmxTransaction();
79
        return $NewEntity;
80
    }
81
82
    private function startEdmxTransaction()
83
    {
84
        $this->oldEdmx = serialize($this->V3Edmx);
85
    }
86
87
    /**
88
     * Pluralizes a word if quantity is not one.
89
     *
90
     * @param int $quantity Number of items
91
     * @param string $singular Singular form of word
92
     * @param string $plural Plural form of word; function will attempt to deduce plural
93
     * form from singular if not provided
94
     * @return string Pluralized word if quantity is not one, otherwise singular
95
     */
96 View Code Duplication
    public static function pluralize($quantity, $singular, $plural = null)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
97
    {
98
        if ($quantity == 1 || !strlen($singular)) {
99
            return $singular;
100
        }
101
        if ($plural !== null) {
102
            return $plural;
103
        }
104
105
        $last_letter = strtolower($singular[strlen($singular) - 1]);
106
        switch ($last_letter) {
107
            case 'y':
108
                return substr($singular, 0, -1) . 'ies';
109
            case 's':
110
                return $singular . 'es';
111
            default:
112
                return $singular . 's';
113
        }
114
    }
115
116
    private function revertEdmxTransaction()
117
    {
118
        $this->V3Edmx = unserialize($this->oldEdmx);
119
    }
120
121
    private function commitEdmxTransaction()
122
    {
123
        $this->oldEdmx = null;
124
    }
125
126
    public function addPropertyToEntityType(
127
        $entityType,
128
        $name,
129
        $type,
130
        $defaultValue = null,
131
        $nullable = false,
132
        $isKey = false,
133
        $storeGeneratedPattern = null,
134
        $summary = null,
135
        $longDescription = null
136
    )
137
    {
138
        $this->startEdmxTransaction();
139
        $NewProperty = new TEntityPropertyType();
140
        $NewProperty->setName($name);
141
        $NewProperty->setType($type);
142
        $NewProperty->setStoreGeneratedPattern($storeGeneratedPattern);
143
        $NewProperty->setNullable($nullable);
144 View Code Duplication
        if (null != $summary || null != $longDescription) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
145
            $documentation = new TDocumentationType();
146
            $documentation->setSummary($summary);
147
            $documentation->setLongDescription($longDescription);
148
            $NewProperty->addToDocumentation($documentation);
149
        }
150
        if (null != $defaultValue) {
151
            $NewProperty->setDefaultValue($defaultValue);
152
        }
153
        $entityType->addToProperty($NewProperty);
154
        if ($isKey) {
155
            $Key = new TPropertyRefType();
156
            $Key->setName($name);
157
            $entityType->addToKey($Key);
158
        }
159
        if (!$this->V3Edmx->isok($this->lastError)) {
160
            $this->revertEdmxTransaction();
161
            return false;
162
        }
163
        $this->commitEdmxTransaction();
164
        return $NewProperty;
165
    }
166
167
    public function addNavigationPropertyToEntityType($entityType)
0 ignored issues
show
Unused Code introduced by
The parameter $entityType is not used and could be removed.

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

Loading history...
168
    {
169
170
    }
171
172
    public function getLastError()
173
    {
174
        return $this->lastError;
175
    }
176
177
    protected function createAssocationSetForAssocation(
178
        TAssociationType $association,
179
        $principalType,
180
        $principalProperty,
181
        $dependentType,
182
        $dependentProperty
183
    )
184
    {
185
        $as = new AssociationSetAnonymousType();
186
        $name = $principalType . "_" . $principalProperty . "_" . $dependentType . "_" . $dependentProperty;
187
        $as->setName($name);
188
        $namespace = $this->V3Edmx->getDataServices()[0]->getNamespace();
189 View Code Duplication
        if (0 == strlen(trim($namespace))) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
190
            $associationSetName = $association->getName();
191
        } else {
192
            $associationSetName = $namespace . "." . $association->getName();
193
        }
194
        $as->setAssociation($associationSetName);
195
        $end1 = new EndAnonymousType();
196
        $end1->setRole($association->getEnd()[0]->getRole());
197
        $end1->setEntitySet($this->pluralize(2, $principalType));
198
        $end2 = new EndAnonymousType();
199
        $end2->setRole($association->getEnd()[1]->getRole());
200
        $end2->setEntitySet($this->pluralize(2, $dependentProperty));
201
        $as->addToEnd($end1);
202
        $as->addToEnd($end2);
203
        return $as;
204
    }
205
206
    protected function createAssocation(
207
        $principalType,
208
        $principalProperty,
209
        $principalMultiplicity,
210
        $dependentType,
211
        $dependentProperty,
212
        $dependentMultiplicity,
213
        array $principalConstraintProperty = null,
214
        array $dependentConstraintProperty = null
215
    )
216
    {
217
        $association = new TAssociationType();
218
        $name = $principalType . "_" . $principalProperty . "_" . $dependentType . "_" . $dependentProperty;
219
        $name = trim($name, "_");
220
        $association->setName($name);
221
222
        $principalEnd = new TAssociationEndType();
223
        $principalEnd->setType($principalType);
224
        $principalEnd->setRole($principalType . "_" . $principalProperty . "_" . $dependentType);
225
        $principalEnd->setMultiplicity($principalMultiplicity);
226
        $dependentEnd = new TAssociationEndType();
227
        $dependentEnd->setType($dependentType);
228
        $dependentEnd->setRole($dependentType . "_" . $dependentProperty . "_" . $principalType);
229
        $dependentEnd->setMultiplicity($dependentMultiplicity);
230
        $association->addToEnd($principalEnd);
231
        $association->addToEnd($dependentEnd);
232
        $principalReferralConstraint = null;
233
        $dependentReferralConstraint = null;
234 View Code Duplication
        if (null != $principalConstraintProperty && 0 < count($principalConstraintProperty)) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
235
            $principalReferralConstraint = new TReferentialConstraintRoleElementType();
236
            $principalReferralConstraint->setRole($principalType . "_" . $principalProperty . "_" . $dependentType);
237
            foreach ($principalConstraintProperty as $pripertyRef) {
238
                $principalReferralConstraint->addToPropertyRef($pripertyRef);
239
            }
240
        }
241 View Code Duplication
        if (null != $dependentConstraintProperty && 0 < count($dependentConstraintProperty)) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
242
            $dependentReferralConstraint = new TReferentialConstraintRoleElementType();
243
            $dependentReferralConstraint->setRole($dependentType . "_" . $dependentProperty . "_" . $principalType);
244
            foreach ($dependentConstraintProperty as $pripertyRef) {
245
                $dependentReferralConstraint->addToPropertyRef($pripertyRef);
246
            }
247
        }
248
249
        if (null != $dependentReferralConstraint || null != $principalReferralConstraint) {
250
            $constraint = new TConstraintType();
251
            $constraint->setPrincipal($principalReferralConstraint);
0 ignored issues
show
Bug introduced by
It seems like $principalReferralConstraint defined by null on line 232 can be null; however, AlgoWeb\ODataMetadata\Me...intType::setPrincipal() does not accept null, maybe add an additional type check?

Unless you are absolutely sure that the expression can never be null because of other conditions, we strongly recommend to add an additional type check to your code:

/** @return stdClass|null */
function mayReturnNull() { }

function doesNotAcceptNull(stdClass $x) { }

// With potential error.
function withoutCheck() {
    $x = mayReturnNull();
    doesNotAcceptNull($x); // Potential error here.
}

// Safe - Alternative 1
function withCheck1() {
    $x = mayReturnNull();
    if ( ! $x instanceof stdClass) {
        throw new \LogicException('$x must be defined.');
    }
    doesNotAcceptNull($x);
}

// Safe - Alternative 2
function withCheck2() {
    $x = mayReturnNull();
    if ($x instanceof stdClass) {
        doesNotAcceptNull($x);
    }
}
Loading history...
252
            $constraint->setDependent($dependentReferralConstraint);
0 ignored issues
show
Bug introduced by
It seems like $dependentReferralConstraint defined by null on line 233 can be null; however, AlgoWeb\ODataMetadata\Me...intType::setDependent() does not accept null, maybe add an additional type check?

Unless you are absolutely sure that the expression can never be null because of other conditions, we strongly recommend to add an additional type check to your code:

/** @return stdClass|null */
function mayReturnNull() { }

function doesNotAcceptNull(stdClass $x) { }

// With potential error.
function withoutCheck() {
    $x = mayReturnNull();
    doesNotAcceptNull($x); // Potential error here.
}

// Safe - Alternative 1
function withCheck1() {
    $x = mayReturnNull();
    if ( ! $x instanceof stdClass) {
        throw new \LogicException('$x must be defined.');
    }
    doesNotAcceptNull($x);
}

// Safe - Alternative 2
function withCheck2() {
    $x = mayReturnNull();
    if ($x instanceof stdClass) {
        doesNotAcceptNull($x);
    }
}
Loading history...
253
            $association->setReferentialConstraint($constraint);
254
        }
255
        return $association;
256
    }
257
}
258