Completed
Push — d64 ( 97323e...2997b8 )
by Welling
06:27
created

ClientFactory::createRemoteClient()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 2
nc 1
nop 2
dl 0
loc 4
ccs 2
cts 2
cp 1
crap 1
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\DirectusPrivilegesTableGateway;
16
use Directus\Database\TableGateway\DirectusSettingsTableGateway;
17
use Directus\Filesystem\Files;
18
use Directus\Filesystem\Filesystem;
19
use Directus\Filesystem\FilesystemFactory;
20
use Directus\Hook\Emitter;
21
use Directus\Util\ArrayUtils;
22
use Directus\Database\TableSchema;
23
24
/**
25
 * Client
26
 *
27
 * @author Welling Guzmán <[email protected]>
28
 */
29
class ClientFactory
30
{
31
    /**
32
     * @var ClientFactory
33
     */
34
    protected static $instance = null;
35
36
    /**
37
     * @var Container
38
     */
39
    protected $container;
40
41
    /**
42
     * @var array
43
     */
44
    protected $config = [];
45
46
    protected $settings = [];
47
48
    protected $emitter;
49
50
    protected $files;
51
52
    /**
53
     * @var array
54
     */
55
    protected $defaultConfig = [
56
        'environment' => 'development',
57
        'database' => [
58
            'driver' => 'pdo_mysql'
59
        ],
60
        'status' => [
61
            'column_name' => 'active',
62
            'deleted_value' => 0,
63
            'active_value' => 1,
64
            'draft_value' => 2,
65
            'mapping' => [
66
                0 => [
67
                    'name' => 'Delete',
68
                    'color' => '#C1272D',
69
                    'sort' => 3
70
                ],
71
                1 => [
72
                    'name' => 'Active',
73
                    'color' => '#5B5B5B',
74
                    'sort' => 1
75
                ],
76
                2 => [
77
                    'name' => 'Draft',
78
                    'color' => '#BBBBBB',
79
                    'sort' => 2
80
                ]
81
            ]
82
        ],
83
        'filesystem' => [
84
            'adapter' => 'local',
85
            // By default media directory are located at the same level of directus root
86
            // To make them a level up outsite the root directory
87
            // use this instead
88
            // Ex: 'root' => realpath(BASE_PATH.'/../storage/uploads'),
89
            // Note: BASE_PATH constant doesn't end with trailing slash
90
            'root' => '/storage/uploads',
91
            // This is the url where all the media will be pointing to
92
            // here all assets will be (yourdomain)/storage/uploads
93
            // same with thumbnails (yourdomain)/storage/uploads/thumbs
94
            'root_url' => '/storage/uploads',
95
            'root_thumb_url' => '/storage/uploads/thumbs',
96
            //   'key'    => 's3-key',
97
            //   'secret' => 's3-key',
98
            //   'region' => 's3-region',
99
            //   'version' => 's3-version',
100
            //   'bucket' => 's3-bucket'
101
        ],
102
    ];
103
104
    /**
105
     * @param $userToken
106
     * @param array $options
107
     *
108
     * @return ClientLocal|ClientRemote
109
     */
110 38
    public static function create($userToken, $options = [])
111
    {
112 38
        if (static::$instance == null) {
113 2
            static::$instance = new static;
114 2
        }
115
116 38
        if (!is_array($userToken)) {
117 38
            $newClient = static::$instance->createRemoteClient($userToken, $options);
118 38
        } else {
119
            $options = $userToken;
120
            $newClient = static::$instance->createLocalClient($options);
121
        }
122
123 38
        return $newClient;
124
    }
125
126
    /**
127
     * Creates a new local client instance
128
     *
129
     * @param array $options
130
     *
131
     * @return ClientLocal
132
     */
133
    public function createLocalClient(array $options)
134
    {
135
        $this->container = $container = new Container();
136
137
        $options = ArrayUtils::defaults($this->defaultConfig, $options);
138
        $container->set('config', $options);
139
140
        $dbConfig = ArrayUtils::get($options, 'database', []);
141
142
        $config = ArrayUtils::omit($options, 'database');
143
        // match the actual directus status mapping config key
144
        $config['statusMapping'] = $config['status']['mapping'];
145
        unset($config['status']['mapping']);
146
147
        if (!defined('STATUS_DELETED_NUM')) {
148
            define('STATUS_DELETED_NUM', ArrayUtils::get($config, 'status.deleted_value', 0));
149
        }
150
151
        if (!defined('STATUS_ACTIVE_NUM')) {
152
            define('STATUS_ACTIVE_NUM', ArrayUtils::get($config, 'status.active_value', 1));
153
        }
154
155
        if (!defined('STATUS_DRAFT_NUM')) {
156
            define('STATUS_DRAFT_NUM', ArrayUtils::get($config, 'status.draft_value', 2));
157
        }
158
159
        if (!defined('STATUS_COLUMN_NAME')) {
160
            define('STATUS_COLUMN_NAME', ArrayUtils::get($config, 'status.column_name', 'active'));
161
        }
162
163
        if (!defined('DIRECTUS_ENV')) {
164
            define('DIRECTUS_ENV', ArrayUtils::get($config, 'environment', 'development'));
165
        }
166
167
        $connection = new Connection($dbConfig);
168
        $connection->connect();
169
        $container->set('connection', $connection);
170
171
        $acl = new \Directus\Permissions\Acl();
172
        $acl->setUserId(1);
173
        $acl->setGroupId(1);
174
        $acl->setGroupPrivileges([
175
            '*' => [
176
                'id' => 1,
177
                'table_name' => '*',
178
                'group_id' => 1,
179
                'read_field_blacklist' => [],
180
                'write_field_blacklist' => [],
181
                'nav_listed' => 1,
182
                'status_id' => 0,
183
                'allow_view' => 2,
184
                'allow_add' => 1,
185
                'allow_edit' => 2,
186
                'allow_delete' => 2,
187
                'allow_alter' => 1
188
            ]
189
        ]);
190
        $container->set('acl', $acl);
191
192
        $schema = new \Directus\Database\Schemas\Sources\MySQLSchema($connection);
193
        $container->set('schemaSource', $schema);
194
        $schema = new \Directus\Database\SchemaManager($schema);
195
        $container->set('schemaManager', $schema);
196
        TableSchema::setSchemaManagerInstance($schema);
197
        TableSchema::setAclInstance($acl);
198
        TableSchema::setConnectionInstance($connection);
199
        TableSchema::setConfig($config);
200
201
        $container->singleton('emitter', function() {
202
            return $this->getEmitter();
203
        });
204
        $container->set('settings', function(Container $container) {
205
            $adapter = $container->get('connection');
206
            $acl = $container->get('acl');
207
            $Settings = new DirectusSettingsTableGateway($adapter, $acl);
208
209
            return $Settings->fetchCollection('files', [
210
                'thumbnail_size', 'thumbnail_quality', 'thumbnail_crop_enabled'
211
            ]);
212
        });
213
        $container->singleton('files', function() {
214
            return $this->getFiles();
215
        });
216
217
        BaseTableGateway::setHookEmitter($container->get('emitter'));
218
        BaseTableGateway::setContainer($container);
219
220
        $client = new ClientLocal($connection);
221
        $client->setContainer($container);
222
223
        return $client;
224
    }
225
226
    public function getFiles()
227
    {
228
        static $files = null;
229
        if ($files == null) {
230
            $config = $this->container->get('config');
231
            $filesystemConfig = ArrayUtils::get($config, 'filesystem', []);
232
            $filesystem = new Filesystem(FilesystemFactory::createAdapter($filesystemConfig));
0 ignored issues
show
Bug introduced by
It seems like \Directus\Filesystem\Fil...pter($filesystemConfig) can be null; however, __construct() does not accept null, maybe add an additional type check?

Unless you are absolutely sure that the expression can never be null because of other conditions, we strongly recommend to add an additional type check to your code:

/** @return stdClass|null */
function mayReturnNull() { }

function doesNotAcceptNull(stdClass $x) { }

// With potential error.
function withoutCheck() {
    $x = mayReturnNull();
    doesNotAcceptNull($x); // Potential error here.
}

// Safe - Alternative 1
function withCheck1() {
    $x = mayReturnNull();
    if ( ! $x instanceof stdClass) {
        throw new \LogicException('$x must be defined.');
    }
    doesNotAcceptNull($x);
}

// Safe - Alternative 2
function withCheck2() {
    $x = mayReturnNull();
    if ($x instanceof stdClass) {
        doesNotAcceptNull($x);
    }
}
Loading history...
233
            $settings = $this->container->get('settings');
234
            $emitter = $this->container->get('emitter');
235
            $files = new Files($filesystem, $filesystemConfig, $settings, $emitter);
236
        }
237
238
        return $files;
239
    }
240
241
    protected function getEmitter()
242
    {
243
        static $emitter = null;
244
        if ($emitter) {
245
            return $emitter;
246
        }
247
248
        $emitter = new Emitter();
249
        $acl = $this->container->get('acl');
250
        $adapter = $this->container->get('connection');
251
252
        $emitter->addAction('table.insert.directus_groups', function ($data) use ($acl, $adapter) {
253
            $privilegesTable = new DirectusPrivilegesTableGateway($adapter, $acl);
254
255
            $privilegesTable->insertPrivilege([
256
                'group_id' => $data['id'],
257
                'allow_view' => 1,
258
                'allow_add' => 0,
259
                'allow_edit' => 1,
260
                'allow_delete' => 0,
261
                'allow_alter' => 0,
262
                'table_name' => 'directus_users',
263
                'read_field_blacklist' => 'token',
264
                'write_field_blacklist' => 'group,token'
265
            ]);
266
        });
267
268
        $emitter->addFilter('table.insert:before', function($payload) {
269
            // $tableName, $data
270
            if (func_num_args() == 2) {
271
                $tableName = func_get_arg(0);
272
                $data = func_get_arg(1);
273
            } else {
274
                $tableName = $payload->tableName;
275
                $data = $payload->data;
276
            }
277
278
            if ($tableName == 'directus_files') {
279
                unset($data['data']);
280
                $data['user'] = 1;
281
            }
282
283
            return func_num_args() == 2 ? $data : $payload;
284
        });
285
286
        // Add file url and thumb url
287
        $config = $this->container->get('config');
288
        $files = $this->container->get('files');
289
        $emitter->addFilter('table.select', function($payload) use ($config, $files) {
290
            if (func_num_args() == 2) {
291
                $result = func_get_arg(0);
292
                $selectState = func_get_arg(1);
293
            } else {
294
                $selectState = $payload->selectState;
295
                $result = $payload->result;
296
            }
297
298
            if ($selectState['table'] == 'directus_files') {
299
                $fileRows = $result->toArray();
300
                foreach ($fileRows as &$row) {
301
                    $fileURL = ArrayUtils::get($config, 'filesystem.root_url', '');
302
                    $thumbnailURL = ArrayUtils::get($config, 'filesystem.root_thumb_url', '');
303
                    $thumbnailFilenameParts = explode('.', $row['name']);
304
                    $thumbnailExtension = array_pop($thumbnailFilenameParts);
305
306
                    $row['url'] = $fileURL . '/' . $row['name'];
307
                    if (in_array($thumbnailExtension, ['tif', 'tiff', 'psd', 'pdf'])) {
308
                        $thumbnailExtension = 'jpg';
309
                    }
310
311
                    $thumbnailFilename = $row['id'] . '.' . $thumbnailExtension;
312
                    $row['thumbnail_url'] = $thumbnailURL . '/' . $thumbnailFilename;
313
314
                    // filename-ext-100-100-true.jpg
315
                    // @TODO: This should be another hook listener
316
                    $row['thumbnail_url'] = null;
317
                    $filename = implode('.', $thumbnailFilenameParts);
318
                    if ($row['type'] == 'embed/vimeo') {
319
                        $oldThumbnailFilename = $row['name'] . '-vimeo-220-124-true.jpg';
320
                    } else {
321
                        $oldThumbnailFilename = $filename . '-' . $thumbnailExtension . '-160-160-true.jpg';
322
                    }
323
324
                    // 314551321-vimeo-220-124-true.jpg
325
                    // hotfix: there's not thumbnail for this file
326
                    if ($files->exists('thumbs/' . $oldThumbnailFilename)) {
327
                        $row['thumbnail_url'] = $thumbnailURL . '/' . $oldThumbnailFilename;
328
                    }
329
330
                    if ($files->exists('thumbs/' . $thumbnailFilename)) {
331
                        $row['thumbnail_url'] = $thumbnailURL . '/' . $thumbnailFilename;
332
                    }
333
334
                    /*
335
                    $embedManager = Bootstrap::get('embedManager');
336
                    $provider = $embedManager->getByType($row['type']);
337
                    $row['html'] = null;
338
                    if ($provider) {
339
                        $row['html'] = $provider->getCode($row);
340
                    }
341
                    */
342
                }
343
344
                $filesArrayObject = new \ArrayObject($fileRows);
345
                $result->initialize($filesArrayObject->getIterator());
346
            }
347
348
            return (func_num_args() == 2) ? $result : $payload;
349
        });
350
351
        return $emitter;
352
    }
353
354
    /**
355
     * Create a new remote client instance
356
     *
357
     * @param $userToken
358
     * @param array $options
359
     *
360
     * @return ClientRemote
361
     */
362 38
    public function createRemoteClient($userToken, array $options = [])
363
    {
364 38
        return new ClientRemote($userToken, $options);
365
    }
366
}