Failed Conditions
Pull Request — master (#57)
by Alex
03:27
created

tryGetRelativeEntitySetPath()   C

Complexity

Conditions 14
Paths 28

Size

Total Lines 74
Code Lines 39

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 14
eloc 39
nc 28
nop 3
dl 0
loc 74
rs 6.2666
c 0
b 0
f 0

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
declare(strict_types=1);
4
5
6
namespace AlgoWeb\ODataMetadata\Helpers;
7
8
use AlgoWeb\ODataMetadata\EdmUtil;
9
use AlgoWeb\ODataMetadata\Interfaces\Expressions\IExpression;
10
use AlgoWeb\ODataMetadata\Interfaces\Expressions\IPathExpression;
11
use AlgoWeb\ODataMetadata\Interfaces\IEntitySet;
12
use AlgoWeb\ODataMetadata\Interfaces\IEntityType;
13
use AlgoWeb\ODataMetadata\Interfaces\IFunctionImport;
14
use AlgoWeb\ODataMetadata\Interfaces\IFunctionParameter;
15
use AlgoWeb\ODataMetadata\Interfaces\IModel;
16
use AlgoWeb\ODataMetadata\Interfaces\INavigationProperty;
17
18
/**
19
 * Trait FunctionImportHelpers.
20
 * @package AlgoWeb\ODataMetadata\Helpers
21
 */
22
trait FunctionImportHelpers
23
{
24
    /**
25
     * Analyzes IFunctionImport::EntitySet expression and returns a static IEdmEntitySet reference if available.
26
     *
27
     * @param  IEntitySet $entitySet the static entity set of the function import
28
     * @return bool       true if the entity set expression of the functionImport contains a static reference to an IEntitySet, otherwise false
29
     */
30
    public function tryGetStaticEntitySet(IEntitySet &$entitySet = null): bool
31
    {
32
        /** @var IFunctionImport $this */
33
        $entitySetReference = $this->getEntitySet();
34
        $entitySet          = ($entitySetReference !== null && $entitySetReference instanceof IEntitySet) ? $entitySetReference : null;
35
        return $entitySet !== null;
36
    }
37
38
    /**
39
     * Analyzes IFunctionImport::EntitySet expression and returns a relative path to an IEntitySet if available.
40
     * The path starts with the parameter and may have optional sequence of NavigationProperty and type casts segments.
41
     *
42
     * @param  IModel                     $model     the model containing the function import
43
     * @param  IFunctionParameter|null    $parameter the function import parameter from which the relative entity set
44
     *                                               path starts
45
     * @param  INavigationProperty[]|null $path      the optional sequence of navigation properties
46
     * @return bool                       true if the entity set expression of the functionImport contains a relative
47
     *                                              path an IEntitySet, otherwise false
48
     */
49
    public function tryGetRelativeEntitySetPath(
50
        IModel $model,
51
        IFunctionParameter &$parameter = null,
52
        array &$path = null
53
    ): bool {
54
        /**
55
         * @var IFunctionImport $this
56
         */
57
        $parameter = null;
58
        $path      = null;
59
60
        $entitySetPath = $this->getEntitySet();
61
        $entitySetPath = $entitySetPath instanceof IPathExpression ? $entitySetPath : null;
62
        if ($entitySetPath === null) {
63
            return false;
64
        }
65
66
        $pathToResolve = $entitySetPath->getPath();
67
        $numSegments   = count($pathToResolve);
68
        if (0 === $numSegments) {
69
            return false;
70
        }
71
72
        // Resolve the first segment as a parameter.
73
        $parameter = $this->findParameter($pathToResolve[0]);
74
        if ($parameter === null) {
75
            return false;
76
        }
77
78
        if (1 === $numSegments) {
79
            $path = [];
80
            return true;
81
        } else {
82
            // Get the entity type of the parameter, treat the rest of the path as a sequence of navprops.
83
            assert($parameter instanceof IFunctionParameter);
84
            /**
85
             * @var IEntityType $entityType
86
             */
87
            $entityType = Helpers::getPathSegmentEntityType($parameter->getType());
88
            /**
89
             * @var INavigationProperty[] $pathList
90
             */
91
            $pathList = [];
92
            for ($i = 1; $i < $numSegments; ++$i) {
93
                $segment = $pathToResolve[$i];
94
                if (EdmUtil::isQualifiedName($segment)) {
95
                    if ($i == count($pathToResolve) - 1) {
96
                        // The last segment must not be type cast.
97
                        return false;
98
                    }
99
                    /**
100
                     * @var IEntityType|null $subType ;
101
                     */
102
                    $subType = $model->findDeclaredType($segment);
103
                    $subType = $subType instanceof IEntityType ? $subType : null;
104
                    if ($subType == null || !$subType->isOrInheritsFrom($entityType)) {
105
                        return false;
106
                    }
107
108
                    $entityType = $subType;
109
                } else {
110
                    $navProp = $entityType->findProperty($segment);
111
                    $navProp = $navProp instanceof INavigationProperty ? $navProp : null;
112
                    if ($navProp == null) {
113
                        return false;
114
                    }
115
116
                    $pathList[] = $navProp;
117
                    $entityType = Helpers::getPathSegmentEntityType($navProp->getType());
0 ignored issues
show
Bug introduced by
It seems like $navProp->getType() can also be of type null; however, parameter $segmentType of AlgoWeb\ODataMetadata\He...PathSegmentEntityType() does only seem to accept AlgoWeb\ODataMetadata\Interfaces\ITypeReference, 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

117
                    $entityType = Helpers::getPathSegmentEntityType(/** @scrutinizer ignore-type */ $navProp->getType());
Loading history...
118
                }
119
            }
120
121
            $path = $pathList;
122
            return true;
123
        }
124
    }
125
126
    /**
127
     * @return IExpression|null gets the entity set containing entities returned by this function import
128
     */
129
    abstract public function getEntitySet(): ?IExpression;
130
}
131