Completed
Push — master ( de9b06...8ea9ba )
by Sebastien
02:40
created

Project::getWorkingDirectory()   C

Complexity

Conditions 9
Paths 7

Size

Total Lines 24
Code Lines 14

Duplication

Lines 12
Ratio 50 %

Importance

Changes 1
Bugs 1 Features 0
Metric Value
c 1
b 1
f 0
dl 12
loc 24
rs 5.3563
cc 9
eloc 14
nc 7
nop 0
1
<?php
2
3
/**
4
 * Drush Cerbere command line tools.
5
 * Copyright (C) 2015 - Sebastien Malot <[email protected]>
6
 *
7
 * This program is free software; you can redistribute it and/or modify
8
 * it under the terms of the GNU General Public License as published by
9
 * the Free Software Foundation; either version 2 of the License, or
10
 * (at your option) any later version.
11
 *
12
 * This program is distributed in the hope that it will be useful,
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
 * GNU General Public License for more details.
16
 *
17
 * You should have received a copy of the GNU General Public License along
18
 * with this program; if not, write to the Free Software Foundation, Inc.,
19
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20
 */
21
22
namespace Cerbere\Model;
23
24
/**
25
 * Class Project
26
 *
27
 * @package Cerbere\Model
28
 */
29
class Project
30
{
31
    /**
32
     * URL to check for updates, if a given project doesn't define its own.
33
     */
34
    const UPDATE_DEFAULT_URL = 'http://updates.drupal.org/release-history';
35
36
    /**
37
     *
38
     */
39
    const INSTALL_TYPE_OFFICIAL = 'official';
40
41
    /**
42
     *
43
     */
44
    const INSTALL_TYPE_DEV = 'dev';
45
46
    /**
47
     *
48
     */
49
    const INSTALL_TYPE_UNKNOWN = 'unknown';
50
51
    /**
52
     *
53
     */
54
    const TYPE_PROJECT_DISTRIBUTION = 'project_distribution';
55
56
    /**
57
     *
58
     */
59
    const TYPE_PROJECT_CORE = 'project_core';
60
61
    /**
62
     *
63
     */
64
    const TYPE_PROJECT_MODULE = 'project_module';
65
66
    /**
67
     *
68
     */
69
    const TYPE_PROJECT_THEME = 'project_theme';
70
71
    /**
72
     *
73
     */
74
    const TYPE_UNKNOWN = 'unknown';
75
76
    /**
77
     * @var
78
     */
79
    protected $project;
80
81
    /**
82
     * @var string
83
     */
84
    protected $filename;
85
86
    /**
87
     * @var
88
     */
89
    protected $name;
90
91
    /**
92
     * @var
93
     */
94
    protected $core;
95
96
    /**
97
     * @var
98
     */
99
    protected $version;
100
101
    /**
102
     * @var
103
     */
104
    protected $status_url;
105
106
    /**
107
     * @var
108
     */
109
    protected $install_type;
110
111
    /**
112
     * @var
113
     */
114
    protected $existing_version;
115
116
    /**
117
     * @var
118
     */
119
    protected $existing_major;
120
121
    /**
122
     * @var array
123
     */
124
    protected $data;
125
126
    // Calculated properties.
127
128
    /**
129
     * @var
130
     */
131
    protected $status;
132
133
    /**
134
     * @var
135
     */
136
    protected $project_status;
137
138
    /**
139
     * @var string
140
     */
141
    protected $project_type;
142
143
    /**
144
     * @var
145
     */
146
    protected $reason;
147
148
    /**
149
     * @var
150
     */
151
    protected $fetch_status;
152
153
    /**
154
     * @var
155
     */
156
    protected $latest_version;
157
158
    /**
159
     * @var
160
     */
161
    protected $latest_dev;
162
163
    /**
164
     * @var
165
     */
166
    protected $dev_version;
167
168
    /**
169
     * @var
170
     */
171
    protected $recommended;
172
173
    /**
174
     * @var
175
     */
176
    protected $datestamp;
177
178
    /**
179
     * @var array
180
     */
181
    protected $releases;
182
183
    /**
184
     * @var array
185
     */
186
    protected $security_updates;
187
188
    /**
189
     * @var array
190
     */
191
    protected $also_available;
192
193
    /**
194
     * @param string $project
195
     * @param string $core
196
     * @param string $version
197
     */
198
    public function __construct($project, $core, $version)
199
    {
200
        $this->project = $project;
201
        $this->name    = $project;
202
        $this->core    = $core;
203
        $this->version = $version;
204
205
        $this->project_type = self::TYPE_UNKNOWN;
206
207
        $this->releases         = array();
208
        $this->security_updates = array();
209
        $this->also_available   = array();
210
211
        $this->init();
212
    }
213
214
    /**
215
     * @return string
216
     */
217
    public function getFilename()
218
    {
219
        return $this->filename;
220
    }
221
222
    /**
223
     * @param string $filename
224
     */
225
    public function setFilename($filename)
226
    {
227
        $this->filename = $filename;
228
229
        $this->init();
230
    }
231
232
    /**
233
     * @return string
234
     */
235
    public function getWorkingDirectory()
236
    {
237
        if ($this->getProject() == 'drupal' && $this->getCore() == '8.x') {
238
            $path = str_replace('\\', '/', dirname($this->getFilename()));
239
240
            // Todo: Optimize.
241 View Code Duplication
            if (($position = strpos($path, '/core/modules/')) !== false) {
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...
242
                return substr($path, 0, $position);
243
            }
244 View Code Duplication
            if (($position = strpos($path, '/core/profiles/')) !== false) {
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...
245
                return substr($path, 0, $position);
246
            }
247 View Code Duplication
            if (($position = strpos($path, '/core/themes/')) !== false) {
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...
248
                return substr($path, 0, $position);
249
            }
250 View Code Duplication
            if (($position = strpos($path, '/core/tests/')) !== false) {
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...
251
                return substr($path, 0, $position);
252
            }
253
        } elseif ($this->getProject() == 'drupal' && $this->getCore() == '7.x') {
254
            return dirname($this->getFilename()) . '/../..';
255
        }
256
257
        return dirname($this->getFilename());
258
    }
259
260
    /**
261
     *
262
     */
263
    protected function init()
264
    {
265
        // Patch project if Drupal detected.
266
        if (isset($this->data['package']) && strtolower($this->data['package']) == 'core') {
267
            $this->name = 'Drupal';
268
269
            $this->data = array(
270
              'name' => $this->name,
271
              'description' => '',
272
              'package' => $this->data['package'],
273
              'core' => $this->data['core'],
274
              'version' => $this->data['version'],
275
              'files' => array(),
276
              'configure' => '',
277
              'project' => 'drupal',
278
              'datestamp' => $this->data['datestamp'],
279
            );
280
        }
281
282
        $this->status_url = self::UPDATE_DEFAULT_URL;
283
284
        // Assume an official release until we see otherwise.
285
        $this->install_type     = self::INSTALL_TYPE_OFFICIAL;
286
        $this->existing_version = $this->version;
287
288
        if (isset($this->version)) {
289
            // Check for development snapshots
290
            if (preg_match('/(dev|HEAD)/', $this->version)) {
291
                $this->install_type = self::INSTALL_TYPE_DEV;
292
            }
293
294
            // Figure out what the currently installed major version is. We need
295
            // to handle both contribution (e.g. "5.x-1.3", major = 1) and core
296
            // (e.g. "5.1", major = 5) version strings.
297
            $matches = array();
298
            if (preg_match('/^(\d+\.x-)?(\d+)\..*$/', $this->version, $matches)) {
299
                $this->existing_major = $matches[2];
300
            } else {
301
                // This would only happen for version strings that don't follow the
302
                // drupal.org convention. We let contribs define "major" in their
303
                // .info in this case, and only if that's missing would we hit this.
304
                $this->existing_major = -1;
305
            }
306
        } else {
307
            // No version info available at all.
308
            $this->install_type     = self::INSTALL_TYPE_UNKNOWN;
309
            $this->existing_version = 'Unknown';
310
            $this->existing_major   = -1;
311
        }
312
    }
313
314
    /**
315
     * @param string  $version
316
     * @param Release $release
317
     */
318
    public function addSecurityUpdate($version, $release)
319
    {
320
        $this->security_updates[$version] = $release;
321
    }
322
323
    /**
324
     * @param string $version_major
325
     * @param string $version
326
     */
327
    public function addAlsoAvailable($version_major, $version)
328
    {
329
        $this->also_available[$version_major] = $version;
330
    }
331
332
    /**
333
     * @return array
334
     */
335
    public function getAlsoAvailable()
336
    {
337
        return $this->also_available;
338
    }
339
340
    /**
341
     * @param string $version_major
342
     * @return bool
343
     */
344
    public function hasAlsoAvailable($version_major)
345
    {
346
        return isset($this->also_available[$version_major]);
347
    }
348
349
    /**
350
     * @return mixed
351
     */
352
    public function getCore()
353
    {
354
        return $this->core;
355
    }
356
357
    /**
358
     * @return mixed
359
     */
360
    public function getDatestamp()
361
    {
362
        return $this->datestamp;
363
    }
364
365
    /**
366
     * @return array
367
     */
368
    public function getDetails()
369
    {
370
        return $this->data;
371
    }
372
373
    /**
374
     * @return string
375
     */
376
    public function getProjectType()
377
    {
378
        return $this->project_type;
379
    }
380
381
    /**
382
     * @param string $type
383
     */
384
    public function setProjectType($type)
385
    {
386
        $this->project_type = $type;
387
    }
388
389
    /**
390
     * @return mixed
391
     */
392
    public function getDevVersion()
393
    {
394
        return $this->dev_version;
395
    }
396
397
    /**
398
     * @param $dev_version
399
     */
400
    public function setDevVersion($dev_version)
401
    {
402
        $this->dev_version = $dev_version;
403
    }
404
405
    /**
406
     * @return string
407
     */
408
    public function getExistingMajor()
409
    {
410
        return $this->existing_major;
411
    }
412
413
    /**
414
     * @return string
415
     */
416
    public function getExistingVersion()
417
    {
418
        return $this->existing_version;
419
    }
420
421
    /**
422
     * @return integer
423
     */
424
    public function getFetchStatus()
425
    {
426
        return $this->fetch_status;
427
    }
428
429
    /**
430
     * @param $fetch_status
431
     */
432
    public function setFetchStatus($fetch_status)
433
    {
434
        $this->fetch_status = $fetch_status;
435
    }
436
437
    /**
438
     * @return string
439
     */
440
    public function getInstallType()
441
    {
442
        return $this->install_type;
443
    }
444
445
    /**
446
     * @return mixed
447
     */
448
    public function getLatestDev()
449
    {
450
        return $this->latest_dev;
451
    }
452
453
    /**
454
     * @param $latest_dev
455
     */
456
    public function setLatestDev($latest_dev)
457
    {
458
        $this->latest_dev = $latest_dev;
459
    }
460
461
    /**
462
     * @return mixed
463
     */
464
    public function getLatestVersion()
465
    {
466
        return $this->latest_version;
467
    }
468
469
    /**
470
     * @param $latest_version
471
     */
472
    public function setLatestVersion($latest_version)
473
    {
474
        $this->latest_version = $latest_version;
475
    }
476
477
    /**
478
     * @return string
479
     */
480
    public function getName()
481
    {
482
        return $this->name;
483
    }
484
485
    /**
486
     * @return string
487
     */
488
    public function getProject()
489
    {
490
        return $this->project;
491
    }
492
493
    /**
494
     * @return int
495
     */
496
    public function getProjectStatus()
497
    {
498
        return $this->project_status;
499
    }
500
501
    /**
502
     * @param int $project_status
503
     */
504
    public function setProjectStatus($project_status)
505
    {
506
        $this->project_status = $project_status;
507
    }
508
509
    /**
510
     * @return string
511
     */
512
    public function getReason()
513
    {
514
        return $this->reason;
515
    }
516
517
    /**
518
     * @param string $reason
519
     */
520
    public function setReason($reason)
521
    {
522
        $this->reason = $reason;
523
    }
524
525
    /**
526
     * @return mixed
527
     */
528
    public function getRecommended()
529
    {
530
        return $this->recommended;
531
    }
532
533
    /**
534
     * @param $recommended
535
     */
536
    public function setRecommended($recommended)
537
    {
538
        $this->recommended = $recommended;
539
    }
540
541
    /**
542
     * @return Release[]
543
     */
544
    public function getReleases()
545
    {
546
        return $this->releases;
547
    }
548
549
    /**
550
     * @param Release[] $releases
551
     */
552
    public function setReleases($releases)
553
    {
554
        $this->releases = $releases;
555
    }
556
557
    /**
558
     * @param string $release
559
     *
560
     * @return Release|false
561
     */
562
    public function getRelease($release)
563
    {
564
        if (isset($this->releases[$release])) {
565
            return $this->releases[$release];
566
        }
567
568
        return false;
569
    }
570
571
    /**
572
     * @return Release[]
573
     */
574
    public function getSecurityUpdates()
575
    {
576
        return $this->security_updates;
577
    }
578
579
    /**
580
     * @param Release[] $security_updates
581
     */
582
    public function setSecurityUpdates($security_updates)
583
    {
584
        $this->security_updates = $security_updates;
585
    }
586
587
    /**
588
     * @return int
589
     */
590
    public function getStatus()
591
    {
592
        return $this->status;
593
    }
594
595
    /**
596
     * @param int $status
597
     */
598
    public function setStatus($status)
599
    {
600
        $this->status = $status;
601
    }
602
603
    /**
604
     * @return string
605
     */
606
    public function getStatusUrl()
607
    {
608
        return $this->status_url;
609
    }
610
611
    /**
612
     * @param string $status_url
613
     */
614
    public function setStatusUrl($status_url)
615
    {
616
        $this->status_url = $status_url;
617
    }
618
619
    /**
620
     * @return string
621
     */
622
    public function getVersion()
623
    {
624
        return $this->version;
625
    }
626
627
    /**
628
     * @return bool
629
     */
630
    public function hasSecurityUpdates()
631
    {
632
        return count($this->security_updates) > 0;
633
    }
634
635
    /**
636
     * @param array $data
637
     */
638
    public function setDetails($data)
639
    {
640
        $this->data = $data;
641
642
        foreach (array('name', 'core', 'version', 'datestamp') as $property) {
643
            if (isset($data[$property])) {
644
                $this->$property = $data[$property];
645
            }
646
        }
647
648
        $this->init();
649
    }
650
651
    /**
652
     * @param string  $version
653
     * @param Release $release
654
     */
655
    public function setRelease($version, Release $release)
656
    {
657
        $this->releases[$version] = $release;
658
    }
659
}
660