Completed
Branch feature/pre-split (669609)
by Anton
03:30
created

ManyToManyLoader::pivotColumns()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 2
nc 1
nop 0
dl 0
loc 4
rs 10
c 0
b 0
f 0
1
<?php
2
/**
3
 * components
4
 *
5
 * @author    Wolfy-J
6
 */
7
namespace Spiral\ORM\Entities\Loaders;
8
9
use Spiral\Database\Builders\SelectQuery;
10
use Spiral\Database\Injections\Parameter;
11
use Spiral\ORM\Entities\Loaders\Traits\WhereTrait;
12
use Spiral\ORM\Entities\Nodes\AbstractNode;
13
use Spiral\ORM\Entities\Nodes\PivotedNode;
14
use Spiral\ORM\Record;
15
16
/**
17
 * ManyToMany loader will not only load related data, but will include pivot table data into record
18
 * property "@pivot". Loader support WHERE conditions for both related data and pivot table.
19
 *
20
 * It's STRONGLY recommended to load many-to-many data using postload method. However relation still
21
 * can be used to filter query.
22
 */
23
class ManyToManyLoader extends RelationLoader
24
{
25
    use WhereTrait;
26
27
    /**
28
     * Default set of relation options. Child implementation might defined their of default options.
29
     *
30
     * @var array
31
     */
32
    protected $options = [
33
        'method'     => self::POSTLOAD,
34
        'minify'     => true,
35
        'alias'      => null,
36
        'pivotAlias' => null,
37
        'using'      => null,
38
        'where'      => null,
39
    ];
40
41
    /**
42
     * {@inheritdoc}
43
     */
44
    protected function configureQuery(SelectQuery $query, array $outerKeys = []): SelectQuery
45
    {
46
        if ($this->isJoined()) {
47
            $query->join(
48
                $this->getMethod() == self::JOIN ? 'INNER' : 'LEFT',
49
                $this->pivotTable() . ' AS ' . $this->pivotAlias(),
50
                [$this->pivotKey(Record::THOUGHT_INNER_KEY) => $this->parentKey(Record::INNER_KEY)]
51
            );
52
        } else {
53
            //TODO: outer keys
54
            $query->join(
55
                $this->getMethod() == self::JOIN ? 'INNER' : 'LEFT',
56
                $this->pivotTable() . ' AS ' . $this->pivotAlias()
57
            )->onWhere(
58
                $this->pivotKey(Record::THOUGHT_INNER_KEY),
59
                new Parameter($outerKeys)
60
            );
61
        }
62
63
        //pivot where
64
65
//        $pivotOuterKey = $this->getPivotKey(RecordEntity::THOUGHT_OUTER_KEY);
1 ignored issue
show
Unused Code Comprehensibility introduced by
50% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
66
        if ($this->isJoined()) {
67
            $query->join(
68
                $this->getMethod() == self::JOIN ? 'INNER' : 'LEFT',
69
                $this->getTable() . ' AS ' . $this->getAlias(),
70
                [$this->pivotKey(Record::THOUGHT_OUTER_KEY) => $this->localKey(Record::OUTER_KEY)]
71
            );
72
        }
73
74
        //normal where
75
76
        return parent::configureQuery($query);
77
    }
78
79
    /**
80
     * Set columns into SelectQuery.
81
     *
82
     * @param SelectQuery $query
83
     * @param bool        $minify    Minify column names (will work in case when query parsed in
84
     *                               FETCH_NUM mode).
85
     * @param string      $prefix    Prefix to be added for each column name.
86
     * @param bool        $overwrite When set to true existed columns will be removed.
87
     */
88
    protected function mountColumns(
89
        SelectQuery $query,
90
        bool $minify = false,
91
        string $prefix = '',
92
        bool $overwrite = false
93
    ) {
94
        /*
95
         * Configuring pivot columns.
96
         */
97
        //Column source alias
98
        $alias = $this->pivotAlias();
99
100
        $columns = $overwrite ? [] : $query->getColumns();
101
        foreach ($this->pivotColumns() as $name) {
102
            $column = $name;
103
104
            if ($minify) {
105
                //Let's use column number instead of full name
106
                $column = 'p_c' . count($columns);
107
            }
108
109
            $columns[] = "{$alias}.{$name} AS {$prefix}{$column}";
110
        }
111
112
        //Updating column set
113
        $query->columns($columns);
114
115
        parent::mountColumns($query, $minify, $prefix, $overwrite);
116
    }
117
118
    /**
119
     * {@inheritdoc}
120
     */
121
    protected function initNode(): AbstractNode
122
    {
123
        $node = new PivotedNode(
124
            $this->schema[Record::RELATION_COLUMNS],
125
            $this->schema[Record::PIVOT_COLUMNS],
126
            $this->schema[Record::OUTER_KEY],
127
            $this->schema[Record::THOUGHT_INNER_KEY],
128
            $this->schema[Record::THOUGHT_OUTER_KEY]
129
        );
130
131
        return $node->asJoined($this->isJoined());
132
    }
133
134
    /**
135
     * Pivot table name.
136
     *
137
     * @return string
138
     */
139
    protected function pivotTable(): string
140
    {
141
        return $this->schema[Record::PIVOT_TABLE];
142
    }
143
144
    /**
145
     * Pivot table alias, depends on relation table alias.
146
     *
147
     * @return string
148
     */
149
    protected function pivotAlias(): string
150
    {
151
        if (!empty($this->options['pivotAlias'])) {
152
            return $this->options['pivotAlias'];
153
        }
154
155
        return $this->getAlias() . '_pivot';
156
    }
157
158
    /**
159
     * @return array
160
     */
161
    protected function pivotColumns(): array
162
    {
163
        return $this->schema[Record::PIVOT_COLUMNS];
164
    }
165
166
    /**
167
     * Key related to pivot table. Must include pivot table alias.
168
     *
169
     * @see pivotKey()
170
     *
171
     * @param string $key
172
     *
173
     * @return null|string
174
     */
175
    protected function pivotKey(string $key)
176
    {
177
        if (!isset($this->schema[$key])) {
178
            return null;
179
        }
180
181
        return $this->pivotAlias() . '.' . $this->schema[$key];
182
    }
183
}