Completed
Push — master ( 92af5e...e903af )
by Jonathan
14s queued 10s
created

DrupalDriver::login()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 5
rs 10
c 0
b 0
f 0
cc 2
nc 2
nop 1
1
<?php
2
3
namespace Drupal\Driver;
4
5
use Drupal\Driver\Cores\CoreAuthenticationInterface;
6
use Drupal\Driver\Exception\BootstrapException;
7
8
use Behat\Behat\Tester\Exception\PendingException;
9
10
/**
11
 * Fully bootstraps Drupal and uses native API calls.
12
 */
13
class DrupalDriver implements DriverInterface, SubDriverFinderInterface, AuthenticationDriverInterface {
14
15
  /**
16
   * Track whether Drupal has been bootstrapped.
17
   *
18
   * @var bool
19
   */
20
  private $bootstrapped = FALSE;
21
22
  /**
23
   * Drupal core object.
24
   *
25
   * @var \Drupal\Driver\Cores\CoreInterface
26
   */
27
  public $core;
28
29
  /**
30
   * System path to the Drupal installation.
31
   *
32
   * @var string
33
   */
34
  private $drupalRoot;
35
36
  /**
37
   * URI for the Drupal installation.
38
   *
39
   * @var string
40
   */
41
  private $uri;
42
43
  /**
44
   * Drupal core version.
45
   *
46
   * @var int
47
   */
48
  public $version;
49
50
  /**
51
   * Set Drupal root and URI.
52
   *
53
   * @param string $drupal_root
54
   *   The Drupal root path.
55
   * @param string $uri
56
   *   The URI for the Drupal installation.
57
   *
58
   * @throws BootstrapException
59
   *   Thrown when the Drupal installation is not found in the given root path.
60
   */
61
  public function __construct($drupal_root, $uri) {
62
    $this->drupalRoot = realpath($drupal_root);
63
    if (!$this->drupalRoot) {
64
      throw new BootstrapException(sprintf('No Drupal installation found at %s', $drupal_root));
65
    }
66
    $this->uri = $uri;
67
    $this->version = $this->getDrupalVersion();
68
  }
69
70
  /**
71
   * {@inheritdoc}
72
   */
73
  public function getRandom() {
74
    return $this->getCore()->getRandom();
75
  }
76
77
  /**
78
   * {@inheritdoc}
79
   */
80
  public function bootstrap() {
81
    $this->getCore()->bootstrap();
82
    $this->bootstrapped = TRUE;
83
  }
84
85
  /**
86
   * {@inheritdoc}
87
   */
88
  public function isBootstrapped() {
89
    // Assume the blackbox is always bootstrapped.
90
    return $this->bootstrapped;
91
  }
92
93
  /**
94
   * {@inheritdoc}
95
   */
96
  public function userCreate(\stdClass $user) {
97
    $this->getCore()->userCreate($user);
98
  }
99
100
  /**
101
   * {@inheritdoc}
102
   */
103
  public function userDelete(\stdClass $user) {
104
    $this->getCore()->userDelete($user);
105
  }
106
107
  /**
108
   * {@inheritdoc}
109
   */
110
  public function processBatch() {
111
    $this->getCore()->processBatch();
112
  }
113
114
  /**
115
   * {@inheritdoc}
116
   */
117
  public function userAddRole(\stdClass $user, $role_name) {
118
    $this->getCore()->userAddRole($user, $role_name);
119
  }
120
121
  /**
122
   * {@inheritdoc}
123
   */
124
  public function fetchWatchdog($count = 10, $type = NULL, $severity = NULL) {
125
    throw new PendingException(sprintf('Currently no ability to access watchdog entries in %s', $this));
126
  }
127
128
  /**
129
   * {@inheritdoc}
130
   */
131
  public function clearCache($type = NULL) {
132
    $this->getCore()->clearCache();
133
  }
134
135
  /**
136
   * {@inheritdoc}
137
   */
138
  public function getSubDriverPaths() {
139
    // Ensure system is bootstrapped.
140
    if (!$this->isBootstrapped()) {
141
      $this->bootstrap();
142
    }
143
144
    return $this->getCore()->getExtensionPathList();
145
  }
146
147
  /**
148
   * Determine major Drupal version.
149
   *
150
   * @return int
151
   *   The major Drupal version.
152
   *
153
   * @throws \Drupal\Driver\Exception\BootstrapException
154
   *   Thrown when the Drupal version could not be determined.
155
   *
156
   * @see drush_drupal_version()
157
   */
158
  public function getDrupalVersion() {
159
    if (!isset($this->version)) {
160
      // Support 6, 7 and 8.
161
      $version_constant_paths = array(
162
        // Drupal 6.
163
        '/modules/system/system.module',
164
        // Drupal 7.
165
        '/includes/bootstrap.inc',
166
        // Drupal 8.
167
        '/autoload.php',
168
        '/core/includes/bootstrap.inc',
169
      );
170
171
      if ($this->drupalRoot === FALSE) {
172
        throw new BootstrapException('`drupal_root` parameter must be defined.');
173
      }
174
175
      foreach ($version_constant_paths as $path) {
176
        if (file_exists($this->drupalRoot . $path)) {
177
          require_once $this->drupalRoot . $path;
178
        }
179
      }
180
      if (defined('VERSION')) {
181
        $version = VERSION;
182
      }
183
      elseif (defined('\Drupal::VERSION')) {
184
        $version = \Drupal::VERSION;
185
      }
186
      else {
187
        throw new BootstrapException('Unable to determine Drupal core version. Supported versions are 6, 7, and 8.');
188
      }
189
190
      // Extract the major version from VERSION.
191
      $version_parts = explode('.', $version);
192
      if (is_numeric($version_parts[0])) {
193
        $this->version = (integer) $version_parts[0];
194
      }
195
      else {
196
        throw new BootstrapException(sprintf('Unable to extract major Drupal core version from version string %s.', $version));
197
      }
198
    }
199
    return $this->version;
200
  }
201
202
  /**
203
   * Instantiate and set Drupal core class.
204
   *
205
   * @param array $available_cores
206
   *   A major-version-keyed array of available core controllers.
207
   */
208
  public function setCore(array $available_cores) {
209
    if (!isset($available_cores[$this->version])) {
210
      throw new BootstrapException(sprintf('There is no available Drupal core controller for Drupal version %s.', $this->version));
211
    }
212
    $this->core = $available_cores[$this->version];
213
  }
214
215
  /**
216
   * Automatically set the core from the current version.
217
   */
218
  public function setCoreFromVersion() {
219
    $core = '\Drupal\Driver\Cores\Drupal' . $this->getDrupalVersion();
220
    $this->core = new $core($this->drupalRoot, $this->uri);
221
  }
222
223
  /**
224
   * Return current core.
225
   */
226
  public function getCore() {
227
    return $this->core;
228
  }
229
230
  /**
231
   * {@inheritdoc}
232
   */
233
  public function createNode($node) {
234
    return $this->getCore()->nodeCreate($node);
235
  }
236
237
  /**
238
   * {@inheritdoc}
239
   */
240
  public function nodeDelete($node) {
241
    return $this->getCore()->nodeDelete($node);
242
  }
243
244
  /**
245
   * {@inheritdoc}
246
   */
247
  public function runCron() {
248
    if (!$this->getCore()->runCron()) {
249
      throw new \Exception('Failed to run cron.');
250
    }
251
  }
252
253
  /**
254
   * {@inheritdoc}
255
   */
256
  public function createTerm(\stdClass $term) {
257
    return $this->getCore()->termCreate($term);
258
  }
259
260
  /**
261
   * {@inheritdoc}
262
   */
263
  public function termDelete(\stdClass $term) {
264
    return $this->getCore()->termDelete($term);
265
  }
266
267
  /**
268
   * {@inheritdoc}
269
   */
270
  public function roleCreate(array $permissions) {
271
    return $this->getCore()->roleCreate($permissions);
272
  }
273
274
  /**
275
   * {@inheritdoc}
276
   */
277
  public function roleDelete($rid) {
278
    $this->getCore()->roleDelete($rid);
279
  }
280
281
  /**
282
   * {@inheritdoc}
283
   */
284
  public function isField($entity_type, $field_name) {
285
    return $this->getCore()->isField($entity_type, $field_name);
286
  }
287
288
  /**
289
   * {@inheritdoc}
290
   */
291
  public function languageCreate($language) {
292
    return $this->getCore()->languageCreate($language);
293
  }
294
295
  /**
296
   * {@inheritdoc}
297
   */
298
  public function languageDelete($language) {
299
    $this->getCore()->languageDelete($language);
300
  }
301
302
  /**
303
   * {@inheritdoc}
304
   */
305
  public function configGet($name, $key) {
306
    return $this->getCore()->configGet($name, $key);
307
  }
308
309
  /**
310
   * {@inheritdoc}
311
   */
312
  public function configSet($name, $key, $value) {
313
    $this->getCore()->configSet($name, $key, $value);
314
  }
315
316
  /**
317
   * {@inheritdoc}
318
   */
319
  public function clearStaticCaches() {
320
    $this->getCore()->clearStaticCaches();
321
  }
322
323
  /**
324
   * {@inheritdoc}
325
   */
326
  public function createEntity($entity_type, \stdClass $entity) {
327
    return $this->getCore()->entityCreate($entity_type, $entity);
0 ignored issues
show
Bug Best Practice introduced by
The return type of return $this->getCore()-...$entity_type, $entity); (Drupal\Core\Entity\EntityInterface) is incompatible with the return type declared by the interface Drupal\Driver\DriverInterface::createEntity of type stdClass.

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...
328
  }
