Completed
Push — master ( 62b9b0...72415f )
by Vitaly
02:50
created

Query::joins()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 9
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 1
Metric Value
dl 0
loc 9
rs 9.6667
c 1
b 0
f 1
cc 1
eloc 7
nc 1
nop 5
1
<?php
2
namespace samsonframework\orm;
3
4
/**
5
 * Universal class for creating database queries 
6
 * @author Vitaly Iegorov <[email protected]>
7
 * @version 2.0
8
 */
9
class Query extends QueryHandler
10
{
11
    /** Class name for interacting with database */
12
    protected $class_name;
13
14
    /**
15
     * Collection of query parameters objects
16
     * @see \samson\activerecord\QueryParams
17
     */
18
    protected $parameters = array();
19
20
    /**
21
     * Reset all query parameters
22
     * @return self Chaining
23
     */
24
    public function flush()
25
    {
26
        foreach ($this->parameters as $param) {
27
            $param->flush();
28
        }
29
30
        return $this;
31
    }
32
33
    /**
34
     * Perform database request and get collection of database record objects
35
     * @see \samson\activerecord\Query::execute()
36
     * @param mixed $return External variable to store query results
37
     * @return mixed If no arguments passed returns query results collection, otherwise query success status
38
     */
39
    public function exec(& $return = null)
40
    {
41
        $args = func_num_args();
42
        return $this->execute($return, $args);
43
    }
44
45
    /**
46
     * Perform database request and get first record from results collection
47
     * @see \samson\activerecord\Query::execute()
48
     * @param mixed $return External variable to store query results
49
     * @return mixed If no arguments passed returns query results first database record object,
50
     * otherwise query success status
51
     */
52
    public function first(& $return = null)
53
    {
54
        $args = func_num_args();
55
        return $this->execute($return, $args, 1);
56
    }
57
58
    /**
59
     * Perform database request and get array of record field values
60
     * @see \samson\activerecord\Query::execute()
61
     * @param string $fieldName Record field name to get value from
62
     * @param string $return External variable to store query results
63
     * @return Ambigous <boolean, NULL, mixed>
64
     */
65
    public function fields($fieldName, & $return = null)
66
    {
67
        // Call handlers stack
68
        $this->_callHandlers();
69
70
        // Perform DB request
71
        $return = db()->fetchColumn($this->class_name, $this, $fieldName);
72
73
        $success = is_array($return) && sizeof($return);
74
75
        // If parent function has arguments - consider them as return value and return request status
76
        if (func_num_args() - 1 > 0) {
77
            return $success;
0 ignored issues
show
Bug Best Practice introduced by
The return type of return $success; (boolean) is incompatible with the return type documented by samsonframework\orm\Query::fields of type samsonframework\orm\Ambigous.

If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.

Let’s take a look at an example:

class Author {
    private $name;

    public function __construct($name) {
        $this->name = $name;
    }

    public function getName() {
        return $this->name;
    }
}

abstract class Post {
    public function getAuthor() {
        return 'Johannes';
    }
}

class BlogPost extends Post {
    public function getAuthor() {
        return new Author('Johannes');
    }
}

class ForumPost extends Post { /* ... */ }

function my_function(Post $post) {
    echo strtoupper($post->getAuthor());
}

Our function my_function expects a Post object, and outputs the author of the post. The base class Post returns a simple string and outputting a simple string will work just fine. However, the child class BlogPost which is a sub-type of Post instead decided to return an object, and is therefore violating the SOLID principles. If a BlogPost were passed to my_function, PHP would not complain, but ultimately fail when executing the strtoupper call in its body.

Loading history...
78
        } else { // Parent function has no arguments, return request result
79
            return $return;
80
        }
81
    }
82
83
    /**
84
     * Perform database request and return different results depending on function arguments.
85
     * @see \samson\activerecord\Record
86
     * @param array $result External variable to store dabatase request results collection
87
     * @param integer|bool $rType Amount of arguments passed to parent function
88
     * @param integer $limit Quantity of records to return
89
     * @param callable $handler External callable handler for results modification
90
     * @param array $handlerArgs External callable handler arguments
91
     * @return boolean/array Boolean if $r_type > 0, otherwise array of request results
0 ignored issues
show
Documentation introduced by
The doc-type boolean/array could not be parsed: Unknown type name "boolean/array" at position 0. (view supported doc-types)

This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.

Loading history...
92
     */
93
    protected function & execute(
94
        & $result = null,
95
        $rType = false,
96
        $limit = null,
97
        $handler = null,
98
        $handlerArgs = array()
99
    ) {
100
        // Call handlers stack
101
        $this->_callHandlers();
102
103
        // Perform DB request
104
        $result = db()->find($this->class_name, $this);
105
106
        // If external result handler is passed - use it
107
        if (isset($handler)) {
108
            // Add results collection to array
109
            array_unshift($handlerArgs, $result);
110
111
            // Call external handler with parameters
112
            $result = call_user_func_array($handler, $handlerArgs);
113
        }
114
115
        // Clear this query
116
        $this->flush();
117
118
        // Count records
119
        $count = sizeof($result);
120
121
        // Define is request was successful
122
        $success = is_array($result) && $count;
123
124
        // Is amount of records is specified
125
        if (isset($limit)) {
126
            // If we have not enough records - return null
127
            if ($count < $limit) {
128
                $result = null;
129
            } elseif ($limit === 1) { // If we need first record
130
                $result = array_shift($result);
131
            } elseif ($limit > 1) { // Slice array for necessary amount
132
                $result = array_slice($result, 0, $limit);
133
            }
134
        }
135
136
        // If parent function has arguments - consider them as return value and return request status
137
        if ($rType > 0) {
138
            return $success;
139
        } else { // Parent function has no arguments, return request result
140
            return $result;
141
        }
142
    }
143
}
144