Passed
Pull Request — master (#202)
by Alex
06:30
created

checkSourceInstance()   A

Complexity

Conditions 5
Paths 3

Size

Total Lines 12
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 6
c 1
b 0
f 0
dl 0
loc 12
rs 9.6111
cc 5
nc 3
nop 2
1
<?php
2
/**
3
 * Created by PhpStorm.
4
 * User: alex
5
 * Date: 14/02/20
6
 * Time: 10:54 PM
7
 */
8
9
namespace AlgoWeb\PODataLaravel\Query;
10
11
use Illuminate\Database\Eloquent\Builder;
12
use Illuminate\Database\Eloquent\Collection;
13
use Illuminate\Database\Eloquent\Model;
14
use Illuminate\Database\Eloquent\Relations\Relation;
15
use Illuminate\Support\Facades\App;
16
use POData\Providers\Metadata\ResourceSet;
17
use POData\UriProcessor\QueryProcessor\SkipTokenParser\SkipTokenInfo;
18
use POData\Common\InvalidOperationException;
19
use POData\Common\ODataException;
20
use POData\UriProcessor\ResourcePathProcessor\SegmentParser\KeyDescriptor;
21
use Symfony\Component\Process\Exception\InvalidArgumentException;
22
23
trait LaravelReadQueryUtilityTrait
24
{
25
    protected $name;
26
27
    /**
28
     * @param SkipTokenInfo $skipToken
29
     * @param Model|Builder $sourceEntityInstance
30
     * @return mixed
31
     * @throws InvalidOperationException
32
     */
33
    protected function processSkipToken(SkipTokenInfo $skipToken, $sourceEntityInstance)
34
    {
35
        $parameters = [];
36
        $processed = [];
37
        $segments = $skipToken->getOrderByInfo()->getOrderByPathSegments();
38
        $values = $skipToken->getOrderByKeysInToken();
39
        $numValues = count($values);
40
        if ($numValues != count($segments)) {
41
            $msg = 'Expected '.count($segments).', got '.$numValues;
42
            throw new InvalidOperationException($msg);
43
        }
44
45
        for ($i = 0; $i < $numValues; $i++) {
46
            $relation = $segments[$i]->isAscending() ? '>' : '<';
47
            $name = $segments[$i]->getSubPathSegments()[0]->getName();
48
            $parameters[$name] = ['direction' => $relation, 'value' => trim($values[$i][0], '\'')];
0 ignored issues
show
Bug introduced by
$values[$i][0] of type POData\Providers\Metadata\Type\IType is incompatible with the type string expected by parameter $str of trim(). ( Ignorable by Annotation )

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

48
            $parameters[$name] = ['direction' => $relation, 'value' => trim(/** @scrutinizer ignore-type */ $values[$i][0], '\'')];
Loading history...
49
        }
50
51
        foreach ($parameters as $name => $line) {
52
            $processed[$name] = ['direction' => $line['direction'], 'value' => $line['value']];
53
            $sourceEntityInstance = $sourceEntityInstance
54
                ->orWhere(
55
                    function (Builder $query) use ($processed) {
56
                        foreach ($processed as $key => $proc) {
57
                            $query->where($key, $proc['direction'], $proc['value']);
58
                        }
59
                    }
60
                );
61
            // now we've handled the later-in-order segment for this key, drop it back to equality in prep
62
            // for next key - same-in-order for processed keys and later-in-order for next
63
            $processed[$name]['direction'] = '=';
64
        }
65
        return $sourceEntityInstance;
66
    }
67
68
    /**
69
     * @param  ResourceSet $resourceSet
70
     * @return mixed
71
     * @throws \ReflectionException
72
     */
73
    protected function getSourceEntityInstance(ResourceSet $resourceSet)
74
    {
75
        $entityClassName = $resourceSet->getResourceType()->getInstanceType()->name;
76
        return App::make($entityClassName);
77
    }
78
79
    /**
80
     * @param Model|Relation|null $source
81
     * @param ResourceSet|null $resourceSet
82
     * @return Model|Relation|mixed|null
83
     * @throws \ReflectionException
84
     */
85
    protected function checkSourceInstance($source, ResourceSet $resourceSet = null)
86
    {
87
        if (!(null == $source || $source instanceof Model || $source instanceof Relation)) {
0 ignored issues
show
introduced by
$source is always a sub-type of Illuminate\Database\Eloquent\Relations\Relation.
Loading history...
88
            $msg = 'Source entity instance must be null, a model, or a relation.';
89
            throw new InvalidArgumentException($msg);
90
        }
91
92
        if (null == $source) {
93
            $source = $this->getSourceEntityInstance(/** @scrutinizer ignore-type */$resourceSet);
94
        }
95
96
        return $source;
97
    }
98
99
    /**
100
     * @param Model|Builder $sourceEntityInstance
101
     * @param  KeyDescriptor|null        $keyDescriptor
102
     * @throws InvalidOperationException
103
     */
104
    protected function processKeyDescriptor(&$sourceEntityInstance, KeyDescriptor $keyDescriptor = null)
105
    {
106
        if ($keyDescriptor) {
107
            $table = ($sourceEntityInstance instanceof Model) ? $sourceEntityInstance->getTable() . '.' : '';
108
            foreach ($keyDescriptor->getValidatedNamedValues() as $key => $value) {
109
                $trimValue = trim($value[0], '\'');
110
                $sourceEntityInstance = $sourceEntityInstance->where($table . $key, $trimValue);
111
            }
112
        }
113
    }
114
115
    /**
116
     * @param  string[]|null $eagerLoad
117
     * @return array
118
     * @throws InvalidOperationException
119
     */
120
    protected function processEagerLoadList(array $eagerLoad = null)
121
    {
122
        $load = (null === $eagerLoad) ? [] : $eagerLoad;
123
        $rawLoad = [];
124
        foreach ($load as $line) {
125
            if (!is_string($line)) {
126
                throw new InvalidOperationException('Eager-load elements must be non-empty strings');
127
            }
128
            $lineParts = explode('/', $line);
129
            $numberOfParts = count($lineParts);
130
            for ($i = 0; $i < $numberOfParts; $i++) {
131
                $lineParts[$i] = $this->getLaravelRelationName($lineParts[$i]);
132
            }
133
            $remixLine = implode('.', $lineParts);
134
            $rawLoad[] = $remixLine;
135
        }
136
        return $rawLoad;
137
    }
138
139
    /**
140
     * @param  string $odataProperty
141
     * @return string
142
     */
143
    protected function getLaravelRelationName($odataProperty)
144
    {
145
        $laravelProperty = $odataProperty;
146
        $pos = strrpos($laravelProperty, '_');
147
        if ($pos !== false) {
148
            $laravelProperty = substr($laravelProperty, 0, $pos);
149
        }
150
        return $laravelProperty;
151
    }
152
}
153