Completed
Push — d64 ( a462d8...ba0200 )
by Welling
02:05
created

ClientLocal   F

Complexity

Total Complexity 71

Size/Duplication

Total Lines 672
Duplicated Lines 21.43 %

Coupling/Cohesion

Components 1
Dependencies 15

Test Coverage

Coverage 0%

Importance

Changes 0
Metric Value
dl 144
loc 672
ccs 0
cts 391
cp 0
rs 2.2526
c 0
b 0
f 0
wmc 71
lcom 1
cbo 15

46 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 4 1
A getTables() 0 4 1
A getTable() 0 4 1
A getColumns() 0 4 1
A getColumn() 0 4 1
A getItems() 0 6 1
A getItem() 0 7 1
A getUsers() 0 5 1
A getUser() 0 4 1
A getGroups() 0 4 1
A getGroup() 0 4 1
A getGroupPrivileges() 0 8 1
A getFiles() 0 4 1
A getFile() 0 4 1
A getSettings() 0 4 1
A getSettingsByCollection() 17 17 1
A updateSettings() 0 10 1
A getMessages() 14 14 2
A getMessage() 14 14 2
A createItem() 15 15 3
A updateItem() 15 15 3
A deleteItem() 0 13 2
A createUser() 0 4 1
A updateUser() 0 4 1
A deleteUser() 0 4 1
A createFile() 0 6 1
A updateFile() 0 8 2
A deleteFile() 0 4 1
A createPreferences() 0 11 2
A createBookmark() 0 20 1
A getBookmark() 0 4 1
A getBookmarks() 0 11 2
A createColumn() 0 10 1
A createGroup() 0 4 1
B createMessage() 0 52 6
A sendMessage() 0 4 1
A createPrivileges() 16 16 1
B createTable() 0 31 4
B createColumnUIOptions() 0 47 4
A getPreferences() 16 16 1
A deleteBookmark() 0 4 1
A deleteColumn() 17 17 2
A deleteGroup() 0 4 1
A deleteTable() 17 17 2
A getActivity() 3 13 2
A getTableGateway() 0 9 2

How to fix   Duplicated Code    Complexity   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

Complex Class

 Tip:   Before tackling complexity, make sure that you eliminate any duplication first. This often can reduce the size of classes significantly.

Complex classes like ClientLocal often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use ClientLocal, and based on these observations, apply Extract Interface, too.

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\DirectusActivityTableGateway;
16
use Directus\Database\TableGateway\DirectusMessagesTableGateway;
17
use Directus\Database\TableGateway\DirectusPreferencesTableGateway;
18
use Directus\Database\TableGateway\DirectusPrivilegesTableGateway;
19
use Directus\Database\TableGateway\DirectusSettingsTableGateway;
20
use Directus\Database\TableGateway\DirectusUiTableGateway;
21
use Directus\Database\TableGateway\DirectusUsersTableGateway;
22
use Directus\Database\TableGateway\RelationalTableGateway;
23
use Directus\Database\TableSchema;
24
use Directus\Util\ArrayUtils;
25
use Directus\Util\DateUtils;
26
use Directus\Util\SchemaUtils;
27
28
/**
29
 * Client Local
30
 *
31
 * Client to Interact with the database directly using Directus Database Component
32
 *
33
 * @author Welling Guzmán <[email protected]>
34
 */
35
class ClientLocal extends AbstractClient
36
{
37
    /**
38
     * @var BaseTableGateway[]
39
     */
40
    protected $tableGateways = [];
41
42
    /**
43
     * @var Connection
44
     */
45
    protected $connection = null;
46
47
    /**
48
     * ClientLocal constructor.
49
     *
50
     * @param $connection
51
     */
52
    public function __construct($connection)
53
    {
54
        $this->connection = $connection;
55
    }
56
57
    /**
58
     * @inheritDoc
59
     */
60
    public function getTables(array $params = [])
61
    {
62
        return $this->createResponseFromData(TableSchema::getTablesSchema($params));
0 ignored issues
show
Bug Compatibility introduced by
The expression $this->createResponseFro...TablesSchema($params)); of type Directus\SDK\Response\En...ctus\SDK\Response\Entry adds the type Directus\SDK\Response\Entry to the return on line 62 which is incompatible with the return type declared by the interface Directus\SDK\RequestsInterface::getTables of type Directus\SDK\Response\EntryCollection.
Loading history...
63
    }
