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\Config\Config; |
14
|
|
|
use Directus\Database\Connection; |
15
|
|
|
use Directus\Database\TableGateway\BaseTableGateway; |
16
|
|
|
use Directus\Database\TableGateway\DirectusSettingsTableGateway; |
17
|
|
|
use Directus\Filesystem\Files; |
18
|
|
|
use Directus\Filesystem\Filesystem; |
19
|
|
|
use Directus\Filesystem\FilesystemFactory; |
20
|
|
|
use Directus\Hash\HashManager; |
21
|
|
|
use Directus\Hook\Emitter; |
22
|
|
|
use Directus\Util\ArrayUtils; |
23
|
|
|
use Directus\Database\TableSchema; |
24
|
|
|
|
25
|
|
|
/** |
26
|
|
|
* Client |
27
|
|
|
* |
28
|
|
|
* @author Welling Guzmán <[email protected]> |
29
|
|
|
*/ |
30
|
|
|
class ClientFactory |
31
|
|
|
{ |
32
|
|
|
/** |
33
|
|
|
* @var ClientFactory |
34
|
|
|
*/ |
35
|
|
|
protected static $instance = null; |
36
|
|
|
|
37
|
|
|
/** |
38
|
|
|
* @var Container |
39
|
|
|
*/ |
40
|
|
|
protected $container; |
41
|
|
|
|
42
|
|
|
/** |
43
|
|
|
* @var array |
44
|
|
|
*/ |
45
|
|
|
protected $config = []; |
46
|
|
|
|
47
|
|
|
protected $settings = []; |
48
|
|
|
|
49
|
|
|
protected $emitter; |
50
|
|
|
|
51
|
|
|
protected $files; |
52
|
|
|
|
53
|
|
|
/** |
54
|
|
|
* @var array |
55
|
|
|
*/ |
56
|
|
|
protected $defaultConfig = [ |
57
|
|
|
'environment' => 'development', |
58
|
|
|
'database' => [ |
59
|
|
|
'driver' => 'pdo_mysql', |
60
|
|
|
'charset' => 'utf8mb4', |
61
|
|
|
'port' => 3306 |
62
|
|
|
], |
63
|
|
|
'status' => [ |
64
|
|
|
'column_name' => 'status', |
65
|
|
|
'deleted_value' => 0, |
66
|
|
|
'active_value' => 1, |
67
|
|
|
'draft_value' => 2, |
68
|
|
|
'mapping' => [ |
69
|
|
|
0 => [ |
70
|
|
|
'name' => 'Deleted', |
71
|
|
|
'text_color' => '#FFFFFF', |
72
|
|
|
'background_color' => '#F44336', |
73
|
|
|
'subdued_in_listing' => true, |
74
|
|
|
'show_listing_badge' => true, |
75
|
|
|
'hidden_globally' => true, |
76
|
|
|
'hard_delete' => false, |
77
|
|
|
'published' => false, |
78
|
|
|
'sort' => 3 |
79
|
|
|
], |
80
|
|
|
1 => [ |
81
|
|
|
'name' => 'Published', |
82
|
|
|
'text_color' => '#FFFFFF', |
83
|
|
|
'background_color' => '#3498DB', |
84
|
|
|
'subdued_in_listing' => false, |
85
|
|
|
'show_listing_badge' => false, |
86
|
|
|
'hidden_globally' => false, |
87
|
|
|
'hard_delete' => false, |
88
|
|
|
'published' => true, |
89
|
|
|
'sort' => 1 |
90
|
|
|
], |
91
|
|
|
2 => [ |
92
|
|
|
'name' => 'Draft', |
93
|
|
|
'text_color' => '#999999', |
94
|
|
|
'background_color' => '#EEEEEE', |
95
|
|
|
'subdued_in_listing' => true, |
96
|
|
|
'show_listing_badge' => true, |
97
|
|
|
'hidden_globally' => false, |
98
|
|
|
'hard_delete' => false, |
99
|
|
|
'published' => false, |
100
|
|
|
'sort' => 2 |
101
|
|
|
] |
102
|
|
|
] |
103
|
|
|
], |
104
|
|
|
'filesystem' => [ |
105
|
|
|
'adapter' => 'local', |
106
|
|
|
// By default media directory are located at the same level of directus root |
107
|
|
|
// To make them a level up outsite the root directory |
108
|
|
|
// use this instead |
109
|
|
|
// Ex: 'root' => realpath(BASE_PATH.'/../storage/uploads'), |
110
|
|
|
// Note: BASE_PATH constant doesn't end with trailing slash |
111
|
|
|
'root' => '/storage/uploads', |
112
|
|
|
// This is the url where all the media will be pointing to |
113
|
|
|
// here all assets will be (yourdomain)/storage/uploads |
114
|
|
|
// same with thumbnails (yourdomain)/storage/uploads/thumbs |
115
|
|
|
'root_url' => '/storage/uploads', |
116
|
|
|
'root_thumb_url' => '/storage/uploads/thumbs', |
117
|
|
|
// 'key' => 's3-key', |
118
|
|
|
// 'secret' => 's3-key', |
119
|
|
|
// 'region' => 's3-region', |
120
|
|
|
// 'version' => 's3-version', |
121
|
|
|
// 'bucket' => 's3-bucket' |
122
|
|
|
], |
123
|
|
|
]; |
124
|
|
|
|
125
|
|
|
/** |
126
|
|
|
* @param $userToken |
127
|
|
|
* @param array $options |
128
|
|
|
* |
129
|
|
|
* @return ClientLocal|ClientRemote |
130
|
|
|
*/ |
131
|
38 |
|
public static function create($userToken, $options = []) |
132
|
|
|
{ |
133
|
38 |
|
if (static::$instance == null) { |
134
|
2 |
|
static::$instance = new static; |
135
|
1 |
|
} |
136
|
|
|
|
137
|
38 |
|
if (!is_array($userToken)) { |
138
|
38 |
|
$newClient = static::$instance->createRemoteClient($userToken, $options); |
139
|
19 |
|
} else { |
140
|
|
|
$options = $userToken; |
141
|
|
|
$newClient = static::$instance->createLocalClient($options); |
142
|
|
|
} |
143
|
|
|
|
144
|
38 |
|
return $newClient; |
145
|
|
|
} |
146
|
|
|
|
147
|
|
|
/** |
148
|
|
|
* Creates a new local client instance |
149
|
|
|
* |
150
|
|
|
* @param array $options |
151
|
|
|
* |
152
|
|
|
* @return ClientLocal |
153
|
|
|
*/ |
154
|
|
|
public function createLocalClient(array $options) |
155
|
|
|
{ |
156
|
|
|
$this->container = $container = new Container(); |
157
|
|
|
|
158
|
|
|
$options = ArrayUtils::defaults($this->defaultConfig, $options); |
159
|
|
|
$container->set('config', new Config($options)); |
160
|
|
|
|
161
|
|
|
$dbConfig = ArrayUtils::get($options, 'database', []); |
162
|
|
|
|
163
|
|
|
$config = ArrayUtils::omit($options, 'database'); |
164
|
|
|
// match the actual directus status mapping config key |
165
|
|
|
$config['statusMapping'] = $config['status']['mapping']; |
166
|
|
|
unset($config['status']['mapping']); |
167
|
|
|
|
168
|
|
|
if (!defined('STATUS_DELETED_NUM')) { |
169
|
|
|
define('STATUS_DELETED_NUM', ArrayUtils::get($config, 'status.deleted_value', 0)); |
170
|
|
|
} |
171
|
|
|
|
172
|
|
|
if (!defined('STATUS_ACTIVE_NUM')) { |
173
|
|
|
define('STATUS_ACTIVE_NUM', ArrayUtils::get($config, 'status.active_value', 1)); |
174
|
|
|
} |
175
|
|
|
|
176
|
|
|
if (!defined('STATUS_DRAFT_NUM')) { |
177
|
|
|
define('STATUS_DRAFT_NUM', ArrayUtils::get($config, 'status.draft_value', 2)); |
178
|
|
|
} |
179
|
|
|
|
180
|
|
|
if (!defined('STATUS_COLUMN_NAME')) { |
181
|
|
|
define('STATUS_COLUMN_NAME', ArrayUtils::get($config, 'status.column_name', 'status')); |
182
|
|
|
} |
183
|
|
|
|
184
|
|
|
if (!defined('DIRECTUS_ENV')) { |
185
|
|
|
define('DIRECTUS_ENV', ArrayUtils::get($config, 'environment', 'development')); |
186
|
|
|
} |
187
|
|
|
|
188
|
|
|
$connection = new Connection($dbConfig); |
189
|
|
|
$connection->connect(); |
190
|
|
|
$container->set('connection', $connection); |
191
|
|
|
$container->set('zendDb', $connection); |
192
|
|
|
|
193
|
|
|
$acl = new \Directus\Permissions\Acl(); |
194
|
|
|
$acl->setUserId(1); |
195
|
|
|
$acl->setGroupId(1); |
196
|
|
|
$acl->setGroupPrivileges([ |
197
|
|
|
'*' => [ |
198
|
|
|
'id' => 1, |
199
|
|
|
'table_name' => '*', |
200
|
|
|
'group_id' => 1, |
201
|
|
|
'read_field_blacklist' => [], |
202
|
|
|
'write_field_blacklist' => [], |
203
|
|
|
'nav_listed' => 1, |
204
|
|
|
'status_id' => 0, |
205
|
|
|
'allow_view' => 2, |
206
|
|
|
'allow_add' => 1, |
207
|
|
|
'allow_edit' => 2, |
208
|
|
|
'allow_delete' => 2, |
209
|
|
|
'allow_alter' => 1 |
210
|
|
|
] |
211
|
|
|
]); |
212
|
|
|
$container->set('acl', $acl); |
213
|
|
|
|
214
|
|
|
$schema = new \Directus\Database\Schemas\Sources\MySQLSchema($connection); |
215
|
|
|
$container->set('schemaSource', $schema); |
216
|
|
|
$schema = new \Directus\Database\SchemaManager($schema); |
217
|
|
|
$container->set('schemaManager', $schema); |
218
|
|
|
TableSchema::setSchemaManagerInstance($schema); |
219
|
|
|
TableSchema::setAclInstance($acl); |
220
|
|
|
TableSchema::setConnectionInstance($connection); |
221
|
|
|
TableSchema::setConfig(new Config($config)); |
222
|
|
|
|
223
|
|
|
$container->singleton('emitter', function() { |
224
|
|
|
return $this->getEmitter(); |
225
|
|
|
}); |
226
|
|
|
$container->set('files_settings', function(Container $container) { |
227
|
|
|
$adapter = $container->get('connection'); |
228
|
|
|
$acl = $container->get('acl'); |
229
|
|
|
$Settings = new DirectusSettingsTableGateway($adapter, $acl); |
|
|
|
|
230
|
|
|
|
231
|
|
|
return $Settings->fetchCollection('files', [ |
|
|
|
|
232
|
|
|
'thumbnail_size', 'thumbnail_quality', 'thumbnail_crop_enabled' |
233
|
|
|
]); |
234
|
|
|
}); |
235
|
|
|
$container->set('app.settings', function (Container $container) { |
236
|
|
|
$DirectusSettingsTableGateway = new \Zend\Db\TableGateway\TableGateway('directus_settings', $container->get('zendDb')); |
|
|
|
|
237
|
|
|
$rowSet = $DirectusSettingsTableGateway->select(); |
|
|
|
|
238
|
|
|
|
239
|
|
|
$settings = []; |
240
|
|
|
foreach ($rowSet as $setting) { |
241
|
|
|
$settings[$setting['collection']][$setting['name']] = $setting['value']; |
242
|
|
|
} |
243
|
|
|
|
244
|
|
|
return $settings; |
245
|
|
|
}); |
246
|
|
|
|
247
|
|
|
$container->singleton('hashManager', function () { |
248
|
|
|
return new HashManager(); |
249
|
|
|
}); |
250
|
|
|
|
251
|
|
|
$container->singleton('files', function() { |
252
|
|
|
return $this->getFiles(); |
253
|
|
|
}); |
254
|
|
|
|
255
|
|
|
BaseTableGateway::setHookEmitter($container->get('emitter')); |
256
|
|
|
BaseTableGateway::setContainer($container); |
257
|
|
|
|
258
|
|
|
$client = new ClientLocal($connection); |
259
|
|
|
$client->setContainer($container); |
260
|
|
|
|
261
|
|
|
return $client; |
262
|
|
|
} |
263
|
|
|
|
264
|
|
|
public function getFiles() |
265
|
|
|
{ |
266
|
|
|
static $files = null; |
267
|
|
|
if ($files == null) { |
268
|
|
|
$config = $this->container->get('config'); |
269
|
|
|
$filesystemConfig = $config->get('filesystem', []); |
270
|
|
|
$filesystem = new Filesystem(FilesystemFactory::createAdapter($filesystemConfig)); |
|
|
|
|
271
|
|
|
$settings = $this->container->get('files_settings'); |
272
|
|
|
$emitter = $this->container->get('emitter'); |
273
|
|
|
$files = new Files($filesystem, $filesystemConfig, $settings, $emitter); |
274
|
|
|
} |
275
|
|
|
|
276
|
|
|
return $files; |
277
|
|
|
} |
278
|
|
|
|
279
|
|
|
protected function getEmitter() |
280
|
|
|
{ |
281
|
|
|
static $emitter = null; |
282
|
|
|
if ($emitter) { |
283
|
|
|
return $emitter; |
284
|
|
|
} |
285
|
|
|
|
286
|
|
|
$emitter = new Emitter(); |
287
|
|
|
$acl = $this->container->get('acl'); |
288
|
|
|
$adapter = $this->container->get('connection'); |
289
|
|
|
|
290
|
|
|
$emitter->addAction('table.insert.directus_groups', function ($data) use ($acl, $adapter) { |
291
|
|
|
$privilegesTable = new DirectDirectusPrivilegesTableGateway($adapter, $acl); |
292
|
|
|
|
293
|
|
|
$privilegesTable->insertPrivilege([ |
294
|
|
|
'group_id' => $data['id'], |
295
|
|
|
'allow_view' => 1, |
296
|
|
|
'allow_add' => 0, |
297
|
|
|
'allow_edit' => 1, |
298
|
|
|
'allow_delete' => 0, |
299
|
|
|
'allow_alter' => 0, |
300
|
|
|
'table_name' => 'directus_users', |
301
|
|
|
'read_field_blacklist' => 'token', |
302
|
|
|
'write_field_blacklist' => 'group,token' |
303
|
|
|
]); |
304
|
|
|
}); |
305
|
|
|
|
306
|
|
|
$emitter->addFilter('table.insert.directus_files:before', function ($payload) { |
307
|
|
|
unset($payload['data']); |
308
|
|
|
$payload['user'] = 1; |
309
|
|
|
|
310
|
|
|
return $payload; |
311
|
|
|
}); |
312
|
|
|
|
313
|
|
|
// Add file url and thumb url |
314
|
|
|
$config = $this->container->get('config'); |
315
|
|
|
$files = $this->container->get('files'); |
316
|
|
|
$emitter->addFilter('table.select', function ($payload) use ($config, $files) { |
317
|
|
|
$selectState = $payload->attribute('selectState'); |
318
|
|
|
|
319
|
|
|
if ($selectState['table'] == 'directus_files') { |
320
|
|
|
$rows = $payload->toArray(); |
321
|
|
|
foreach ($rows as &$row) { |
322
|
|
|
$fileURL = $config->get('filesystem.root_url', ''); |
323
|
|
|
$thumbnailURL = $config->get('filesystem.root_thumb_url', ''); |
324
|
|
|
$thumbnailFilenameParts = explode('.', $row['name']); |
325
|
|
|
$thumbnailExtension = array_pop($thumbnailFilenameParts); |
326
|
|
|
|
327
|
|
|
$row['url'] = $fileURL . '/' . $row['name']; |
328
|
|
|
if (in_array($thumbnailExtension, ['tif', 'tiff', 'psd', 'pdf'])) { |
329
|
|
|
$thumbnailExtension = 'jpg'; |
330
|
|
|
} |
331
|
|
|
|
332
|
|
|
$thumbnailFilename = $row['id'] . '.' . $thumbnailExtension; |
333
|
|
|
$row['thumbnail_url'] = $thumbnailURL . '/' . $thumbnailFilename; |
334
|
|
|
|
335
|
|
|
// filename-ext-100-100-true.jpg |
336
|
|
|
// @TODO: This should be another hook listener |
337
|
|
|
$row['thumbnail_url'] = null; |
338
|
|
|
$filename = implode('.', $thumbnailFilenameParts); |
339
|
|
|
if ($row['type'] == 'embed/vimeo') { |
340
|
|
|
$oldThumbnailFilename = $row['name'] . '-vimeo-220-124-true.jpg'; |
341
|
|
|
} else { |
342
|
|
|
$oldThumbnailFilename = $filename . '-' . $thumbnailExtension . '-160-160-true.jpg'; |
343
|
|
|
} |
344
|
|
|
|
345
|
|
|
// 314551321-vimeo-220-124-true.jpg |
346
|
|
|
// hotfix: there's not thumbnail for this file |
347
|
|
|
$row['old_thumbnail_url'] = $thumbnailURL . '/' . $oldThumbnailFilename; |
348
|
|
|
$row['thumbnail_url'] = $thumbnailURL . '/' . $thumbnailFilename; |
349
|
|
|
|
350
|
|
|
/* |
351
|
|
|
$embedManager = Bootstrap::get('embedManager'); |
352
|
|
|
$provider = $embedManager->getByType($row['type']); |
353
|
|
|
$row['html'] = null; |
354
|
|
|
if ($provider) { |
355
|
|
|
$row['html'] = $provider->getCode($row); |
356
|
|
|
} |
357
|
|
|
*/ |
358
|
|
|
} |
359
|
|
|
|
360
|
|
|
$payload->replace($rows); |
361
|
|
|
} |
362
|
|
|
|
363
|
|
|
return $payload; |
364
|
|
|
}); |
365
|
|
|
|
366
|
|
|
return $emitter; |
367
|
|
|
} |
368
|
|
|
|
369
|
|
|
/** |
370
|
|
|
* Create a new remote client instance |
371
|
|
|
* |
372
|
|
|
* @param $userToken |
373
|
|
|
* @param array $options |
374
|
|
|
* |
375
|
|
|
* @return ClientRemote |
376
|
|
|
*/ |
377
|
38 |
|
public function createRemoteClient($userToken, array $options = []) |
378
|
|
|
{ |
379
|
38 |
|
return new ClientRemote($userToken, $options); |
380
|
|
|
} |
381
|
|
|
} |
382
|
|
|
|
This check examines a number of code elements and verifies that they conform to the given naming conventions.
You can set conventions for local variables, abstract classes, utility classes, constant, properties, methods, parameters, interfaces, classes, exceptions and special methods.