Test Failed
Push — master ( a835f3...4c7cec )
by Julien
04:50
created

EagerLoading::firstWith()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 1
c 1
b 0
f 0
nc 1
nop 1
dl 0
loc 3
ccs 0
cts 2
cp 0
crap 2
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 Zemit\Mvc\Model\EagerLoading\Loader;
15
16
trait EagerLoading
17
{
18
    /**
19
     * <code>
20
     * <?php
21
     *
22
     * $limit  = 100;
23
     * $offset = max(0, $this->request->getQuery('page', 'int') - 1) * $limit;
24
     *
25
     * $manufacturers = Manufacturer::with('Robots.Parts', [
26
     *     'limit' => [$limit, $offset]
27
     * ]);
28
     *
29
     * foreach ($manufacturers as $manufacturer) {
30
     *     foreach ($manufacturer->robots as $robot) {
31
     *         foreach ($robot->parts as $part) { ... }
32
     *     }
33
     * }
34
     *
35
     * </code>
36
     *
37
     * @param mixed ...$arguments
38
     */
39
    public static function findWith(array ...$arguments)
40
    {
41
        $parameters = self::getParametersFromArguments($arguments);
42
        $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

42
        /** @scrutinizer ignore-call */ 
43
        $list = static::find($parameters);
Loading history...
43
        if ($list->count()) {
44
            return Loader::fromResultset($list, ...$arguments);
45
        }
46
        
47
        return $list;
48
    }
49
    
50
    /**
51
     * Same as EagerLoadingTrait::findWith() for a single record
52
     *
53
     * @param mixed ...$arguments
54
     * @return false|\Phalcon\Mvc\ModelInterface
55
     */
56
    public static function findFirstWith(array ...$arguments)
57
    {
58
        $parameters = self::getParametersFromArguments($arguments);
59
        $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

59
        /** @scrutinizer ignore-call */ 
60
        $entity = static::findFirst($parameters);
Loading history...
60
        if ($entity) {
61
            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

61
            return Loader::fromModel(/** @scrutinizer ignore-type */ $entity, ...$arguments);
Loading history...
62
        }
63
        
64
        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...
65
    }
66
    
67
    /**
68
     * @deprecated
69
     * Alias of findWith
70
     */
71
    public static function with(array ...$arguments)
72
    {
73
        return self::findWith(...$arguments);
74
    }
75
    
76
    /**
77
     * @deprecated
78
     * Alias of findWith
79
     */
80
    public static function firstWith(array ...$arguments)
81
    {
82
        return self::findWith(...$arguments);
83
    }
84
    
85
    /**
86
     * Call magic method to make the with works in an implicit way
87
     * @todo change it to behavior missingMethods()
88
     * @todo change it
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
            $parameters = self::getParametersFromArguments($arguments);
97
            $entity = parent::$forwardMethod($parameters);
98
            
99
            if ($entity) {
100
                return Loader::fromModel($entity, ...$arguments);
101
            }
102
            
103
            return $entity;
104
        }
105
        
106
        // List - FindWithBy...
107
        elseif (strpos($method, 'findWithBy') === 0 || strpos($method, 'withBy') === 0) {
108
            
109
            $forwardMethod = str_replace(['findWithBy', 'withBy'], 'findBy', $method);
110
            $parameters = self::getParametersFromArguments($arguments);
111
            $list = parent::$forwardMethod($parameters);
112
            
113
            if ($list->count()) {
114
                return Loader::fromResultset($list, ...$arguments);
115
            }
116
            
117
            return $list;
118
        }
119
    
120
        return parent::$method(...$arguments);
121
    }
122
    
123
    /**
124
     * <code>
125
     *
126
     * $manufacturer = Manufacturer::findFirstById(51);
127
     *
128
     * $manufacturer->load('Robots.Parts');
129
     *
130
     * foreach ($manufacturer->robots as $robot) {
131
     *    foreach ($robot->parts as $part) { ... }
132
     * }
133
     *
134
     * </code>
135
     *
136
     * @param mixed ...$arguments
137
     * @return \Phalcon\Mvc\ModelInterface
138
     */
139
    public function load(array ...$arguments)
140
    {
141
        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

141
        return Loader::fromModel(/** @scrutinizer ignore-type */ $this, ...$arguments);
Loading history...
142
    }
143
    
144
    /**
145
     * Get the query parameters from a list of arguments
146
     * @return mixed
147
     */
148
    public static function getParametersFromArguments(array &$arguments)
149
    {
150
        $parameters = null;
151
        
152
        if (!empty($arguments)) {
153
            $numArgs = count($arguments);
154
            $lastArg = $numArgs - 1;
155
            
156
            if ($numArgs >= 2) {
157
                $parameters = $arguments[$lastArg];
158
                unset($arguments[$lastArg]);
159
                
160
                if (isset($parameters['columns'])) {
161
                    throw new \LogicException('Results from database must be full models, do not use `columns` key');
162
                }
163
            }
164
        }
165
        
166
        return $parameters;
167
    }
168
}
169