64
65
    /**
66
     * @inheritDoc
67
     */
68
    public function getTable($tableName)
69
    {
70
        return $this->createResponseFromData(TableSchema::getSchemaArray($tableName));
0 ignored issues
show
Bug Compatibility introduced by
The expression $this->createResponseFro...hemaArray($tableName)); of type Directus\SDK\Response\En...ctus\SDK\Response\Entry adds the type Directus\SDK\Response\EntryCollection to the return on line 70 which is incompatible with the return type declared by the interface Directus\SDK\RequestsInterface::getTable of type Directus\SDK\Response\Entry.
Loading history...
71
    }
72
73
    /**
74
     * @inheritDoc
75
     */
76
    public function getColumns($tableName, array $params = [])
77
    {
78
        return $this->createResponseFromData(TableSchema::getColumnSchemaArray($tableName, $params));
0 ignored issues
show
Bug Compatibility introduced by
The expression $this->createResponseFro...($tableName, $params)); of type Directus\SDK\Response\En...ctus\SDK\Response\Entry adds the type Directus\SDK\Response\Entry to the return on line 78 which is incompatible with the return type declared by the interface Directus\SDK\RequestsInterface::getColumns of type Directus\SDK\Response\EntryCollection.
Loading history...
79
    }
80
81
    /**
82
     * @inheritDoc
83
     */
84
    public function getColumn($tableName, $columnName)
85
    {
86
        return $this->createResponseFromData(TableSchema::getColumnSchema($tableName, $columnName)->toArray());
0 ignored issues
show
Bug Compatibility introduced by
The expression $this->createResponseFro...olumnName)->toArray()); of type Directus\SDK\Response\En...ctus\SDK\Response\Entry adds the type Directus\SDK\Response\EntryCollection to the return on line 86 which is incompatible with the return type declared by the interface Directus\SDK\RequestsInterface::getColumn of type Directus\SDK\Response\Entry.
Loading history...
87
    }
88
89
    /**
90
     * @inheritDoc
91
     */
92
    public function getItems($tableName, array $params = [])
93
    {
94
        $tableGateway = $this->getTableGateway($tableName);
95
96
        return $this->createResponseFromData($tableGateway->getItems($params));
0 ignored issues
show
Bug Compatibility introduced by
The expression $this->createResponseFro...ay->getItems($params)); of type Directus\SDK\Response\En...ctus\SDK\Response\Entry adds the type Directus\SDK\Response\Entry to the return on line 96 which is incompatible with the return type declared by the interface Directus\SDK\RequestsInterface::getItems of type Directus\SDK\Response\EntryCollection.
Loading history...
97
    }
98
99
    /**
100
     * @inheritDoc
101
     */
102
    public function getItem($tableName, $id, array $params = [])
103
    {
104
        // @TODO: Dynamic ID
105
        return $this->getItems($tableName, array_merge($params, [
0 ignored issues
show
Bug Best Practice introduced by
The return type of return $this->getItems($..., array('id' => $id))); (Directus\SDK\Response\EntryCollection) is incompatible with the return type declared by the interface Directus\SDK\RequestsInterface::getItem of type Directus\SDK\Response\Entry.

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...
106
            'id' => $id
107
        ]));
108
    }
109
110
    /**
111
     * @inheritDoc
112
     */
113
    public function getUsers(array $params = [])
114
    {
115
        // @TODO: store the directus tables somewhere (SchemaManager?)
116
        return $this->getItems('directus_users', $params);
117
    }
118
119
    /**
120
     * @inheritDoc
121
     */
122
    public function getUser($id, array $params = [])
123
    {
124
        return $this->getItem('directus_users', $id, $params);
0 ignored issues
show
Bug Best Practice introduced by
The return type of return $this->getItem('d..._users', $id, $params); (Directus\SDK\Response\EntryCollection) is incompatible with the return type declared by the interface Directus\SDK\RequestsInterface::getUser of type Directus\SDK\Response\Entry.

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...
125
    }
126
127
    /**
128
     * @inheritDoc
129
     */
130
    public function getGroups(array $params = [])
131
    {
132
        return $this->getItems('directus_groups', $params);
133
    }
134
135
    /**
136
     * @inheritDoc
137
     */
138
    public function getGroup($id, array $params = [])
