TableGateway   A
last analyzed

Complexity

Total Complexity 31

Size/Duplication

Total Lines 268
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 8

Importance

Changes 1
Bugs 0 Features 0
Metric Value
wmc 31
lcom 1
cbo 8
dl 0
loc 268
rs 9.8
c 1
b 0
f 0

13 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 8 1
A getSelect() 0 4 1
B with() 0 26 4
B loadColumns() 0 49 6
A setCommentAsLabel() 0 14 4
B prepare() 0 27 6
A find() 0 4 1
A cleanDataForSql() 0 11 3
A insert() 0 5 1
A update() 0 4 1
A delete() 0 4 1
A getDbAdapter() 0 4 1
A getPaginatorAdapter() 0 4 1
1
<?php
2
3
namespace AtDataGrid\DataSource\ZendDb;
4
5
use AtDataGrid\Filter\FilterInterface;
6
use AtDataGrid\Filter\ZendSqlFilter;
7
use Zend\Db\Adapter\Adapter;
8
use Zend\Db\Metadata\Metadata;
9
use Zend\Db\Sql\Select;
10
use Zend\Db\TableGateway\Feature\RowGatewayFeature;
11
use Zend\Db\TableGateway\TableGateway as ZendTableGateway;
12
use Zend\Paginator\Adapter\DbSelect as DbSelectPaginatorAdapter;
13
use AtDataGrid\DataSource\AbstractDataSource;
14
use AtDataGrid\Column;
15
16
class TableGateway extends AbstractDataSource
17
{
18
    /**
19
     * @var ZendTableGateway
20
     */
21
    protected $tableGateway;
22
23
    /**
24
     * @var Select
25
     */
26
    protected $select;
27
28
    /**
29
     * Base table columns
30
     *
31
     * @var array
32
     */
33
    protected $tableColumns = [];
34
35
    /**
36
     * Joined tables
37
     *
38
     * @var array
39
     */
40
    protected $joinedTables = [];
41
42
    /**
43
     * Joined table columns
44
     *
45
     * @var array
46
     */
47
    protected $joinedColumns = [];
48
49
    /**
50
     * @param ZendTableGateway $tableGateway
51
     */
52
    public function __construct(ZendTableGateway $tableGateway)
53
	{
54
        $tableGateway->getFeatureSet()->addFeature(new RowGatewayFeature());
55
        $this->tableGateway = $tableGateway;
56
57
        $this->select = $tableGateway->getSql()->select();
58
        $this->paginatorAdapter = new DbSelectPaginatorAdapter($this->select, $tableGateway->getAdapter());
59
	}
60
61
    /**
62
     * @return Select
63
     */
64
    public function getSelect()
65
    {
66
        return $this->select;
67
    }
68
69
    /**
70
     * Join other table and collect joined columns
71
     *
72
     * @param $joinedTableName
73
     * @param $alias
74
     * @param $keyName
75
     * @param $foreignKeyName
76
     * @param null $columns
77
     */
78
    public function with($joinedTableName, $alias, $keyName, $foreignKeyName, $columns = null)
79
    {
80
        $tableMetadata = new Metadata($this->getDbAdapter());
81
        $joinedTableColumns = $tableMetadata->getColumns($joinedTableName);
82
83
        $joinedColumns = [];
84
85
        foreach ($joinedTableColumns as $column) {
86
            $columnName = $column->getName();
87
88
            if ($columns != null && ! in_array($columnName, $columns)) {
89
                continue;
90
            }
91
92
            $fullColumnName = $alias . '__' . $columnName;
93
94
            $joinedColumns[$fullColumnName] = $columnName;
95
            $this->joinedColumns[$fullColumnName] = $fullColumnName;
96
        }
97
98
        $this->getSelect()->join(
99
            [$alias => $joinedTableName],
100
            $this->tableGateway->getTable(). '.' . $keyName . ' = '. $alias . '.' . $foreignKeyName,
101
            $joinedColumns
102
        );
103
    }
104
105
    /**
106
     * @return array
107
     */
108
    public function loadColumns()
109
    {
110
        $columns = array();
111
        $tableMetadata = new Metadata($this->getDbAdapter());
112
        $baseTableColumns = $tableMetadata->getColumns($this->tableGateway->getTable());
113
114
        // Setup default settings for base table column fields
115
        foreach ($baseTableColumns as $column) {
116
            $columnName = $column->getName();
117
            $columnDataType = $column->getDataType();
118
119
            $this->tableColumns[] = $columnName;
120
121
            // @todo Move it to separate class
122
            switch (true) {
123
                case in_array($columnDataType, ['datetime', 'timestamp', 'time']):
124
                    $column = new Column\DateTime($columnName);
125
                    break;
126
127
                case in_array($columnDataType, ['date', 'year']):
128
                    $column = new Column\Date($columnName);
129
                    break;
130
131
                case in_array($columnDataType, ['mediumtext', 'text', 'longtext']):
132
                    $column = new Column\Textarea($columnName);
133
                    break;
134
135
                default:
136
                    $column = new Column\Literal($columnName);
137
                    break;
138
            }
139
140
            $column->setLabel($columnName);
141
142
            $columns[$columnName] = $column;
143
        }
144
145
        // Setup default settings for joined table column fields
146
        foreach ($this->joinedColumns as $columnName) {
147
            $column = new Column\Literal($columnName);
148
            $column->setLabel($columnName);
149
150
            $columns[$columnName] = $column;
151
        }
152
153
        $this->setCommentAsLabel($columns);
154
155
        return $columns;
156
    }
157
158
    /**
159
     * @param $columns
160
     */
161
    protected function setCommentAsLabel($columns)
162
    {
163
        $query = 'SELECT COLUMN_NAME as name, COLUMN_COMMENT as comment FROM information_schema.COLUMNS
164
            WHERE TABLE_SCHEMA = "' . $this->getDbAdapter()->getCurrentSchema() . '" AND TABLE_NAME = "' . $this->tableGateway->getTable() . '"';
165
166
        $columnsInfo = $this->getDbAdapter()->query($query, Adapter::QUERY_MODE_EXECUTE);
167
        if ($columnsInfo) {
168
            foreach ($columnsInfo as $info) {
169
                if (!empty($info['comment'])) {
170
                    $columns[$info['name']]->setLabel($info['comment']);
171
                }
172
            }
173
        }
174
    }
175
176
    /**
177
     * @param $order ['field1' => 'direction1', 'field2' => 'direction2']
178
     * @param array $filters
179
     * @return $this
180
     * @throws \Exception
181
     */
182
    public function prepare($order = [], $filters = [])
183
    {
184
        // Sorting
185
        if (!empty($order)) {
186
            if (in_array(key($order), $this->tableColumns)) {
187
                $this->getSelect()->order($order);
188
            }
189
        }
190
191
        // Filtering
192
        foreach ($filters as $columnName => $filter) {
193
            if (!$filter instanceof FilterInterface) {
194
                throw new \RuntimeException('Data grid filter must implements FilterInterface');
195
            }
196
197
            if (!$filter instanceof ZendSqlFilter) {
198
                throw new \RuntimeException('ZendDb/TableGateway data source requires Filter\ZendSql filters');
199
            }
200
            $filter->apply($this->getSelect(), $this->tableGateway->getTable(). '.' . $columnName, $filter->getValue());
201
        }
202
203
        $this->getEventManager()->trigger(self::EVENT_DATASOURCE_PREPARE_POST, $this->getSelect());
204
205
        //var_dump($this->getSelect()->getSqlString());exit;
0 ignored issues
show
Unused Code Comprehensibility introduced by
80% 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...
206
207
        return $this;
208
    }
209
210
    /**
211
     * Return row by identifier (primary key)
212
     *
213
     * @param $key
214
     * @return array|mixed
215
     */
216
    public function find($key)
217
    {
218
        return $this->tableGateway->select([$this->getIdentifierFieldName() => $key])->current();
219
    }
220
221
    /**
222
     * Get only fields which present in table
223
     *
224
     * @param array $data
225
     * @return array
226
     */
227
    protected function cleanDataForSql($data = [])
228
    {
229
        $cleanData = [];
230
        foreach ($data as $key => $value) {
231
            if (in_array($key, $this->tableColumns)) {
232
                $cleanData[$key] = $value;
233
            }
234
        }
235
236
        return $cleanData;
237
    }
238
239
    /**
240
     * @param $data
241
     * @return int|mixed
242
     */
243
    public function insert($data)
244
    {
245
        $this->tableGateway->insert($this->cleanDataForSql($data));
246
        return $this->tableGateway->getLastInsertValue();
247
    }
248
249
    /**
250
     * @param $data
251
     * @param $key
252
     * @return int|mixed
253
     */
254
    public function update($data, $key)
255
    {
256
        return $this->tableGateway->update($this->cleanDataForSql($data), [$this->getIdentifierFieldName() => $key]);
257
    }
258
259
    /**
260
     * @param $key
261
     * @return int|mixed
262
     */
263
    public function delete($key)
264
    {
265
        return $this->tableGateway->delete([$this->getIdentifierFieldName() => $key]);
266
    }
267
268
    /**
269
     * @return Adapter|\Zend\Db\Adapter\AdapterInterface
270
     */
271
    protected function getDbAdapter()
272
    {
273
        return $this->tableGateway->getAdapter();
274
    }
275
276
    /**
277
     * @return DbSelectPaginatorAdapter
278
     */
279
    public function getPaginatorAdapter()
280
    {
281
        return $this->paginatorAdapter;
282
    }
283
}