1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
namespace Drupal\Driver\Cores; |
4
|
|
|
|
5
|
|
|
use Drupal\Driver\Exception\BootstrapException; |
6
|
|
|
|
7
|
|
|
/** |
8
|
|
|
* Drupal 7 core. |
9
|
|
|
*/ |
10
|
|
|
class Drupal7 extends AbstractCore { |
11
|
|
|
|
12
|
|
|
/** |
13
|
|
|
* {@inheritdoc} |
14
|
|
|
*/ |
15
|
|
|
public function bootstrap() { |
16
|
|
|
// Validate, and prepare environment for Drupal bootstrap. |
17
|
|
|
if (!defined('DRUPAL_ROOT')) { |
18
|
|
|
define('DRUPAL_ROOT', $this->drupalRoot); |
19
|
|
|
require_once DRUPAL_ROOT . '/includes/bootstrap.inc'; |
20
|
|
|
$this->validateDrupalSite(); |
21
|
|
|
} |
22
|
|
|
|
23
|
|
|
// Bootstrap Drupal. |
24
|
|
|
chdir(DRUPAL_ROOT); |
25
|
|
|
drupal_bootstrap(DRUPAL_BOOTSTRAP_CONFIGURATION); |
26
|
|
|
if (empty($GLOBALS['databases'])) { |
27
|
|
|
throw new BootstrapException('Missing database setting, verify the database configuration in settings.php.'); |
28
|
|
|
} |
29
|
|
|
drupal_bootstrap(DRUPAL_BOOTSTRAP_FULL); |
30
|
|
|
} |
31
|
|
|
|
32
|
|
|
/** |
33
|
|
|
* {@inheritdoc} |
34
|
|
|
*/ |
35
|
|
|
public function clearCache() { |
36
|
|
|
drupal_flush_all_caches(); |
37
|
|
|
} |
38
|
|
|
|
39
|
|
|
/** |
40
|
|
|
* {@inheritdoc} |
41
|
|
|
*/ |
42
|
|
|
public function nodeCreate($node) { |
43
|
|
|
// Assign authorship if none exists and `author` is passed. |
44
|
|
View Code Duplication |
if (!isset($node->uid) && !empty($node->author) && ($user = user_load_by_name($node->author))) { |
|
|
|
|
45
|
|
|
$node->uid = $user->uid; |
46
|
|
|
} |
47
|
|
|
|
48
|
|
|
// Convert properties to expected structure. |
49
|
|
|
$this->expandEntityProperties($node); |
50
|
|
|
|
51
|
|
|
// Attempt to decipher any fields that may be specified. |
52
|
|
|
$this->expandEntityFields('node', $node); |
53
|
|
|
|
54
|
|
|
// Set defaults that haven't already been set. |
55
|
|
|
$defaults = clone $node; |
56
|
|
|
node_object_prepare($defaults); |
57
|
|
|
$node = (object) array_merge((array) $defaults, (array) $node); |
58
|
|
|
|
59
|
|
|
node_save($node); |
60
|
|
|
return $node; |
61
|
|
|
} |
62
|
|
|
|
63
|
|
|
/** |
64
|
|
|
* {@inheritdoc} |
65
|
|
|
*/ |
66
|
|
|
public function nodeDelete($node) { |
67
|
|
|
node_delete($node->nid); |
68
|
|
|
} |
69
|
|
|
|
70
|
|
|
/** |
71
|
|
|
* Implements CoreInterface::runCron(). |
72
|
|
|
*/ |
73
|
|
|
public function runCron() { |
74
|
|
|
return drupal_cron_run(); |
75
|
|
|
} |
76
|
|
|
|
77
|
|
|
/** |
78
|
|
|
* {@inheritdoc} |
79
|
|
|
*/ |
80
|
|
|
public function userCreate(\stdClass $user) { |
81
|
|
|
// Default status to TRUE if not explicitly creating a blocked user. |
82
|
|
|
if (!isset($user->status)) { |
83
|
|
|
$user->status = 1; |
84
|
|
|
} |
85
|
|
|
|
86
|
|
|
// Clone user object, otherwise user_save() changes the password to the |
87
|
|
|
// hashed password. |
88
|
|
|
$account = clone $user; |
89
|
|
|
|
90
|
|
|
// Attempt to decipher any fields that may be specified. |
91
|
|
|
$this->expandEntityFields('user', $account); |
92
|
|
|
|
93
|
|
|
user_save($account, (array) $account); |
94
|
|
|
|
95
|
|
|
// Store UID. |
96
|
|
|
$user->uid = $account->uid; |
97
|
|
|
} |
98
|
|
|
|
99
|
|
|
/** |
100
|
|
|
* {@inheritdoc} |
101
|
|
|
*/ |
102
|
|
|
public function userDelete(\stdClass $user) { |
103
|
|
|
user_cancel([], $user->uid, 'user_cancel_delete'); |
104
|
|
|
} |
105
|
|
|
|
106
|
|
|
/** |
107
|
|
|
* {@inheritdoc} |
108
|
|
|
*/ |
109
|
|
|
public function processBatch() { |
110
|
|
|
$batch =& batch_get(); |
111
|
|
|
$batch['progressive'] = FALSE; |
112
|
|
|
batch_process(); |
113
|
|
|
} |
114
|
|
|
|
115
|
|
|
/** |
116
|
|
|
* {@inheritdoc} |
117
|
|
|
*/ |
118
|
|
|
public function userAddRole(\stdClass $user, $role_name) { |
119
|
|
|
$role = user_role_load_by_name($role_name); |
120
|
|
|
|
121
|
|
|
if (!$role) { |
122
|
|
|
throw new \RuntimeException(sprintf('No role "%s" exists.', $role_name)); |
123
|
|
|
} |
124
|
|
|
|
125
|
|
|
user_multiple_role_edit([$user->uid], 'add_role', $role->rid); |
126
|
|
|
$account = user_load($user->uid); |
127
|
|
|
$user->roles = $account->roles; |
128
|
|
|
|
129
|
|
|
} |
130
|
|
|
|
131
|
|
|
/** |
132
|
|
|
* Check to make sure that the array of permissions are valid. |
133
|
|
|
* |
134
|
|
|
* @param array $permissions |
135
|
|
|
* Permissions to check. |
136
|
|
|
* @param bool $reset |
137
|
|
|
* Reset cached available permissions. |
138
|
|
|
* |
139
|
|
|
* @return bool |
140
|
|
|
* TRUE or FALSE depending on whether the permissions are valid. |
141
|
|
|
*/ |
142
|
|
|
protected function checkPermissions(array $permissions, $reset = FALSE) { |
143
|
|
|
$available = &drupal_static(__FUNCTION__); |
144
|
|
|
|
145
|
|
|
if (!isset($available) || $reset) { |
146
|
|
|
$available = array_keys(module_invoke_all('permission')); |
147
|
|
|
} |
148
|
|
|
|
149
|
|
|
$valid = TRUE; |
150
|
|
|
foreach ($permissions as $permission) { |
151
|
|
|
if (!in_array($permission, $available)) { |
152
|
|
|
$valid = FALSE; |
153
|
|
|
} |
154
|
|
|
} |
155
|
|
|
return $valid; |
156
|
|
|
} |
157
|
|
|
|
158
|
|
|
/** |
159
|
|
|
* {@inheritdoc} |
160
|
|
|
*/ |
161
|
|
|
public function roleCreate(array $permissions) { |
162
|
|
|
|
163
|
|
|
// Both machine name and permission title are allowed. |
164
|
|
|
$all_permissions = $this->getAllPermissions(); |
165
|
|
|
|
166
|
|
|
foreach ($permissions as $key => $name) { |
167
|
|
|
if (!isset($all_permissions[$name])) { |
168
|
|
|
$search = array_search($name, $all_permissions); |
169
|
|
|
if (!$search) { |
170
|
|
|
throw new \RuntimeException(sprintf("No permission '%s' exists.", $name)); |
171
|
|
|
} |
172
|
|
|
$permissions[$key] = $search; |
173
|
|
|
} |
174
|
|
|
} |
175
|
|
|
|
176
|
|
|
// Create new role. |
177
|
|
|
$role = new \stdClass(); |
178
|
|
|
$role->name = $this->random->name(8); |
179
|
|
|
user_role_save($role); |
180
|
|
|
user_role_grant_permissions($role->rid, $permissions); |
181
|
|
|
|
182
|
|
|
if ($role && !empty($role->rid)) { |
183
|
|
|
return $role->name; |
184
|
|
|
} |
185
|
|
|
|
186
|
|
|
throw new \RuntimeException(sprintf('Failed to create a role with "" permission(s).', implode(', ', $permissions))); |
187
|
|
|
} |
188
|
|
|
|
189
|
|
|
/** |
190
|
|
|
* {@inheritdoc} |
191
|
|
|
*/ |
192
|
|
|
public function roleDelete($role_name) { |
193
|
|
|
$role = user_role_load_by_name($role_name); |
194
|
|
|
user_role_delete((int) $role->rid); |
195
|
|
|
} |
196
|
|
|
|
197
|
|
|
/** |
198
|
|
|
* {@inheritdoc} |
199
|
|
|
*/ |
200
|
|
View Code Duplication |
public function validateDrupalSite() { |
|
|
|
|
201
|
|
|
if ('default' !== $this->uri) { |
202
|
|
|
// Fake the necessary HTTP headers that Drupal needs: |
203
|
|
|
$drupal_base_url = parse_url($this->uri); |
204
|
|
|
// If there's no url scheme set, add http:// and re-parse the url |
205
|
|
|
// so the host and path values are set accurately. |
206
|
|
|
if (!array_key_exists('scheme', $drupal_base_url)) { |
207
|
|
|
$drupal_base_url = parse_url($this->uri); |
208
|
|
|
} |
209
|
|
|
// Fill in defaults. |
210
|
|
|
$drupal_base_url += [ |
211
|
|
|
'path' => NULL, |
212
|
|
|
'host' => NULL, |
213
|
|
|
'port' => NULL, |
214
|
|
|
]; |
215
|
|
|
$_SERVER['HTTP_HOST'] = $drupal_base_url['host']; |
216
|
|
|
|
217
|
|
|
if ($drupal_base_url['port']) { |
218
|
|
|
$_SERVER['HTTP_HOST'] .= ':' . $drupal_base_url['port']; |
219
|
|
|
} |
220
|
|
|
$_SERVER['SERVER_PORT'] = $drupal_base_url['port']; |
221
|
|
|
|
222
|
|
|
if (array_key_exists('path', $drupal_base_url)) { |
223
|
|
|
$_SERVER['PHP_SELF'] = $drupal_base_url['path'] . '/index.php'; |
224
|
|
|
} |
225
|
|
|
else { |
226
|
|
|
$_SERVER['PHP_SELF'] = '/index.php'; |
227
|
|
|
} |
228
|
|
|
} |
229
|
|
|
else { |
230
|
|
|
$_SERVER['HTTP_HOST'] = 'default'; |
231
|
|
|
$_SERVER['PHP_SELF'] = '/index.php'; |
232
|
|
|
} |
233
|
|
|
|
234
|
|
|
$_SERVER['REQUEST_URI'] = $_SERVER['SCRIPT_NAME'] = $_SERVER['PHP_SELF']; |
235
|
|
|
$_SERVER['REMOTE_ADDR'] = '127.0.0.1'; |
236
|
|
|
$_SERVER['REQUEST_METHOD'] = NULL; |
237
|
|
|
|
238
|
|
|
$_SERVER['SERVER_SOFTWARE'] = NULL; |
239
|
|
|
$_SERVER['HTTP_USER_AGENT'] = NULL; |
240
|
|
|
|
241
|
|
|
$conf_path = conf_path(TRUE, TRUE); |
242
|
|
|
$conf_file = $this->drupalRoot . "/$conf_path/settings.php"; |
243
|
|
|
if (!file_exists($conf_file)) { |
244
|
|
|
throw new BootstrapException(sprintf('Could not find a Drupal settings.php file at "%s"', $conf_file)); |
245
|
|
|
} |
246
|
|
|
$drushrc_file = $this->drupalRoot . "/$conf_path/drushrc.php"; |
247
|
|
|
if (file_exists($drushrc_file)) { |
248
|
|
|
require_once $drushrc_file; |
249
|
|
|
} |
250
|
|
|
} |
251
|
|
|
|
252
|
|
|
/** |
253
|
|
|
* Expands properties on the given entity object to the expected structure. |
254
|
|
|
* |
255
|
|
|
* @param object $entity |
256
|
|
|
* The entity object. |
257
|
|
|
*/ |
258
|
|
View Code Duplication |
protected function expandEntityProperties(\stdClass $entity) { |
|
|
|
|
259
|
|
|
// The created field may come in as a readable date, rather than a |
260
|
|
|
// timestamp. |
261
|
|
|
if (isset($entity->created) && !is_numeric($entity->created)) { |
262
|
|
|
$entity->created = strtotime($entity->created); |
263
|
|
|
} |
264
|
|
|
|
265
|
|
|
// Map human-readable node types to machine node types. |
266
|
|
|
$types = \node_type_get_types(); |
267
|
|
|
foreach ($types as $type) { |
268
|
|
|
if ($entity->type == $type->name) { |
269
|
|
|
$entity->type = $type->type; |
270
|
|
|
continue; |
271
|
|
|
} |
272
|
|
|
} |
273
|
|
|
} |
274
|
|
|
|
275
|
|
|
/** |
276
|
|
|
* {@inheritdoc} |
277
|
|
|
*/ |
278
|
|
|
public function termCreate(\stdClass $term) { |
279
|
|
|
// Map vocabulary names to vid, these take precedence over machine names. |
280
|
|
View Code Duplication |
if (!isset($term->vid)) { |
|
|
|
|
281
|
|
|
$vocabularies = \taxonomy_get_vocabularies(); |
282
|
|
|
foreach ($vocabularies as $vid => $vocabulary) { |
283
|
|
|
if ($vocabulary->name == $term->vocabulary_machine_name) { |
284
|
|
|
$term->vid = $vocabulary->vid; |
285
|
|
|
} |
286
|
|
|
} |
287
|
|
|
} |
288
|
|
|
|
289
|
|
|
if (!isset($term->vid)) { |
290
|
|
|
|
291
|
|
|
// Try to load vocabulary by machine name. |
292
|
|
|
$vocabularies = \taxonomy_vocabulary_load_multiple(FALSE, [ |
293
|
|
|
'machine_name' => $term->vocabulary_machine_name, |
294
|
|
|
]); |
295
|
|
|
if (!empty($vocabularies)) { |
296
|
|
|
$vids = array_keys($vocabularies); |
297
|
|
|
$term->vid = reset($vids); |
298
|
|
|
} |
299
|
|
|
} |
300
|
|
|
|
301
|
|
|
// If `parent` is set, look up a term in this vocab with that name. |
302
|
|
View Code Duplication |
if (isset($term->parent)) { |
|
|
|
|
303
|
|
|
$parent = \taxonomy_get_term_by_name($term->parent, $term->vocabulary_machine_name); |
304
|
|
|
if (!empty($parent)) { |
305
|
|
|
$parent = reset($parent); |
306
|
|
|
$term->parent = $parent->tid; |
307
|
|
|
} |
308
|
|
|
} |
309
|
|
|
|
310
|
|
|
if (empty($term->vid)) { |
311
|
|
|
throw new \Exception(sprintf('No "%s" vocabulary found.', $term->vocabulary_machine_name)); |
312
|
|
|
} |
313
|
|
|
|
314
|
|
|
// Attempt to decipher any fields that may be specified. |
315
|
|
|
$this->expandEntityFields('taxonomy_term', $term); |
316
|
|
|
|
317
|
|
|
\taxonomy_term_save($term); |
318
|
|
|
|
319
|
|
|
return $term; |
320
|
|
|
} |
321
|
|
|
|
322
|
|
|
/** |
323
|
|
|
* {@inheritdoc} |
324
|
|
|
*/ |
325
|
|
|
public function termDelete(\stdClass $term) { |
326
|
|
|
$status = 0; |
327
|
|
|
if (isset($term->tid)) { |
328
|
|
|
$status = \taxonomy_term_delete($term->tid); |
329
|
|
|
} |
330
|
|
|
// Will be SAVED_DELETED (3) on success. |
331
|
|
|
return $status; |
332
|
|
|
} |
333
|
|
|
|
334
|
|
|
/** |
335
|
|
|
* {@inheritdoc} |
336
|
|
|
*/ |
337
|
|
|
public function languageCreate(\stdClass $language) { |
338
|
|
|
if (!module_exists('locale')) { |
339
|
|
|
throw new \Exception(sprintf("%s::%s line %s: This driver requires the 'locale' module be enabled in order to create languages", get_class($this), __FUNCTION__, __LINE__)); |
340
|
|
|
} |
341
|
|
|
include_once DRUPAL_ROOT . '/includes/iso.inc'; |
342
|
|
|
include_once DRUPAL_ROOT . '/includes/locale.inc'; |
343
|
|
|
|
344
|
|
|
// Get all predefined languages, regardless if they are enabled or not. |
345
|
|
|
$predefined_languages = _locale_get_predefined_list(); |
346
|
|
|
|
347
|
|
|
// If the language code is not valid then throw an InvalidArgumentException. |
348
|
|
|
if (!isset($predefined_languages[$language->langcode])) { |
349
|
|
|
throw new InvalidArgumentException("There is no predefined language with langcode '{$language->langcode}'."); |
350
|
|
|
} |
351
|
|
|
|
352
|
|
|
// Enable a language only if it has not been enabled already. |
353
|
|
|
$enabled_languages = locale_language_list(); |
354
|
|
|
if (!isset($enabled_languages[$language->langcode])) { |
355
|
|
|
locale_add_language($language->langcode); |
356
|
|
|
return $language; |
357
|
|
|
} |
358
|
|
|
|
359
|
|
|
return FALSE; |
360
|
|
|
} |
361
|
|
|
|
362
|
|
|
/** |
363
|
|
|
* {@inheritdoc} |
364
|
|
|
*/ |
365
|
|
|
public function languageDelete(\stdClass $language) { |
366
|
|
|
$langcode = $language->langcode; |
367
|
|
|
// Do not remove English or the default language. |
368
|
|
|
if (!in_array($langcode, [language_default('language'), 'en'])) { |
369
|
|
|
// @see locale_languages_delete_form_submit(). |
370
|
|
|
$languages = language_list(); |
371
|
|
|
if (isset($languages[$langcode])) { |
372
|
|
|
// Remove translations first. |
373
|
|
|
db_delete('locales_target') |
374
|
|
|
->condition('language', $langcode) |
375
|
|
|
->execute(); |
376
|
|
|
cache_clear_all('locale:' . $langcode, 'cache'); |
377
|
|
|
// With no translations, this removes existing JavaScript translations |
378
|
|
|
// file. |
379
|
|
|
_locale_rebuild_js($langcode); |
380
|
|
|
// Remove the language. |
381
|
|
|
db_delete('languages') |
382
|
|
|
->condition('language', $langcode) |
383
|
|
|
->execute(); |
384
|
|
|
db_update('node') |
385
|
|
|
->fields(['language' => '']) |
386
|
|
|
->condition('language', $langcode) |
387
|
|
|
->execute(); |
388
|
|
|
if ($languages[$langcode]->enabled) { |
389
|
|
|
variable_set('language_count', variable_get('language_count', 1) - 1); |
390
|
|
|
} |
391
|
|
|
module_invoke_all('multilingual_settings_changed'); |
392
|
|
|
drupal_static_reset('language_list'); |
393
|
|
|
} |
394
|
|
|
|
395
|
|
|
// Changing the language settings impacts the interface: |
396
|
|
|
cache_clear_all('*', 'cache_page', TRUE); |
397
|
|
|
} |
398
|
|
|
} |
399
|
|
|
|
400
|
|
|
/** |
401
|
|
|
* {@inheritdoc} |
402
|
|
|
*/ |
403
|
|
|
public function configGet($name, $key = '') { |
404
|
|
|
throw new \Exception('Getting config is not yet implemented for Drupal 7.'); |
405
|
|
|
} |
406
|
|
|
|
407
|
|
|
/** |
408
|
|
|
* {@inheritdoc} |
409
|
|
|
*/ |
410
|
|
|
public function configGetOriginal($name, $key = '') { |
411
|
|
|
throw new \Exception('Getting original config is not yet implemented for Drupal 7.'); |
412
|
|
|
} |
413
|
|
|
|
414
|
|
|
/** |
415
|
|
|
* {@inheritdoc} |
416
|
|
|
*/ |
417
|
|
|
public function configSet($name, $key, $value) { |
418
|
|
|
throw new \Exception('Setting config is not yet implemented for Drupal 7.'); |
419
|
|
|
} |
420
|
|
|
|
421
|
|
|
/** |
422
|
|
|
* Helper function to get all permissions. |
423
|
|
|
* |
424
|
|
|
* @return array |
425
|
|
|
* Array keyed by permission name, with the human-readable title as the |
426
|
|
|
* value. |
427
|
|
|
*/ |
428
|
|
View Code Duplication |
protected function getAllPermissions() { |
|
|
|
|
429
|
|
|
$permissions = []; |
430
|
|
|
foreach (module_invoke_all('permission') as $name => $permission) { |
431
|
|
|
$permissions[$name] = $permission['title']; |
432
|
|
|
} |
433
|
|
|
return $permissions; |
434
|
|
|
} |
435
|
|
|
|
436
|
|
|
/** |
437
|
|
|
* {@inheritdoc} |
438
|
|
|
*/ |
439
|
|
|
public function getModuleList() { |
440
|
|
|
return module_list(); |
441
|
|
|
} |
442
|
|
|
|
443
|
|
|
/** |
444
|
|
|
* {@inheritdoc} |
445
|
|
|
*/ |
446
|
|
View Code Duplication |
public function getExtensionPathList() { |
|
|
|
|
447
|
|
|
$paths = []; |
448
|
|
|
|
449
|
|
|
// Get enabled modules. |
450
|
|
|
$modules = $this->getModuleList(); |
451
|
|
|
foreach ($modules as $module) { |
452
|
|
|
$paths[] = $this->drupalRoot . DIRECTORY_SEPARATOR . \drupal_get_path('module', $module); |
453
|
|
|
} |
454
|
|
|
|
455
|
|
|
return $paths; |
456
|
|
|
} |
457
|
|
|
|
458
|
|
|
/** |
459
|
|
|
* {@inheritdoc} |
460
|
|
|
*/ |
461
|
|
|
public function getEntityFieldTypes($entity_type, array $base_fields = []) { |
462
|
|
|
$return = []; |
463
|
|
|
$fields = field_info_field_map(); |
464
|
|
|
foreach ($fields as $field_name => $field) { |
465
|
|
|
if (array_key_exists($entity_type, $field['bundles'])) { |
466
|
|
|
$return[$field_name] = $field['type']; |
467
|
|
|
} |
468
|
|
|
} |
469
|
|
|
return $return; |
470
|
|
|
} |
471
|
|
|
|
472
|
|
|
/** |
473
|
|
|
* {@inheritdoc} |
474
|
|
|
*/ |
475
|
|
|
public function isField($entity_type, $field_name) { |
476
|
|
|
$map = field_info_field_map(); |
477
|
|
|
return !empty($map[$field_name]) && array_key_exists($entity_type, $map[$field_name]['bundles']); |
478
|
|
|
} |
479
|
|
|
|
480
|
|
|
/** |
481
|
|
|
* {@inheritdoc} |
482
|
|
|
*/ |
483
|
|
|
public function clearStaticCaches() { |
484
|
|
|
drupal_static_reset(); |
485
|
|
|
} |
486
|
|
|
|
487
|
|
|
/** |
488
|
|
|
* {@inheritdoc} |
489
|
|
|
*/ |
490
|
|
|
public function entityCreate($entity_type, $entity) { |
491
|
|
|
$info = entity_get_info($entity_type); |
492
|
|
|
// If the bundle field is empty, put the inferred bundle value in it. |
493
|
|
|
$bundle_key = $info['entity keys']['bundle']; |
494
|
|
View Code Duplication |
if (!isset($entity->$bundle_key) && isset($entity->step_bundle)) { |
|
|
|
|
495
|
|
|
$entity->$bundle_key = $entity->step_bundle; |
496
|
|
|
} |
497
|
|
|
|
498
|
|
|
// Throw an exception if a bundle is specified but does not exist. |
499
|
|
|
if (isset($entity->$bundle_key) && ($entity->$bundle_key !== NULL)) { |
500
|
|
|
$bundles = $info['bundles']; |
501
|
|
View Code Duplication |
if (!in_array($entity->$bundle_key, array_keys($bundles))) { |
|
|
|
|
502
|
|
|
throw new \Exception("Cannot create entity because provided bundle {$entity->$bundle_key} does not exist."); |
503
|
|
|
} |
504
|
|
|
} |
505
|
|
|
if (empty($entity_type)) { |
506
|
|
|
throw new \Exception("You must specify an entity type to create an entity."); |
507
|
|
|
} |
508
|
|
|
|
509
|
|
|
$this->expandEntityFields($entity_type, $entity); |
510
|
|
|
$createdEntity = entity_create($entity_type, (array) $entity); |
511
|
|
|
|
512
|
|
|
// In D7 it's possible that $createdEntity is not of class Entity, so we |
513
|
|
|
// must use entity_save(). |
514
|
|
|
entity_save($entity_type, $createdEntity); |
515
|
|
|
|
516
|
|
|
list($id) = entity_extract_ids($entity_type, $createdEntity); |
517
|
|
|
$createdEntity->id = $id; |
518
|
|
|
|
519
|
|
|
return $createdEntity; |
520
|
|
|
} |
521
|
|
|
|
522
|
|
|
/** |
523
|
|
|
* {@inheritdoc} |
524
|
|
|
*/ |
525
|
|
|
public function entityDelete($entity_type, $entity) { |
526
|
|
|
// In D7 it's possible that $entity is not of class Entity, so we must use |
527
|
|
|
// entity_delete(). |
528
|
|
|
list($id) = entity_extract_ids($entity_type, $entity); |
529
|
|
|
entity_delete($entity_type, $id); |
530
|
|
|
} |
531
|
|
|
|
532
|
|
|
/** |
533
|
|
|
* {@inheritdoc} |
534
|
|
|
*/ |
535
|
|
|
public function startCollectingMail() { |
536
|
|
|
// @todo create a D7 version of this function |
537
|
|
|
throw new \Exception('Mail testing is not yet implemented for Drupal 7.'); |
538
|
|
|
} |
539
|
|
|
|
540
|
|
|
/** |
541
|
|
|
* {@inheritdoc} |
542
|
|
|
*/ |
543
|
|
|
public function stopCollectingMail() { |
544
|
|
|
// @todo create a D7 version of this function |
545
|
|
|
throw new \Exception('Mail testing is not yet implemented for Drupal 7.'); |
546
|
|
|
} |
547
|
|
|
|
548
|
|
|
/** |
549
|
|
|
* {@inheritdoc} |
550
|
|
|
*/ |
551
|
|
|
public function getMail() { |
552
|
|
|
// @todo create a D7 version of this function |
553
|
|
|
throw new \Exception('Mail testing is not yet implemented for Drupal 7.'); |
554
|
|
|
} |
555
|
|
|
|
556
|
|
|
/** |
557
|
|
|
* {@inheritdoc} |
558
|
|
|
*/ |
559
|
|
|
public function clearMail() { |
560
|
|
|
// @todo create a D7 version of this function |
561
|
|
|
throw new \Exception('Mail testing is not yet implemented for Drupal 7.'); |
562
|
|
|
} |
563
|
|
|
|
564
|
|
|
/** |
565
|
|
|
* {@inheritdoc} |
566
|
|
|
*/ |
567
|
|
|
public function sendMail($body, $subject = '', $to = '', $langcode = '') { |
568
|
|
|
// @todo create a D7 version of this function |
569
|
|
|
throw new \Exception('Mail testing is not yet implemented for Drupal 7.'); |
570
|
|
|
} |
571
|
|
|
|
572
|
|
|
} |
573
|
|
|
|
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.