139
    {
140
        return $this->getItem('directus_groups', $id, $params);
0 ignored issues
show
Bug Best Practice introduced by
The return type of return $this->getItem('d...groups', $id, $params); (Directus\SDK\Response\EntryCollection) is incompatible with the return type declared by the interface Directus\SDK\RequestsInterface::getGroup of type Directus\SDK\Response\Entry.

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...
141
    }
142
143
    /**
144
     * @inheritDoc
145
     */
146
    public function getGroupPrivileges($groupID)
147
    {
148
        $this->getItems('directus_privileges', [
149
            'filter' => [
150
                'group_id' => ['eq' => $groupID]
151
            ]
152
        ]);
153
    }
154
155
    /**
156
     * @inheritDoc
157
     */
158
    public function getFiles(array $params = [])
159
    {
160
        return $this->getItems('directus_files', $params);
161
    }
162
163
    /**
164
     * @inheritDoc
165
     */
166
    public function getFile($id, array $params = [])
167
    {
168
        return $this->getItem('directus_files', $id, $params);
0 ignored issues
show
Bug Best Practice introduced by
The return type of return $this->getItem('d..._files', $id, $params); (Directus\SDK\Response\EntryCollection) is incompatible with the return type declared by the interface Directus\SDK\RequestsInterface::getFile of type Directus\SDK\Response\Entry.

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...
169
    }
170
171
    /**
172
     * @inheritDoc
173
     */
174
    public function getSettings()
175
    {
176
        return $this->getItems('directus_settings');
177
    }
178
179
    /**
180
     * @inheritDoc
181
     */
182 View Code Duplication
    public function getSettingsByCollection($collectionName)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
183
    {
184
        $connection = $this->container->get('connection');
185
        $acl = $this->container->get('acl');
186
        $tableGateway = new DirectusSettingsTableGateway($connection, $acl);
187
188
        $data = [
189
            'meta' => [
190
                'table' => 'directus_settings',
191
                'type' => 'entry',
192
                'settings_collection' => $collectionName
193
            ],
194
            'data' => $tableGateway->fetchCollection($collectionName)
195
        ];
196
197
        return $this->createResponseFromData($data);
0 ignored issues
show
Bug Compatibility introduced by
The expression $this->createResponseFromData($data); of type Directus\SDK\Response\En...ctus\SDK\Response\Entry adds the type Directus\SDK\Response\Entry to the return on line 197 which is incompatible with the return type declared by the interface Directus\SDK\RequestsInt...getSettingsByCollection of type Directus\SDK\Response\EntryCollection.
Loading history...
198
    }
199
200
    /**
201
     * @inheritdoc
202
     */
203
    public function updateSettings($collection, array $data)
204
    {
205
        $connection = $this->container->get('connection');
206
        $acl = $this->container->get('acl');
207
        $tableGateway = new DirectusSettingsTableGateway($connection, $acl);
208
209
        $tableGateway->setValues($collection, $data);
210
211
        return $this->getSettingsByCollection($collection);
0 ignored issues
show
Bug Best Practice introduced by
The return type of return $this->getSetting...ollection($collection); (Directus\SDK\Response\EntryCollection) is incompatible with the return type declared by the interface Directus\SDK\RequestsInterface::updateSettings of type Directus\SDK\Response\Entry.

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...
212
    }
213
214
    /**
215
     * @inheritDoc
216
     */
217 View Code Duplication
    public function getMessages($userId = null)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
218
    {
219
        $connection = $this->container->get('connection');
220
        $acl = $this->container->get('acl');
221
222
        if ($userId === null) {
223
            $userId = $acl->getUserId();
224
        }
225
226
        $messagesTableGateway = new DirectusMessagesTableGateway($connection, $acl);
227
        $result = $messagesTableGateway->fetchMessagesInboxWithHeaders($userId);
228
229
        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 229 which is incompatible with the return type declared by the interface Directus\SDK\RequestsInterface::getMessages of type Directus\SDK\Response\EntryCollection.
Loading history...
230
    }
231
232 View Code Duplication
    public function getMessage($id, $userId = null)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
