Completed
Push — master ( 852076...2b713c )
by Alex
23s queued 14s
created

Helpers::AnnotationValue()   B

Complexity

Conditions 7
Paths 11

Size

Total Lines 25
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 1 Features 0
Metric Value
cc 7
eloc 13
c 2
b 1
f 0
nc 11
nop 2
dl 0
loc 25
rs 8.8333
1
<?php
2
3
declare(strict_types=1);
4
5
6
namespace AlgoWeb\ODataMetadata\Helpers;
7
8
use AlgoWeb\ODataMetadata\CsdlConstants;
9
use AlgoWeb\ODataMetadata\EdmConstants;
10
use AlgoWeb\ODataMetadata\Exception\InvalidOperationException;
11
use AlgoWeb\ODataMetadata\Interfaces\IEntityType;
12
use AlgoWeb\ODataMetadata\Interfaces\IModel;
13
use AlgoWeb\ODataMetadata\Interfaces\INavigationProperty;
14
use AlgoWeb\ODataMetadata\Interfaces\ITypeReference;
15
use AlgoWeb\ODataMetadata\StringConst;
16
17
abstract class Helpers
18
{
19
    public const AssociationNameEscapeChar          = '_';
20
    public const AssociationNameEscapeString        = '_';
21
    public const AssociationNameEscapeStringEscaped = '__';
22
23
    public static function GetPathSegmentEntityType(ITypeReference $segmentType): IEntityType
24
    {
25
        return ($segmentType->IsCollection() ? $segmentType->AsCollection()->ElementType() : $segmentType)->AsEntity()->EntityDefinition();
26
    }
27
    public static function FindAcrossModels(IModel $model, string $qualifiedName, callable $finder, $ambiguousCreator)
28
    {
29
        $candidate = $finder($model, $qualifiedName);
30
31
        foreach ($model->getReferencedModels() as $reference) {
32
            $fromReference = $finder($reference, $qualifiedName);
33
            if ($fromReference != null) {
34
                $candidate = $candidate == null ? $fromReference : $ambiguousCreator($candidate, $fromReference);
35
            }
36
        }
37
38
        return $candidate;
39
    }
40
41
42
    /**
43
     * @param  string     $typeOf     type of the annotation being returned
44
     * @param  mixed      $annotation
45
     * @return mixed|null
46
     */
47
    public static function AnnotationValue(string $typeOf, $annotation)
48
    {
49
        if ($annotation != null) {
50
            if ('array' === $typeOf) {
51
                $isSpecificAnnotation = is_array($annotation);
52
            } elseif ('string' === $typeOf) {
53
                $isSpecificAnnotation = is_string($annotation);
54
            } elseif ('?string' === $typeOf) {
55
                $isSpecificAnnotation = (null !== $annotation) || is_string($annotation);
56
            } else {
57
                $isSpecificAnnotation = is_a($annotation, $typeOf);
58
            }
59
60
            if ($isSpecificAnnotation) {
61
                return $annotation;
62
            }
63
64
            /**if ($annotation instanceof IValue)
65
            {
66
            }*/
67
68
            throw new InvalidOperationException(StringConst::Annotations_TypeMismatch(get_class($annotation), $typeOf));
69
        }
70
71
        return null;
72
    }
73
74
    public static function classNameToLocalName(string $className): string
75
    {
76
        // Use the name of the type as its local name for annotations.
77
        // Filter out special characters to produce a valid name:
78
        // '.'                      Appears in qualified names.
79
        // '`', '[', ']', ','       Appear in generic instantiations.
80
        // '+'                      Appears in names of local classes.
81
        return str_replace(
82
            '_',
83
            '_____',
84
            str_replace(
85
                '.',
86
                '_',
87
                str_replace(
88
                    '[',
89
                    '',
90
                    str_replace(
91
                        ']',
92
                        '',
93
                        str_replace(
94
                            ',',
95
                            '__',
96
                            str_replace(
97
                                '`',
98
                                '___',
99
                                str_replace(
100
                                    '+',
101
                                    '____',
102
                                    $className
103
                                )
104
                            )
105
                        )
106
                    )
107
                )
108
            )
109
        );
110
    }
111
112
    /**
113
     * Gets the namespace used for the association serialized for a navigation property.
114
     *
115
     * @param  IModel              $model    model containing the navigation property
116
     * @param  INavigationProperty $property the navigation property
117
     * @return string              the association namespace
118
     */
119
    public static function GetAssociationNamespace(IModel $model, INavigationProperty $property): string
120
    {
121
        $property->PopulateCaches();
122
        $associationNamespace = $model->GetAnnotationValue('string', $property, EdmConstants::InternalUri, CsdlConstants::AssociationNamespaceAnnotation);
123
        if ($associationNamespace == null) {
124
            $associationNamespace = $property->GetPrimary()->DeclaringEntityType()->getNamespace();
125
        }
126
127
        return $associationNamespace;
128
    }
129
130
131
    public static function GetQualifiedAndEscapedPropertyName(INavigationProperty $property): string
132
    {
133
        return
134
            str_replace('.', self::AssociationNameEscapeChar, self::EscapeName($property->DeclaringEntityType()->getNamespace())) .
0 ignored issues
show
Bug introduced by
It seems like $property->DeclaringEntityType()->getNamespace() can also be of type null; however, parameter $name of AlgoWeb\ODataMetadata\He...s\Helpers::EscapeName() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

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

134
            str_replace('.', self::AssociationNameEscapeChar, self::EscapeName(/** @scrutinizer ignore-type */ $property->DeclaringEntityType()->getNamespace())) .
Loading history...
135
            self::AssociationNameEscapeChar .
136
            self::EscapeName($property->DeclaringEntityType()->getNamespace()) .
137
            self::AssociationNameEscapeChar .
138
            self::EscapeName($property->getName());
139
    }
140
141
    private static function EscapeName(string $name): string
142
    {
143
        return str_replace(self::AssociationNameEscapeString, self::AssociationNameEscapeStringEscaped, $name);
144
    }
145
}
146