Completed
Push — d64 ( 014843...e3735b )
by Welling
02:39
created

ClientLocal::fetchTables()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 0
dl 0
loc 4
ccs 0
cts 1
cp 0
crap 2
rs 10
c 0
b 0
f 0
1
<?php
2
3
/**
4
 * Directus – <http://getdirectus.com>
5
 *
6
 * @link      The canonical repository – <https://github.com/directus/directus>
7
 * @copyright Copyright 2006-2016 RANGER Studio, LLC – <http://rangerstudio.com>
8
 * @license   GNU General Public License (v3) – <http://www.gnu.org/copyleft/gpl.html>
9
 */
10
11
namespace Directus\SDK;
12
13
use Directus\Database\Connection;
14
use Directus\Database\TableGateway\BaseTableGateway;
15
use Directus\Database\TableGateway\DirectusMessagesTableGateway;
16
use Directus\Database\TableGateway\RelationalTableGateway;
17
use Directus\Database\TableSchema;
18
use Directus\SDK\Response\EntryCollection;
19
use Directus\SDK\Response\Entry;
20
use Zend\Db\Sql\Select;
21
22
/**
23
 * Client Local
24
 *
25
 * Client to Interact with the database directly using Directus Database Component
26
 *
27
 * @author Welling Guzmán <[email protected]>
28
 */
29
class ClientLocal implements RequestsInterface
30
{
31
    /**
32
     * @var BaseTableGateway[]
33
     */
34
    protected $tableGateways = [];
35
36
    /**
37
     * @var Connection
38
     */
39
    protected $connection = null;
40
41
    /**
42
     * ClientLocal constructor.
43
     *
44
     * @param $connection
45
     */
46
    public function __construct($connection)
47
    {
48
        $this->connection = $connection;
49
    }
50
51
    /**
52
     * Gets the list of tables name in the database
53
     *
54
     * @param array $params
55
     *
56
     * @return array
57
     */
58
    public function getTables(array $params = [])
59
    {
60
        return TableSchema::getTablesSchema($params);
61
    }
62
63
    /**
64
     * Gets all the columns in the database
65
     *
66
     * @param array $params
67
     *
68
     * @return array
69
     */
70
    public function getColumns(array $params = [])
71
    {
72
        return TableSchema::getColumnsSchema($params);
73
    }
74
75
    /**
76
     * Gets table columns
77
     *
78
     * @param $tableName
79
     * @param array $params
80
     *
81
     * @return \Directus\Database\Object\Column[]
82
     */
83
    public function getTableColumns($tableName, array $params = [])
84
    {
85
        $tables = TableSchema::getTableColumnsSchema($tableName, $params);
0 ignored issues
show
Bug introduced by
The method getTableColumnsSchema() does not exist on Directus\Database\TableSchema. Did you maybe mean getTable()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
86
87
        return $tables;
88
    }
89
90
    /**
91
     * Gets all the entries in the given table name
92
     *
93
     * @param string $tableName
94
     * @param array $params
95
     *
96
     * @return Entry|EntryCollection
97
     */
98
    public function getEntries($tableName, array $params = [])
99
    {
100
        $tableGateway = $this->getTableGateway($tableName);
101
102
        return $this->createResponseFromData($tableGateway->getEntries($params));
103
    }
104
105
    /**
106
     * Gets an entry in the given table name with the given id
107
     *
108
     * @param string $tableName
109
     * @param mixed $id
110
     * @param array $params
111
     *
112
     * @return array|mixed
113
     */
114
    public function getEntry($tableName, $id, array $params = [])
115
    {
116
        // @TODO: Dynamic ID
117
        return $this->getEntries($tableName, array_merge($params, [
0 ignored issues
show
Bug Best Practice introduced by
The return type of return $this->getEntries..., array('id' => $id))); (Directus\SDK\Response\En...esponse\EntryCollection) is incompatible with the return type declared by the interface Directus\SDK\RequestsInterface::getEntry of type array.

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...
118
            'id' => $id
119
        ]));
120
    }
121
122
    /**
123
     * Gets the list of users
124
     *
125
     * @param array $params
126
     *
127
     * @return array|mixed
128
     */
129
    public function getUsers(array $params = [])
130
    {
131
        // @TODO: store the directus tables somewhere (SchemaManager?)
132
        return $this->getEntries('directus_users', $params);
0 ignored issues
show
Bug Best Practice introduced by
The return type of return $this->getEntries...ectus_users', $params); (Directus\SDK\Response\En...esponse\EntryCollection) is incompatible with the return type declared by the interface Directus\SDK\RequestsInterface::getUsers of type array.

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...
133
    }
134
135
    /**
136
     * Gets an user by the given id
137
     *
138
     * @param $id
139
     * @param array $params
140
     *
141
     * @return array|mixed
142
     */
143
    public function getUser($id, array $params = [])
144
    {
145
        return $this->getEntry('directus_users', $id, $params);
0 ignored issues
show
Bug Best Practice introduced by
The return type of return $this->getEntry('..._users', $id, $params); (Directus\SDK\Response\En...esponse\EntryCollection) is incompatible with the return type declared by the interface Directus\SDK\RequestsInterface::getUser of type array.

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...
146
    }
147
148
    /**
149
     * @inheritDoc
150
     */
151
    public function fetchTables()
152
    {
153
        // TODO: Implement fetchTables() method.
154
    }
155
156
    /**
157
     * @inheritDoc
158
     */
159
    public function fetchTableInfo($tableName)
160
    {
161
        // TODO: Implement fetchTableInfo() method.
162
    }
163
164
    /**
165
     * @inheritDoc
166
     */
167
    public function fetchColumns($tableName)
0 ignored issues
show
Unused Code introduced by
The parameter $tableName is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
168
    {
169
        // TODO: Implement fetchColumns() method.
170
    }