233
    {
234
        $connection = $this->container->get('connection');
235
        $acl = $this->container->get('acl');
236
237
        if ($userId === null) {
238
            $userId = $acl->getUserId();
239
        }
240
241
        $messagesTableGateway = new DirectusMessagesTableGateway($connection, $acl);
242
        $message = $messagesTableGateway->fetchMessageWithRecipients($id, $userId);
243
244
        return $this->createResponseFromData($message);
0 ignored issues
show
Bug Compatibility introduced by
The expression $this->createResponseFromData($message); of type Directus\SDK\Response\En...ctus\SDK\Response\Entry adds the type Directus\SDK\Response\EntryCollection to the return on line 244 which is incompatible with the return type declared by the interface Directus\SDK\RequestsInterface::getMessage of type Directus\SDK\Response\Entry.
Loading history...
245
    }
246
247
    /**
248
     * @inheritDoc
249
     */
250 View Code Duplication
    public function createItem($tableName, array $data)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
251
    {
252
        $tableGateway = $this->getTableGateway($tableName);
253
        $data = $this->processData($tableName, $data);
254
255
        foreach($data as $key => $value) {
256
            if ($value instanceof File) {
257
                $data[$key] = $this->processFile($value);
258
            }
259
        }
260
261
        $newRecord = $tableGateway->manageRecordUpdate($tableName, $data);
262
263
        return $this->getItem($tableName, $newRecord[$tableGateway->primaryKeyFieldName]);
0 ignored issues
show
Bug Best Practice introduced by
The return type of return $this->getItem($t...>primaryKeyFieldName]); (Directus\SDK\Response\EntryCollection) is incompatible with the return type declared by the interface Directus\SDK\RequestsInterface::createItem of type Directus\SDK\Response\Entry.

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...
264
    }
265
266
    /**
267
     * @inheritDoc
268
     */
269 View Code Duplication
    public function updateItem($tableName, $id, array $data)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
270
    {
271
        $tableGateway = $this->getTableGateway($tableName);
272
        $data = $this->processData($tableName, $data);
273
274
        foreach($data as $key => $value) {
275
            if ($value instanceof File) {
276
                $data[$key] = $this->processFile($value);
277
            }
278
        }
279
280
        $updatedRecord = $tableGateway->manageRecordUpdate($tableName, array_merge($data, ['id' => $id]));
281
282
        return $this->getItem($tableName, $updatedRecord[$tableGateway->primaryKeyFieldName]);
283
    }
284
285
    /**
286
     * @inheritDoc
287
     */
288
    public function deleteItem($tableName, $ids)
289
    {
290
        // @TODO: Accept EntryCollection and Entry
291
        $tableGateway = $this->getTableGateway($tableName);
292
293
        if (!is_array($ids)) {
294
            $ids = [$ids];
295
        }
296
297
        return $tableGateway->delete(function($delete) use ($ids) {
298
            return $delete->where->in('id', $ids);
299
        });
300
    }
301
302
    /**
303
     * @inheritDoc
304
     */
305
    public function createUser(array $data)
306
    {
307
        return $this->createItem('directus_users', $data);
0 ignored issues
show
Bug Best Practice introduced by
The return type of return $this->createItem...irectus_users', $data); (Directus\SDK\Response\EntryCollection) is incompatible with the return type declared by the interface Directus\SDK\RequestsInterface::createUser of type Directus\SDK\Response\Entry.

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...
308
    }
309
310
    /**
311
     * @inheritDoc
312
     */
313
    public function updateUser($id, array $data)
314
    {
315
        return $this->updateItem('directus_users', $id, $data);
316
    }
317
318
    /**
319
     * @inheritDoc
320
     */
321
    public function deleteUser($ids)
322
    {
323
        return $this->deleteItem('directus_users', $ids);
324
    }
325
326
    /**
327
     * @inheritDoc
328
     */
329
    public function createFile(File $file)
330
    {
331
        $data = $this->processFile($file);
332
333
        return $this->createItem('directus_files', $data);
0 ignored issues
show
Bug Best Practice introduced by
The return type of return $this->createItem...irectus_files', $data); (Directus\SDK\Response\EntryCollection) is incompatible with the return type declared by the interface Directus\SDK\RequestsInterface::createFile of type Directus\SDK\Response\Entry.

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...
334
    }
335
336
    /**
337
     * @inheritDoc
338
     */
339
    public function updateFile($id, $data)
340
    {
341
        if ($data instanceof File) {
342
            $data = $this->processFile($data);
343
        }
344
345
        return $this->updateItem('directus_files', $id, $data);
346
    }
347
348
    /**
349
     * @inheritDoc
350
     */
351
    public function deleteFile($ids)
352
    {
353
        return $this->deleteItem('directus_files', $ids);
354
    }
