Issues (126)

src/Helpers/Helpers.php (1 issue)

Labels
Severity
1
<?php
2
3
declare(strict_types=1);
4
5
namespace AlgoWeb\ODataMetadata\Helpers;
6
7
use AlgoWeb\ODataMetadata\CsdlConstants;
8
use AlgoWeb\ODataMetadata\EdmConstants;
9
use AlgoWeb\ODataMetadata\Exception\InvalidOperationException;
10
use AlgoWeb\ODataMetadata\Interfaces\IEntityType;
11
use AlgoWeb\ODataMetadata\Interfaces\IModel;
12
use AlgoWeb\ODataMetadata\Interfaces\INavigationProperty;
13
use AlgoWeb\ODataMetadata\Interfaces\ITypeReference;
14
use AlgoWeb\ODataMetadata\StringConst;
15
16
abstract class Helpers
17
{
18
    public const AssociationNameEscapeChar          = '_';
19
    public const AssociationNameEscapeString        = '_';
20
    public const AssociationNameEscapeStringEscaped = '__';
21
22
    public static function getPathSegmentEntityType(ITypeReference $segmentType): IEntityType
23
    {
24
        return ($segmentType->isCollection() ? $segmentType->asCollection()->elementType() : $segmentType)->asEntity()->entityDefinition();
25
    }
26
    public static function findAcrossModels(IModel $model, string $qualifiedName, callable $finder, $ambiguousCreator)
27
    {
28
        $candidate = $finder($model, $qualifiedName);
29
30
        foreach ($model->getReferencedModels() as $reference) {
31
            $fromReference = $finder($reference, $qualifiedName);
32
            if ($fromReference != null) {
33
                $candidate = $candidate == null ? $fromReference : $ambiguousCreator($candidate, $fromReference);
34
            }
35
        }
36
37
        return $candidate;
38
    }
39
40
41
    /**
42
     * @param  string     $typeOf     type of the annotation being returned
43
     * @param  mixed      $annotation
44
     * @return mixed|null
45
     */
46
    public static function annotationValue(string $typeOf, $annotation)
47
    {
48
        if ($annotation != null) {
49
            if ('array' === $typeOf) {
50
                $isSpecificAnnotation = is_array($annotation);
51
            } elseif ('string' === $typeOf) {
52
                $isSpecificAnnotation = is_string($annotation);
53
            } elseif ('?string' === $typeOf) {
54
                $isSpecificAnnotation = (null !== $annotation) || is_string($annotation);
55
            } else {
56
                $isSpecificAnnotation = is_a($annotation, $typeOf);
57
            }
58
59
            if ($isSpecificAnnotation) {
60
                return $annotation;
61
            }
62
63
            /**if ($annotation instanceof IValue)
64
            {
65
            }*/
66
67
            throw new InvalidOperationException(StringConst::Annotations_TypeMismatch(get_class($annotation), $typeOf));
68
        }
69
70
        return null;
71
    }
72
73
    public static function classNameToLocalName(string $className): string
74
    {
75
        // Use the name of the type as its local name for annotations.
76
        // Filter out special characters to produce a valid name:
77
        // '.'                      Appears in qualified names.
78
        // '`', '[', ']', ','       Appear in generic instantiations.
79
        // '+'                      Appears in names of local classes.
80
        return str_replace(
81
            '_',
82
            '_____',
83
            str_replace(
84
                '.',
85
                '_',
86
                str_replace(
87
                    '[',
88
                    '',
89
                    str_replace(
90
                        ']',
91
                        '',
92
                        str_replace(
93
                            ',',
94
                            '__',
95
                            str_replace(
96
                                '`',
97
                                '___',
98
                                str_replace(
99
                                    '+',
100
                                    '____',
101
                                    $className
102
                                )
103
                            )
104
                        )
105
                    )
106
                )
107
            )
108
        );
109
    }
110
111
    /**
112
     * Gets the namespace used for the association serialized for a navigation property.
113
     *
114
     * @param  IModel              $model    model containing the navigation property
115
     * @param  INavigationProperty $property the navigation property
116
     * @return string              the association namespace
117
     */
118
    public static function getAssociationNamespace(IModel $model, INavigationProperty $property): string
119
    {
120
        $property->populateCaches();
121
        $associationNamespace = $model->getAnnotationValue('string', $property, EdmConstants::InternalUri, CsdlConstants::AssociationNamespaceAnnotation);
122
        if ($associationNamespace == null) {
123
            $associationNamespace = $property->getPrimary()->declaringEntityType()->getNamespace();
124
        }
125
126
        return $associationNamespace;
127
    }
128
129
130
    public static function getQualifiedAndEscapedPropertyName(INavigationProperty $property): string
131
    {
132
        return
133
            str_replace('.', self::AssociationNameEscapeChar, self::escapeName($property->declaringEntityType()->getNamespace())) .
0 ignored issues
show
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

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