getCurrentExpandedProjectionNode()   B
last analyzed

Complexity

Conditions 7
Paths 10

Size

Total Lines 32
Code Lines 17

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 17
c 1
b 0
f 0
dl 0
loc 32
rs 8.8333
cc 7
nc 10
nop 0
1
<?php
2
3
declare(strict_types=1);
4
/**
5
 * Created by PhpStorm.
6
 * User: alex
7
 * Date: 15/02/20
8
 * Time: 8:05 PM.
9
 */
10
namespace AlgoWeb\PODataLaravel\Serialisers;
11
12
use POData\Common\InvalidOperationException;
13
use POData\UriProcessor\QueryProcessor\ExpandProjectionParser\ExpandedProjectionNode;
14
use POData\UriProcessor\QueryProcessor\ExpandProjectionParser\ProjectionNode;
15
use POData\UriProcessor\QueryProcessor\ExpandProjectionParser\RootProjectionNode;
16
use POData\UriProcessor\RequestDescription;
17
18
trait SerialiseNavigationTrait
19
{
20
    /**
21
     * @var RootProjectionNode
22
     */
23
    protected $rootNode = null;
24
25
    /**
26
     * Find a 'ExpandedProjectionNode' instance in the projection tree
27
     * which describes the current segment.
28
     *
29
     * @throws InvalidOperationException
30
     * @return null|RootProjectionNode|ExpandedProjectionNode
31
     */
32
    protected function getCurrentExpandedProjectionNode()
33
    {
34
        if (null === $this->rootNode) {
35
            $this->rootNode = $this->getRequest()->getRootProjectionNode();
36
        }
37
        $expandedProjectionNode = $this->rootNode;
38
        if (null === $expandedProjectionNode) {
39
            return null;
40
        }
41
        $segmentNames = $this->getLightStack();
42
        $depth        = count($segmentNames);
43
        // $depth == 1 means serialization of root entry
44
        //(the resource identified by resource path) is going on,
45
        //so control won't get into the below for loop.
46
        //we will directly return the root node,
47
        //which is 'ExpandedProjectionNode'
48
        // for resource identified by resource path.
49
        if (!empty($segmentNames)) {
50
            for ($i = 1; $i < $depth; ++$i) {
51
                $segName                = $segmentNames[$i]['prop'];
52
                $expandedProjectionNode = $expandedProjectionNode->findNode($segName);
53
                if (null === $expandedProjectionNode) {
54
                    throw new InvalidOperationException('is_null($expandedProjectionNode)');
55
                }
56
                if (!$expandedProjectionNode instanceof ExpandedProjectionNode) {
57
                    $msg = '$expandedProjectionNode not instanceof ExpandedProjectionNode';
58
                    throw new InvalidOperationException($msg);
59
                }
60
            }
61
        }
62
63
        return $expandedProjectionNode;
64
    }
65
66
    /**
67
     * Gets collection of projection nodes under the current node.
68
     *
69
     * @throws InvalidOperationException
70
     * @return ProjectionNode[]|ExpandedProjectionNode[]|null List of nodes describing projections for the current
71
     *                                                        segment, If this method returns null it means no
72
     *                                                        projections are to be applied and the entire resource for
73
     *                                                        the current segment should be serialized, If it returns
74
     *                                                        non-null only the properties described by the returned
75
     *                                                        projection segments should be serialized
76
     */
77
    protected function getProjectionNodes()
78
    {
79
        $expandedProjectionNode = $this->getCurrentExpandedProjectionNode();
80
        if (null === $expandedProjectionNode || $expandedProjectionNode->canSelectAllProperties()) {
81
            return null;
82
        }
83
84
        return $expandedProjectionNode->getChildNodes();
85
    }
86
87
    /**
88
     * Check whether to expand a navigation property or not.
89
     *
90
     * @param string $navigationPropertyName Name of navigation property in question
91
     *
92
     * @throws InvalidOperationException
93
     * @return bool                      True if the given navigation should be expanded, otherwise false
94
     */
95
    protected function shouldExpandSegment(string $navigationPropertyName)
96
    {
97
        $expandedProjectionNode = $this->getCurrentExpandedProjectionNode();
98
        if (null === $expandedProjectionNode) {
99
            return false;
100
        }
101
        $expandedProjectionNode = $expandedProjectionNode->findNode($navigationPropertyName);
102
103
        // null is a valid input to an instanceof call as of PHP 5.6 - will always return false
104
        return $expandedProjectionNode instanceof ExpandedProjectionNode;
105
    }
106
107
    /**
108
     * Gets reference to the request submitted by client.
109
     *
110
     * @throws InvalidOperationException
111
     * @return RequestDescription
112
     */
113
    abstract public function getRequest();
114
115
    /**
116
     * @return array[]
117
     */
118
    abstract protected function getLightStack();
119
}
120