JoinClause   A
last analyzed

Complexity

Total Complexity 7

Size/Duplication

Total Lines 144
Duplicated Lines 0 %

Test Coverage

Coverage 60.71%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 29
c 1
b 0
f 0
dl 0
loc 144
ccs 17
cts 28
cp 0.6071
rs 10
wmc 7

6 Methods

Rating   Name   Duplication   Size   Complexity  
A forSubQuery() 0 3 1
A orOn() 0 3 1
A newQuery() 0 3 1
A on() 0 6 2
A __construct() 0 17 1
A newParentQuery() 0 8 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace LaravelFreelancerNL\Aranguent\Query;
6
7
use Closure;
8
use Illuminate\Database\Query\Builder as IlluminateQueryBuilder;
9
use Illuminate\Database\Query\Expression;
10
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...
11
use LaravelFreelancerNL\Aranguent\Connection;
12
13
class JoinClause extends Builder
14
{
15
    /**
16
     * The type of join being performed.
17
     *
18
     * @var string
19
     */
20
    public $type;
21
22
    /**
23
     * The table the join clause is joining to.
24
     *
25
     * @var Expression|string
26
     */
27
    public $table;
28
29
    /**
30
     * The connection of the parent query builder.
31
     *
32
     * @var \Illuminate\Database\ConnectionInterface
33
     */
34
    protected $parentConnection;
35
36
    /**
37
     * The grammar of the parent query builder.
38
     *
39
     * @var \Illuminate\Database\Query\Grammars\Grammar
40
     */
41
    protected $parentGrammar;
42
43
    /**
44
     * The processor of the parent query builder.
45
     *
46
     * @var Processor
47
     */
48
    protected $parentProcessor;
49
50
    /**
51
     * The class name of the parent query builder.
52
     *
53
     * @var class-string<IlluminateQueryBuilder>
0 ignored issues
show
Documentation Bug introduced by
The doc comment class-string<IlluminateQueryBuilder> at position 0 could not be parsed: Unknown type name 'class-string' at position 0 in class-string<IlluminateQueryBuilder>.
Loading history...
54
     */
55
    protected $parentClass;
56
57
    /**
58
     * Create a new join clause instance.
59
     *
60
     * @param  string  $type
61
     * @param  Expression|string  $table
62
     * @return void
63
     */
64 28
    public function __construct(IlluminateQueryBuilder $parentQuery, $type, $table)
65
    {
66 28
        $this->type = $type;
67 28
        $this->table = $table;
68 28
        $this->parentClass = get_class($parentQuery);
69 28
        $this->parentGrammar = $parentQuery->getGrammar();
70 28
        $this->parentProcessor = $parentQuery->getProcessor();
71 28
        $this->parentConnection = $parentQuery->getConnection();
72
73 28
        parent::__construct(
74 28
            $this->parentConnection,
75 28
            $this->parentGrammar,
76 28
            $this->parentProcessor,
77 28
        );
78
79 28
        $this->registerTableAlias($table);
80 28
        $this->importTableAliases($parentQuery);
81
    }
82
83
    /**
84
     * Add an "on" clause to the join.
85
     *
86
     * On clauses can be chained, e.g.
87
     *
88
     *  $join->on('contacts.user_id', '=', 'users.id')
89
     *       ->on('contacts.info_id', '=', 'info.id')
90
     *
91
     * will produce the following SQL:
92
     *
93
     * on `contacts`.`user_id` = `users`.`id` and `contacts`.`info_id` = `info`.`id`
94
     *
95
     * @param  \Closure|string  $first
96
     * @param  string|null  $operator
97
     * @param  Expression|string|null  $second
98
     * @param  string  $boolean
99
     * @return $this
100
     *
101
     * @throws \InvalidArgumentException
102
     */
103 27
    public function on($first, $operator = null, $second = null, $boolean = 'and')
104
    {
105 27
        if ($first instanceof Closure) {
106
            return $this->whereNested($first, $boolean);
107
        }
108 27
        return $this->whereColumn($first, $operator, $second, $boolean);
109
    }
110
111
    /**
112
     * Add an "or on" clause to the join.
113
     *
114
     * @param  \Closure|string  $first
115
     * @param  string|null  $operator
116
     * @param  string|null  $second
117
     * @return JoinClause
118
     */
119
    public function orOn($first, $operator = null, $second = null)
120
    {
121
        return $this->on($first, $operator, $second, 'or');
122
    }
123
124
    /**
125
     * Get a new instance of the join clause builder.
126
     *
127
     * @return JoinClause
128
     */
129
    public function newQuery()
130
    {
131
        return new self($this->newParentQuery(), $this->type, $this->table);
132
    }
133
134
    /**
135
     * Create a new query instance for sub-query.
136
     *
137
     * @return \Illuminate\Database\Query\Builder
138
     */
139
    protected function forSubQuery()
140
    {
141
        return $this->newParentQuery()->newQuery();
142
    }
143
144
    /**
145
     * Create a new parent query instance.
146
     *
147
     * @return Builder
148
     */
149
    protected function newParentQuery()
150
    {
151
        $class = $this->parentClass;
152
153
        $newParentQuery = new $class($this->parentConnection, $this->parentGrammar, $this->parentProcessor);
154
        assert($newParentQuery instanceof Builder);
155
156
        return $newParentQuery;
157
    }
158
}
159