355
356
    public function createPreferences($data)
357
    {
358
        if (!ArrayUtils::contains($data, ['title', 'table_name'])) {
359
            throw new \Exception('title and table_name are required');
360
        }
361
362
        $acl = $this->container->get('acl');
363
        $data['user'] = $acl->getUserId();
364
365
        return $this->createItem('directus_preferences', $data);
0 ignored issues
show
Bug Best Practice introduced by
The return type of return $this->createItem...s_preferences', $data); (Directus\SDK\Response\EntryCollection) is incompatible with the return type declared by the interface Directus\SDK\RequestsInterface::createPreferences of type Directus\SDK\Response\Entry.

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...
366
    }
367
368
    /**
369
     * @inheritdoc
370
     */
371
    public function createBookmark($data)
372
    {
373
        $acl = $this->container->get('acl');
374
        $data['user'] = $acl->getUserId();
375
376
        $preferences = $this->createPreferences(ArrayUtils::pick($data, [
377
            'title', 'table_name', 'sort', 'status', 'search_string', 'sort_order', 'columns_visible', 'user'
378
        ]));
379
380
        $title = $preferences->title;
0 ignored issues
show
Bug introduced by
The property title does not seem to exist in Directus\SDK\Response\EntryCollection.

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
381
        $tableName = $preferences->table_name;
0 ignored issues
show
Bug introduced by
The property table_name does not seem to exist in Directus\SDK\Response\EntryCollection.

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
382
        $bookmarkData = [
383
            'section' => 'search',
384
            'title' => $title,
385
            'url' => 'tables/' . $tableName . '/pref/' . $title,
386
            'user' => $data['user']
387
        ];
388
389
        return $this->createItem('directus_bookmarks', $bookmarkData);
0 ignored issues
show
Bug Best Practice introduced by
The return type of return $this->createItem...marks', $bookmarkData); (Directus\SDK\Response\EntryCollection) is incompatible with the return type declared by the interface Directus\SDK\RequestsInterface::createBookmark of type Directus\SDK\Response\Entry.

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...
390
    }
391
392
    /**
393
     * @inheritdoc
394
     */
395
    public function getBookmark($id)
396
    {
397
        return $this->getItem('directus_bookmarks', $id);
0 ignored issues
show
Bug Best Practice introduced by
The return type of return $this->getItem('directus_bookmarks', $id); (Directus\SDK\Response\EntryCollection) is incompatible with the return type declared by the interface Directus\SDK\RequestsInterface::getBookmark of type Directus\SDK\Response\Entry.

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...
398
    }
399
400
    /**
401
     * @inheritdoc
402
     */
403
    public function getBookmarks($userId = null)
404
    {
405
        $filters = [];
406
        if ($userId !== null) {
407
            $filters = [
408
                'filters' => ['user' => ['eq' => $userId]]
409
            ];
410
        }
411
412
        return $this->getItems('directus_bookmarks', $filters);
0 ignored issues
show
Bug Best Practice introduced by
The return type of return $this->getItems('..._bookmarks', $filters); (Directus\SDK\Response\EntryCollection) is incompatible with the return type declared by the interface Directus\SDK\RequestsInterface::getBookmarks of type Directus\SDK\Response\Entry.

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...
413
    }
414
415
    /**
416
     * @inheritdoc
417
     */
418
    public function createColumn($data)
419
    {
420
        $data = $this->parseColumnData($data);
421
422
        $tableGateway = $this->getTableGateway($data['table_name']);
423
424
        $tableGateway->addColumn($data['table_name'], ArrayUtils::omit($data, ['table_name']));
425
426
        return $this->getColumn($data['table_name'], $data['column_name']);
427
    }
428
429
    /**
430
     * @inheritdoc
431
     */
432
    public function createGroup(array $data)
433
    {
434
        return $this->createItem('directus_groups', $data);
0 ignored issues
show
Bug Best Practice introduced by
The return type of return $this->createItem...rectus_groups', $data); (Directus\SDK\Response\EntryCollection) is incompatible with the return type declared by the interface Directus\SDK\RequestsInterface::createGroup of type Directus\SDK\Response\Entry.

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...
435
    }
436
437
    /**
438
     * @inheritdoc
439
     */
440
    public function createMessage(array $data)
