Test Failed
Push — master ( 4c7cec...9fd0ac )
by Julien
05:42
created

EagerLoading::findWithBy()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 10
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 6

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 2
eloc 5
c 1
b 0
f 0
nc 2
nop 2
dl 0
loc 10
ccs 0
cts 6
cp 0
crap 6
rs 10
1
<?php
2
3
/**
4
 * This file is part of the Zemit Framework.
5
 *
6
 * (c) Zemit Team <[email protected]>
7
 *
8
 * For the full copyright and license information, please view the LICENSE.txt
9
 * file that was distributed with this source code.
10
 */
11
12
namespace Zemit\Mvc\Model;
13
14
use Phalcon\Mvc\ModelInterface;
15
use Zemit\Mvc\Model\EagerLoading\Loader;
16
17
trait EagerLoading
18
{
19
    /**
20
     * <code>
21
     * <?php
22
     *
23
     * $limit  = 100;
24
     * $offset = max(0, $this->request->getQuery('page', 'int') - 1) * $limit;
25
     *
26
     * $manufacturers = Manufacturer::with('Robots.Parts', [
27
     *     'limit' => [$limit, $offset]
28
     * ]);
29
     *
30
     * foreach ($manufacturers as $manufacturer) {
31
     *     foreach ($manufacturer->robots as $robot) {
32
     *         foreach ($robot->parts as $part) { ... }
33
     *     }
34
     * }
35
     *
36
     * </code>
37
     *
38
     * @param mixed ...$arguments
39
     */
40
    public static function findWith(array ...$arguments)
41
    {
42
        $parameters = self::getParametersFromArguments($arguments);
43
        $list = static::find($parameters);
0 ignored issues
show
Bug introduced by
The method find() does not exist on Zemit\Mvc\Model\EagerLoading. Since you implemented __callStatic, consider adding a @method annotation. ( Ignorable by Annotation )

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

43
        /** @scrutinizer ignore-call */ 
44
        $list = static::find($parameters);
Loading history...
44
        if ($list->count()) {
45
            return Loader::fromResultset($list, ...$arguments);
46
        }
47
        
48
        return $list;
49
    }
50
    
51
    /**
52
     * Same as EagerLoadingTrait::findWith() for a single record
53
     *
54
     * @param mixed ...$arguments
55
     * @return false|\Phalcon\Mvc\ModelInterface
56
     */
57
    public static function findFirstWith(array ...$arguments)
58
    {
59
        $parameters = self::getParametersFromArguments($arguments);
60
        $entity = static::findFirst($parameters);
0 ignored issues
show
Bug introduced by
The method findFirst() does not exist on Zemit\Mvc\Model\EagerLoading. Since you implemented __callStatic, consider adding a @method annotation. ( Ignorable by Annotation )

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

60
        /** @scrutinizer ignore-call */ 
61
        $entity = static::findFirst($parameters);
Loading history...
61
        if ($entity) {
62
            return Loader::fromModel($entity, ...$arguments);
0 ignored issues
show
Bug introduced by
It seems like $entity can also be of type Phalcon\Mvc\ModelInterface[]; however, parameter $subject of Zemit\Mvc\Model\EagerLoading\Loader::fromModel() does only seem to accept Phalcon\Mvc\ModelInterface, 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

62
            return Loader::fromModel(/** @scrutinizer ignore-type */ $entity, ...$arguments);
Loading history...
63
        }
64
        
65
        return $entity;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $entity also could return the type Phalcon\Mvc\ModelInterface[] which is incompatible with the documented return type Phalcon\Mvc\ModelInterface|false.
Loading history...
66
    }
67
    
68
    /**
69
     * @deprecated
70
     * Alias of findWith
71
     */
72
    public static function with(array ...$arguments)
73
    {
74
        return self::findWith(...$arguments);
75
    }
76
    
77
    /**
78
     * @deprecated
79
     * Alias of findWith
80
     */
81
    public static function firstWith(array ...$arguments)
82
    {
83
        return self::findWith(...$arguments);
84
    }
85
    
86
    /**
87
     * Call magic method to make the with works in an implicit way
88
     * @todo change it to behavior missingMethods()
89
     */
90
    public static function __callStatic(string $method, array $arguments = [])
91
    {
92
        // Single - FindFirstBy...
93
        if (strpos($method, 'findFirstWithBy') === 0 || strpos($method, 'firstWithBy') === 0) {
94
            
95
            $forwardMethod = str_replace(['findFirstWithBy', 'firstWithBy'], 'findFirstBy', $method);
96
            return self::findFirstWithBy($forwardMethod, $arguments);
97
        }
98
        
99
        // List - FindWithBy...
100
        elseif (strpos($method, 'findWithBy') === 0 || strpos($method, 'withBy') === 0) {
101
    
102
            $forwardMethod = str_replace(['findWithBy', 'withBy'], 'findBy', $method);
103
            return self::findWithBy($forwardMethod, $arguments);
104
        }
105
    
106
        return parent::$method(...$arguments);
107
    }
108
    
109
    /**
110
     * Call native Phalcon FindFirstBy function then eager load relationships from the model
111
     */
112
    private static function findFirstWithBy(string $forwardMethod, array $arguments): ModelInterface
113
    {
114
        $parameters = self::getParametersFromArguments($arguments);
115
        $entity = parent::$forwardMethod($parameters);
116
    
117
        if ($entity) {
118
            return Loader::fromModel($entity, ...$arguments);
119
        }
120
    
121
        return $entity;
122
    }
123
    
124
    /**
125
     * Call native Phalcon findBy function then eager load relationships from the resultset
126
     */
127
    private static function findWithBy(string $forwardMethod, array $arguments): ?array
128
    {
129
        $parameters = self::getParametersFromArguments($arguments);
130
        $list = parent::$forwardMethod($parameters);
131
    
132
        if ($list->count()) {
133
            return Loader::fromResultset($list, ...$arguments);
134
        }
135
    
136
        return $list;
137
    }
138
    
139
    /**
140
     * <code>
141
     *
142
     * $manufacturer = Manufacturer::findFirstById(51);
143
     *
144
     * $manufacturer->load('Robots.Parts');
145
     *
146
     * foreach ($manufacturer->robots as $robot) {
147
     *    foreach ($robot->parts as $part) { ... }
148
     * }
149
     *
150
     * </code>
151
     *
152
     * @param mixed ...$arguments
153
     * @return \Phalcon\Mvc\ModelInterface
154
     */
155
    public function load(array ...$arguments)
156
    {
157
        return Loader::fromModel($this, ...$arguments);
0 ignored issues
show
Bug introduced by
$this of type Zemit\Mvc\Model\EagerLoading is incompatible with the type Phalcon\Mvc\ModelInterface expected by parameter $subject of Zemit\Mvc\Model\EagerLoading\Loader::fromModel(). ( Ignorable by Annotation )

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

157
        return Loader::fromModel(/** @scrutinizer ignore-type */ $this, ...$arguments);
Loading history...
158
    }
159
    
160
    /**
161
     * Get the query parameters from a list of arguments
162
     * @return mixed
163
     */
164
    public static function getParametersFromArguments(array &$arguments)
165
    {
166
        $parameters = null;
167
        
168
        if (!empty($arguments)) {
169
            $numArgs = count($arguments);
170
            $lastArg = $numArgs - 1;
171
            
172
            if ($numArgs >= 2) {
173
                $parameters = $arguments[$lastArg];
174
                unset($arguments[$lastArg]);
175
                
176
                if (isset($parameters['columns'])) {
177
                    throw new \LogicException('Results from database must be full models, do not use `columns` key');
178
                }
179
            }
180
        }
181
        
182
        return $parameters;
183
    }
184
}
185