Passed
Pull Request — master (#202)
by Alex
05:37
created

getLaravelRelationName()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 8
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 5
c 1
b 0
f 0
dl 0
loc 8
rs 10
cc 2
nc 2
nop 1
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
    /**
26
     * @param SkipTokenInfo $skipToken
27
     * @param Model|Builder $sourceEntityInstance
28
     * @return mixed
29
     * @throws InvalidOperationException
30
     */
31
    protected function processSkipToken(SkipTokenInfo $skipToken, $sourceEntityInstance)
32
    {
33
        $parameters = [];
34
        $processed = [];
35
        $segments = $skipToken->getOrderByInfo()->getOrderByPathSegments();
36
        $values = $skipToken->getOrderByKeysInToken();
37
        $numValues = count($values);
38
        if ($numValues != count($segments)) {
39
            $msg = 'Expected '.count($segments).', got '.$numValues;
40
            throw new InvalidOperationException($msg);
41
        }
42
43
        for ($i = 0; $i < $numValues; $i++) {
44
            $relation = $segments[$i]->isAscending() ? '>' : '<';
45
            $name = $segments[$i]->getSubPathSegments()[0]->getName();
46
            $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

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