441
    {
442
        $this->requiredAttributes(['from', 'message', 'subject'], $data);
443
        $this->requiredOneAttribute(['to', 'toGroup'], $data);
444
445
        $recipients = $this->getMessagesTo($data);
446
        $recipients = explode(',', $recipients);
447
        ArrayUtils::remove($data, ['to', 'toGroup']);
448
449
        $groupRecipients = [];
450
        $userRecipients = [];
451
        foreach ($recipients as $recipient) {
452
            $typeAndId = explode('_', $recipient);
453
            if ($typeAndId[0] == 0) {
454
                $userRecipients[] = $typeAndId[1];
455
            } else {
456
                $groupRecipients[] = $typeAndId[1];
457
            }
458
        }
459
460
        $ZendDb = $this->container->get('connection');
461
        $acl = $this->container->get('acl');
462
        if (count($groupRecipients) > 0) {
463
            $usersTableGateway = new DirectusUsersTableGateway($ZendDb, $acl);
464
            $result = $usersTableGateway->findActiveUserIdsByGroupIds($groupRecipients);
465
            foreach ($result as $item) {
466
                $userRecipients[] = $item['id'];
467
            }
468
        }
469
470
        $userRecipients[] = $acl->getUserId();
471
472
        $messagesTableGateway = new DirectusMessagesTableGateway($ZendDb, $acl);
473
        $id = $messagesTableGateway->sendMessage($data, array_unique($userRecipients), $acl->getUserId());
474
475
        if ($id) {
476
            $Activity = new DirectusActivityTableGateway($ZendDb, $acl);
477
            $data['id'] = $id;
478
            $Activity->recordMessage($data, $acl->getUserId());
479
        }
480
481
        $message = $messagesTableGateway->fetchMessageWithRecipients($id, $acl->getUserId());
482
        $response = [
483
            'meta' => [
484
                'type' => 'item',
485
                'table' => 'directus_messages'
486
            ],
487
            'data' => $message
488
        ];
489
490
        return $this->createResponseFromData($response);
0 ignored issues
show
Bug Compatibility introduced by
The expression $this->createResponseFromData($response); of type Directus\SDK\Response\En...ctus\SDK\Response\Entry adds the type Directus\SDK\Response\EntryCollection to the return on line 490 which is incompatible with the return type declared by the interface Directus\SDK\RequestsInterface::createMessage of type Directus\SDK\Response\Entry.
Loading history...
491
    }
492
493
    /**
494
     * @inheritdoc
495
     */
496
    public function sendMessage(array $data)
497
    {
498
        return $this->createMessage($data);
499
    }
500
501 View Code Duplication
    public function createPrivileges(array $data)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
502
    {
503
        $connection = $this->container->get('connection');
504
        $acl = $this->container->get('acl');
505
        $privileges = new DirectusPrivilegesTableGateway($connection, $acl);
506
507
        $response = [
508
            'meta' => [
509
                'type' => 'item',
510
                'table' => 'directus_privileges'
511
            ],
512
            'data' => $privileges->insertPrivilege($data)
513
        ];
514
515
        return $this->createResponseFromData($response);
0 ignored issues
show
Bug Compatibility introduced by
The expression $this->createResponseFromData($response); of type Directus\SDK\Response\En...ctus\SDK\Response\Entry adds the type Directus\SDK\Response\EntryCollection to the return on line 515 which is incompatible with the return type declared by the interface Directus\SDK\RequestsInterface::createPrivileges of type Directus\SDK\Response\Entry.
Loading history...
516
    }
517
518
    public function createTable($name, array $data = [])