171
172
    /**
173
     * @inheritDoc
174
     */
175
    public function fetchColumnInfo($tableName, $columnName)
176
    {
177
        // TODO: Implement fetchColumnInfo() method.
178
    }
179
180
    /**
181
     * @inheritDoc
182
     */
183
    public function fetchItems($tableName = null, $conditions = [])
184
    {
185
        if ($tableName == null) {
186
            $tableName = $this->getTable();
0 ignored issues
show
Bug introduced by
The method getTable() does not exist on Directus\SDK\ClientLocal. Did you maybe mean getTables()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
187
        }
188
189
        $select = new Select($tableName);
190
191
        // Conditional to honor the active column, (does not check if column exists)
192
        if (isset($conditions['active'])) {
193
            $select->where->equalTo('active', $conditions['active']);
194
        }
195
196
        // Order by "id desc" by default or by a parameter value
197
        if (isset($conditions['sort'])) {
198
            $select->order($conditions['sort']);
199
        }
200
201
        return $this->selectWith($select);
0 ignored issues
show
Bug introduced by
The method selectWith() does not seem to exist on object<Directus\SDK\ClientLocal>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
202
    }
203
204
    /**
205
     * @inheritDoc
206
     */
207
    public function fetchItem($tableName, $itemID)
0 ignored issues
show
Unused Code introduced by
The parameter $tableName is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $itemID is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
208
    {
209
        // TODO: Implement fetchItem() method.
210
    }
211
212
    /**
213
     * @inheritDoc
214
     */
215
    public function fetchGroups()
216
    {
217
        // TODO: Implement fetchGroups() method.
218
    }
219
220
    /**
221
     * @inheritDoc
222
     */
223
    public function fetchGroupInfo($groupID)
224
    {
225
        // TODO: Implement fetchGroupInfo() method.
226
    }
227
228
    /**
229
     * @inheritDoc
230
     */
231
    public function fetchGroupPrivileges($groupID)
232
    {
233
        // TODO: Implement fetchGroupPrivileges() method.
234
    }
235
236
    /**
237
     * @inheritDoc
238
     */
239
    public function getFiles(array $params = [])
240
    {
241
        return $this->getEntries('directus_files', $params);
242
    }
243
244
    /**
245
     * @inheritDoc
246
     */
247
    public function getFile($id, array $params = [])
248
    {
249
        return $this->getEntry('directus_files', $id, $params);
250
    }
251
252
    /**
253
     * @inheritDoc
254
     */
255
    public function fetchSettings()
256
    {
257
        // TODO: Implement fetchSettings() method.
258
    }
259
260
    /**
261
     * @inheritDoc
262
     */
263
    public function fetchSettingCollection($collectionName)
264
    {
265
        // TODO: Implement fetchSettingCollection() method.
266
    }
267
268
    /**
269
     * @inheritDoc
270
     */
271
    public function getMessages($userId)
272
    {
273
        $messagesTableGateway = new DirectusMessagesTableGateway($this->connection, null);
0 ignored issues
show
Documentation introduced by
null is of type null, but the function expects a object<Directus\Acl\Acl>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
274
        $result = $messagesTableGateway->fetchMessagesInboxWithHeaders($userId);
275
276
        return $this->createResponseFromData($result);
0 ignored issues
show
Bug Compatibility introduced by
The expression $this->createResponseFromData($result); of type Directus\SDK\Response\En...ctus\SDK\Response\Entry adds the type Directus\SDK\Response\Entry to the return on line 276 which is incompatible with the return type declared by the interface Directus\SDK\RequestsInterface::getMessages of type Directus\SDK\Response\EntryCollection.
Loading history...
277
    }
278
279
    /**
280
     * @inheritDoc
281
     */
282
    public function createEntry($tableName, array $data)
283
    {
284
        $tableGateway = $this->getTableGateway($tableName);
285
        $newRecord = $tableGateway->manageRecordUpdate($tableName, $data);
286
287
        return $this->createResponseFromData($newRecord->toArray());
0 ignored issues
show
Bug Compatibility introduced by
The expression $this->createResponseFro...$newRecord->toArray()); of type Directus\SDK\Response\En...ctus\SDK\Response\Entry adds the type Directus\SDK\Response\EntryCollection to the return on line 287 which is incompatible with the return type declared by the interface Directus\SDK\RequestsInterface::createEntry of type Directus\SDK\Response\Entry.
Loading history...
288
    }
289
290
    /**
291
     * @inheritDoc
292
     */
293
    public function deleteEntry($tableName, $ids)
294
    {
295
        // @TODO: Accept EntryCollection and Entry
296
        $tableGateway = $this->getTableGateway($tableName);
297
298
        if (!is_array($ids)) {
299
            $ids = [$ids];
300
        }
301
302
        return $tableGateway->delete(function($delete) use ($ids) {
303
            return $delete->where->in('id', $ids);
304
        });
305
    }
306
307
    /**
308
     * Get a table gateway for the given table name
309
     *
310
     * @param $tableName
311
     *
312
     * @return RelationalTableGateway
313
     */
314
    protected function getTableGateway($tableName)
315
    {
316
        if (!array_key_exists($tableName, $this->tableGateways)) {
317
            $acl = TableSchema::getAclInstance();
318
            $this->tableGateways[$tableName] = new RelationalTableGateway($tableName, $this->connection, $acl);
319
        }
320
321
        return $this->tableGateways[$tableName];
322
    }
323
324
    // @TODO: move to a builder class
325
    protected function createResponseFromData($data)
326
    {
327
        if (isset($data['rows'])) {
328
            $response = new EntryCollection($data);
329
        } else {
330
            $response = new Entry($data);
331
        }
332
333
        return $response;
334
    }
335
}
336