329
330
  /**
331
   * {@inheritdoc}
332
   */
333
  public function entityDelete($entity_type, \stdClass $entity) {
334
    return $this->getCore()->entityDelete($entity_type, $entity);
335
  }
336
337
  /**
338
   * {@inheritdoc}
339
   */
340
  public function startCollectingMail() {
341
    return $this->getCore()->startCollectingMail();
342
  }
343
344
  /**
345
   * {@inheritdoc}
346
   */
347
  public function stopCollectingMail() {
348
    return $this->getCore()->stopCollectingMail();
349
  }
350
351
  /**
352
   * {@inheritdoc}
353
   */
354
  public function getMail() {
355
    return $this->getCore()->getMail();
356
  }
357
358
  /**
359
   * {@inheritdoc}
360
   */
361
  public function clearMail() {
362
    return $this->getCore()->clearMail();
363
  }
364
365
  /**
366
   * {@inheritdoc}
367
   */
368
  public function sendMail($body, $subject, $to, $langcode) {
369
    return $this->getCore()->sendMail($body, $subject, $to, $langcode);
370
  }
371
372
  /**
373
   * {@inheritdoc}
374
   */
375
  public function login(\stdClass $user) {
376
    if ($this->getCore() instanceof CoreAuthenticationInterface) {
377
      $this->getCore()->login($user);
378
    }
379
  }
380
381
  /**
382
   * {@inheritdoc}
383
   */
384
  public function logout() {
385
    if ($this->getCore() instanceof CoreAuthenticationInterface) {
386
      $this->getCore()->logout();
387
    }
388
  }
389
390
}
391