Passed
Pull Request — master (#211)
by Alex
05:13
created

SerialiserUtilities::checkElementsInput()   B

Complexity

Conditions 7
Paths 5

Size

Total Lines 11
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 7
c 0
b 0
f 0
dl 0
loc 11
rs 8.8333
cc 7
nc 5
nop 1
1
<?php
2
/**
3
 * Created by PhpStorm.
4
 * User: alex
5
 * Date: 16/02/20
6
 * Time: 1:19 PM.
7
 */
8
namespace AlgoWeb\PODataLaravel\Serialisers;
9
10
use Illuminate\Database\Eloquent\Model;
11
use Illuminate\Support\Collection;
12
use POData\Common\InvalidOperationException;
13
use POData\Common\Messages;
14
use POData\Common\ODataException;
15
use POData\Providers\Metadata\IMetadataProvider;
16
use POData\Providers\Metadata\ResourceEntityType;
17
use POData\Providers\Metadata\ResourceType;
18
use POData\Providers\Metadata\Type\IType;
19
use POData\Providers\Query\QueryResult;
20
21
abstract class SerialiserUtilities
22
{
23
    /**
24
     * @param  int  $resourceKind
25
     * @return bool
26
     */
27
    public static function isMatchPrimitive($resourceKind)
28
    {
29
        if (16 > $resourceKind) {
30
            return false;
31
        }
32
        if (28 < $resourceKind) {
33
            return false;
34
        }
35
        return 0 == ($resourceKind % 4);
36
    }
37
38
    /**
39
     * @param  QueryResult               $entryObjects
40
     * @throws InvalidOperationException
41
     */
42
    public static function checkElementsInput(QueryResult &$entryObjects)
43
    {
44
        $res = $entryObjects->results;
45
        if (!(is_array($res) || $res instanceof Collection)) {
46
            throw new InvalidOperationException('!is_array($entryObjects->results)');
47
        }
48
        if (is_array($res) && 0 == count($res)) {
49
            $entryObjects->hasMore = false;
50
        }
51
        if ($res instanceof Collection && 0 == $res->count()) {
52
            $entryObjects->hasMore = false;
53
        }
54
    }
55
56
    /**
57
     * @param  QueryResult               $entryObject
58
     * @throws InvalidOperationException
59
     */
60
    public static function checkSingleElementInput(QueryResult $entryObject)
61
    {
62
        if (!$entryObject->results instanceof Model) {
63
            $res = $entryObject->results;
64
            $msg = is_array($res) ? 'Entry object must be single Model' : get_class($res);
65
            throw new InvalidOperationException($msg);
66
        }
67
    }
68
69
    /**
70
     * @param  Model                     $entityInstance
71
     * @param  ResourceType              $resourceType
72
     * @param  string                    $containerName
73
     * @throws InvalidOperationException
74
     * @throws ODataException
75
     * @throws \ReflectionException
76
     * @return string
77
     */
78
    public static function getEntryInstanceKey($entityInstance, ResourceType $resourceType, $containerName)
79
    {
80
        $typeName = $resourceType->getName();
81
        $keyProperties = $resourceType->getKeyProperties();
82
        if (0 == count($keyProperties)) {
83
            throw new InvalidOperationException('count($keyProperties) == 0');
84
        }
85
        $keyString = $containerName . '(';
86
        $comma = null;
87
        foreach ($keyProperties as $keyName => $resourceProperty) {
88
            $keyType = $resourceProperty->getInstanceType();
89
            if (!$keyType instanceof IType) {
90
                throw new InvalidOperationException('$keyType not instanceof IType');
91
            }
92
            $keyName = $resourceProperty->getName();
93
            $keyValue = $entityInstance->$keyName;
94
            if (!isset($keyValue)) {
95
                throw ODataException::createInternalServerError(
96
                    Messages::badQueryNullKeysAreNotSupported($typeName, $keyName)
97
                );
98
            }
99
100
            $keyValue = $keyType->convertToOData($keyValue);
101
            $keyString .= $comma . $keyName . '=' . $keyValue;
102
            $comma = ',';
103
        }
104
105
        $keyString .= ')';
106
107
        return $keyString;
108
    }
109
110
    /**
111
     * @param  ResourceEntityType              $resourceType
112
     * @param  IMetadataProvider               $metadata
113
     * @param  string                          $payloadClass
114
     * @throws InvalidOperationException
115
     * @throws \ReflectionException
116
     * @return ResourceEntityType|ResourceType
117
     */
118
    public static function getConcreteTypeFromAbstractType(
119
        ResourceEntityType $resourceType,
120
        IMetadataProvider $metadata,
121
        $payloadClass
122
    ) {
123
        if ($resourceType->isAbstract()) {
124
            $derived = $metadata->getDerivedTypes($resourceType);
125
            if (0 == count($derived)) {
126
                throw new InvalidOperationException('Supplied abstract type must have at least one derived type');
127
            }
128
            $derived = array_filter(
129
                $derived,
130
                function (ResourceType $element) {
131
                    return !$element->isAbstract();
132
                }
133
            );
134
            foreach ($derived as $rawType) {
135
                $name = $rawType->getInstanceType()->getName();
136
                if ($payloadClass == $name) {
137
                    $resourceType = $rawType;
138
                    break;
139
                }
140
            }
141
        }
142
        // despite all set up, checking, etc, if we haven't picked a concrete resource type,
143
        // wheels have fallen off, so blow up
144
        if ($resourceType->isAbstract()) {
145
            throw new InvalidOperationException('Concrete resource type not selected for payload ' . $payloadClass);
146
        }
147
        return $resourceType;
148
    }
149
}
150