Completed
Push — devops/catch-breaking-changes-... ( 88c9a6 )
by Bas
28s queued 18s
created

JoinClause::forSubQuery()   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
nc 1
nop 0
dl 0
loc 3
ccs 0
cts 2
cp 0
crap 2
rs 10
c 1
b 0
f 0
1
<?php
2
3
namespace LaravelFreelancerNL\Aranguent\Query;
4
5
use Closure;
6
use Illuminate\Database\ConnectionInterface;
7
use Illuminate\Database\Query\Processors\Processor;
0 ignored issues
show
Bug introduced by
This use statement conflicts with another class in this namespace, LaravelFreelancerNL\Aranguent\Query\Processor. Consider defining an alias.

Let?s assume that you have a directory layout like this:

.
|-- OtherDir
|   |-- Bar.php
|   `-- Foo.php
`-- SomeDir
    `-- Foo.php

and let?s assume the following content of Bar.php:

// Bar.php
namespace OtherDir;

use SomeDir\Foo; // This now conflicts the class OtherDir\Foo

If both files OtherDir/Foo.php and SomeDir/Foo.php are loaded in the same runtime, you will see a PHP error such as the following:

PHP Fatal error:  Cannot use SomeDir\Foo as Foo because the name is already in use in OtherDir/Foo.php

However, as OtherDir/Foo.php does not necessarily have to be loaded and the error is only triggered if it is loaded before OtherDir/Bar.php, this problem might go unnoticed for a while. In order to prevent this error from surfacing, you must import the namespace with a different alias:

// Bar.php
namespace OtherDir;

use SomeDir\Foo as SomeDirFoo; // There is no conflict anymore.
Loading history...
8
9
class JoinClause extends Builder
10
{
11
    /**
12
     * The type of join being performed.
13
     *
14
     * @var string
15
     */
16
    public $type;
17
18
    /**
19
     * The table the join clause is joining to.
20
     *
21
     * @var string
22
     */
23
    public $table;
24
25
    /**
26
     * The connection of the parent query builder.
27
     *
28
     * @var ConnectionInterface
29
     */
30
    protected $parentConnection;
31
32
    /**
33
     * The grammar of the parent query builder.
34
     *
35
     * @var Grammar
36
     */
37
    protected $parentGrammar;
38
39
    /**
40
     * The processor of the parent query builder.
41
     *
42
     * @var Processor
43
     */
44
    protected $parentProcessor;
45
46
    /**
47
     * The class name of the parent query builder.
48
     *
49
     * @var string
50
     */
51
    protected $parentClass;
52
53
    /**
54
     * Create a new join clause instance.
55
     *
56
     * @param Builder $parentQuery
57
     * @param string  $type
58
     * @param string  $table
59
     *
60
     * @return void
61
     */
62 17
    public function __construct(Builder $parentQuery, $type, $table)
63
    {
64 17
        $this->type = $type;
65 17
        $this->table = $table;
66 17
        $this->parentClass = get_class($parentQuery);
67 17
        $this->parentGrammar = $parentQuery->getGrammar();
0 ignored issues
show
Documentation Bug introduced by
It seems like $parentQuery->getGrammar() of type Illuminate\Database\Query\Grammars\Grammar is incompatible with the declared type LaravelFreelancerNL\Aranguent\Query\Grammar of property $parentGrammar.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
68 17
        $this->parentProcessor = $parentQuery->getProcessor();
69 17
        $this->parentConnection = $parentQuery->getConnection();
70
71 17
        parent::__construct(
72 17
            $this->parentConnection,
73 17
            $this->parentGrammar,
0 ignored issues
show
Bug introduced by
$this->parentGrammar of type Illuminate\Database\Query\Grammars\Grammar is incompatible with the type LaravelFreelancerNL\Aranguent\Query\Grammar|null expected by parameter $grammar of LaravelFreelancerNL\Aran...\Builder::__construct(). ( Ignorable by Annotation )

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

73
            /** @scrutinizer ignore-type */ $this->parentGrammar,
Loading history...
74 17
            $this->parentProcessor
75
        );
76
    }
77
78
    /**
79
     * Add an "on" clause to the join.
80
     *
81
     * On clauses can be chained, e.g.
82
     *
83
     *  $join->on('contacts.user_id', '=', 'users.id')
84
     *       ->on('contacts.info_id', '=', 'info.id')
85
     *
86
     * will produce the following SQL:
87
     *
88
     * on `contacts`.`user_id` = `users`.`id` and `contacts`.`info_id` = `info`.`id`
89
     *
90
     * @param \Closure|string                                   $first
91
     * @param string|null                                       $operator
92
     * @param \Illuminate\Database\Query\Expression|string|null $second
93
     * @param string                                            $boolean
94
     *
95
     * @throws \InvalidArgumentException
96
     *
97
     * @return $this
98
     */
99 16
    public function on($first, $operator = null, $second = null, $boolean = 'and')
100
    {
101 16
        if ($first instanceof Closure) {
102
            return $this->whereNested($first, $boolean);
103
        }
104
105 16
        return $this->whereColumn($first, $operator, $second, $boolean);
106
    }
107
108
    /**
109
     * Add an "or on" clause to the join.
110
     *
111
     * @param \Closure|string $first
112
     * @param string|null     $operator
113
     * @param string|null     $second
114
     *
115
     * @return JoinClause
116
     */
117
    public function orOn($first, $operator = null, $second = null)
118
    {
119
        return $this->on($first, $operator, $second, 'or');
120
    }
121
122
    /**
123
     * Get a new instance of the join clause builder.
124
     *
125
     * @return JoinClause
126
     */
127
    public function newQuery()
128
    {
129
        return new self($this->newParentQuery(), $this->type, $this->table);
130
    }
131
132
    /**
133
     * Create a new query instance for sub-query.
134
     *
135
     * @return Builder
136
     */
137
    protected function forSubQuery()
138
    {
139
        return $this->newParentQuery()->newQuery();
140
    }
141
142
    /**
143
     * Create a new parent query instance.
144
     *
145
     * @return Builder
146
     */
147
    protected function newParentQuery()
148
    {
149
        $class = $this->parentClass;
150
151
        return new $class($this->parentConnection, $this->parentGrammar, $this->parentProcessor);
152
    }
153
}
154