519
    {
520
        $isTableNameAlphanumeric = preg_match("/[a-z0-9]+/i", $name);
521
        $zeroOrMoreUnderscoresDashes = preg_match("/[_-]*/i", $name);
522
523
        if (!($isTableNameAlphanumeric && $zeroOrMoreUnderscoresDashes)) {
524
            return $this->createResponseFromData(['error' => ['message' => 'invalid_table_name']]);
0 ignored issues
show
Bug Compatibility introduced by
The expression $this->createResponseFro...invalid_table_name'))); of type Directus\SDK\Response\En...ctus\SDK\Response\Entry adds the type Directus\SDK\Response\EntryCollection to the return on line 524 which is incompatible with the return type declared by the interface Directus\SDK\RequestsInterface::createTable of type Directus\SDK\Response\Entry.
Loading history...
525
        }
526
527
        $schema = $this->container->get('schemaManager');
528
        $emitter = $this->container->get('emitter');
529
        if (!$schema->tableExists($name)) {
530
            $emitter->run('table.create:before', $name);
531
            // Through API:
532
            // Remove spaces and symbols from table name
533
            // And in lowercase
534
            $name = SchemaUtils::cleanTableName($name);
535
            $schema->createTable($name);
536
            $emitter->run('table.create', $name);
537
            $emitter->run('table.create:after', $name);
538
        }
539
540
        $connection = $this->container->get('connection');
541
        $acl = $this->container->get('acl');
542
        $privileges = new DirectusPrivilegesTableGateway($connection, $acl);
543
544
        return $this->createResponseFromData($privileges->insertPrivilege([
1 ignored issue
show
Bug Compatibility introduced by
The expression $this->createResponseFro...able_name' => $name))); of type Directus\SDK\Response\En...ctus\SDK\Response\Entry adds the type Directus\SDK\Response\EntryCollection to the return on line 544 which is incompatible with the return type declared by the interface Directus\SDK\RequestsInterface::createTable of type Directus\SDK\Response\Entry.
Loading history...
545
            'group_id' => 1,
546
            'table_name' => $name
547
        ]));
548
    }
549
550
    /**
551
     * @inheritdoc
552
     */
553
    public function createColumnUIOptions(array $data)
554
    {
555
        $this->requiredAttributes(['table', 'column', 'ui', 'options'], $data);
556
        $tableGateway = $this->getTableGateway('directus_ui');
557
558
        $table = $data['table'];
559
        $column = $data['column'];
560
        $ui = $data['ui'];
561
562
        $data = $data['options'];
563
        $keys = ['table_name' => $table, 'column_name' => $column, 'ui_name' => $ui];
564
        $uis = to_name_value($data, $keys);
565
566
        $column_settings = [];
567
        foreach ($uis as $col) {
568
            $existing = $tableGateway->select(['table_name' => $table, 'column_name' => $column, 'ui_name' => $ui, 'name' => $col['name']])->toArray();
569
            if (count($existing) > 0) {
570
                $col['id'] = $existing[0]['id'];
571
            }
572
            array_push($column_settings, $col);
573
        }
574
        $tableGateway->updateCollection($column_settings);
575
576
        $connection = $this->container->get('connection');
577
        $acl = $this->container->get('acl');
578
        $UiOptions = new DirectusUiTableGateway($connection, $acl);
579
        $response = $UiOptions->fetchOptions($table, $column, $ui);
580
581
        if (!$response) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $response of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
582
            $response = [
583
                'error' => [
584
                    'message' => sprintf('unable_to_find_column_%s_options_for_%s', ['column' => $column, 'ui' => $ui])
585
                ],
586
                'success' => false
587
            ];
588
        } else {
589
            $response = [
590
                'meta' => [
591
                    'type' => 'item',
592
                    'table' => 'directus_ui'
593
                ],
594
                'data' => $response
595
            ];
596
        }
597
598
        return $this->createResponseFromData($response);
0 ignored issues
show
Bug Compatibility introduced by
The expression $this->createResponseFromData($response); of type Directus\SDK\Response\En...ctus\SDK\Response\Entry adds the type Directus\SDK\Response\EntryCollection to the return on line 598 which is incompatible with the return type declared by the interface Directus\SDK\RequestsInt...::createColumnUIOptions of type Directus\SDK\Response\Entry.
Loading history...
599
    }
600
601 View Code Duplication
    public function getPreferences($table, $user)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
602
    {
603
        $acl = $this->container->get('acl');
604
        $connection = $this->container->get('connection');
605
        $preferencesTableGateway = new DirectusPreferencesTableGateway($connection, $acl);
606
607
        $response = [
608
            'meta' => [
609
                'type' => 'item',
610
                'table' => 'directus_preferences'
611
            ],
612
            'data' => $preferencesTableGateway->fetchByUserAndTableAndTitle($user, $table)
613
        ];
614
615
        return $this->createResponseFromData($response);
0 ignored issues
show
Bug Compatibility introduced by
The expression $this->createResponseFromData($response); of type Directus\SDK\Response\En...ctus\SDK\Response\Entry adds the type Directus\SDK\Response\EntryCollection to the return on line 615 which is incompatible with the return type declared by the interface Directus\SDK\RequestsInterface::getPreferences of type Directus\SDK\Response\Entry.
Loading history...
616
    }
617
618
    /**
619
     * @inheritdoc
620
     */
621
    public function deleteBookmark($id)
622
    {
623
        return $this->deleteItem('directus_bookmarks', $id);
0 ignored issues
show
Bug Best Practice introduced by
The return type of return $this->deleteItem...ectus_bookmarks', $id); (integer) is incompatible with the return type declared by the interface Directus\SDK\RequestsInterface::deleteBookmark of type Directus\SDK\Response\Entry.

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...
624
    }
625
626
    /**
627
     * @inheritdoc
628
     */
629 View Code Duplication
    public function deleteColumn($name, $table)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
630
    {
631
        $tableGateway = $this->getTableGateway($table);
632
        $success = $tableGateway->dropColumn($name);
633
634
        $response = [
635
            'success' => (bool) $success
636
        ];
637
638
        if (!$success) {
639
            $response['error'] = [
640
                'message' => sprintf('unable_to_remove_column_%s', ['column_name' => $name])
641
            ];
642
        }
643
644
        return $this->createResponseFromData($response);
0 ignored issues
show
Bug Compatibility introduced by
The expression $this->createResponseFromData($response); of type Directus\SDK\Response\En...ctus\SDK\Response\Entry adds the type Directus\SDK\Response\EntryCollection to the return on line 644 which is incompatible with the return type declared by the interface Directus\SDK\RequestsInterface::deleteColumn of type Directus\SDK\Response\Entry.
Loading history...
645
    }
646
647
    /**
648
     * @inheritdoc
649
     */
650
    public function deleteGroup($id)
651
    {
652
        return $this->deleteItem('directus_groups', $id);
0 ignored issues
show
Bug Best Practice introduced by
The return type of return $this->deleteItem('directus_groups', $id); (integer) is incompatible with the return type declared by the interface Directus\SDK\RequestsInterface::deleteGroup of type Directus\SDK\Response\Entry.

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...
653
    }
654
655
    /**
656
     * @inheritdoc
657
     */
658 View Code Duplication
    public function deleteTable($name)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
659
    {
660
        $tableGateway = $this->getTableGateway($name);
661
        $success = $tableGateway->drop();
662
663
        $response = [
664
            'success' => (bool) $success
665
        ];
666
667
        if (!$success) {
668
            $response['error'] = [
669
                'message' => sprintf('unable_to_remove_table_%s', ['table_name' => $name])
670
            ];
671
        }
672
673
        return $this->createResponseFromData($response);
0 ignored issues
show
Bug Compatibility introduced by
The expression $this->createResponseFromData($response); of type Directus\SDK\Response\En...ctus\SDK\Response\Entry adds the type Directus\SDK\Response\EntryCollection to the return on line 673 which is incompatible with the return type declared by the interface Directus\SDK\RequestsInterface::deleteTable of type Directus\SDK\Response\Entry.
Loading history...
674
    }
675
676
    public function getActivity(array $params = [])
677
    {
678
        $connection = $this->container->get('connection');
679
        $acl = $this->container->get('acl');
680
        $tableGateway = new DirectusActivityTableGateway($connection, $acl);
681 View Code Duplication
        if (!ArrayUtils::has($params, 'filters.datetime')) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
682
            $params['filters']['datetime'] = ['>=' => DateUtils::daysAgo(30)];
683
        }
684
685
        $data = $tableGateway->fetchFeed($params);
686
687
        return $this->createResponseFromData($data);
0 ignored issues
show
Bug Compatibility introduced by
The expression $this->createResponseFromData($data); of type Directus\SDK\Response\En...ctus\SDK\Response\Entry adds the type Directus\SDK\Response\EntryCollection to the return on line 687 which is incompatible with the return type declared by the interface Directus\SDK\RequestsInterface::getActivity of type Directus\SDK\Response\Entry.
Loading history...
688
    }
689
690
    /**
691
     * Get a table gateway for the given table name
692
     *
693
     * @param $tableName
694
     *
695
     * @return RelationalTableGateway
696
     */
697
    protected function getTableGateway($tableName)
698
    {
699
        if (!array_key_exists($tableName, $this->tableGateways)) {
700
            $acl = TableSchema::getAclInstance();
701
            $this->tableGateways[$tableName] = new RelationalTableGateway($tableName, $this->connection, $acl);
702
        }
703
704
        return $this->tableGateways[$tableName];
705
    }
706
}
707