Completed
Pull Request — master (#489)
by Helpful
03:34
created
code/model/DNTag.php 2 patches
Indentation   +51 added lines, -51 removed lines patch added patch discarded remove patch
@@ -5,66 +5,66 @@
 block discarded – undo
5 5
 class DNTag extends ViewableData
6 6
 {
7 7
 
8
-    /**
9
-     * @var Gitonomy\Git\Reference\Tag
10
-     */
11
-    protected $tag = null;
8
+	/**
9
+	 * @var Gitonomy\Git\Reference\Tag
10
+	 */
11
+	protected $tag = null;
12 12
 
13
-    protected $project = null;
13
+	protected $project = null;
14 14
 
15
-    protected $data = null;
15
+	protected $data = null;
16 16
 
17
-    protected $name = null;
17
+	protected $name = null;
18 18
 
19
-    protected $references = null;
19
+	protected $references = null;
20 20
 
21
-    private static $casting = array(
22
-        'Name' => 'Text',
23
-        'SHA' => 'Text'
24
-    );
21
+	private static $casting = array(
22
+		'Name' => 'Text',
23
+		'SHA' => 'Text'
24
+	);
25 25
 
26
-    /**
27
-     * @param Tag $tag
28
-     * @param DNProject $project
29
-     * @param DNData $data
30
-     */
31
-    public function __construct(Tag $tag, DNProject $project, DNData $data)
32
-    {
33
-        $this->tag = $tag;
34
-        $this->project = $project;
35
-        $this->data = $data;
36
-    }
26
+	/**
27
+	 * @param Tag $tag
28
+	 * @param DNProject $project
29
+	 * @param DNData $data
30
+	 */
31
+	public function __construct(Tag $tag, DNProject $project, DNData $data)
32
+	{
33
+		$this->tag = $tag;
34
+		$this->project = $project;
35
+		$this->data = $data;
36
+	}
37 37
 
38
-    /**
39
-     * @return string
40
-     */
41
-    public function Name()
42
-    {
43
-        return htmlentities($this->tag->getName());
44
-    }
38
+	/**
39
+	 * @return string
40
+	 */
41
+	public function Name()
42
+	{
43
+		return htmlentities($this->tag->getName());
44
+	}
45 45
 
46
-    /**
47
-     * @return string
48
-     */
49
-    public function SHA()
50
-    {
51
-        return htmlentities($this->tag->getCommitHash());
52
-    }
46
+	/**
47
+	 * @return string
48
+	 */
49
+	public function SHA()
50
+	{
51
+		return htmlentities($this->tag->getCommitHash());
52
+	}
53 53
 
54
-    /**
55
-     * @return SS_Datetime
56
-     */
57
-    public function Created()
58
-    {
59
-        $created = $this->tag->getCommit()->getCommitterDate();
54
+	/**
55
+	 * @return SS_Datetime
56
+	 */
57
+	public function Created()
58
+	{
59
+		$created = $this->tag->getCommit()->getCommitterDate();
60 60
 
61
-        // gitonomy sets the time to UTC, so now we set the timezone to
62
-        // whatever PHP is set to (date.timezone). This will change in the future if each
63
-        // deploynaut user has their own timezone
64
-        $created->setTimezone(new DateTimeZone(date_default_timezone_get()));
61
+		// gitonomy sets the time to UTC, so now we set the timezone to
62
+		// whatever PHP is set to (date.timezone). This will change in the future if each
63
+		// deploynaut user has their own timezone
64
+		$created->setTimezone(new DateTimeZone(date_default_timezone_get()));
65 65
 
66
-        $d = new SS_Datetime();
67
-        $d->setValue($created->format('Y-m-d H:i:s'));
68
-        return $d;
69
-    }
66
+		$d = new SS_Datetime();
67
+		$d->setValue($created->format('Y-m-d H:i:s'));
68
+		return $d;
69
+	}
70 70
 }
Please login to merge, or discard this patch.
Braces   +5 added lines, -10 removed lines patch added patch discarded remove patch
@@ -2,8 +2,7 @@  discard block
 block discarded – undo
2 2
 
3 3
 use Gitonomy\Git\Reference\Tag;
4 4
 
5
-class DNTag extends ViewableData
6
-{
5
+class DNTag extends ViewableData {
7 6
 
8 7
     /**
9 8
      * @var Gitonomy\Git\Reference\Tag
@@ -28,8 +27,7 @@  discard block
 block discarded – undo
28 27
      * @param DNProject $project
29 28
      * @param DNData $data
30 29
      */
31
-    public function __construct(Tag $tag, DNProject $project, DNData $data)
32
-    {
30
+    public function __construct(Tag $tag, DNProject $project, DNData $data) {
33 31
         $this->tag = $tag;
34 32
         $this->project = $project;
35 33
         $this->data = $data;
@@ -38,24 +36,21 @@  discard block
 block discarded – undo
38 36
     /**
39 37
      * @return string
40 38
      */
41
-    public function Name()
42
-    {
39
+    public function Name() {
43 40
         return htmlentities($this->tag->getName());
44 41
     }
45 42
 
46 43
     /**
47 44
      * @return string
48 45
      */
49
-    public function SHA()
50
-    {
46
+    public function SHA() {
51 47
         return htmlentities($this->tag->getCommitHash());
52 48
     }
53 49
 
54 50
     /**
55 51
      * @return SS_Datetime
56 52
      */
57
-    public function Created()
58
-    {
53
+    public function Created() {
59 54
         $created = $this->tag->getCommit()->getCommitterDate();
60 55
 
61 56
         // gitonomy sets the time to UTC, so now we set the timezone to
Please login to merge, or discard this patch.
code/model/GitonomyCache.php 3 patches
Indentation   +9 added lines, -9 removed lines patch added patch discarded remove patch
@@ -5,14 +5,14 @@
 block discarded – undo
5 5
  */
6 6
 class GitonomyCache
7 7
 {
8
-    public static $cache = array();
8
+	public static $cache = array();
9 9
 
10
-    public static function getIncludingBranches($commit)
11
-    {
12
-        $cacheKey = 'getIncludingBranches-' . $commit->getRepository()->getPath() . '-' . $commit->gethash();
13
-        if (!isset(self::$cache[$cacheKey])) {
14
-            self::$cache[$cacheKey] = $commit->getIncludingBranches();
15
-        }
16
-        return self::$cache[$cacheKey];
17
-    }
10
+	public static function getIncludingBranches($commit)
11
+	{
12
+		$cacheKey = 'getIncludingBranches-' . $commit->getRepository()->getPath() . '-' . $commit->gethash();
13
+		if (!isset(self::$cache[$cacheKey])) {
14
+			self::$cache[$cacheKey] = $commit->getIncludingBranches();
15
+		}
16
+		return self::$cache[$cacheKey];
17
+	}
18 18
 }
Please login to merge, or discard this patch.
Spacing   +1 added lines, -1 removed lines patch added patch discarded remove patch
@@ -10,7 +10,7 @@
 block discarded – undo
10 10
     public static function getIncludingBranches($commit)
11 11
     {
12 12
         $cacheKey = 'getIncludingBranches-' . $commit->getRepository()->getPath() . '-' . $commit->gethash();
13
-        if (!isset(self::$cache[$cacheKey])) {
13
+        if(!isset(self::$cache[$cacheKey])) {
14 14
             self::$cache[$cacheKey] = $commit->getIncludingBranches();
15 15
         }
16 16
         return self::$cache[$cacheKey];
Please login to merge, or discard this patch.
Braces   +2 added lines, -4 removed lines patch added patch discarded remove patch
@@ -3,12 +3,10 @@
 block discarded – undo
3 3
 /**
4 4
  * Helper class caching expensive gitonomy calls
5 5
  */
6
-class GitonomyCache
7
-{
6
+class GitonomyCache {
8 7
     public static $cache = array();
9 8
 
10
-    public static function getIncludingBranches($commit)
11
-    {
9
+    public static function getIncludingBranches($commit) {
12 10
         $cacheKey = 'getIncludingBranches-' . $commit->getRepository()->getPath() . '-' . $commit->gethash();
13 11
         if (!isset(self::$cache[$cacheKey])) {
14 12
             self::$cache[$cacheKey] = $commit->getIncludingBranches();
Please login to merge, or discard this patch.
code/model/Pipeline.php 4 patches
Indentation   +1079 added lines, -1079 removed lines patch added patch discarded remove patch
@@ -114,1083 +114,1083 @@
 block discarded – undo
114 114
 class Pipeline extends DataObject implements PipelineData
115 115
 {
116 116
 
117
-    /**
118
-     * Messages
119
-     */
120
-    const ALERT_ABORT = 'Abort';
121
-    const ALERT_SUCCESS = 'Success';
122
-    const ALERT_FAILURE = 'Failure';
123
-    const ALERT_ROLLBACK_STARTED = 'RollbackStarted';
124
-    const ALERT_ROLLBACK_SUCCESS = 'RollbackSuccess';
125
-    const ALERT_ROLLBACK_FAILURE = 'RollbackFailure';
126
-
127
-    /**
128
-     * - Status: Current status of this Pipeline. Running means 'currently executing a {@link PipelineStep}'.
129
-     *           See the {@link PipelineControllerTask} class for why this is important.
130
-     * - SHA:    This is the Git SHA that the pipeline is acting on. This is passed into the {@link PipelineStep}
131
-     *           objects so that the steps know what to smoketest, deploy, etc.
132
-     *
133
-     * @var array
134
-     */
135
-    private static $db = array(
136
-        'Status' => 'Enum("Running,Complete,Failed,Aborted,Rollback,Queued", "Queued")',
137
-        'Config' => 'Text', // serialized array of configuration for this pipeline
138
-        'SHA' => 'Varchar(255)',
139
-        'DryRun' => 'Boolean', // Try if this deployment is a test dryrun
140
-        'LastMessageSent' => 'Varchar(255)' // ID of last message sent
141
-    );
142
-
143
-    /**
144
-     * - Author:      The {@link Member} object that started this pipeline running.
145
-     * - Environment: The {@link DNEnvironment} that this Pipeline is associated to.
146
-     * - CurrentStep: The current {@link PipelineStep} object that is keeping this pipeline alive. This should be
147
-     *                cleared when the last step is complete.
148
-     *
149
-     * @var array
150
-     */
151
-    private static $has_one = array(
152
-        'Author' => 'Member',
153
-        'Environment' => 'DNEnvironment',
154
-        'CurrentStep' => 'PipelineStep',
155
-        // to be used for rollbacks
156
-        "PreviousSnapshot" => "DNDataTransfer",
157
-        "PreviousDeployment" => 'DNDeployment',
158
-        "CurrentDeployment" => "DNDeployment",
159
-        "RollbackStep1" => "PipelineStep",
160
-        "RollbackStep2" => "PipelineStep"
161
-    );
162
-
163
-    /**
164
-     * - Steps: These are ordered by the `PipelineStep`.`Order` attribute.
165
-     *
166
-     * @var array
167
-     */
168
-    private static $has_many = array(
169
-        'Steps' => 'PipelineStep'
170
-    );
171
-
172
-    /**
173
-     * @var array
174
-     */
175
-    private static $summary_fields = array(
176
-        'ID' => 'ID',
177
-        'Status' => 'Status',
178
-        'SHA' => 'SHA',
179
-        'Author.Title' => 'Author',
180
-        'CurrentStep.Name' => 'Current Step',
181
-        'Created' => 'Created',
182
-        'LastEdited' => 'Last Updated'
183
-    );
184
-
185
-    /**
186
-     * @var string
187
-     */
188
-    private static $default_sort = '"Created" DESC';
189
-
190
-    /**
191
-     * @var array
192
-     */
193
-    private static $cast = array(
194
-        'RunningDescription' => 'HTMLText'
195
-    );
196
-
197
-    /**
198
-     * @config
199
-     * @var array
200
-     */
201
-    private static $dependencies = array(
202
-        'MessagingService' => '%$ConfirmationMessagingService'
203
-    );
204
-
205
-    /**
206
-     * Currently assigned messaging service
207
-     *
208
-     * @var ConfirmationMessagingService
209
-     */
210
-    private $messagingService = null;
211
-
212
-    /**
213
-     * @param ConfirmationMessagingService $service
214
-     */
215
-    public function setMessagingService(ConfirmationMessagingService $service)
216
-    {
217
-        $this->messagingService = $service;
218
-    }
219
-
220
-    /**
221
-     * @return ConfirmationMessagingService
222
-     */
223
-    public function getMessagingService()
224
-    {
225
-        return $this->messagingService;
226
-    }
227
-
228
-    public function __isset($property)
229
-    {
230
-        // Workaround fixed in https://github.com/silverstripe/silverstripe-framework/pull/3201
231
-        // Remove this once we update to a version of framework which supports this
232
-        if ($property === 'MessagingService') {
233
-            return !empty($this->messagingService);
234
-        }
235
-        return parent::__isset($property);
236
-    }
237
-
238
-    /**
239
-     * Retrieve message template replacements
240
-     *
241
-     * @return array
242
-     */
243
-    public function getReplacements()
244
-    {
245
-        // Get member who began this request
246
-        $author = $this->Author();
247
-        $environment = $this->Environment();
248
-        return array(
249
-            '<abortlink>' => Director::absoluteURL($this->Environment()->Link()),
250
-            '<pipelinelink>' => Director::absoluteURL($this->Link()),
251
-            '<requester>' => $author->Title,
252
-            '<requester-email>' => $author->Email,
253
-            '<environment>' => $environment->Name,
254
-            '<project>' => $environment->Project()->Name,
255
-            '<commitsha>' => $this->SHA
256
-        );
257
-    }
258
-
259
-    /**
260
-     * Title of this step
261
-     *
262
-     * @return string
263
-     */
264
-    public function getTitle()
265
-    {
266
-        return "Pipeline {$this->ID} (Status: {$this->Status})";
267
-    }
268
-
269
-    /**
270
-     * @param Member $member
271
-     */
272
-    public function canAbort($member = null)
273
-    {
274
-        // Owner can abort
275
-        $member = $member ?: Member::currentUser();
276
-        if (!$member) {
277
-            return false;
278
-        }
279
-        if ($member->ID == $this->AuthorID) {
280
-            return true;
281
-        }
282
-
283
-        // Check environment permission
284
-        return $this->Environment()->canAbort($member);
285
-    }
286
-
287
-    /**
288
-     * Get status of currently running step
289
-     *
290
-     * @return string Status description (html format)
291
-     */
292
-    public function getRunningDescription()
293
-    {
294
-        if (!$this->isActive()) {
295
-            return 'This pipeline is not currently running';
296
-        }
297
-        $result = '';
298
-        if ($step = $this->CurrentStep()) {
299
-            $result = $step->getRunningDescription();
300
-        }
301
-        return $result ?: 'This pipeline is currently running';
302
-    }
303
-
304
-    /**
305
-     * Get options for the currently running pipeline, if and only if it is currently running
306
-     *
307
-     * @return ArrayList List of items with a Link and Title attribute
308
-     */
309
-    public function RunningOptions()
310
-    {
311
-        if (!$this->isActive()) {
312
-            return null;
313
-        }
314
-        $actions = array();
315
-
316
-        // Let current step update the current list of options
317
-        if (($step = $this->CurrentStep()) && ($step->isRunning())) {
318
-            $actions = $step->allowedActions();
319
-        }
320
-        return new ArrayList($actions);
321
-    }
322
-
323
-    /**
324
-     * Get possible logs for the currently pipeline
325
-     *
326
-     * @return ArrayList List of logs with a Link and Title attribute
327
-     */
328
-    public function LogOptions()
329
-    {
330
-        if (!$this->isActive()) {
331
-            return null;
332
-        }
333
-
334
-        $logs = array();
335
-
336
-        $logs[] = array(
337
-            'ButtonText' => 'Pipeline Log',
338
-            'Link' => $this->Link()
339
-        );
340
-
341
-        if ($this->PreviousSnapshotID > 0) {
342
-            $logs[] = array(
343
-                'ButtonText' => 'Snapshot Log',
344
-                'Link' => $this->PreviousSnapshot()->Link()
345
-            );
346
-        }
347
-
348
-        if ($this->CurrentDeploymentID > 0) {
349
-            $logs[] = array(
350
-                'ButtonText' => 'Deployment Log',
351
-                'Link' => $this->CurrentDeployment()->Link()
352
-            );
353
-        }
354
-
355
-        // Get logs from rollback steps (only for RollbackSteps).
356
-        $rollbackSteps = array($this->RollbackStep1(), $this->RollbackStep2());
357
-        foreach ($rollbackSteps as $rollback) {
358
-            if ($rollback->exists() && $rollback->ClassName == 'RollbackStep') {
359
-                if ($rollback->RollbackDeploymentID > 0) {
360
-                    $logs[] = array(
361
-                        'ButtonText' => 'Rollback Log',
362
-                        'Link' => $rollback->RollbackDeployment()->Link()
363
-                    );
364
-                }
365
-
366
-                if ($rollback->RollbackDatabaseID > 0) {
367
-                    $logs[] = array(
368
-                        'ButtonText' => 'Rollback DB Log',
369
-                        'Link' => $rollback->RollbackDatabase()->Link()
370
-                    );
371
-                }
372
-            }
373
-        }
374
-
375
-        return new ArrayList($logs);
376
-    }
377
-
378
-    /**
379
-     * Cached of config merged with defaults
380
-     *
381
-     * @var array|null
382
-     */
383
-    protected $mergedConfig;
384
-
385
-    /**
386
-     * Get this pipeline configuration. If the configuration has been serialized
387
-     * and saved into the Config field, it'll use that. If that field is empty,
388
-     * it'll read the YAML file directly and return that instead.
389
-     *
390
-     * @return array
391
-     * @throws Exception
392
-     */
393
-    public function getConfigData()
394
-    {
395
-        // Lazy load if necessary
396
-        $data = null;
397
-        if (!$this->Config && ($data = $this->Environment()->loadPipelineConfig())) {
398
-            $this->Config = serialize($data);
399
-        }
400
-
401
-        // Merge with defaults
402
-        if ($this->Config) {
403
-            if (!$this->mergedConfig) {
404
-                $this->mergedConfig = $data ?: unserialize($this->Config);
405
-                if ($default = self::config()->default_config) {
406
-                    Config::merge_array_low_into_high($this->mergedConfig, $default);
407
-                }
408
-            }
409
-            return $this->mergedConfig;
410
-        }
411
-
412
-        // Fail if no data available
413
-        $path = $this->Environment()->getPipelineFilename();
414
-        throw new Exception(sprintf('YAML configuration for pipeline not found at path "%s"', $path));
415
-    }
416
-
417
-    public function setConfig($data)
418
-    {
419
-        $this->mergedConfig = null;
420
-        return parent::setField('Config', $data);
421
-    }
422
-
423
-    /**
424
-     * Retrieve the value of a specific config setting
425
-     *
426
-     * @param string $setting Settings
427
-     * @return mixed Value of setting, or null if not set
428
-     */
429
-    public function getConfigSetting($setting)
430
-    {
431
-        $source = $this->getConfigData();
432
-
433
-        foreach (func_get_args() as $setting) {
434
-            if (empty($source[$setting])) {
435
-                return null;
436
-            }
437
-            $source = $source[$setting];
438
-        }
439
-
440
-        return $source;
441
-    }
442
-
443
-    /**
444
-     * @return FieldList
445
-     */
446
-    public function getCMSFields()
447
-    {
448
-        $fields = new FieldList(new TabSet('Root'));
449
-
450
-        // Main fields
451
-        $fields->addFieldsToTab('Root.Main', array(
452
-            TextField::create('SHA')
453
-                ->setDescription('SHA of the commit this pipeline is running against')
454
-                ->performReadonlyTransformation(),
455
-            TextField::create('AuthorName', 'Author', ($author = $this->Author()) ? $author->Title : null)
456
-                ->setDescription('Person who initiated this pipeline')
457
-                ->performReadonlyTransformation(),
458
-            DropdownField::create('Status', 'Status', $this->dbObject('Status')->enumValues()),
459
-            DropdownField::create('CurrentStepID', 'Current Step', $this->Steps()->map('ID', 'TreeTitle')),
460
-            TextField::create(
461
-                'CurrentDeployment_Label',
462
-                'Current Deployment',
463
-                $this->CurrentDeployment()->getTitle()
464
-            )    ->setDescription('Deployment generated by this pipeline')
465
-                ->performReadonlyTransformation(),
466
-        ));
467
-
468
-        // Backup fields
469
-        $fields->addFieldsToTab('Root.Backups', array(
470
-            TextField::create(
471
-                'PreviousDeployment_Label',
472
-                'Previous Deployment',
473
-                $this->PreviousDeployment()->getTitle()
474
-            )    ->setDescription('Prior deployment to revert to if this pipeline fails')
475
-                ->performReadonlyTransformation(),
476
-            TextField::create(
477
-                'PreviousSnapshot_Label',
478
-                'Previous DB Snapshot',
479
-                $this->PreviousSnapshot()->getTitle()
480
-            )    ->setDescription('Database backup to revert to if this pipeline fails')
481
-                ->performReadonlyTransformation()
482
-        ));
483
-
484
-        if ($log = $this->LogContent()) {
485
-            $fields->addFieldToTab(
486
-                'Root.Main',
487
-                ToggleCompositeField::create(
488
-                    'PipelineLog',
489
-                    'Pipeline Log',
490
-                    LiteralField::create('LogText', nl2br(Convert::raw2xml($log)))
491
-                )
492
-            );
493
-        }
494
-
495
-        // Steps
496
-        $stepConfig = GridFieldConfig_RecordEditor::create();
497
-        $steps = GridField::create('Steps', 'Pipeline Steps', $this->Steps(), $stepConfig);
498
-        $fields->addFieldsToTab('Root.PipelineSteps', $steps);
499
-
500
-        return $fields;
501
-    }
502
-
503
-    /**
504
-     * Return a dependent {@link DNEnvironment} based on this pipeline's dependent environment configuration.
505
-     *
506
-     * @return DNEnvironment
507
-     */
508
-    public function getDependentEnvironment()
509
-    {
510
-        // dependent environment not available
511
-        $projectName = $this->getConfigSetting('PipelineConfig', 'DependsOnProject');
512
-        $environmentName = $this->getConfigSetting('PipelineConfig', 'DependsOnEnvironment');
513
-        if (empty($projectName) || empty($environmentName)) {
514
-            return null;
515
-        }
516
-
517
-        $project = DNProject::get()->filter('Name', $projectName)->first();
518
-        if (!($project && $project->exists())) {
519
-            throw new Exception(sprintf('Could not find dependent project "%s"', $projectName));
520
-        }
521
-
522
-        $environment = DNEnvironment::get()->filter(array(
523
-            'ProjectID' => $project->ID,
524
-            'Name' => $environmentName
525
-        ))->first();
526
-
527
-        if (!($environment && $environment->exists())) {
528
-            throw new Exception(sprintf(
529
-                'Could not find dependent environment "%s" in project "%s"',
530
-                $environmentName,
531
-                $projectName
532
-            ));
533
-        }
534
-
535
-        return $environment;
536
-    }
537
-
538
-    /**
539
-     * Generate a step from a name, config, and sort order
540
-     *
541
-     * @throws Exception
542
-     * @param string $name
543
-     * @param array $stepConfig
544
-     * @param int $order
545
-     * @return PipelineStep
546
-     */
547
-    protected function generateStep($name, $stepConfig, $order = 0)
548
-    {
549
-        $stepClass = isset($stepConfig['Class']) ? $stepConfig['Class'] : $stepConfig;
550
-
551
-        if (empty($stepClass)) {
552
-            throw new Exception(
553
-                sprintf('Missing or empty Class specifier for step "%s"', $name)
554
-            );
555
-        }
556
-
557
-        if (!is_subclass_of($stepClass, 'PipelineStep')) {
558
-            throw new Exception(
559
-                sprintf('%s is not a valid "Class" field name for step "%s"', var_export($stepClass, true), $name)
560
-            );
561
-        }
562
-
563
-        $step = $stepClass::create();
564
-        $step->Name = $name;
565
-        $step->PipelineID = $this->ID;
566
-        $step->Order = $order;
567
-        $step->Status = 'Queued';
568
-        $step->Config = serialize($stepConfig);
569
-        $step->write();
570
-
571
-        return $step;
572
-    }
573
-
574
-    /**
575
-     * Starts the pipeline process.
576
-     *
577
-     * Reads a YAML configuration from the linked {@link DNEnvironment}
578
-     * and builds the {@link PipelineStep} objects and runs them.
579
-     *
580
-     * Note that this method doesn't actually start any {@link PipelineStep} objects, that is handled by
581
-     * {@link self::checkPipelineStatus()}, and the daemon running the process.
582
-     *
583
-     * @throws LogicException
584
-     * @return boolean
585
-     */
586
-    public function start()
587
-    {
588
-        // Ensure there are no other running {@link Pipeline} objects for this {@link DNEnvironment}
589
-        // Requires that $this->EnvironmentID has been set
590
-        $env = $this->Environment();
591
-        if (!($env && $env->exists())) {
592
-            throw new LogicException("This pipeline needs a valid environment to run on.");
593
-        }
594
-
595
-        if ($env->HasCurrentPipeline()) {
596
-            throw new LogicException("You can only run one pipeline at a time on this environment.");
597
-        }
598
-
599
-        $this->write(); // ensure we've written this record first
600
-
601
-        // Instantiate steps.
602
-        foreach ($this->getConfigSetting('Steps') as $name => $stepConfig) {
603
-            $this->pushPipelineStep($name, $stepConfig);
604
-        }
605
-
606
-        $this->Status = 'Running';
607
-        $this->write();
608
-
609
-        $this->log('Started logging for this pipeline!');
610
-
611
-        return true;
612
-    }
613
-
614
-    /**
615
-     * Mark this Pipeline as completed.
616
-     */
617
-    public function markComplete()
618
-    {
619
-        $this->Status = "Complete";
620
-        $this->log("Pipeline completed successfully.");
621
-        $this->write();
622
-        // Some steps may pre-emptively send a success message before the pipeline itself has completed
623
-        if ($this->LastMessageSent !== self::ALERT_SUCCESS) {
624
-            $this->sendMessage(self::ALERT_SUCCESS);
625
-        }
626
-    }
627
-
628
-    /**
629
-     * @return bool true if this Pipeline has successfully completed all {@link PipelineStep} steps already.
630
-     */
631
-    public function isComplete()
632
-    {
633
-        return $this->Status == "Complete";
634
-    }
635
-
636
-    /**
637
-     * True if the pipeline is running but NOT doing a rollback
638
-     *
639
-     * @return bool
640
-     */
641
-    public function isRunning()
642
-    {
643
-        return $this->Status == "Running";
644
-    }
645
-
646
-    /**
647
-     * True if the pipeline is running or doing a rollback
648
-     *
649
-     * @return bool
650
-     */
651
-    public function isActive()
652
-    {
653
-        return $this->isRunning() || $this->isRollback();
654
-    }
655
-
656
-    /**
657
-     * Push a step to the end of a pipeline
658
-     *
659
-     * @param string $name
660
-     * @param array $stepConfig
661
-     * @return PipelineStep
662
-     */
663
-    private function pushPipelineStep($name, $stepConfig)
664
-    {
665
-        $lastStep = $this->Steps()->sort("Order DESC")->first();
666
-        $order = $lastStep ? $lastStep->Order + 1 : 1;
667
-        return $this->generateStep($name, $stepConfig, $order);
668
-    }
669
-
670
-    /**
671
-     * The rollback has finished - close the pipeline and send relevant messages.
672
-     */
673
-    protected function finaliseRollback()
674
-    {
675
-
676
-        // Figure out the status by inspecting specific rollback steps.
677
-        $success = true;
678
-        $rollback1 = $this->RollbackStep1();
679
-        $rollback2 = $this->RollbackStep2();
680
-        if (!empty($rollback1) && $rollback1->Status == 'Failed') {
681
-            $success = false;
682
-        }
683
-        if (!empty($rollback2) && $rollback2->Status == 'Failed') {
684
-            $success = false;
685
-        }
686
-
687
-        // Send messages.
688
-        if ($success) {
689
-            $this->log("Pipeline failed, but rollback completed successfully.");
690
-            $this->sendMessage(self::ALERT_ROLLBACK_SUCCESS);
691
-        } else {
692
-            $this->log("Pipeline failed, rollback failed.");
693
-            $this->sendMessage(self::ALERT_ROLLBACK_FAILURE);
694
-        }
695
-
696
-        // Finish off the pipeline - rollback will only be triggered on a failed pipeline.
697
-        $this->Status = 'Failed';
698
-        $this->write();
699
-    }
700
-
701
-    /**
702
-     * Initiate a rollback. Moves the pipeline to the 'Rollback' status.
703
-     */
704
-    protected function beginRollback()
705
-    {
706
-        $this->log("Beginning rollback...");
707
-        $this->sendMessage(self::ALERT_ROLLBACK_STARTED);
708
-
709
-        // Add rollback step.
710
-        $configRollback1 = $this->getConfigSetting('RollbackStep1');
711
-        $stepRollback1 = $this->pushPipelineStep('RollbackStep1', $configRollback1);
712
-        $this->RollbackStep1ID = $stepRollback1->ID;
713
-        $this->CurrentStepID = $stepRollback1->ID;
714
-        $this->Status = 'Rollback';
715
-
716
-        // Add smoke test step, if available, for later processing.
717
-        $configRollback2 = $this->getConfigSetting('RollbackStep2');
718
-        if ($configRollback2) {
719
-            $stepRollback2 = $this->pushPipelineStep('RollbackStep2', $configRollback2);
720
-            $this->RollbackStep2ID = $stepRollback2->ID;
721
-        }
722
-
723
-        $this->write();
724
-
725
-        $stepRollback1->start();
726
-    }
727
-
728
-    /**
729
-     * Check if pipeline currently permits a rollback.
730
-     * This could be influenced by both the current state and by the specific configuration.
731
-     *
732
-     * @return boolean
733
-     */
734
-    protected function canStartRollback()
735
-    {
736
-        // The rollback cannot run twice.
737
-        if ($this->isRollback()) {
738
-            return false;
739
-        }
740
-
741
-        // Rollbacks must be configured.
742
-        if (!$this->getConfigSetting('RollbackStep1')) {
743
-            return false;
744
-        }
745
-
746
-        // On dryrun let rollback run
747
-        if ($this->DryRun) {
748
-            return true;
749
-        }
750
-
751
-        // Pipeline must have ran a deployment to be able to rollback.
752
-        $deploy = $this->CurrentDeployment();
753
-        $previous = $this->PreviousDeployment();
754
-        if (!$deploy->exists() || !$previous->exists()) {
755
-            return false;
756
-        }
757
-
758
-        return true;
759
-    }
760
-
761
-    /**
762
-     * Notify Pipeline that a step has failed and failure processing should kick in. If rollback steps are present
763
-     * the pipeline will be put into 'Rollback' state. After rollback is complete, regardless of the rollback result,
764
-     * the pipeline will be failed.
765
-     *
766
-     * @param bool $notify Set to false to disable notifications for this failure
767
-     */
768
-    public function markFailed($notify = true)
769
-    {
770
-        // Abort all running or queued steps.
771
-        $steps = $this->Steps();
772
-        foreach ($steps as $step) {
773
-            if ($step->isQueued() || $step->isRunning()) {
774
-                $step->abort();
775
-            }
776
-        }
777
-
778
-        if ($this->canStartRollback()) {
779
-            $this->beginRollback();
780
-        } elseif ($this->isRollback()) {
781
-            $this->finaliseRollback();
782
-        } else {
783
-            // Not able to roll back - fail immediately.
784
-            $this->Status = 'Failed';
785
-            $this->log("Pipeline failed, not running rollback (not configured or not applicable yet).");
786
-            $this->write();
787
-            if ($notify) {
788
-                $this->sendMessage(self::ALERT_FAILURE);
789
-            }
790
-        }
791
-    }
792
-
793
-    /**
794
-     * @return bool true if this Pipeline failed to execute all {@link PipelineStep} steps successfully
795
-     */
796
-    public function isFailed()
797
-    {
798
-        return $this->Status == "Failed";
799
-    }
800
-
801
-    /**
802
-     * @return bool true if this Pipeline is rolling back.
803
-     */
804
-    public function isRollback()
805
-    {
806
-        return $this->Status == "Rollback";
807
-    }
808
-
809
-    /**
810
-     * Mark this Pipeline as aborted
811
-     */
812
-    public function markAborted()
813
-    {
814
-        $this->Status = 'Aborted';
815
-        $logMessage = sprintf(
816
-            "Pipeline processing aborted. %s (%s) aborted the pipeline",
817
-            Member::currentUser()->Name,
818
-            Member::currentUser()->Email
819
-        );
820
-        $this->log($logMessage);
821
-        $this->write();
822
-
823
-        // Abort all running or queued steps.
824
-        $steps = $this->Steps();
825
-        foreach ($steps as $step) {
826
-            if ($step->isQueued() || $step->isRunning()) {
827
-                $step->abort();
828
-            }
829
-        }
830
-
831
-        // Send notification to users about this event
832
-        $this->sendMessage(self::ALERT_ABORT);
833
-    }
834
-
835
-    /**
836
-     * Finds a message template for a given role and message
837
-     *
838
-     * @param string $messageID Message ID
839
-     * @return array Resulting array(subject, message)
840
-     */
841
-    protected function generateMessageTemplate($messageID)
842
-    {
843
-        $subject = $this->getConfigSetting('PipelineConfig', 'Subjects', $messageID);
844
-        $message = $this->getConfigSetting('PipelineConfig', 'Messages', $messageID);
845
-        $substitutions = $this->getReplacements();
846
-        return $this->injectMessageReplacements($message, $subject, $substitutions);
847
-    }
848
-
849
-    /**
850
-     * Substitute templated variables into the given message and subject
851
-     *
852
-     * @param string $message
853
-     * @param string $subject
854
-     * @param array $substitutions
855
-     * @return array Resulting array(subject, message)
856
-     */
857
-    public function injectMessageReplacements($message, $subject, $substitutions)
858
-    {
859
-        // Handle empty messages
860
-        if (empty($subject) && empty($message)) {
861
-            return array(null, null);
862
-        }
863
-
864
-        // Check if there's a role specific message
865
-        $subjectText = str_replace(
866
-            array_keys($substitutions),
867
-            array_values($substitutions),
868
-            $subject ?: $message
869
-        );
870
-        $messageText = str_replace(
871
-            array_keys($substitutions),
872
-            array_values($substitutions),
873
-            $message ?: $subject
874
-        );
875
-
876
-
877
-        return array($subjectText, $messageText);
878
-    }
879
-
880
-    /**
881
-     * Sends a specific message to all marked recipients, including the author of this pipeline
882
-     *
883
-     * @param string $messageID Message ID. One of 'Abort', 'Success', or 'Failure', or some custom message
884
-     * @return boolean|null True if successful
885
-     */
886
-    public function sendMessage($messageID)
887
-    {
888
-        // Check message, subject, and additional arguments to include
889
-        list($subject, $message) = $this->generateMessageTemplate($messageID);
890
-        if (empty($subject) || empty($message)) {
891
-            $this->log("Skipping sending message. None configured for $messageID");
892
-            return true;
893
-        }
894
-
895
-        // Save last sent message
896
-        $this->LastMessageSent = $messageID;
897
-        $this->write();
898
-
899
-        // Setup messaging arguments
900
-        $arguments = array_merge(
901
-            $this->getConfigSetting('PipelineConfig', 'ServiceArguments') ?: array(),
902
-            array('subject' => $subject)
903
-        );
904
-
905
-        // Send message to author
906
-        if ($author = $this->Author()) {
907
-            $this->log("Pipeline sending $messageID message to {$author->Email}");
908
-            $this->messagingService->sendMessage($this, $message, $author, $arguments);
909
-        } else {
910
-            $this->log("Skipping sending message to missing author");
911
-        }
912
-
913
-        // Get additional recipients
914
-        $recipients = $this->getConfigSetting('PipelineConfig', 'Recipients', $messageID);
915
-        if (empty($recipients)) {
916
-            $this->log("Skipping sending message to empty recipients");
917
-        } else {
918
-            $recipientsStr = is_array($recipients) ? implode(',', $recipients) : $recipients;
919
-            $this->log("Pipeline sending $messageID message to $recipientsStr");
920
-            $this->messagingService->sendMessage($this, $message, $recipients, $arguments);
921
-        }
922
-    }
923
-
924
-    /**
925
-     * @return bool true if this Pipeline has been aborted
926
-     */
927
-    public function isAborted()
928
-    {
929
-        return $this->Status === "Aborted";
930
-    }
931
-
932
-    /**
933
-     * This method should be called only by the {@link CheckPipelineStatus} controller. It iterates through all the
934
-     * {@link PipelineStep} objects associated with this Pipeline, and finds a place where the pipeline has stalled
935
-     * (where one step has completed, but the next one has yet to start). It will then start the next step if required.
936
-     *
937
-     * We check here whether the {@link PipelineStep} finished successfully, and will mark the Pipeline as Failed if
938
-     * the step failed, but this is only a fallback, and should not be relied upon. The individual {@link PipelineStep}
939
-     * should mark itself as failed and then call {@link Pipeline::markFailed()} directly.
940
-     *
941
-     * If the Pipeline has run out of steps, then it will mark the pipeline as completed.
942
-     */
943
-    public function checkPipelineStatus()
944
-    {
945
-        $message = "";
946
-
947
-        if (!$this->isActive()) {
948
-            $message = "Pipeline::checkPipelineStatus() should only be called on running or rolling back pipelines.";
949
-        }
950
-
951
-        if (!$this->ID || !$this->isInDB()) {
952
-            $message = "Pipeline::checkPipelineStatus() can only be called on pipelines already saved.";
953
-        }
954
-
955
-        $currentStep = ($this->CurrentStep() && $this->CurrentStep()->isInDB())
956
-            ? $this->CurrentStep()
957
-            : null;
958
-
959
-        if ($currentStep && $currentStep->PipelineID != $this->ID) {
960
-            $message = sprintf(
961
-                "The current step (#%d) has a pipeline ID (#%d) that doesn't match this pipeline's ID (#%d).",
962
-                $currentStep->ID,
963
-                $currentStep->PipelineID,
964
-                $this->ID
965
-            );
966
-        }
967
-
968
-        if ($message) {
969
-            $this->log($message);
970
-            throw new LogicException($message);
971
-        }
972
-
973
-        // Fallback check only: this shouldn't be called unless a {@link PipelineStep} has been implemented incorrectly
974
-        if ($currentStep && $currentStep->isFailed() && !$this->isFailed() && !$this->isRollback()) {
975
-            $this->log(sprintf("Marking pipeline step (#%d) as failed - this pipeline step needs to be amended to mark"
976
-                . " the pipeline (as well as itself) as failed to ensure consistency.",
977
-                $this->CurrentStep()->ID
978
-            ));
979
-
980
-            $this->markFailed();
981
-            return;
982
-        }
983
-
984
-        // If this is the first time the Pipeline is run, then we don't have a CurrentStep, so set it,
985
-        // start it running, and return
986
-        if (!$currentStep) {
987
-            $step = $this->Steps()->first();
988
-            $this->CurrentStepID = $step->ID;
989
-            $this->write();
990
-
991
-            $this->log("Starting first pipeline step...");
992
-            $step->start();
993
-        } elseif ($currentStep->isFinished()) {
994
-            // Sort through the list of {@link PipelineStep} objects to find the next step we need to start.
995
-            $this->log("Finding next step to execute...");
996
-            $nextStep = $this->findNextStep();
997
-
998
-            if (!$nextStep) {
999
-
1000
-                // Special handling, since the main pipeline has already failed at this stage.
1001
-                if ($this->isRollback()) {
1002
-                    $this->finaliseRollback();
1003
-                    return false;
1004
-                }
1005
-
1006
-                // Double check for any steps that failed, but didn't notify the pipeline via markFailed.
1007
-                $failedSteps = PipelineStep::get()->filter(array(
1008
-                    'PipelineID' => $this->ID,
1009
-                    'Status' => 'Failed'
1010
-                ))->count();
1011
-                if ($failedSteps) {
1012
-                    $this->log('At least one of the steps has failed marking the pipeline as failed');
1013
-                    $this->markFailed();
1014
-                    return false;
1015
-                }
1016
-
1017
-                // We've reached the end of this pipeline successfully!
1018
-                $this->markComplete();
1019
-                return;
1020
-            } else {
1021
-                $this->CurrentStepID = $nextStep->ID;
1022
-                $this->write();
1023
-                // Otherwise, kick off the next step
1024
-                $this->log(sprintf("Found the next step (#%s), starting it now...", $nextStep->Name));
1025
-                $nextStep->start();
1026
-            }
1027
-        // if the current step is failing run it again
1028
-        } elseif ($step = $this->CurrentStep()) {
1029
-            $step->start();
1030
-        }
1031
-    }
1032
-
1033
-    /**
1034
-     * Finds the next {@link PipelineStep} that needs to execute. Relies on $this->CurrentStep() being a valid step.
1035
-     *
1036
-     * @return DataObject|null The next step in the pipeline, or null if none remain.
1037
-     */
1038
-    protected function findNextStep()
1039
-    {
1040
-        // otherwise get next step in chain
1041
-        $currentStep = $this->CurrentStep();
1042
-
1043
-        return $this
1044
-            ->Steps()
1045
-            ->filter("Status", "Queued")
1046
-            ->filter("Order:GreaterThanOrEqual", $currentStep->Order)
1047
-            ->exclude("ID", $currentStep->ID)
1048
-            ->sort("Order ASC")
1049
-            ->first();
1050
-    }
1051
-
1052
-    /**
1053
-     * Finds the previous {@link PipelineStep} that executed. Relies on $this->CurrentStep() being a valid step.
1054
-     *
1055
-     * @return DataObject|null The previous step in the pipeline, or null if this is the first.
1056
-     */
1057
-    public function findPreviousStep()
1058
-    {
1059
-        // otherwise get previous step in chain
1060
-        $currentStep = $this->CurrentStep();
1061
-
1062
-        return $this
1063
-            ->Steps()
1064
-            ->filter("Status", "Finished")
1065
-            ->filter("Order:LessThanOrEqual", $currentStep->Order)
1066
-            ->exclude("ID", $currentStep->ID)
1067
-            ->sort("Order DESC")
1068
-            ->first();
1069
-    }
1070
-
1071
-    /**
1072
-     * Write to a common log file. This log file will be the same regardless of how often this pipeline is re-created
1073
-     * from the database. To this end, it needs to know the database ID of this pipeline instance, so that it can
1074
-     * generate the correct filename to open.
1075
-     *
1076
-     * This also includes the calling class and method name that called ->log() in the first place, so we can trace
1077
-     * back where it was written from.
1078
-     *
1079
-     * @param string $message The message to log
1080
-     * @throws LogicException Thrown if we can't log yet because we don't know what to log to (no db record yet).
1081
-     */
1082
-    public function log($message = "")
1083
-    {
1084
-        $log = $this->getLogger();
1085
-
1086
-        // Taken from Debug::caller(), amended for our purposes to filter out the intermediate call to
1087
-        // PipelineStep->log(), so that our log message shows where the log message was actually created from.
1088
-        $bt = debug_backtrace();
1089
-
1090
-        $index = ($bt[1]['class'] == 'PipelineStep') ? 2 : 1;
1091
-
1092
-        $caller = $bt[$index];
1093
-        $caller['line'] = $bt[($index - 1)]['line']; // Overwrite line and file to be the the line/file that actually
1094
-        $caller['file'] = $bt[($index - 1)]['file']; // called the function, not where the function is defined.
1095
-        // In case it wasn't called from a class
1096
-        if (!isset($caller['class'])) {
1097
-            $caller['class'] = '';
1098
-        }
1099
-        // In case it doesn't have a type (wasn't called from class)
1100
-        if (!isset($caller['type'])) {
1101
-            $caller['type'] = '';
1102
-        }
1103
-
1104
-        $log->write(sprintf(
1105
-            "[%s::%s() (line %d)] %s",
1106
-            $caller['class'],
1107
-            $caller['function'],
1108
-            $caller['line'],
1109
-            $message
1110
-        ));
1111
-    }
1112
-
1113
-    /**
1114
-     * Returns the {@link DeploynautLogFile} instance that will actually write to this log file.
1115
-     *
1116
-     * @return DeploynautLogFile
1117
-     * @throws RuntimeException
1118
-     */
1119
-    public function getLogger()
1120
-    {
1121
-        if (!$this->isInDB()) {
1122
-            throw new RuntimeException("Can't write to a log file until we know the database ID.");
1123
-        }
1124
-
1125
-        if (!$this->Environment()) {
1126
-            throw new RuntimeException("Can't write to a log file until we have an Environment.");
1127
-        }
1128
-
1129
-        if ($this->Environment() && !$this->Environment()->Project()) {
1130
-            throw new RuntimeException("Can't write to a log file until we have the Environment's project.");
1131
-        }
1132
-
1133
-        $environment = $this->Environment();
1134
-        $filename = sprintf('%s.pipeline.%d.log', $environment->getFullName('.'), $this->ID);
1135
-
1136
-        return Injector::inst()->createWithArgs('DeploynautLogFile', array($filename));
1137
-    }
1138
-
1139
-    /**
1140
-     * @return bool
1141
-     */
1142
-    public function getDryRun()
1143
-    {
1144
-        return $this->getField('DryRun');
1145
-    }
1146
-
1147
-    /**
1148
-     * @param string|null $action
1149
-     *
1150
-     * @return string
1151
-     */
1152
-    public function Link($action = null)
1153
-    {
1154
-        return Controller::join_links($this->Environment()->Link(), 'pipeline', $this->ID, $action);
1155
-    }
1156
-
1157
-    /**
1158
-     * Link to an action on the current step
1159
-     *
1160
-     * @param string|null $action
1161
-     * @return string
1162
-     */
1163
-    public function StepLink($action = null)
1164
-    {
1165
-        return Controller::join_links($this->Link('step'), $action);
1166
-    }
1167
-
1168
-    /**
1169
-     * @return string
1170
-     */
1171
-    public function AbortLink()
1172
-    {
1173
-        return $this->Link('abort');
1174
-    }
1175
-
1176
-    /**
1177
-     * @return string
1178
-     */
1179
-    public function LogLink()
1180
-    {
1181
-        return $this->Link('log');
1182
-    }
1183
-
1184
-    /**
1185
-     * @return string
1186
-     */
1187
-    public function LogContent()
1188
-    {
1189
-        if ($this->exists() && $this->Environment()) {
1190
-            $logger = $this->getLogger();
1191
-            if ($logger->exists()) {
1192
-                return $logger->content();
1193
-            }
1194
-        }
1195
-    }
117
+	/**
118
+	 * Messages
119
+	 */
120
+	const ALERT_ABORT = 'Abort';
121
+	const ALERT_SUCCESS = 'Success';
122
+	const ALERT_FAILURE = 'Failure';
123
+	const ALERT_ROLLBACK_STARTED = 'RollbackStarted';
124
+	const ALERT_ROLLBACK_SUCCESS = 'RollbackSuccess';
125
+	const ALERT_ROLLBACK_FAILURE = 'RollbackFailure';
126
+
127
+	/**
128
+	 * - Status: Current status of this Pipeline. Running means 'currently executing a {@link PipelineStep}'.
129
+	 *           See the {@link PipelineControllerTask} class for why this is important.
130
+	 * - SHA:    This is the Git SHA that the pipeline is acting on. This is passed into the {@link PipelineStep}
131
+	 *           objects so that the steps know what to smoketest, deploy, etc.
132
+	 *
133
+	 * @var array
134
+	 */
135
+	private static $db = array(
136
+		'Status' => 'Enum("Running,Complete,Failed,Aborted,Rollback,Queued", "Queued")',
137
+		'Config' => 'Text', // serialized array of configuration for this pipeline
138
+		'SHA' => 'Varchar(255)',
139
+		'DryRun' => 'Boolean', // Try if this deployment is a test dryrun
140
+		'LastMessageSent' => 'Varchar(255)' // ID of last message sent
141
+	);
142
+
143
+	/**
144
+	 * - Author:      The {@link Member} object that started this pipeline running.
145
+	 * - Environment: The {@link DNEnvironment} that this Pipeline is associated to.
146
+	 * - CurrentStep: The current {@link PipelineStep} object that is keeping this pipeline alive. This should be
147
+	 *                cleared when the last step is complete.
148
+	 *
149
+	 * @var array
150
+	 */
151
+	private static $has_one = array(
152
+		'Author' => 'Member',
153
+		'Environment' => 'DNEnvironment',
154
+		'CurrentStep' => 'PipelineStep',
155
+		// to be used for rollbacks
156
+		"PreviousSnapshot" => "DNDataTransfer",
157
+		"PreviousDeployment" => 'DNDeployment',
158
+		"CurrentDeployment" => "DNDeployment",
159
+		"RollbackStep1" => "PipelineStep",
160
+		"RollbackStep2" => "PipelineStep"
161
+	);
162
+
163
+	/**
164
+	 * - Steps: These are ordered by the `PipelineStep`.`Order` attribute.
165
+	 *
166
+	 * @var array
167
+	 */
168
+	private static $has_many = array(
169
+		'Steps' => 'PipelineStep'
170
+	);
171
+
172
+	/**
173
+	 * @var array
174
+	 */
175
+	private static $summary_fields = array(
176
+		'ID' => 'ID',
177
+		'Status' => 'Status',
178
+		'SHA' => 'SHA',
179
+		'Author.Title' => 'Author',
180
+		'CurrentStep.Name' => 'Current Step',
181
+		'Created' => 'Created',
182
+		'LastEdited' => 'Last Updated'
183
+	);
184
+
185
+	/**
186
+	 * @var string
187
+	 */
188
+	private static $default_sort = '"Created" DESC';
189
+
190
+	/**
191
+	 * @var array
192
+	 */
193
+	private static $cast = array(
194
+		'RunningDescription' => 'HTMLText'
195
+	);
196
+
197
+	/**
198
+	 * @config
199
+	 * @var array
200
+	 */
201
+	private static $dependencies = array(
202
+		'MessagingService' => '%$ConfirmationMessagingService'
203
+	);
204
+
205
+	/**
206
+	 * Currently assigned messaging service
207
+	 *
208
+	 * @var ConfirmationMessagingService
209
+	 */
210
+	private $messagingService = null;
211
+
212
+	/**
213
+	 * @param ConfirmationMessagingService $service
214
+	 */
215
+	public function setMessagingService(ConfirmationMessagingService $service)
216
+	{
217
+		$this->messagingService = $service;
218
+	}
219
+
220
+	/**
221
+	 * @return ConfirmationMessagingService
222
+	 */
223
+	public function getMessagingService()
224
+	{
225
+		return $this->messagingService;
226
+	}
227
+
228
+	public function __isset($property)
229
+	{
230
+		// Workaround fixed in https://github.com/silverstripe/silverstripe-framework/pull/3201
231
+		// Remove this once we update to a version of framework which supports this
232
+		if ($property === 'MessagingService') {
233
+			return !empty($this->messagingService);
234
+		}
235
+		return parent::__isset($property);
236
+	}
237
+
238
+	/**
239
+	 * Retrieve message template replacements
240
+	 *
241
+	 * @return array
242
+	 */
243
+	public function getReplacements()
244
+	{
245
+		// Get member who began this request
246
+		$author = $this->Author();
247
+		$environment = $this->Environment();
248
+		return array(
249
+			'<abortlink>' => Director::absoluteURL($this->Environment()->Link()),
250
+			'<pipelinelink>' => Director::absoluteURL($this->Link()),
251
+			'<requester>' => $author->Title,
252
+			'<requester-email>' => $author->Email,
253
+			'<environment>' => $environment->Name,
254
+			'<project>' => $environment->Project()->Name,
255
+			'<commitsha>' => $this->SHA
256
+		);
257
+	}
258
+
259
+	/**
260
+	 * Title of this step
261
+	 *
262
+	 * @return string
263
+	 */
264
+	public function getTitle()
265
+	{
266
+		return "Pipeline {$this->ID} (Status: {$this->Status})";
267
+	}
268
+
269
+	/**
270
+	 * @param Member $member
271
+	 */
272
+	public function canAbort($member = null)
273
+	{
274
+		// Owner can abort
275
+		$member = $member ?: Member::currentUser();
276
+		if (!$member) {
277
+			return false;
278
+		}
279
+		if ($member->ID == $this->AuthorID) {
280
+			return true;
281
+		}
282
+
283
+		// Check environment permission
284
+		return $this->Environment()->canAbort($member);
285
+	}
286
+
287
+	/**
288
+	 * Get status of currently running step
289
+	 *
290
+	 * @return string Status description (html format)
291
+	 */
292
+	public function getRunningDescription()
293
+	{
294
+		if (!$this->isActive()) {
295
+			return 'This pipeline is not currently running';
296
+		}
297
+		$result = '';
298
+		if ($step = $this->CurrentStep()) {
299
+			$result = $step->getRunningDescription();
300
+		}
301
+		return $result ?: 'This pipeline is currently running';
302
+	}
303
+
304
+	/**
305
+	 * Get options for the currently running pipeline, if and only if it is currently running
306
+	 *
307
+	 * @return ArrayList List of items with a Link and Title attribute
308
+	 */
309
+	public function RunningOptions()
310
+	{
311
+		if (!$this->isActive()) {
312
+			return null;
313
+		}
314
+		$actions = array();
315
+
316
+		// Let current step update the current list of options
317
+		if (($step = $this->CurrentStep()) && ($step->isRunning())) {
318
+			$actions = $step->allowedActions();
319
+		}
320
+		return new ArrayList($actions);
321
+	}
322
+
323
+	/**
324
+	 * Get possible logs for the currently pipeline
325
+	 *
326
+	 * @return ArrayList List of logs with a Link and Title attribute
327
+	 */
328
+	public function LogOptions()
329
+	{
330
+		if (!$this->isActive()) {
331
+			return null;
332
+		}
333
+
334
+		$logs = array();
335
+
336
+		$logs[] = array(
337
+			'ButtonText' => 'Pipeline Log',
338
+			'Link' => $this->Link()
339
+		);
340
+
341
+		if ($this->PreviousSnapshotID > 0) {
342
+			$logs[] = array(
343
+				'ButtonText' => 'Snapshot Log',
344
+				'Link' => $this->PreviousSnapshot()->Link()
345
+			);
346
+		}
347
+
348
+		if ($this->CurrentDeploymentID > 0) {
349
+			$logs[] = array(
350
+				'ButtonText' => 'Deployment Log',
351
+				'Link' => $this->CurrentDeployment()->Link()
352
+			);
353
+		}
354
+
355
+		// Get logs from rollback steps (only for RollbackSteps).
356
+		$rollbackSteps = array($this->RollbackStep1(), $this->RollbackStep2());
357
+		foreach ($rollbackSteps as $rollback) {
358
+			if ($rollback->exists() && $rollback->ClassName == 'RollbackStep') {
359
+				if ($rollback->RollbackDeploymentID > 0) {
360
+					$logs[] = array(
361
+						'ButtonText' => 'Rollback Log',
362
+						'Link' => $rollback->RollbackDeployment()->Link()
363
+					);
364
+				}
365
+
366
+				if ($rollback->RollbackDatabaseID > 0) {
367
+					$logs[] = array(
368
+						'ButtonText' => 'Rollback DB Log',
369
+						'Link' => $rollback->RollbackDatabase()->Link()
370
+					);
371
+				}
372
+			}
373
+		}
374
+
375
+		return new ArrayList($logs);
376
+	}
377
+
378
+	/**
379
+	 * Cached of config merged with defaults
380
+	 *
381
+	 * @var array|null
382
+	 */
383
+	protected $mergedConfig;
384
+
385
+	/**
386
+	 * Get this pipeline configuration. If the configuration has been serialized
387
+	 * and saved into the Config field, it'll use that. If that field is empty,
388
+	 * it'll read the YAML file directly and return that instead.
389
+	 *
390
+	 * @return array
391
+	 * @throws Exception
392
+	 */
393
+	public function getConfigData()
394
+	{
395
+		// Lazy load if necessary
396
+		$data = null;
397
+		if (!$this->Config && ($data = $this->Environment()->loadPipelineConfig())) {
398
+			$this->Config = serialize($data);
399
+		}
400
+
401
+		// Merge with defaults
402
+		if ($this->Config) {
403
+			if (!$this->mergedConfig) {
404
+				$this->mergedConfig = $data ?: unserialize($this->Config);
405
+				if ($default = self::config()->default_config) {
406
+					Config::merge_array_low_into_high($this->mergedConfig, $default);
407
+				}
408
+			}
409
+			return $this->mergedConfig;
410
+		}
411
+
412
+		// Fail if no data available
413
+		$path = $this->Environment()->getPipelineFilename();
414
+		throw new Exception(sprintf('YAML configuration for pipeline not found at path "%s"', $path));
415
+	}
416
+
417
+	public function setConfig($data)
418
+	{
419
+		$this->mergedConfig = null;
420
+		return parent::setField('Config', $data);
421
+	}
422
+
423
+	/**
424
+	 * Retrieve the value of a specific config setting
425
+	 *
426
+	 * @param string $setting Settings
427
+	 * @return mixed Value of setting, or null if not set
428
+	 */
429
+	public function getConfigSetting($setting)
430
+	{
431
+		$source = $this->getConfigData();
432
+
433
+		foreach (func_get_args() as $setting) {
434
+			if (empty($source[$setting])) {
435
+				return null;
436
+			}
437
+			$source = $source[$setting];
438
+		}
439
+
440
+		return $source;
441
+	}
442
+
443
+	/**
444
+	 * @return FieldList
445
+	 */
446
+	public function getCMSFields()
447
+	{
448
+		$fields = new FieldList(new TabSet('Root'));
449
+
450
+		// Main fields
451
+		$fields->addFieldsToTab('Root.Main', array(
452
+			TextField::create('SHA')
453
+				->setDescription('SHA of the commit this pipeline is running against')
454
+				->performReadonlyTransformation(),
455
+			TextField::create('AuthorName', 'Author', ($author = $this->Author()) ? $author->Title : null)
456
+				->setDescription('Person who initiated this pipeline')
457
+				->performReadonlyTransformation(),
458
+			DropdownField::create('Status', 'Status', $this->dbObject('Status')->enumValues()),
459
+			DropdownField::create('CurrentStepID', 'Current Step', $this->Steps()->map('ID', 'TreeTitle')),
460
+			TextField::create(
461
+				'CurrentDeployment_Label',
462
+				'Current Deployment',
463
+				$this->CurrentDeployment()->getTitle()
464
+			)    ->setDescription('Deployment generated by this pipeline')
465
+				->performReadonlyTransformation(),
466
+		));
467
+
468
+		// Backup fields
469
+		$fields->addFieldsToTab('Root.Backups', array(
470
+			TextField::create(
471
+				'PreviousDeployment_Label',
472
+				'Previous Deployment',
473
+				$this->PreviousDeployment()->getTitle()
474
+			)    ->setDescription('Prior deployment to revert to if this pipeline fails')
475
+				->performReadonlyTransformation(),
476
+			TextField::create(
477
+				'PreviousSnapshot_Label',
478
+				'Previous DB Snapshot',
479
+				$this->PreviousSnapshot()->getTitle()
480
+			)    ->setDescription('Database backup to revert to if this pipeline fails')
481
+				->performReadonlyTransformation()
482
+		));
483
+
484
+		if ($log = $this->LogContent()) {
485
+			$fields->addFieldToTab(
486
+				'Root.Main',
487
+				ToggleCompositeField::create(
488
+					'PipelineLog',
489
+					'Pipeline Log',
490
+					LiteralField::create('LogText', nl2br(Convert::raw2xml($log)))
491
+				)
492
+			);
493
+		}
494
+
495
+		// Steps
496
+		$stepConfig = GridFieldConfig_RecordEditor::create();
497
+		$steps = GridField::create('Steps', 'Pipeline Steps', $this->Steps(), $stepConfig);
498
+		$fields->addFieldsToTab('Root.PipelineSteps', $steps);
499
+
500
+		return $fields;
501
+	}
502
+
503
+	/**
504
+	 * Return a dependent {@link DNEnvironment} based on this pipeline's dependent environment configuration.
505
+	 *
506
+	 * @return DNEnvironment
507
+	 */
508
+	public function getDependentEnvironment()
509
+	{
510
+		// dependent environment not available
511
+		$projectName = $this->getConfigSetting('PipelineConfig', 'DependsOnProject');
512
+		$environmentName = $this->getConfigSetting('PipelineConfig', 'DependsOnEnvironment');
513
+		if (empty($projectName) || empty($environmentName)) {
514
+			return null;
515
+		}
516
+
517
+		$project = DNProject::get()->filter('Name', $projectName)->first();
518
+		if (!($project && $project->exists())) {
519
+			throw new Exception(sprintf('Could not find dependent project "%s"', $projectName));
520
+		}
521
+
522
+		$environment = DNEnvironment::get()->filter(array(
523
+			'ProjectID' => $project->ID,
524
+			'Name' => $environmentName
525
+		))->first();
526
+
527
+		if (!($environment && $environment->exists())) {
528
+			throw new Exception(sprintf(
529
+				'Could not find dependent environment "%s" in project "%s"',
530
+				$environmentName,
531
+				$projectName
532
+			));
533
+		}
534
+
535
+		return $environment;
536
+	}
537
+
538
+	/**
539
+	 * Generate a step from a name, config, and sort order
540
+	 *
541
+	 * @throws Exception
542
+	 * @param string $name
543
+	 * @param array $stepConfig
544
+	 * @param int $order
545
+	 * @return PipelineStep
546
+	 */
547
+	protected function generateStep($name, $stepConfig, $order = 0)
548
+	{
549
+		$stepClass = isset($stepConfig['Class']) ? $stepConfig['Class'] : $stepConfig;
550
+
551
+		if (empty($stepClass)) {
552
+			throw new Exception(
553
+				sprintf('Missing or empty Class specifier for step "%s"', $name)
554
+			);
555
+		}
556
+
557
+		if (!is_subclass_of($stepClass, 'PipelineStep')) {
558
+			throw new Exception(
559
+				sprintf('%s is not a valid "Class" field name for step "%s"', var_export($stepClass, true), $name)
560
+			);
561
+		}
562
+
563
+		$step = $stepClass::create();
564
+		$step->Name = $name;
565
+		$step->PipelineID = $this->ID;
566
+		$step->Order = $order;
567
+		$step->Status = 'Queued';
568
+		$step->Config = serialize($stepConfig);
569
+		$step->write();
570
+
571
+		return $step;
572
+	}
573
+
574
+	/**
575
+	 * Starts the pipeline process.
576
+	 *
577
+	 * Reads a YAML configuration from the linked {@link DNEnvironment}
578
+	 * and builds the {@link PipelineStep} objects and runs them.
579
+	 *
580
+	 * Note that this method doesn't actually start any {@link PipelineStep} objects, that is handled by
581
+	 * {@link self::checkPipelineStatus()}, and the daemon running the process.
582
+	 *
583
+	 * @throws LogicException
584
+	 * @return boolean
585
+	 */
586
+	public function start()
587
+	{
588
+		// Ensure there are no other running {@link Pipeline} objects for this {@link DNEnvironment}
589
+		// Requires that $this->EnvironmentID has been set
590
+		$env = $this->Environment();
591
+		if (!($env && $env->exists())) {
592
+			throw new LogicException("This pipeline needs a valid environment to run on.");
593
+		}
594
+
595
+		if ($env->HasCurrentPipeline()) {
596
+			throw new LogicException("You can only run one pipeline at a time on this environment.");
597
+		}
598
+
599
+		$this->write(); // ensure we've written this record first
600
+
601
+		// Instantiate steps.
602
+		foreach ($this->getConfigSetting('Steps') as $name => $stepConfig) {
603
+			$this->pushPipelineStep($name, $stepConfig);
604
+		}
605
+
606
+		$this->Status = 'Running';
607
+		$this->write();
608
+
609
+		$this->log('Started logging for this pipeline!');
610
+
611
+		return true;
612
+	}
613
+
614
+	/**
615
+	 * Mark this Pipeline as completed.
616
+	 */
617
+	public function markComplete()
618
+	{
619
+		$this->Status = "Complete";
620
+		$this->log("Pipeline completed successfully.");
621
+		$this->write();
622
+		// Some steps may pre-emptively send a success message before the pipeline itself has completed
623
+		if ($this->LastMessageSent !== self::ALERT_SUCCESS) {
624
+			$this->sendMessage(self::ALERT_SUCCESS);
625
+		}
626
+	}
627
+
628
+	/**
629
+	 * @return bool true if this Pipeline has successfully completed all {@link PipelineStep} steps already.
630
+	 */
631
+	public function isComplete()
632
+	{
633
+		return $this->Status == "Complete";
634
+	}
635
+
636
+	/**
637
+	 * True if the pipeline is running but NOT doing a rollback
638
+	 *
639
+	 * @return bool
640
+	 */
641
+	public function isRunning()
642
+	{
643
+		return $this->Status == "Running";
644
+	}
645
+
646
+	/**
647
+	 * True if the pipeline is running or doing a rollback
648
+	 *
649
+	 * @return bool
650
+	 */
651
+	public function isActive()
652
+	{
653
+		return $this->isRunning() || $this->isRollback();
654
+	}
655
+
656
+	/**
657
+	 * Push a step to the end of a pipeline
658
+	 *
659
+	 * @param string $name
660
+	 * @param array $stepConfig
661
+	 * @return PipelineStep
662
+	 */
663
+	private function pushPipelineStep($name, $stepConfig)
664
+	{
665
+		$lastStep = $this->Steps()->sort("Order DESC")->first();
666
+		$order = $lastStep ? $lastStep->Order + 1 : 1;
667
+		return $this->generateStep($name, $stepConfig, $order);
668
+	}
669
+
670
+	/**
671
+	 * The rollback has finished - close the pipeline and send relevant messages.
672
+	 */
673
+	protected function finaliseRollback()
674
+	{
675
+
676
+		// Figure out the status by inspecting specific rollback steps.
677
+		$success = true;
678
+		$rollback1 = $this->RollbackStep1();
679
+		$rollback2 = $this->RollbackStep2();
680
+		if (!empty($rollback1) && $rollback1->Status == 'Failed') {
681
+			$success = false;
682
+		}
683
+		if (!empty($rollback2) && $rollback2->Status == 'Failed') {
684
+			$success = false;
685
+		}
686
+
687
+		// Send messages.
688
+		if ($success) {
689
+			$this->log("Pipeline failed, but rollback completed successfully.");
690
+			$this->sendMessage(self::ALERT_ROLLBACK_SUCCESS);
691
+		} else {
692
+			$this->log("Pipeline failed, rollback failed.");
693
+			$this->sendMessage(self::ALERT_ROLLBACK_FAILURE);
694
+		}
695
+
696
+		// Finish off the pipeline - rollback will only be triggered on a failed pipeline.
697
+		$this->Status = 'Failed';
698
+		$this->write();
699
+	}
700
+
701
+	/**
702
+	 * Initiate a rollback. Moves the pipeline to the 'Rollback' status.
703
+	 */
704
+	protected function beginRollback()
705
+	{
706
+		$this->log("Beginning rollback...");
707
+		$this->sendMessage(self::ALERT_ROLLBACK_STARTED);
708
+
709
+		// Add rollback step.
710
+		$configRollback1 = $this->getConfigSetting('RollbackStep1');
711
+		$stepRollback1 = $this->pushPipelineStep('RollbackStep1', $configRollback1);
712
+		$this->RollbackStep1ID = $stepRollback1->ID;
713
+		$this->CurrentStepID = $stepRollback1->ID;
714
+		$this->Status = 'Rollback';
715
+
716
+		// Add smoke test step, if available, for later processing.
717
+		$configRollback2 = $this->getConfigSetting('RollbackStep2');
718
+		if ($configRollback2) {
719
+			$stepRollback2 = $this->pushPipelineStep('RollbackStep2', $configRollback2);
720
+			$this->RollbackStep2ID = $stepRollback2->ID;
721
+		}
722
+
723
+		$this->write();
724
+
725
+		$stepRollback1->start();
726
+	}
727
+
728
+	/**
729
+	 * Check if pipeline currently permits a rollback.
730
+	 * This could be influenced by both the current state and by the specific configuration.
731
+	 *
732
+	 * @return boolean
733
+	 */
734
+	protected function canStartRollback()
735
+	{
736
+		// The rollback cannot run twice.
737
+		if ($this->isRollback()) {
738
+			return false;
739
+		}
740
+
741
+		// Rollbacks must be configured.
742
+		if (!$this->getConfigSetting('RollbackStep1')) {
743
+			return false;
744
+		}
745
+
746
+		// On dryrun let rollback run
747
+		if ($this->DryRun) {
748
+			return true;
749
+		}
750
+
751
+		// Pipeline must have ran a deployment to be able to rollback.
752
+		$deploy = $this->CurrentDeployment();
753
+		$previous = $this->PreviousDeployment();
754
+		if (!$deploy->exists() || !$previous->exists()) {
755
+			return false;
756
+		}
757
+
758
+		return true;
759
+	}
760
+
761
+	/**
762
+	 * Notify Pipeline that a step has failed and failure processing should kick in. If rollback steps are present
763
+	 * the pipeline will be put into 'Rollback' state. After rollback is complete, regardless of the rollback result,
764
+	 * the pipeline will be failed.
765
+	 *
766
+	 * @param bool $notify Set to false to disable notifications for this failure
767
+	 */
768
+	public function markFailed($notify = true)
769
+	{
770
+		// Abort all running or queued steps.
771
+		$steps = $this->Steps();
772
+		foreach ($steps as $step) {
773
+			if ($step->isQueued() || $step->isRunning()) {
774
+				$step->abort();
775
+			}
776
+		}
777
+
778
+		if ($this->canStartRollback()) {
779
+			$this->beginRollback();
780
+		} elseif ($this->isRollback()) {
781
+			$this->finaliseRollback();
782
+		} else {
783
+			// Not able to roll back - fail immediately.
784
+			$this->Status = 'Failed';
785
+			$this->log("Pipeline failed, not running rollback (not configured or not applicable yet).");
786
+			$this->write();
787
+			if ($notify) {
788
+				$this->sendMessage(self::ALERT_FAILURE);
789
+			}
790
+		}
791
+	}
792
+
793
+	/**
794
+	 * @return bool true if this Pipeline failed to execute all {@link PipelineStep} steps successfully
795
+	 */
796
+	public function isFailed()
797
+	{
798
+		return $this->Status == "Failed";
799
+	}
800
+
801
+	/**
802
+	 * @return bool true if this Pipeline is rolling back.
803
+	 */
804
+	public function isRollback()
805
+	{
806
+		return $this->Status == "Rollback";
807
+	}
808
+
809
+	/**
810
+	 * Mark this Pipeline as aborted
811
+	 */
812
+	public function markAborted()
813
+	{
814
+		$this->Status = 'Aborted';
815
+		$logMessage = sprintf(
816
+			"Pipeline processing aborted. %s (%s) aborted the pipeline",
817
+			Member::currentUser()->Name,
818
+			Member::currentUser()->Email
819
+		);
820
+		$this->log($logMessage);
821
+		$this->write();
822
+
823
+		// Abort all running or queued steps.
824
+		$steps = $this->Steps();
825
+		foreach ($steps as $step) {
826
+			if ($step->isQueued() || $step->isRunning()) {
827
+				$step->abort();
828
+			}
829
+		}
830
+
831
+		// Send notification to users about this event
832
+		$this->sendMessage(self::ALERT_ABORT);
833
+	}
834
+
835
+	/**
836
+	 * Finds a message template for a given role and message
837
+	 *
838
+	 * @param string $messageID Message ID
839
+	 * @return array Resulting array(subject, message)
840
+	 */
841
+	protected function generateMessageTemplate($messageID)
842
+	{
843
+		$subject = $this->getConfigSetting('PipelineConfig', 'Subjects', $messageID);
844
+		$message = $this->getConfigSetting('PipelineConfig', 'Messages', $messageID);
845
+		$substitutions = $this->getReplacements();
846
+		return $this->injectMessageReplacements($message, $subject, $substitutions);
847
+	}
848
+
849
+	/**
850
+	 * Substitute templated variables into the given message and subject
851
+	 *
852
+	 * @param string $message
853
+	 * @param string $subject
854
+	 * @param array $substitutions
855
+	 * @return array Resulting array(subject, message)
856
+	 */
857
+	public function injectMessageReplacements($message, $subject, $substitutions)
858
+	{
859
+		// Handle empty messages
860
+		if (empty($subject) && empty($message)) {
861
+			return array(null, null);
862
+		}
863
+
864
+		// Check if there's a role specific message
865
+		$subjectText = str_replace(
866
+			array_keys($substitutions),
867
+			array_values($substitutions),
868
+			$subject ?: $message
869
+		);
870
+		$messageText = str_replace(
871
+			array_keys($substitutions),
872
+			array_values($substitutions),
873
+			$message ?: $subject
874
+		);
875
+
876
+
877
+		return array($subjectText, $messageText);
878
+	}
879
+
880
+	/**
881
+	 * Sends a specific message to all marked recipients, including the author of this pipeline
882
+	 *
883
+	 * @param string $messageID Message ID. One of 'Abort', 'Success', or 'Failure', or some custom message
884
+	 * @return boolean|null True if successful
885
+	 */
886
+	public function sendMessage($messageID)
887
+	{
888
+		// Check message, subject, and additional arguments to include
889
+		list($subject, $message) = $this->generateMessageTemplate($messageID);
890
+		if (empty($subject) || empty($message)) {
891
+			$this->log("Skipping sending message. None configured for $messageID");
892
+			return true;
893
+		}
894
+
895
+		// Save last sent message
896
+		$this->LastMessageSent = $messageID;
897
+		$this->write();
898
+
899
+		// Setup messaging arguments
900
+		$arguments = array_merge(
901
+			$this->getConfigSetting('PipelineConfig', 'ServiceArguments') ?: array(),
902
+			array('subject' => $subject)
903
+		);
904
+
905
+		// Send message to author
906
+		if ($author = $this->Author()) {
907
+			$this->log("Pipeline sending $messageID message to {$author->Email}");
908
+			$this->messagingService->sendMessage($this, $message, $author, $arguments);
909
+		} else {
910
+			$this->log("Skipping sending message to missing author");
911
+		}
912
+
913
+		// Get additional recipients
914
+		$recipients = $this->getConfigSetting('PipelineConfig', 'Recipients', $messageID);
915
+		if (empty($recipients)) {
916
+			$this->log("Skipping sending message to empty recipients");
917
+		} else {
918
+			$recipientsStr = is_array($recipients) ? implode(',', $recipients) : $recipients;
919
+			$this->log("Pipeline sending $messageID message to $recipientsStr");
920
+			$this->messagingService->sendMessage($this, $message, $recipients, $arguments);
921
+		}
922
+	}
923
+
924
+	/**
925
+	 * @return bool true if this Pipeline has been aborted
926
+	 */
927
+	public function isAborted()
928
+	{
929
+		return $this->Status === "Aborted";
930
+	}
931
+
932
+	/**
933
+	 * This method should be called only by the {@link CheckPipelineStatus} controller. It iterates through all the
934
+	 * {@link PipelineStep} objects associated with this Pipeline, and finds a place where the pipeline has stalled
935
+	 * (where one step has completed, but the next one has yet to start). It will then start the next step if required.
936
+	 *
937
+	 * We check here whether the {@link PipelineStep} finished successfully, and will mark the Pipeline as Failed if
938
+	 * the step failed, but this is only a fallback, and should not be relied upon. The individual {@link PipelineStep}
939
+	 * should mark itself as failed and then call {@link Pipeline::markFailed()} directly.
940
+	 *
941
+	 * If the Pipeline has run out of steps, then it will mark the pipeline as completed.
942
+	 */
943
+	public function checkPipelineStatus()
944
+	{
945
+		$message = "";
946
+
947
+		if (!$this->isActive()) {
948
+			$message = "Pipeline::checkPipelineStatus() should only be called on running or rolling back pipelines.";
949
+		}
950
+
951
+		if (!$this->ID || !$this->isInDB()) {
952
+			$message = "Pipeline::checkPipelineStatus() can only be called on pipelines already saved.";
953
+		}
954
+
955
+		$currentStep = ($this->CurrentStep() && $this->CurrentStep()->isInDB())
956
+			? $this->CurrentStep()
957
+			: null;
958
+
959
+		if ($currentStep && $currentStep->PipelineID != $this->ID) {
960
+			$message = sprintf(
961
+				"The current step (#%d) has a pipeline ID (#%d) that doesn't match this pipeline's ID (#%d).",
962
+				$currentStep->ID,
963
+				$currentStep->PipelineID,
964
+				$this->ID
965
+			);
966
+		}
967
+
968
+		if ($message) {
969
+			$this->log($message);
970
+			throw new LogicException($message);
971
+		}
972
+
973
+		// Fallback check only: this shouldn't be called unless a {@link PipelineStep} has been implemented incorrectly
974
+		if ($currentStep && $currentStep->isFailed() && !$this->isFailed() && !$this->isRollback()) {
975
+			$this->log(sprintf("Marking pipeline step (#%d) as failed - this pipeline step needs to be amended to mark"
976
+				. " the pipeline (as well as itself) as failed to ensure consistency.",
977
+				$this->CurrentStep()->ID
978
+			));
979
+
980
+			$this->markFailed();
981
+			return;
982
+		}
983
+
984
+		// If this is the first time the Pipeline is run, then we don't have a CurrentStep, so set it,
985
+		// start it running, and return
986
+		if (!$currentStep) {
987
+			$step = $this->Steps()->first();
988
+			$this->CurrentStepID = $step->ID;
989
+			$this->write();
990
+
991
+			$this->log("Starting first pipeline step...");
992
+			$step->start();
993
+		} elseif ($currentStep->isFinished()) {
994
+			// Sort through the list of {@link PipelineStep} objects to find the next step we need to start.
995
+			$this->log("Finding next step to execute...");
996
+			$nextStep = $this->findNextStep();
997
+
998
+			if (!$nextStep) {
999
+
1000
+				// Special handling, since the main pipeline has already failed at this stage.
1001
+				if ($this->isRollback()) {
1002
+					$this->finaliseRollback();
1003
+					return false;
1004
+				}
1005
+
1006
+				// Double check for any steps that failed, but didn't notify the pipeline via markFailed.
1007
+				$failedSteps = PipelineStep::get()->filter(array(
1008
+					'PipelineID' => $this->ID,
1009
+					'Status' => 'Failed'
1010
+				))->count();
1011
+				if ($failedSteps) {
1012
+					$this->log('At least one of the steps has failed marking the pipeline as failed');
1013
+					$this->markFailed();
1014
+					return false;
1015
+				}
1016
+
1017
+				// We've reached the end of this pipeline successfully!
1018
+				$this->markComplete();
1019
+				return;
1020
+			} else {
1021
+				$this->CurrentStepID = $nextStep->ID;
1022
+				$this->write();
1023
+				// Otherwise, kick off the next step
1024
+				$this->log(sprintf("Found the next step (#%s), starting it now...", $nextStep->Name));
1025
+				$nextStep->start();
1026
+			}
1027
+		// if the current step is failing run it again
1028
+		} elseif ($step = $this->CurrentStep()) {
1029
+			$step->start();
1030
+		}
1031
+	}
1032
+
1033
+	/**
1034
+	 * Finds the next {@link PipelineStep} that needs to execute. Relies on $this->CurrentStep() being a valid step.
1035
+	 *
1036
+	 * @return DataObject|null The next step in the pipeline, or null if none remain.
1037
+	 */
1038
+	protected function findNextStep()
1039
+	{
1040
+		// otherwise get next step in chain
1041
+		$currentStep = $this->CurrentStep();
1042
+
1043
+		return $this
1044
+			->Steps()
1045
+			->filter("Status", "Queued")
1046
+			->filter("Order:GreaterThanOrEqual", $currentStep->Order)
1047
+			->exclude("ID", $currentStep->ID)
1048
+			->sort("Order ASC")
1049
+			->first();
1050
+	}
1051
+
1052
+	/**
1053
+	 * Finds the previous {@link PipelineStep} that executed. Relies on $this->CurrentStep() being a valid step.
1054
+	 *
1055
+	 * @return DataObject|null The previous step in the pipeline, or null if this is the first.
1056
+	 */
1057
+	public function findPreviousStep()
1058
+	{
1059
+		// otherwise get previous step in chain
1060
+		$currentStep = $this->CurrentStep();
1061
+
1062
+		return $this
1063
+			->Steps()
1064
+			->filter("Status", "Finished")
1065
+			->filter("Order:LessThanOrEqual", $currentStep->Order)
1066
+			->exclude("ID", $currentStep->ID)
1067
+			->sort("Order DESC")
1068
+			->first();
1069
+	}
1070
+
1071
+	/**
1072
+	 * Write to a common log file. This log file will be the same regardless of how often this pipeline is re-created
1073
+	 * from the database. To this end, it needs to know the database ID of this pipeline instance, so that it can
1074
+	 * generate the correct filename to open.
1075
+	 *
1076
+	 * This also includes the calling class and method name that called ->log() in the first place, so we can trace
1077
+	 * back where it was written from.
1078
+	 *
1079
+	 * @param string $message The message to log
1080
+	 * @throws LogicException Thrown if we can't log yet because we don't know what to log to (no db record yet).
1081
+	 */
1082
+	public function log($message = "")
1083
+	{
1084
+		$log = $this->getLogger();
1085
+
1086
+		// Taken from Debug::caller(), amended for our purposes to filter out the intermediate call to
1087
+		// PipelineStep->log(), so that our log message shows where the log message was actually created from.
1088
+		$bt = debug_backtrace();
1089
+
1090
+		$index = ($bt[1]['class'] == 'PipelineStep') ? 2 : 1;
1091
+
1092
+		$caller = $bt[$index];
1093
+		$caller['line'] = $bt[($index - 1)]['line']; // Overwrite line and file to be the the line/file that actually
1094
+		$caller['file'] = $bt[($index - 1)]['file']; // called the function, not where the function is defined.
1095
+		// In case it wasn't called from a class
1096
+		if (!isset($caller['class'])) {
1097
+			$caller['class'] = '';
1098
+		}
1099
+		// In case it doesn't have a type (wasn't called from class)
1100
+		if (!isset($caller['type'])) {
1101
+			$caller['type'] = '';
1102
+		}
1103
+
1104
+		$log->write(sprintf(
1105
+			"[%s::%s() (line %d)] %s",
1106
+			$caller['class'],
1107
+			$caller['function'],
1108
+			$caller['line'],
1109
+			$message
1110
+		));
1111
+	}
1112
+
1113
+	/**
1114
+	 * Returns the {@link DeploynautLogFile} instance that will actually write to this log file.
1115
+	 *
1116
+	 * @return DeploynautLogFile
1117
+	 * @throws RuntimeException
1118
+	 */
1119
+	public function getLogger()
1120
+	{
1121
+		if (!$this->isInDB()) {
1122
+			throw new RuntimeException("Can't write to a log file until we know the database ID.");
1123
+		}
1124
+
1125
+		if (!$this->Environment()) {
1126
+			throw new RuntimeException("Can't write to a log file until we have an Environment.");
1127
+		}
1128
+
1129
+		if ($this->Environment() && !$this->Environment()->Project()) {
1130
+			throw new RuntimeException("Can't write to a log file until we have the Environment's project.");
1131
+		}
1132
+
1133
+		$environment = $this->Environment();
1134
+		$filename = sprintf('%s.pipeline.%d.log', $environment->getFullName('.'), $this->ID);
1135
+
1136
+		return Injector::inst()->createWithArgs('DeploynautLogFile', array($filename));
1137
+	}
1138
+
1139
+	/**
1140
+	 * @return bool
1141
+	 */
1142
+	public function getDryRun()
1143
+	{
1144
+		return $this->getField('DryRun');
1145
+	}
1146
+
1147
+	/**
1148
+	 * @param string|null $action
1149
+	 *
1150
+	 * @return string
1151
+	 */
1152
+	public function Link($action = null)
1153
+	{
1154
+		return Controller::join_links($this->Environment()->Link(), 'pipeline', $this->ID, $action);
1155
+	}
1156
+
1157
+	/**
1158
+	 * Link to an action on the current step
1159
+	 *
1160
+	 * @param string|null $action
1161
+	 * @return string
1162
+	 */
1163
+	public function StepLink($action = null)
1164
+	{
1165
+		return Controller::join_links($this->Link('step'), $action);
1166
+	}
1167
+
1168
+	/**
1169
+	 * @return string
1170
+	 */
1171
+	public function AbortLink()
1172
+	{
1173
+		return $this->Link('abort');
1174
+	}
1175
+
1176
+	/**
1177
+	 * @return string
1178
+	 */
1179
+	public function LogLink()
1180
+	{
1181
+		return $this->Link('log');
1182
+	}
1183
+
1184
+	/**
1185
+	 * @return string
1186
+	 */
1187
+	public function LogContent()
1188
+	{
1189
+		if ($this->exists() && $this->Environment()) {
1190
+			$logger = $this->getLogger();
1191
+			if ($logger->exists()) {
1192
+				return $logger->content();
1193
+			}
1194
+		}
1195
+	}
1196 1196
 }
Please login to merge, or discard this patch.
Spacing   +67 added lines, -67 removed lines patch added patch discarded remove patch
@@ -229,7 +229,7 @@  discard block
 block discarded – undo
229 229
     {
230 230
         // Workaround fixed in https://github.com/silverstripe/silverstripe-framework/pull/3201
231 231
         // Remove this once we update to a version of framework which supports this
232
-        if ($property === 'MessagingService') {
232
+        if($property === 'MessagingService') {
233 233
             return !empty($this->messagingService);
234 234
         }
235 235
         return parent::__isset($property);
@@ -273,10 +273,10 @@  discard block
 block discarded – undo
273 273
     {
274 274
         // Owner can abort
275 275
         $member = $member ?: Member::currentUser();
276
-        if (!$member) {
276
+        if(!$member) {
277 277
             return false;
278 278
         }
279
-        if ($member->ID == $this->AuthorID) {
279
+        if($member->ID == $this->AuthorID) {
280 280
             return true;
281 281
         }
282 282
 
@@ -291,11 +291,11 @@  discard block
 block discarded – undo
291 291
      */
292 292
     public function getRunningDescription()
293 293
     {
294
-        if (!$this->isActive()) {
294
+        if(!$this->isActive()) {
295 295
             return 'This pipeline is not currently running';
296 296
         }
297 297
         $result = '';
298
-        if ($step = $this->CurrentStep()) {
298
+        if($step = $this->CurrentStep()) {
299 299
             $result = $step->getRunningDescription();
300 300
         }
301 301
         return $result ?: 'This pipeline is currently running';
@@ -308,13 +308,13 @@  discard block
 block discarded – undo
308 308
      */
309 309
     public function RunningOptions()
310 310
     {
311
-        if (!$this->isActive()) {
311
+        if(!$this->isActive()) {
312 312
             return null;
313 313
         }
314 314
         $actions = array();
315 315
 
316 316
         // Let current step update the current list of options
317
-        if (($step = $this->CurrentStep()) && ($step->isRunning())) {
317
+        if(($step = $this->CurrentStep()) && ($step->isRunning())) {
318 318
             $actions = $step->allowedActions();
319 319
         }
320 320
         return new ArrayList($actions);
@@ -327,7 +327,7 @@  discard block
 block discarded – undo
327 327
      */
328 328
     public function LogOptions()
329 329
     {
330
-        if (!$this->isActive()) {
330
+        if(!$this->isActive()) {
331 331
             return null;
332 332
         }
333 333
 
@@ -338,14 +338,14 @@  discard block
 block discarded – undo
338 338
             'Link' => $this->Link()
339 339
         );
340 340
 
341
-        if ($this->PreviousSnapshotID > 0) {
341
+        if($this->PreviousSnapshotID > 0) {
342 342
             $logs[] = array(
343 343
                 'ButtonText' => 'Snapshot Log',
344 344
                 'Link' => $this->PreviousSnapshot()->Link()
345 345
             );
346 346
         }
347 347
 
348
-        if ($this->CurrentDeploymentID > 0) {
348
+        if($this->CurrentDeploymentID > 0) {
349 349
             $logs[] = array(
350 350
                 'ButtonText' => 'Deployment Log',
351 351
                 'Link' => $this->CurrentDeployment()->Link()
@@ -354,16 +354,16 @@  discard block
 block discarded – undo
354 354
 
355 355
         // Get logs from rollback steps (only for RollbackSteps).
356 356
         $rollbackSteps = array($this->RollbackStep1(), $this->RollbackStep2());
357
-        foreach ($rollbackSteps as $rollback) {
358
-            if ($rollback->exists() && $rollback->ClassName == 'RollbackStep') {
359
-                if ($rollback->RollbackDeploymentID > 0) {
357
+        foreach($rollbackSteps as $rollback) {
358
+            if($rollback->exists() && $rollback->ClassName == 'RollbackStep') {
359
+                if($rollback->RollbackDeploymentID > 0) {
360 360
                     $logs[] = array(
361 361
                         'ButtonText' => 'Rollback Log',
362 362
                         'Link' => $rollback->RollbackDeployment()->Link()
363 363
                     );
364 364
                 }
365 365
 
366
-                if ($rollback->RollbackDatabaseID > 0) {
366
+                if($rollback->RollbackDatabaseID > 0) {
367 367
                     $logs[] = array(
368 368
                         'ButtonText' => 'Rollback DB Log',
369 369
                         'Link' => $rollback->RollbackDatabase()->Link()
@@ -394,15 +394,15 @@  discard block
 block discarded – undo
394 394
     {
395 395
         // Lazy load if necessary
396 396
         $data = null;
397
-        if (!$this->Config && ($data = $this->Environment()->loadPipelineConfig())) {
397
+        if(!$this->Config && ($data = $this->Environment()->loadPipelineConfig())) {
398 398
             $this->Config = serialize($data);
399 399
         }
400 400
 
401 401
         // Merge with defaults
402
-        if ($this->Config) {
403
-            if (!$this->mergedConfig) {
402
+        if($this->Config) {
403
+            if(!$this->mergedConfig) {
404 404
                 $this->mergedConfig = $data ?: unserialize($this->Config);
405
-                if ($default = self::config()->default_config) {
405
+                if($default = self::config()->default_config) {
406 406
                     Config::merge_array_low_into_high($this->mergedConfig, $default);
407 407
                 }
408 408
             }
@@ -430,8 +430,8 @@  discard block
 block discarded – undo
430 430
     {
431 431
         $source = $this->getConfigData();
432 432
 
433
-        foreach (func_get_args() as $setting) {
434
-            if (empty($source[$setting])) {
433
+        foreach(func_get_args() as $setting) {
434
+            if(empty($source[$setting])) {
435 435
                 return null;
436 436
             }
437 437
             $source = $source[$setting];
@@ -481,7 +481,7 @@  discard block
 block discarded – undo
481 481
                 ->performReadonlyTransformation()
482 482
         ));
483 483
 
484
-        if ($log = $this->LogContent()) {
484
+        if($log = $this->LogContent()) {
485 485
             $fields->addFieldToTab(
486 486
                 'Root.Main',
487 487
                 ToggleCompositeField::create(
@@ -510,12 +510,12 @@  discard block
 block discarded – undo
510 510
         // dependent environment not available
511 511
         $projectName = $this->getConfigSetting('PipelineConfig', 'DependsOnProject');
512 512
         $environmentName = $this->getConfigSetting('PipelineConfig', 'DependsOnEnvironment');
513
-        if (empty($projectName) || empty($environmentName)) {
513
+        if(empty($projectName) || empty($environmentName)) {
514 514
             return null;
515 515
         }
516 516
 
517 517
         $project = DNProject::get()->filter('Name', $projectName)->first();
518
-        if (!($project && $project->exists())) {
518
+        if(!($project && $project->exists())) {
519 519
             throw new Exception(sprintf('Could not find dependent project "%s"', $projectName));
520 520
         }
521 521
 
@@ -524,7 +524,7 @@  discard block
 block discarded – undo
524 524
             'Name' => $environmentName
525 525
         ))->first();
526 526
 
527
-        if (!($environment && $environment->exists())) {
527
+        if(!($environment && $environment->exists())) {
528 528
             throw new Exception(sprintf(
529 529
                 'Could not find dependent environment "%s" in project "%s"',
530 530
                 $environmentName,
@@ -548,13 +548,13 @@  discard block
 block discarded – undo
548 548
     {
549 549
         $stepClass = isset($stepConfig['Class']) ? $stepConfig['Class'] : $stepConfig;
550 550
 
551
-        if (empty($stepClass)) {
551
+        if(empty($stepClass)) {
552 552
             throw new Exception(
553 553
                 sprintf('Missing or empty Class specifier for step "%s"', $name)
554 554
             );
555 555
         }
556 556
 
557
-        if (!is_subclass_of($stepClass, 'PipelineStep')) {
557
+        if(!is_subclass_of($stepClass, 'PipelineStep')) {
558 558
             throw new Exception(
559 559
                 sprintf('%s is not a valid "Class" field name for step "%s"', var_export($stepClass, true), $name)
560 560
             );
@@ -588,18 +588,18 @@  discard block
 block discarded – undo
588 588
         // Ensure there are no other running {@link Pipeline} objects for this {@link DNEnvironment}
589 589
         // Requires that $this->EnvironmentID has been set
590 590
         $env = $this->Environment();
591
-        if (!($env && $env->exists())) {
591
+        if(!($env && $env->exists())) {
592 592
             throw new LogicException("This pipeline needs a valid environment to run on.");
593 593
         }
594 594
 
595
-        if ($env->HasCurrentPipeline()) {
595
+        if($env->HasCurrentPipeline()) {
596 596
             throw new LogicException("You can only run one pipeline at a time on this environment.");
597 597
         }
598 598
 
599 599
         $this->write(); // ensure we've written this record first
600 600
 
601 601
         // Instantiate steps.
602
-        foreach ($this->getConfigSetting('Steps') as $name => $stepConfig) {
602
+        foreach($this->getConfigSetting('Steps') as $name => $stepConfig) {
603 603
             $this->pushPipelineStep($name, $stepConfig);
604 604
         }
605 605
 
@@ -620,7 +620,7 @@  discard block
 block discarded – undo
620 620
         $this->log("Pipeline completed successfully.");
621 621
         $this->write();
622 622
         // Some steps may pre-emptively send a success message before the pipeline itself has completed
623
-        if ($this->LastMessageSent !== self::ALERT_SUCCESS) {
623
+        if($this->LastMessageSent !== self::ALERT_SUCCESS) {
624 624
             $this->sendMessage(self::ALERT_SUCCESS);
625 625
         }
626 626
     }
@@ -677,15 +677,15 @@  discard block
 block discarded – undo
677 677
         $success = true;
678 678
         $rollback1 = $this->RollbackStep1();
679 679
         $rollback2 = $this->RollbackStep2();
680
-        if (!empty($rollback1) && $rollback1->Status == 'Failed') {
680
+        if(!empty($rollback1) && $rollback1->Status == 'Failed') {
681 681
             $success = false;
682 682
         }
683
-        if (!empty($rollback2) && $rollback2->Status == 'Failed') {
683
+        if(!empty($rollback2) && $rollback2->Status == 'Failed') {
684 684
             $success = false;
685 685
         }
686 686
 
687 687
         // Send messages.
688
-        if ($success) {
688
+        if($success) {
689 689
             $this->log("Pipeline failed, but rollback completed successfully.");
690 690
             $this->sendMessage(self::ALERT_ROLLBACK_SUCCESS);
691 691
         } else {
@@ -715,7 +715,7 @@  discard block
 block discarded – undo
715 715
 
716 716
         // Add smoke test step, if available, for later processing.
717 717
         $configRollback2 = $this->getConfigSetting('RollbackStep2');
718
-        if ($configRollback2) {
718
+        if($configRollback2) {
719 719
             $stepRollback2 = $this->pushPipelineStep('RollbackStep2', $configRollback2);
720 720
             $this->RollbackStep2ID = $stepRollback2->ID;
721 721
         }
@@ -734,24 +734,24 @@  discard block
 block discarded – undo
734 734
     protected function canStartRollback()
735 735
     {
736 736
         // The rollback cannot run twice.
737
-        if ($this->isRollback()) {
737
+        if($this->isRollback()) {
738 738
             return false;
739 739
         }
740 740
 
741 741
         // Rollbacks must be configured.
742
-        if (!$this->getConfigSetting('RollbackStep1')) {
742
+        if(!$this->getConfigSetting('RollbackStep1')) {
743 743
             return false;
744 744
         }
745 745
 
746 746
         // On dryrun let rollback run
747
-        if ($this->DryRun) {
747
+        if($this->DryRun) {
748 748
             return true;
749 749
         }
750 750
 
751 751
         // Pipeline must have ran a deployment to be able to rollback.
752 752
         $deploy = $this->CurrentDeployment();
753 753
         $previous = $this->PreviousDeployment();
754
-        if (!$deploy->exists() || !$previous->exists()) {
754
+        if(!$deploy->exists() || !$previous->exists()) {
755 755
             return false;
756 756
         }
757 757
 
@@ -769,22 +769,22 @@  discard block
 block discarded – undo
769 769
     {
770 770
         // Abort all running or queued steps.
771 771
         $steps = $this->Steps();
772
-        foreach ($steps as $step) {
773
-            if ($step->isQueued() || $step->isRunning()) {
772
+        foreach($steps as $step) {
773
+            if($step->isQueued() || $step->isRunning()) {
774 774
                 $step->abort();
775 775
             }
776 776
         }
777 777
 
778
-        if ($this->canStartRollback()) {
778
+        if($this->canStartRollback()) {
779 779
             $this->beginRollback();
780
-        } elseif ($this->isRollback()) {
780
+        } elseif($this->isRollback()) {
781 781
             $this->finaliseRollback();
782 782
         } else {
783 783
             // Not able to roll back - fail immediately.
784 784
             $this->Status = 'Failed';
785 785
             $this->log("Pipeline failed, not running rollback (not configured or not applicable yet).");
786 786
             $this->write();
787
-            if ($notify) {
787
+            if($notify) {
788 788
                 $this->sendMessage(self::ALERT_FAILURE);
789 789
             }
790 790
         }
@@ -822,8 +822,8 @@  discard block
 block discarded – undo
822 822
 
823 823
         // Abort all running or queued steps.
824 824
         $steps = $this->Steps();
825
-        foreach ($steps as $step) {
826
-            if ($step->isQueued() || $step->isRunning()) {
825
+        foreach($steps as $step) {
826
+            if($step->isQueued() || $step->isRunning()) {
827 827
                 $step->abort();
828 828
             }
829 829
         }
@@ -857,7 +857,7 @@  discard block
 block discarded – undo
857 857
     public function injectMessageReplacements($message, $subject, $substitutions)
858 858
     {
859 859
         // Handle empty messages
860
-        if (empty($subject) && empty($message)) {
860
+        if(empty($subject) && empty($message)) {
861 861
             return array(null, null);
862 862
         }
863 863
 
@@ -887,7 +887,7 @@  discard block
 block discarded – undo
887 887
     {
888 888
         // Check message, subject, and additional arguments to include
889 889
         list($subject, $message) = $this->generateMessageTemplate($messageID);
890
-        if (empty($subject) || empty($message)) {
890
+        if(empty($subject) || empty($message)) {
891 891
             $this->log("Skipping sending message. None configured for $messageID");
892 892
             return true;
893 893
         }
@@ -903,7 +903,7 @@  discard block
 block discarded – undo
903 903
         );
904 904
 
905 905
         // Send message to author
906
-        if ($author = $this->Author()) {
906
+        if($author = $this->Author()) {
907 907
             $this->log("Pipeline sending $messageID message to {$author->Email}");
908 908
             $this->messagingService->sendMessage($this, $message, $author, $arguments);
909 909
         } else {
@@ -912,7 +912,7 @@  discard block
 block discarded – undo
912 912
 
913 913
         // Get additional recipients
914 914
         $recipients = $this->getConfigSetting('PipelineConfig', 'Recipients', $messageID);
915
-        if (empty($recipients)) {
915
+        if(empty($recipients)) {
916 916
             $this->log("Skipping sending message to empty recipients");
917 917
         } else {
918 918
             $recipientsStr = is_array($recipients) ? implode(',', $recipients) : $recipients;
@@ -944,11 +944,11 @@  discard block
 block discarded – undo
944 944
     {
945 945
         $message = "";
946 946
 
947
-        if (!$this->isActive()) {
947
+        if(!$this->isActive()) {
948 948
             $message = "Pipeline::checkPipelineStatus() should only be called on running or rolling back pipelines.";
949 949
         }
950 950
 
951
-        if (!$this->ID || !$this->isInDB()) {
951
+        if(!$this->ID || !$this->isInDB()) {
952 952
             $message = "Pipeline::checkPipelineStatus() can only be called on pipelines already saved.";
953 953
         }
954 954
 
@@ -956,7 +956,7 @@  discard block
 block discarded – undo
956 956
             ? $this->CurrentStep()
957 957
             : null;
958 958
 
959
-        if ($currentStep && $currentStep->PipelineID != $this->ID) {
959
+        if($currentStep && $currentStep->PipelineID != $this->ID) {
960 960
             $message = sprintf(
961 961
                 "The current step (#%d) has a pipeline ID (#%d) that doesn't match this pipeline's ID (#%d).",
962 962
                 $currentStep->ID,
@@ -965,13 +965,13 @@  discard block
 block discarded – undo
965 965
             );
966 966
         }
967 967
 
968
-        if ($message) {
968
+        if($message) {
969 969
             $this->log($message);
970 970
             throw new LogicException($message);
971 971
         }
972 972
 
973 973
         // Fallback check only: this shouldn't be called unless a {@link PipelineStep} has been implemented incorrectly
974
-        if ($currentStep && $currentStep->isFailed() && !$this->isFailed() && !$this->isRollback()) {
974
+        if($currentStep && $currentStep->isFailed() && !$this->isFailed() && !$this->isRollback()) {
975 975
             $this->log(sprintf("Marking pipeline step (#%d) as failed - this pipeline step needs to be amended to mark"
976 976
                 . " the pipeline (as well as itself) as failed to ensure consistency.",
977 977
                 $this->CurrentStep()->ID
@@ -983,22 +983,22 @@  discard block
 block discarded – undo
983 983
 
984 984
         // If this is the first time the Pipeline is run, then we don't have a CurrentStep, so set it,
985 985
         // start it running, and return
986
-        if (!$currentStep) {
986
+        if(!$currentStep) {
987 987
             $step = $this->Steps()->first();
988 988
             $this->CurrentStepID = $step->ID;
989 989
             $this->write();
990 990
 
991 991
             $this->log("Starting first pipeline step...");
992 992
             $step->start();
993
-        } elseif ($currentStep->isFinished()) {
993
+        } elseif($currentStep->isFinished()) {
994 994
             // Sort through the list of {@link PipelineStep} objects to find the next step we need to start.
995 995
             $this->log("Finding next step to execute...");
996 996
             $nextStep = $this->findNextStep();
997 997
 
998
-            if (!$nextStep) {
998
+            if(!$nextStep) {
999 999
 
1000 1000
                 // Special handling, since the main pipeline has already failed at this stage.
1001
-                if ($this->isRollback()) {
1001
+                if($this->isRollback()) {
1002 1002
                     $this->finaliseRollback();
1003 1003
                     return false;
1004 1004
                 }
@@ -1008,7 +1008,7 @@  discard block
 block discarded – undo
1008 1008
                     'PipelineID' => $this->ID,
1009 1009
                     'Status' => 'Failed'
1010 1010
                 ))->count();
1011
-                if ($failedSteps) {
1011
+                if($failedSteps) {
1012 1012
                     $this->log('At least one of the steps has failed marking the pipeline as failed');
1013 1013
                     $this->markFailed();
1014 1014
                     return false;
@@ -1025,7 +1025,7 @@  discard block
 block discarded – undo
1025 1025
                 $nextStep->start();
1026 1026
             }
1027 1027
         // if the current step is failing run it again
1028
-        } elseif ($step = $this->CurrentStep()) {
1028
+        } elseif($step = $this->CurrentStep()) {
1029 1029
             $step->start();
1030 1030
         }
1031 1031
     }
@@ -1093,11 +1093,11 @@  discard block
 block discarded – undo
1093 1093
         $caller['line'] = $bt[($index - 1)]['line']; // Overwrite line and file to be the the line/file that actually
1094 1094
         $caller['file'] = $bt[($index - 1)]['file']; // called the function, not where the function is defined.
1095 1095
         // In case it wasn't called from a class
1096
-        if (!isset($caller['class'])) {
1096
+        if(!isset($caller['class'])) {
1097 1097
             $caller['class'] = '';
1098 1098
         }
1099 1099
         // In case it doesn't have a type (wasn't called from class)
1100
-        if (!isset($caller['type'])) {
1100
+        if(!isset($caller['type'])) {
1101 1101
             $caller['type'] = '';
1102 1102
         }
1103 1103
 
@@ -1118,15 +1118,15 @@  discard block
 block discarded – undo
1118 1118
      */
1119 1119
     public function getLogger()
1120 1120
     {
1121
-        if (!$this->isInDB()) {
1121
+        if(!$this->isInDB()) {
1122 1122
             throw new RuntimeException("Can't write to a log file until we know the database ID.");
1123 1123
         }
1124 1124
 
1125
-        if (!$this->Environment()) {
1125
+        if(!$this->Environment()) {
1126 1126
             throw new RuntimeException("Can't write to a log file until we have an Environment.");
1127 1127
         }
1128 1128
 
1129
-        if ($this->Environment() && !$this->Environment()->Project()) {
1129
+        if($this->Environment() && !$this->Environment()->Project()) {
1130 1130
             throw new RuntimeException("Can't write to a log file until we have the Environment's project.");
1131 1131
         }
1132 1132
 
@@ -1186,9 +1186,9 @@  discard block
 block discarded – undo
1186 1186
      */
1187 1187
     public function LogContent()
1188 1188
     {
1189
-        if ($this->exists() && $this->Environment()) {
1189
+        if($this->exists() && $this->Environment()) {
1190 1190
             $logger = $this->getLogger();
1191
-            if ($logger->exists()) {
1191
+            if($logger->exists()) {
1192 1192
                 return $logger->content();
1193 1193
             }
1194 1194
         }
Please login to merge, or discard this patch.
Braces   +44 added lines, -88 removed lines patch added patch discarded remove patch
@@ -111,8 +111,7 @@  discard block
 block discarded – undo
111 111
  *
112 112
  * @method HasManyList Steps()
113 113
  */
114
-class Pipeline extends DataObject implements PipelineData
115
-{
114
+class Pipeline extends DataObject implements PipelineData {
116 115
 
117 116
     /**
118 117
      * Messages
@@ -212,21 +211,18 @@  discard block
 block discarded – undo
212 211
     /**
213 212
      * @param ConfirmationMessagingService $service
214 213
      */
215
-    public function setMessagingService(ConfirmationMessagingService $service)
216
-    {
214
+    public function setMessagingService(ConfirmationMessagingService $service) {
217 215
         $this->messagingService = $service;
218 216
     }
219 217
 
220 218
     /**
221 219
      * @return ConfirmationMessagingService
222 220
      */
223
-    public function getMessagingService()
224
-    {
221
+    public function getMessagingService() {
225 222
         return $this->messagingService;
226 223
     }
227 224
 
228
-    public function __isset($property)
229
-    {
225
+    public function __isset($property) {
230 226
         // Workaround fixed in https://github.com/silverstripe/silverstripe-framework/pull/3201
231 227
         // Remove this once we update to a version of framework which supports this
232 228
         if ($property === 'MessagingService') {
@@ -240,8 +236,7 @@  discard block
 block discarded – undo
240 236
      *
241 237
      * @return array
242 238
      */
243
-    public function getReplacements()
244
-    {
239
+    public function getReplacements() {
245 240
         // Get member who began this request
246 241
         $author = $this->Author();
247 242
         $environment = $this->Environment();
@@ -261,16 +256,14 @@  discard block
 block discarded – undo
261 256
      *
262 257
      * @return string
263 258
      */
264
-    public function getTitle()
265
-    {
259
+    public function getTitle() {
266 260
         return "Pipeline {$this->ID} (Status: {$this->Status})";
267 261
     }
268 262
 
269 263
     /**
270 264
      * @param Member $member
271 265
      */
272
-    public function canAbort($member = null)
273
-    {
266
+    public function canAbort($member = null) {
274 267
         // Owner can abort
275 268
         $member = $member ?: Member::currentUser();
276 269
         if (!$member) {
@@ -289,8 +282,7 @@  discard block
 block discarded – undo
289 282
      *
290 283
      * @return string Status description (html format)
291 284
      */
292
-    public function getRunningDescription()
293
-    {
285
+    public function getRunningDescription() {
294 286
         if (!$this->isActive()) {
295 287
             return 'This pipeline is not currently running';
296 288
         }
@@ -306,8 +298,7 @@  discard block
 block discarded – undo
306 298
      *
307 299
      * @return ArrayList List of items with a Link and Title attribute
308 300
      */
309
-    public function RunningOptions()
310
-    {
301
+    public function RunningOptions() {
311 302
         if (!$this->isActive()) {
312 303
             return null;
313 304
         }
@@ -325,8 +316,7 @@  discard block
 block discarded – undo
325 316
      *
326 317
      * @return ArrayList List of logs with a Link and Title attribute
327 318
      */
328
-    public function LogOptions()
329
-    {
319
+    public function LogOptions() {
330 320
         if (!$this->isActive()) {
331 321
             return null;
332 322
         }
@@ -390,8 +380,7 @@  discard block
 block discarded – undo
390 380
      * @return array
391 381
      * @throws Exception
392 382
      */
393
-    public function getConfigData()
394
-    {
383
+    public function getConfigData() {
395 384
         // Lazy load if necessary
396 385
         $data = null;
397 386
         if (!$this->Config && ($data = $this->Environment()->loadPipelineConfig())) {
@@ -414,8 +403,7 @@  discard block
 block discarded – undo
414 403
         throw new Exception(sprintf('YAML configuration for pipeline not found at path "%s"', $path));
415 404
     }
416 405
 
417
-    public function setConfig($data)
418
-    {
406
+    public function setConfig($data) {
419 407
         $this->mergedConfig = null;
420 408
         return parent::setField('Config', $data);
421 409
     }
@@ -426,8 +414,7 @@  discard block
 block discarded – undo
426 414
      * @param string $setting Settings
427 415
      * @return mixed Value of setting, or null if not set
428 416
      */
429
-    public function getConfigSetting($setting)
430
-    {
417
+    public function getConfigSetting($setting) {
431 418
         $source = $this->getConfigData();
432 419
 
433 420
         foreach (func_get_args() as $setting) {
@@ -443,8 +430,7 @@  discard block
 block discarded – undo
443 430
     /**
444 431
      * @return FieldList
445 432
      */
446
-    public function getCMSFields()
447
-    {
433
+    public function getCMSFields() {
448 434
         $fields = new FieldList(new TabSet('Root'));
449 435
 
450 436
         // Main fields
@@ -505,8 +491,7 @@  discard block
 block discarded – undo
505 491
      *
506 492
      * @return DNEnvironment
507 493
      */
508
-    public function getDependentEnvironment()
509
-    {
494
+    public function getDependentEnvironment() {
510 495
         // dependent environment not available
511 496
         $projectName = $this->getConfigSetting('PipelineConfig', 'DependsOnProject');
512 497
         $environmentName = $this->getConfigSetting('PipelineConfig', 'DependsOnEnvironment');
@@ -544,8 +529,7 @@  discard block
 block discarded – undo
544 529
      * @param int $order
545 530
      * @return PipelineStep
546 531
      */
547
-    protected function generateStep($name, $stepConfig, $order = 0)
548
-    {
532
+    protected function generateStep($name, $stepConfig, $order = 0) {
549 533
         $stepClass = isset($stepConfig['Class']) ? $stepConfig['Class'] : $stepConfig;
550 534
 
551 535
         if (empty($stepClass)) {
@@ -583,8 +567,7 @@  discard block
 block discarded – undo
583 567
      * @throws LogicException
584 568
      * @return boolean
585 569
      */
586
-    public function start()
587
-    {
570
+    public function start() {
588 571
         // Ensure there are no other running {@link Pipeline} objects for this {@link DNEnvironment}
589 572
         // Requires that $this->EnvironmentID has been set
590 573
         $env = $this->Environment();
@@ -614,8 +597,7 @@  discard block
 block discarded – undo
614 597
     /**
615 598
      * Mark this Pipeline as completed.
616 599
      */
617
-    public function markComplete()
618
-    {
600
+    public function markComplete() {
619 601
         $this->Status = "Complete";
620 602
         $this->log("Pipeline completed successfully.");
621 603
         $this->write();
@@ -628,8 +610,7 @@  discard block
 block discarded – undo
628 610
     /**
629 611
      * @return bool true if this Pipeline has successfully completed all {@link PipelineStep} steps already.
630 612
      */
631
-    public function isComplete()
632
-    {
613
+    public function isComplete() {
633 614
         return $this->Status == "Complete";
634 615
     }
635 616
 
@@ -638,8 +619,7 @@  discard block
 block discarded – undo
638 619
      *
639 620
      * @return bool
640 621
      */
641
-    public function isRunning()
642
-    {
622
+    public function isRunning() {
643 623
         return $this->Status == "Running";
644 624
     }
645 625
 
@@ -648,8 +628,7 @@  discard block
 block discarded – undo
648 628
      *
649 629
      * @return bool
650 630
      */
651
-    public function isActive()
652
-    {
631
+    public function isActive() {
653 632
         return $this->isRunning() || $this->isRollback();
654 633
     }
655 634
 
@@ -660,8 +639,7 @@  discard block
 block discarded – undo
660 639
      * @param array $stepConfig
661 640
      * @return PipelineStep
662 641
      */
663
-    private function pushPipelineStep($name, $stepConfig)
664
-    {
642
+    private function pushPipelineStep($name, $stepConfig) {
665 643
         $lastStep = $this->Steps()->sort("Order DESC")->first();
666 644
         $order = $lastStep ? $lastStep->Order + 1 : 1;
667 645
         return $this->generateStep($name, $stepConfig, $order);
@@ -670,8 +648,7 @@  discard block
 block discarded – undo
670 648
     /**
671 649
      * The rollback has finished - close the pipeline and send relevant messages.
672 650
      */
673
-    protected function finaliseRollback()
674
-    {
651
+    protected function finaliseRollback() {
675 652
 
676 653
         // Figure out the status by inspecting specific rollback steps.
677 654
         $success = true;
@@ -701,8 +678,7 @@  discard block
 block discarded – undo
701 678
     /**
702 679
      * Initiate a rollback. Moves the pipeline to the 'Rollback' status.
703 680
      */
704
-    protected function beginRollback()
705
-    {
681
+    protected function beginRollback() {
706 682
         $this->log("Beginning rollback...");
707 683
         $this->sendMessage(self::ALERT_ROLLBACK_STARTED);
708 684
 
@@ -731,8 +707,7 @@  discard block
 block discarded – undo
731 707
      *
732 708
      * @return boolean
733 709
      */
734
-    protected function canStartRollback()
735
-    {
710
+    protected function canStartRollback() {
736 711
         // The rollback cannot run twice.
737 712
         if ($this->isRollback()) {
738 713
             return false;
@@ -765,8 +740,7 @@  discard block
 block discarded – undo
765 740
      *
766 741
      * @param bool $notify Set to false to disable notifications for this failure
767 742
      */
768
-    public function markFailed($notify = true)
769
-    {
743
+    public function markFailed($notify = true) {
770 744
         // Abort all running or queued steps.
771 745
         $steps = $this->Steps();
772 746
         foreach ($steps as $step) {
@@ -793,24 +767,21 @@  discard block
 block discarded – undo
793 767
     /**
794 768
      * @return bool true if this Pipeline failed to execute all {@link PipelineStep} steps successfully
795 769
      */
796
-    public function isFailed()
797
-    {
770
+    public function isFailed() {
798 771
         return $this->Status == "Failed";
799 772
     }
800 773
 
801 774
     /**
802 775
      * @return bool true if this Pipeline is rolling back.
803 776
      */
804
-    public function isRollback()
805
-    {
777
+    public function isRollback() {
806 778
         return $this->Status == "Rollback";
807 779
     }
808 780
 
809 781
     /**
810 782
      * Mark this Pipeline as aborted
811 783
      */
812
-    public function markAborted()
813
-    {
784
+    public function markAborted() {
814 785
         $this->Status = 'Aborted';
815 786
         $logMessage = sprintf(
816 787
             "Pipeline processing aborted. %s (%s) aborted the pipeline",
@@ -838,8 +809,7 @@  discard block
 block discarded – undo
838 809
      * @param string $messageID Message ID
839 810
      * @return array Resulting array(subject, message)
840 811
      */
841
-    protected function generateMessageTemplate($messageID)
842
-    {
812
+    protected function generateMessageTemplate($messageID) {
843 813
         $subject = $this->getConfigSetting('PipelineConfig', 'Subjects', $messageID);
844 814
         $message = $this->getConfigSetting('PipelineConfig', 'Messages', $messageID);
845 815
         $substitutions = $this->getReplacements();
@@ -854,8 +824,7 @@  discard block
 block discarded – undo
854 824
      * @param array $substitutions
855 825
      * @return array Resulting array(subject, message)
856 826
      */
857
-    public function injectMessageReplacements($message, $subject, $substitutions)
858
-    {
827
+    public function injectMessageReplacements($message, $subject, $substitutions) {
859 828
         // Handle empty messages
860 829
         if (empty($subject) && empty($message)) {
861 830
             return array(null, null);
@@ -883,8 +852,7 @@  discard block
 block discarded – undo
883 852
      * @param string $messageID Message ID. One of 'Abort', 'Success', or 'Failure', or some custom message
884 853
      * @return boolean|null True if successful
885 854
      */
886
-    public function sendMessage($messageID)
887
-    {
855
+    public function sendMessage($messageID) {
888 856
         // Check message, subject, and additional arguments to include
889 857
         list($subject, $message) = $this->generateMessageTemplate($messageID);
890 858
         if (empty($subject) || empty($message)) {
@@ -924,8 +892,7 @@  discard block
 block discarded – undo
924 892
     /**
925 893
      * @return bool true if this Pipeline has been aborted
926 894
      */
927
-    public function isAborted()
928
-    {
895
+    public function isAborted() {
929 896
         return $this->Status === "Aborted";
930 897
     }
931 898
 
@@ -940,8 +907,7 @@  discard block
 block discarded – undo
940 907
      *
941 908
      * If the Pipeline has run out of steps, then it will mark the pipeline as completed.
942 909
      */
943
-    public function checkPipelineStatus()
944
-    {
910
+    public function checkPipelineStatus() {
945 911
         $message = "";
946 912
 
947 913
         if (!$this->isActive()) {
@@ -1035,8 +1001,7 @@  discard block
 block discarded – undo
1035 1001
      *
1036 1002
      * @return DataObject|null The next step in the pipeline, or null if none remain.
1037 1003
      */
1038
-    protected function findNextStep()
1039
-    {
1004
+    protected function findNextStep() {
1040 1005
         // otherwise get next step in chain
1041 1006
         $currentStep = $this->CurrentStep();
1042 1007
 
@@ -1054,8 +1019,7 @@  discard block
 block discarded – undo
1054 1019
      *
1055 1020
      * @return DataObject|null The previous step in the pipeline, or null if this is the first.
1056 1021
      */
1057
-    public function findPreviousStep()
1058
-    {
1022
+    public function findPreviousStep() {
1059 1023
         // otherwise get previous step in chain
1060 1024
         $currentStep = $this->CurrentStep();
1061 1025
 
@@ -1079,8 +1043,7 @@  discard block
 block discarded – undo
1079 1043
      * @param string $message The message to log
1080 1044
      * @throws LogicException Thrown if we can't log yet because we don't know what to log to (no db record yet).
1081 1045
      */
1082
-    public function log($message = "")
1083
-    {
1046
+    public function log($message = "") {
1084 1047
         $log = $this->getLogger();
1085 1048
 
1086 1049
         // Taken from Debug::caller(), amended for our purposes to filter out the intermediate call to
@@ -1116,8 +1079,7 @@  discard block
 block discarded – undo
1116 1079
      * @return DeploynautLogFile
1117 1080
      * @throws RuntimeException
1118 1081
      */
1119
-    public function getLogger()
1120
-    {
1082
+    public function getLogger() {
1121 1083
         if (!$this->isInDB()) {
1122 1084
             throw new RuntimeException("Can't write to a log file until we know the database ID.");
1123 1085
         }
@@ -1139,8 +1101,7 @@  discard block
 block discarded – undo
1139 1101
     /**
1140 1102
      * @return bool
1141 1103
      */
1142
-    public function getDryRun()
1143
-    {
1104
+    public function getDryRun() {
1144 1105
         return $this->getField('DryRun');
1145 1106
     }
1146 1107
 
@@ -1149,8 +1110,7 @@  discard block
 block discarded – undo
1149 1110
      *
1150 1111
      * @return string
1151 1112
      */
1152
-    public function Link($action = null)
1153
-    {
1113
+    public function Link($action = null) {
1154 1114
         return Controller::join_links($this->Environment()->Link(), 'pipeline', $this->ID, $action);
1155 1115
     }
1156 1116
 
@@ -1160,32 +1120,28 @@  discard block
 block discarded – undo
1160 1120
      * @param string|null $action
1161 1121
      * @return string
1162 1122
      */
1163
-    public function StepLink($action = null)
1164
-    {
1123
+    public function StepLink($action = null) {
1165 1124
         return Controller::join_links($this->Link('step'), $action);
1166 1125
     }
1167 1126
 
1168 1127
     /**
1169 1128
      * @return string
1170 1129
      */
1171
-    public function AbortLink()
1172
-    {
1130
+    public function AbortLink() {
1173 1131
         return $this->Link('abort');
1174 1132
     }
1175 1133
 
1176 1134
     /**
1177 1135
      * @return string
1178 1136
      */
1179
-    public function LogLink()
1180
-    {
1137
+    public function LogLink() {
1181 1138
         return $this->Link('log');
1182 1139
     }
1183 1140
 
1184 1141
     /**
1185 1142
      * @return string
1186 1143
      */
1187
-    public function LogContent()
1188
-    {
1144
+    public function LogContent() {
1189 1145
         if ($this->exists() && $this->Environment()) {
1190 1146
             $logger = $this->getLogger();
1191 1147
             if ($logger->exists()) {
Please login to merge, or discard this patch.
Upper-Lower-Casing   +1 added lines, -1 removed lines patch added patch discarded remove patch
@@ -263,7 +263,7 @@
 block discarded – undo
263 263
      */
264 264
     public function getTitle()
265 265
     {
266
-        return "Pipeline {$this->ID} (Status: {$this->Status})";
266
+        return "pipeline {$this->ID} (Status: {$this->Status})";
267 267
     }
268 268
 
269 269
     /**
Please login to merge, or discard this patch.
code/model/PipelineData.php 2 patches
Indentation   +12 added lines, -12 removed lines patch added patch discarded remove patch
@@ -3,17 +3,17 @@
 block discarded – undo
3 3
 interface PipelineData
4 4
 {
5 5
 
6
-    /**
7
-     * Is this a dry run?
8
-     *
9
-     * @return bool
10
-     */
11
-    public function getDryRun();
6
+	/**
7
+	 * Is this a dry run?
8
+	 *
9
+	 * @return bool
10
+	 */
11
+	public function getDryRun();
12 12
 
13
-    /**
14
-     * Log message
15
-     *
16
-     * @param string $message The message to log
17
-     */
18
-    public function log($message);
13
+	/**
14
+	 * Log message
15
+	 *
16
+	 * @param string $message The message to log
17
+	 */
18
+	public function log($message);
19 19
 }
Please login to merge, or discard this patch.
Braces   +1 added lines, -2 removed lines patch added patch discarded remove patch
@@ -1,7 +1,6 @@
 block discarded – undo
1 1
 <?php
2 2
 
3
-interface PipelineData
4
-{
3
+interface PipelineData {
5 4
 
6 5
     /**
7 6
      * Is this a dry run?
Please login to merge, or discard this patch.
code/model/jobs/DNCreateEnvironment.php 3 patches
Indentation   +193 added lines, -193 removed lines patch added patch discarded remove patch
@@ -16,197 +16,197 @@
 block discarded – undo
16 16
 class DNCreateEnvironment extends DataObject
17 17
 {
18 18
 
19
-    /**
20
-     * @var array
21
-     */
22
-    private static $db = array(
23
-        'Data' => 'Text',
24
-        'ResqueToken' => 'Varchar(255)',
25
-        "Status" => "Enum('Queued, Started, Finished, Failed, n/a', 'n/a')",
26
-        'IsInitialEnvironment' => 'Boolean',
27
-    );
28
-
29
-    /**
30
-     * @var array
31
-     */
32
-    private static $has_one = array(
33
-        'Project' => 'DNProject',
34
-        'Creator' => 'Member'
35
-    );
36
-
37
-    /**
38
-     *
39
-     * @param int $int
40
-     * @return string
41
-     */
42
-    public static function map_resque_status($int)
43
-    {
44
-        $remap = array(
45
-            Resque_Job_Status::STATUS_WAITING => "Queued",
46
-            Resque_Job_Status::STATUS_RUNNING => "Running",
47
-            Resque_Job_Status::STATUS_FAILED => "Failed",
48
-            Resque_Job_Status::STATUS_COMPLETE => "Complete",
49
-            false => "Invalid",
50
-        );
51
-        return $remap[$int];
52
-    }
53
-
54
-    /**
55
-     * @return string
56
-     */
57
-    public function Name()
58
-    {
59
-        $data = unserialize($this->Data);
60
-        return !empty($data['Name']) ? Convert::raw2xml($data['Name']) : '';
61
-    }
62
-
63
-    /**
64
-     * @return string
65
-     */
66
-    public function Link()
67
-    {
68
-        return Controller::join_links($this->Project()->Link(), 'createenv', $this->ID);
69
-    }
70
-
71
-    /**
72
-     * @return string
73
-     */
74
-    public function LogLink()
75
-    {
76
-        return $this->Link() . '/log';
77
-    }
78
-
79
-    /**
80
-     * @return boolean
81
-     */
82
-    public function canView($member = null)
83
-    {
84
-        return $this->Project()->canView($member);
85
-    }
86
-
87
-    /**
88
-     * Return a path to the log file.
89
-     * @return string
90
-     */
91
-    protected function logfile()
92
-    {
93
-        return sprintf(
94
-            '%s.createenv.%s.log',
95
-            $this->Project()->Name,
96
-            $this->ID
97
-        );
98
-    }
99
-
100
-    /**
101
-     * @return DeploynautLogFile
102
-     */
103
-    public function log()
104
-    {
105
-        return Injector::inst()->createWithArgs('DeploynautLogFile', array($this->logfile()));
106
-    }
107
-
108
-    public function LogContent()
109
-    {
110
-        return $this->log()->content();
111
-    }
112
-
113
-    /**
114
-     * Returns the status of the resque job
115
-     *
116
-     * @return string
117
-     */
118
-    public function ResqueStatus()
119
-    {
120
-        $status = new Resque_Job_Status($this->ResqueToken);
121
-        $statusCode = $status->get();
122
-        // The Resque job can no longer be found, fallback to the DNDeployment.Status
123
-        if ($statusCode === false) {
124
-            // Translate from the DNDeployment.Status to the Resque job status for UI purposes
125
-            switch ($this->Status) {
126
-                case 'Finished':
127
-                    return 'Complete';
128
-                case 'Started':
129
-                    return 'Running';
130
-                default:
131
-                    return $this->Status;
132
-            }
133
-        }
134
-        return self::map_resque_status($statusCode);
135
-    }
136
-
137
-    /**
138
-     * Start a resque job for this creation.
139
-     *
140
-     * @return string Resque token
141
-     */
142
-    protected function enqueueCreation()
143
-    {
144
-        $project = $this->Project();
145
-        $log = $this->log();
146
-
147
-        $args = array(
148
-            'createID' => $this->ID,
149
-            'logfile' => $this->logfile(),
150
-            'projectName' => $project->Name
151
-        );
152
-
153
-        if (!$this->CreatorID) {
154
-            $this->CreatorID = Member::currentUserID();
155
-        }
156
-
157
-        if ($this->CreatorID) {
158
-            $creator = $this->Creator();
159
-            $message = sprintf(
160
-                'Environment creation for project %s initiated by %s (%s), with IP address %s',
161
-                $project->Name,
162
-                $creator->getName(),
163
-                $creator->Email,
164
-                Controller::curr()->getRequest()->getIP()
165
-            );
166
-            $log->write($message);
167
-        }
168
-
169
-        return Resque::enqueue('create', 'CreateEnvJob', $args, true);
170
-    }
171
-
172
-    public function start()
173
-    {
174
-        $log = $this->log();
175
-        $token = $this->enqueueCreation();
176
-        $this->ResqueToken = $token;
177
-        $this->Status = 'Queued';
178
-        $this->write();
179
-
180
-        $message = sprintf('Environment creation queued as job %s', $token);
181
-        $log->write($message);
182
-    }
183
-
184
-    public function createEnvironment()
185
-    {
186
-        $backend = $this->getBackend();
187
-        if ($backend) {
188
-            return $backend->createEnvironment($this);
189
-        }
190
-        throw new Exception("Unable to find backend.");
191
-    }
192
-
193
-    /**
194
-     * Fetches the EnvironmentCreateBackend based on the EnvironmentType saved to this job.
195
-     *
196
-     * @return EnvironmentCreateBackend|null
197
-     * @throws Exception
198
-     */
199
-    public function getBackend()
200
-    {
201
-        $data = unserialize($this->Data);
202
-        if (isset($data['EnvironmentType']) && class_exists($data['EnvironmentType'])) {
203
-            $env = Injector::inst()->get($data['EnvironmentType']);
204
-            if ($env instanceof EnvironmentCreateBackend) {
205
-                return $env;
206
-            } else {
207
-                throw new Exception("Invalid backend: " . $data['EnvironmentType']);
208
-            }
209
-        }
210
-        return null;
211
-    }
19
+	/**
20
+	 * @var array
21
+	 */
22
+	private static $db = array(
23
+		'Data' => 'Text',
24
+		'ResqueToken' => 'Varchar(255)',
25
+		"Status" => "Enum('Queued, Started, Finished, Failed, n/a', 'n/a')",
26
+		'IsInitialEnvironment' => 'Boolean',
27
+	);
28
+
29
+	/**
30
+	 * @var array
31
+	 */
32
+	private static $has_one = array(
33
+		'Project' => 'DNProject',
34
+		'Creator' => 'Member'
35
+	);
36
+
37
+	/**
38
+	 *
39
+	 * @param int $int
40
+	 * @return string
41
+	 */
42
+	public static function map_resque_status($int)
43
+	{
44
+		$remap = array(
45
+			Resque_Job_Status::STATUS_WAITING => "Queued",
46
+			Resque_Job_Status::STATUS_RUNNING => "Running",
47
+			Resque_Job_Status::STATUS_FAILED => "Failed",
48
+			Resque_Job_Status::STATUS_COMPLETE => "Complete",
49
+			false => "Invalid",
50
+		);
51
+		return $remap[$int];
52
+	}
53
+
54
+	/**
55
+	 * @return string
56
+	 */
57
+	public function Name()
58
+	{
59
+		$data = unserialize($this->Data);
60
+		return !empty($data['Name']) ? Convert::raw2xml($data['Name']) : '';
61
+	}
62
+
63
+	/**
64
+	 * @return string
65
+	 */
66
+	public function Link()
67
+	{
68
+		return Controller::join_links($this->Project()->Link(), 'createenv', $this->ID);
69
+	}
70
+
71
+	/**
72
+	 * @return string
73
+	 */
74
+	public function LogLink()
75
+	{
76
+		return $this->Link() . '/log';
77
+	}
78
+
79
+	/**
80
+	 * @return boolean
81
+	 */
82
+	public function canView($member = null)
83
+	{
84
+		return $this->Project()->canView($member);
85
+	}
86
+
87
+	/**
88
+	 * Return a path to the log file.
89
+	 * @return string
90
+	 */
91
+	protected function logfile()
92
+	{
93
+		return sprintf(
94
+			'%s.createenv.%s.log',
95
+			$this->Project()->Name,
96
+			$this->ID
97
+		);
98
+	}
99
+
100
+	/**
101
+	 * @return DeploynautLogFile
102
+	 */
103
+	public function log()
104
+	{
105
+		return Injector::inst()->createWithArgs('DeploynautLogFile', array($this->logfile()));
106
+	}
107
+
108
+	public function LogContent()
109
+	{
110
+		return $this->log()->content();
111
+	}
112
+
113
+	/**
114
+	 * Returns the status of the resque job
115
+	 *
116
+	 * @return string
117
+	 */
118
+	public function ResqueStatus()
119
+	{
120
+		$status = new Resque_Job_Status($this->ResqueToken);
121
+		$statusCode = $status->get();
122
+		// The Resque job can no longer be found, fallback to the DNDeployment.Status
123
+		if ($statusCode === false) {
124
+			// Translate from the DNDeployment.Status to the Resque job status for UI purposes
125
+			switch ($this->Status) {
126
+				case 'Finished':
127
+					return 'Complete';
128
+				case 'Started':
129
+					return 'Running';
130
+				default:
131
+					return $this->Status;
132
+			}
133
+		}
134
+		return self::map_resque_status($statusCode);
135
+	}
136
+
137
+	/**
138
+	 * Start a resque job for this creation.
139
+	 *
140
+	 * @return string Resque token
141
+	 */
142
+	protected function enqueueCreation()
143
+	{
144
+		$project = $this->Project();
145
+		$log = $this->log();
146
+
147
+		$args = array(
148
+			'createID' => $this->ID,
149
+			'logfile' => $this->logfile(),
150
+			'projectName' => $project->Name
151
+		);
152
+
153
+		if (!$this->CreatorID) {
154
+			$this->CreatorID = Member::currentUserID();
155
+		}
156
+
157
+		if ($this->CreatorID) {
158
+			$creator = $this->Creator();
159
+			$message = sprintf(
160
+				'Environment creation for project %s initiated by %s (%s), with IP address %s',
161
+				$project->Name,
162
+				$creator->getName(),
163
+				$creator->Email,
164
+				Controller::curr()->getRequest()->getIP()
165
+			);
166
+			$log->write($message);
167
+		}
168
+
169
+		return Resque::enqueue('create', 'CreateEnvJob', $args, true);
170
+	}
171
+
172
+	public function start()
173
+	{
174
+		$log = $this->log();
175
+		$token = $this->enqueueCreation();
176
+		$this->ResqueToken = $token;
177
+		$this->Status = 'Queued';
178
+		$this->write();
179
+
180
+		$message = sprintf('Environment creation queued as job %s', $token);
181
+		$log->write($message);
182
+	}
183
+
184
+	public function createEnvironment()
185
+	{
186
+		$backend = $this->getBackend();
187
+		if ($backend) {
188
+			return $backend->createEnvironment($this);
189
+		}
190
+		throw new Exception("Unable to find backend.");
191
+	}
192
+
193
+	/**
194
+	 * Fetches the EnvironmentCreateBackend based on the EnvironmentType saved to this job.
195
+	 *
196
+	 * @return EnvironmentCreateBackend|null
197
+	 * @throws Exception
198
+	 */
199
+	public function getBackend()
200
+	{
201
+		$data = unserialize($this->Data);
202
+		if (isset($data['EnvironmentType']) && class_exists($data['EnvironmentType'])) {
203
+			$env = Injector::inst()->get($data['EnvironmentType']);
204
+			if ($env instanceof EnvironmentCreateBackend) {
205
+				return $env;
206
+			} else {
207
+				throw new Exception("Invalid backend: " . $data['EnvironmentType']);
208
+			}
209
+		}
210
+		return null;
211
+	}
212 212
 }
Please login to merge, or discard this patch.
Spacing   +7 added lines, -7 removed lines patch added patch discarded remove patch
@@ -120,9 +120,9 @@  discard block
 block discarded – undo
120 120
         $status = new Resque_Job_Status($this->ResqueToken);
121 121
         $statusCode = $status->get();
122 122
         // The Resque job can no longer be found, fallback to the DNDeployment.Status
123
-        if ($statusCode === false) {
123
+        if($statusCode === false) {
124 124
             // Translate from the DNDeployment.Status to the Resque job status for UI purposes
125
-            switch ($this->Status) {
125
+            switch($this->Status) {
126 126
                 case 'Finished':
127 127
                     return 'Complete';
128 128
                 case 'Started':
@@ -150,11 +150,11 @@  discard block
 block discarded – undo
150 150
             'projectName' => $project->Name
151 151
         );
152 152
 
153
-        if (!$this->CreatorID) {
153
+        if(!$this->CreatorID) {
154 154
             $this->CreatorID = Member::currentUserID();
155 155
         }
156 156
 
157
-        if ($this->CreatorID) {
157
+        if($this->CreatorID) {
158 158
             $creator = $this->Creator();
159 159
             $message = sprintf(
160 160
                 'Environment creation for project %s initiated by %s (%s), with IP address %s',
@@ -184,7 +184,7 @@  discard block
 block discarded – undo
184 184
     public function createEnvironment()
185 185
     {
186 186
         $backend = $this->getBackend();
187
-        if ($backend) {
187
+        if($backend) {
188 188
             return $backend->createEnvironment($this);
189 189
         }
190 190
         throw new Exception("Unable to find backend.");
@@ -199,9 +199,9 @@  discard block
 block discarded – undo
199 199
     public function getBackend()
200 200
     {
201 201
         $data = unserialize($this->Data);
202
-        if (isset($data['EnvironmentType']) && class_exists($data['EnvironmentType'])) {
202
+        if(isset($data['EnvironmentType']) && class_exists($data['EnvironmentType'])) {
203 203
             $env = Injector::inst()->get($data['EnvironmentType']);
204
-            if ($env instanceof EnvironmentCreateBackend) {
204
+            if($env instanceof EnvironmentCreateBackend) {
205 205
                 return $env;
206 206
             } else {
207 207
                 throw new Exception("Invalid backend: " . $data['EnvironmentType']);
Please login to merge, or discard this patch.
Braces   +14 added lines, -28 removed lines patch added patch discarded remove patch
@@ -13,8 +13,7 @@  discard block
 block discarded – undo
13 13
  * @method Member Creator()
14 14
  * @property int $CreatorID
15 15
  */
16
-class DNCreateEnvironment extends DataObject
17
-{
16
+class DNCreateEnvironment extends DataObject {
18 17
 
19 18
     /**
20 19
      * @var array
@@ -39,8 +38,7 @@  discard block
 block discarded – undo
39 38
      * @param int $int
40 39
      * @return string
41 40
      */
42
-    public static function map_resque_status($int)
43
-    {
41
+    public static function map_resque_status($int) {
44 42
         $remap = array(
45 43
             Resque_Job_Status::STATUS_WAITING => "Queued",
46 44
             Resque_Job_Status::STATUS_RUNNING => "Running",
@@ -54,8 +52,7 @@  discard block
 block discarded – undo
54 52
     /**
55 53
      * @return string
56 54
      */
57
-    public function Name()
58
-    {
55
+    public function Name() {
59 56
         $data = unserialize($this->Data);
60 57
         return !empty($data['Name']) ? Convert::raw2xml($data['Name']) : '';
61 58
     }
@@ -63,24 +60,21 @@  discard block
 block discarded – undo
63 60
     /**
64 61
      * @return string
65 62
      */
66
-    public function Link()
67
-    {
63
+    public function Link() {
68 64
         return Controller::join_links($this->Project()->Link(), 'createenv', $this->ID);
69 65
     }
70 66
 
71 67
     /**
72 68
      * @return string
73 69
      */
74
-    public function LogLink()
75
-    {
70
+    public function LogLink() {
76 71
         return $this->Link() . '/log';
77 72
     }
78 73
 
79 74
     /**
80 75
      * @return boolean
81 76
      */
82
-    public function canView($member = null)
83
-    {
77
+    public function canView($member = null) {
84 78
         return $this->Project()->canView($member);
85 79
     }
86 80
 
@@ -88,8 +82,7 @@  discard block
 block discarded – undo
88 82
      * Return a path to the log file.
89 83
      * @return string
90 84
      */
91
-    protected function logfile()
92
-    {
85
+    protected function logfile() {
93 86
         return sprintf(
94 87
             '%s.createenv.%s.log',
95 88
             $this->Project()->Name,
@@ -100,13 +93,11 @@  discard block
 block discarded – undo
100 93
     /**
101 94
      * @return DeploynautLogFile
102 95
      */
103
-    public function log()
104
-    {
96
+    public function log() {
105 97
         return Injector::inst()->createWithArgs('DeploynautLogFile', array($this->logfile()));
106 98
     }
107 99
 
108
-    public function LogContent()
109
-    {
100
+    public function LogContent() {
110 101
         return $this->log()->content();
111 102
     }
112 103
 
@@ -115,8 +106,7 @@  discard block
 block discarded – undo
115 106
      *
116 107
      * @return string
117 108
      */
118
-    public function ResqueStatus()
119
-    {
109
+    public function ResqueStatus() {
120 110
         $status = new Resque_Job_Status($this->ResqueToken);
121 111
         $statusCode = $status->get();
122 112
         // The Resque job can no longer be found, fallback to the DNDeployment.Status
@@ -139,8 +129,7 @@  discard block
 block discarded – undo
139 129
      *
140 130
      * @return string Resque token
141 131
      */
142
-    protected function enqueueCreation()
143
-    {
132
+    protected function enqueueCreation() {
144 133
         $project = $this->Project();
145 134
         $log = $this->log();
146 135
 
@@ -169,8 +158,7 @@  discard block
 block discarded – undo
169 158
         return Resque::enqueue('create', 'CreateEnvJob', $args, true);
170 159
     }
171 160
 
172
-    public function start()
173
-    {
161
+    public function start() {
174 162
         $log = $this->log();
175 163
         $token = $this->enqueueCreation();
176 164
         $this->ResqueToken = $token;
@@ -181,8 +169,7 @@  discard block
 block discarded – undo
181 169
         $log->write($message);
182 170
     }
183 171
 
184
-    public function createEnvironment()
185
-    {
172
+    public function createEnvironment() {
186 173
         $backend = $this->getBackend();
187 174
         if ($backend) {
188 175
             return $backend->createEnvironment($this);
@@ -196,8 +183,7 @@  discard block
 block discarded – undo
196 183
      * @return EnvironmentCreateBackend|null
197 184
      * @throws Exception
198 185
      */
199
-    public function getBackend()
200
-    {
186
+    public function getBackend() {
201 187
         $data = unserialize($this->Data);
202 188
         if (isset($data['EnvironmentType']) && class_exists($data['EnvironmentType'])) {
203 189
             $env = Injector::inst()->get($data['EnvironmentType']);
Please login to merge, or discard this patch.
code/model/jobs/DNDataTransfer.php 3 patches
Indentation   +270 added lines, -270 removed lines patch added patch discarded remove patch
@@ -34,274 +34,274 @@
 block discarded – undo
34 34
 class DNDataTransfer extends DataObject
35 35
 {
36 36
 
37
-    private static $db = array(
38
-        "ResqueToken" => "Varchar(255)",
39
-        // Observe that this is not the same as Resque status, since ResqueStatus is not persistent.
40
-        "Status" => "Enum('Queued, Started, Finished, Failed, n/a', 'n/a')",
41
-        "Direction" => "Enum('get, push', 'get')",
42
-        "Mode" => "Enum('all, assets, db', '')",
43
-        "Origin" => "Enum('EnvironmentTransfer,ManualUpload', 'EnvironmentTransfer')",
44
-    );
45
-
46
-    private static $has_one = array(
47
-        "Environment" => "DNEnvironment",
48
-        "Author" => "Member",
49
-        "DataArchive" => "DNDataArchive",
50
-        "BackupDataTransfer" => "DNDataTransfer" // denotes an automated backup done for a push of this data transfer
51
-    );
52
-
53
-    private static $singular_name = 'Data Transfer';
54
-
55
-    private static $plural_name = 'Data Transfers';
56
-
57
-    private static $summary_fields = array(
58
-        'Created' => 'Created',
59
-        'Author.Title' => 'Author',
60
-        'Environment.Project.Name' => 'Project',
61
-        'Environment.Name' => 'Environment',
62
-        'Status' => 'Status',
63
-        'Origin' => 'Origin',
64
-    );
65
-
66
-    private static $searchable_fields = array(
67
-        'Environment.Project.Name' => array(
68
-            'title' => 'Project',
69
-        ),
70
-        'Environment.Name' => array(
71
-            'title' => 'Environment',
72
-        ),
73
-        'Status' => array(
74
-            'title' => 'Status',
75
-        ),
76
-        'Origin' => array(
77
-            'title' => 'Origin',
78
-        ),
79
-        'Mode' => array(
80
-            'title' => 'Mode',
81
-        ),
82
-        'Direction' => array(
83
-            'title' => 'Direction',
84
-        ),
85
-    );
86
-
87
-    /**
88
-     * When running the transfer, should a backup be performed before pushing the data?
89
-     * @var bool
90
-     */
91
-    protected $backupBeforePush = true;
92
-
93
-    /**
94
-     * @param int $int
95
-     * @return string
96
-     */
97
-    public static function map_resque_status($int)
98
-    {
99
-        $remap = array(
100
-            Resque_Job_Status::STATUS_WAITING => "Queued",
101
-            Resque_Job_Status::STATUS_RUNNING => "Running",
102
-            Resque_Job_Status::STATUS_FAILED => "Failed",
103
-            Resque_Job_Status::STATUS_COMPLETE => "Complete",
104
-            false => "Invalid",
105
-        );
106
-        return $remap[$int];
107
-    }
108
-
109
-    /**
110
-     * @param boolean $value
111
-     */
112
-    public function setBackupBeforePush($value)
113
-    {
114
-        $this->backupBeforePush = $value;
115
-    }
116
-
117
-    public function getTitle()
118
-    {
119
-        return $this->dbObject('Created')->Nice() . " (Status: {$this->Status})";
120
-    }
121
-
122
-    public function Link()
123
-    {
124
-        return Controller::join_links($this->Environment()->Project()->Link(), 'transfer', $this->ID);
125
-    }
126
-
127
-    public function LogLink()
128
-    {
129
-        return Controller::join_links($this->Link(), 'log');
130
-    }
131
-
132
-    public function getDefaultSearchContext()
133
-    {
134
-        $context = parent::getDefaultSearchContext();
135
-        $context->getFields()->dataFieldByName('Status')->setHasEmptyDefault(true);
136
-        $context->getFields()->dataFieldByName('Origin')->setHasEmptyDefault(true);
137
-
138
-        return $context;
139
-    }
140
-
141
-    public function getCMSFields()
142
-    {
143
-        $fields = parent::getCMSFields();
144
-        $fields->removeByName('EnvironmentID');
145
-        $fields->removeByName('ArchiveFile');
146
-        $fields->addFieldsToTab(
147
-            'Root.Main',
148
-            array(
149
-                new ReadonlyField('ProjectName', 'Project', $this->Environment()->Project()->Name),
150
-                new ReadonlyField('EnvironmentName', 'Environment', $this->Environment()->Name),
151
-                new ReadonlyField(
152
-                    'DataArchive',
153
-                    'Archive File',
154
-                    sprintf(
155
-                        '<a href="%s">%s</a>',
156
-                        $this->DataArchive()->ArchiveFile()->AbsoluteURL,
157
-                        $this->DataArchive()->ArchiveFile()->Filename
158
-                    )
159
-                ),
160
-            )
161
-        );
162
-        $fields = $fields->makeReadonly();
163
-
164
-        return $fields;
165
-    }
166
-
167
-    /**
168
-     * Queue a transfer job
169
-     */
170
-    public function start()
171
-    {
172
-        $env = $this->Environment();
173
-        $log = $this->log();
174
-
175
-        $args = array(
176
-            'dataTransferID' => $this->ID,
177
-            'logfile' => $this->logfile(),
178
-            'backupBeforePush' => $this->backupBeforePush
179
-        );
180
-
181
-        if (!$this->AuthorID) {
182
-            $this->AuthorID = Member::currentUserID();
183
-        }
184
-
185
-        if ($this->AuthorID) {
186
-            $author = $this->Author();
187
-            $message = sprintf(
188
-                'Data transfer on %s (%s, %s) initiated by %s (%s), with IP address %s',
189
-                $env->getFullName(),
190
-                $this->Direction,
191
-                $this->Mode,
192
-                $author->getName(),
193
-                $author->Email,
194
-                Controller::curr()->getRequest()->getIP()
195
-            );
196
-            $log->write($message);
197
-        }
198
-
199
-        $token = Resque::enqueue('git', 'DataTransferJob', $args, true);
200
-        $this->ResqueToken = $token;
201
-        $this->write();
202
-
203
-        $message = sprintf('Data transfer queued as job %s', $token);
204
-        $log->write($message);
205
-    }
206
-
207
-    /**
208
-     * @param Member|null $member
209
-     * @return bool
210
-     */
211
-    public function canView($member = null)
212
-    {
213
-        return $this->Environment()->canView($member);
214
-    }
215
-
216
-    /**
217
-     * Return a path to the log file.
218
-     * @return string
219
-     */
220
-    protected function logfile()
221
-    {
222
-        return sprintf(
223
-            '%s.datatransfer.%s.log',
224
-            $this->Environment()->getFullName('.'),
225
-            $this->ID
226
-        );
227
-    }
228
-
229
-    /**
230
-     * @return \DeploynautLogFile
231
-     */
232
-    public function log()
233
-    {
234
-        return new DeploynautLogFile($this->logfile());
235
-    }
236
-
237
-    /**
238
-     * @return string
239
-     */
240
-    public function LogContent()
241
-    {
242
-        return $this->log()->content();
243
-    }
244
-
245
-    public function getDescription()
246
-    {
247
-        $envName = $this->Environment()->getFullName();
248
-        if ($this->Direction == 'get') {
249
-            if ($this->Origin == 'ManualUpload') {
250
-                $description = 'Manual upload of ' . $this->getModeNice() . ' to ' . $envName;
251
-            } elseif ($this->IsBackupDataTransfer()) {
252
-                $description = 'Automated backup of ' . $this->getModeNice() . ' from ' . $envName;
253
-            } else {
254
-                $description = 'Backup of ' . $this->getModeNice() . ' to ' . $envName;
255
-            }
256
-        } else {
257
-            $description = 'Restore ' . $this->getModeNice() . ' to ' . $envName;
258
-        }
259
-
260
-        return $description;
261
-    }
262
-
263
-    public function getModeNice()
264
-    {
265
-        if ($this->Mode == 'all') {
266
-            return 'database and assets';
267
-        } else {
268
-            return $this->Mode;
269
-        }
270
-    }
271
-
272
-    /**
273
-     * Is this transfer an automated backup of a push transfer?
274
-     * @return boolean
275
-     */
276
-    public function IsBackupDataTransfer()
277
-    {
278
-        return DB::query(sprintf(
279
-            'SELECT COUNT("ID") FROM "DNDataTransfer" WHERE "BackupDataTransferID" = %d',
280
-            $this->ID
281
-        ))->value();
282
-    }
283
-
284
-    /**
285
-     * Returns the status of the resque job
286
-     *
287
-     * @return string
288
-     */
289
-    public function ResqueStatus()
290
-    {
291
-        $status = new Resque_Job_Status($this->ResqueToken);
292
-        $statusCode = $status->get();
293
-        // The Resque job can no longer be found, fallback to the DNDataTransfer.Status
294
-        if ($statusCode === false) {
295
-            // Translate from the DNDataTransfer.Status to the Resque job status for UI purposes
296
-            switch ($this->Status) {
297
-                case 'Finished':
298
-                    return 'Complete';
299
-                case 'Started':
300
-                    return 'Running';
301
-                default:
302
-                    return $this->Status;
303
-            }
304
-        }
305
-        return self::map_resque_status($statusCode);
306
-    }
37
+	private static $db = array(
38
+		"ResqueToken" => "Varchar(255)",
39
+		// Observe that this is not the same as Resque status, since ResqueStatus is not persistent.
40
+		"Status" => "Enum('Queued, Started, Finished, Failed, n/a', 'n/a')",
41
+		"Direction" => "Enum('get, push', 'get')",
42
+		"Mode" => "Enum('all, assets, db', '')",
43
+		"Origin" => "Enum('EnvironmentTransfer,ManualUpload', 'EnvironmentTransfer')",
44
+	);
45
+
46
+	private static $has_one = array(
47
+		"Environment" => "DNEnvironment",
48
+		"Author" => "Member",
49
+		"DataArchive" => "DNDataArchive",
50
+		"BackupDataTransfer" => "DNDataTransfer" // denotes an automated backup done for a push of this data transfer
51
+	);
52
+
53
+	private static $singular_name = 'Data Transfer';
54
+
55
+	private static $plural_name = 'Data Transfers';
56
+
57
+	private static $summary_fields = array(
58
+		'Created' => 'Created',
59
+		'Author.Title' => 'Author',
60
+		'Environment.Project.Name' => 'Project',
61
+		'Environment.Name' => 'Environment',
62
+		'Status' => 'Status',
63
+		'Origin' => 'Origin',
64
+	);
65
+
66
+	private static $searchable_fields = array(
67
+		'Environment.Project.Name' => array(
68
+			'title' => 'Project',
69
+		),
70
+		'Environment.Name' => array(
71
+			'title' => 'Environment',
72
+		),
73
+		'Status' => array(
74
+			'title' => 'Status',
75
+		),
76
+		'Origin' => array(
77
+			'title' => 'Origin',
78
+		),
79
+		'Mode' => array(
80
+			'title' => 'Mode',
81
+		),
82
+		'Direction' => array(
83
+			'title' => 'Direction',
84
+		),
85
+	);
86
+
87
+	/**
88
+	 * When running the transfer, should a backup be performed before pushing the data?
89
+	 * @var bool
90
+	 */
91
+	protected $backupBeforePush = true;
92
+
93
+	/**
94
+	 * @param int $int
95
+	 * @return string
96
+	 */
97
+	public static function map_resque_status($int)
98
+	{
99
+		$remap = array(
100
+			Resque_Job_Status::STATUS_WAITING => "Queued",
101
+			Resque_Job_Status::STATUS_RUNNING => "Running",
102
+			Resque_Job_Status::STATUS_FAILED => "Failed",
103
+			Resque_Job_Status::STATUS_COMPLETE => "Complete",
104
+			false => "Invalid",
105
+		);
106
+		return $remap[$int];
107
+	}
108
+
109
+	/**
110
+	 * @param boolean $value
111
+	 */
112
+	public function setBackupBeforePush($value)
113
+	{
114
+		$this->backupBeforePush = $value;
115
+	}
116
+
117
+	public function getTitle()
118
+	{
119
+		return $this->dbObject('Created')->Nice() . " (Status: {$this->Status})";
120
+	}
121
+
122
+	public function Link()
123
+	{
124
+		return Controller::join_links($this->Environment()->Project()->Link(), 'transfer', $this->ID);
125
+	}
126
+
127
+	public function LogLink()
128
+	{
129
+		return Controller::join_links($this->Link(), 'log');
130
+	}
131
+
132
+	public function getDefaultSearchContext()
133
+	{
134
+		$context = parent::getDefaultSearchContext();
135
+		$context->getFields()->dataFieldByName('Status')->setHasEmptyDefault(true);
136
+		$context->getFields()->dataFieldByName('Origin')->setHasEmptyDefault(true);
137
+
138
+		return $context;
139
+	}
140
+
141
+	public function getCMSFields()
142
+	{
143
+		$fields = parent::getCMSFields();
144
+		$fields->removeByName('EnvironmentID');
145
+		$fields->removeByName('ArchiveFile');
146
+		$fields->addFieldsToTab(
147
+			'Root.Main',
148
+			array(
149
+				new ReadonlyField('ProjectName', 'Project', $this->Environment()->Project()->Name),
150
+				new ReadonlyField('EnvironmentName', 'Environment', $this->Environment()->Name),
151
+				new ReadonlyField(
152
+					'DataArchive',
153
+					'Archive File',
154
+					sprintf(
155
+						'<a href="%s">%s</a>',
156
+						$this->DataArchive()->ArchiveFile()->AbsoluteURL,
157
+						$this->DataArchive()->ArchiveFile()->Filename
158
+					)
159
+				),
160
+			)
161
+		);
162
+		$fields = $fields->makeReadonly();
163
+
164
+		return $fields;
165
+	}
166
+
167
+	/**
168
+	 * Queue a transfer job
169
+	 */
170
+	public function start()
171
+	{
172
+		$env = $this->Environment();
173
+		$log = $this->log();
174
+
175
+		$args = array(
176
+			'dataTransferID' => $this->ID,
177
+			'logfile' => $this->logfile(),
178
+			'backupBeforePush' => $this->backupBeforePush
179
+		);
180
+
181
+		if (!$this->AuthorID) {
182
+			$this->AuthorID = Member::currentUserID();
183
+		}
184
+
185
+		if ($this->AuthorID) {
186
+			$author = $this->Author();
187
+			$message = sprintf(
188
+				'Data transfer on %s (%s, %s) initiated by %s (%s), with IP address %s',
189
+				$env->getFullName(),
190
+				$this->Direction,
191
+				$this->Mode,
192
+				$author->getName(),
193
+				$author->Email,
194
+				Controller::curr()->getRequest()->getIP()
195
+			);
196
+			$log->write($message);
197
+		}
198
+
199
+		$token = Resque::enqueue('git', 'DataTransferJob', $args, true);
200
+		$this->ResqueToken = $token;
201
+		$this->write();
202
+
203
+		$message = sprintf('Data transfer queued as job %s', $token);
204
+		$log->write($message);
205
+	}
206
+
207
+	/**
208
+	 * @param Member|null $member
209
+	 * @return bool
210
+	 */
211
+	public function canView($member = null)
212
+	{
213
+		return $this->Environment()->canView($member);
214
+	}
215
+
216
+	/**
217
+	 * Return a path to the log file.
218
+	 * @return string
219
+	 */
220
+	protected function logfile()
221
+	{
222
+		return sprintf(
223
+			'%s.datatransfer.%s.log',
224
+			$this->Environment()->getFullName('.'),
225
+			$this->ID
226
+		);
227
+	}
228
+
229
+	/**
230
+	 * @return \DeploynautLogFile
231
+	 */
232
+	public function log()
233
+	{
234
+		return new DeploynautLogFile($this->logfile());
235
+	}
236
+
237
+	/**
238
+	 * @return string
239
+	 */
240
+	public function LogContent()
241
+	{
242
+		return $this->log()->content();
243
+	}
244
+
245
+	public function getDescription()
246
+	{
247
+		$envName = $this->Environment()->getFullName();
248
+		if ($this->Direction == 'get') {
249
+			if ($this->Origin == 'ManualUpload') {
250
+				$description = 'Manual upload of ' . $this->getModeNice() . ' to ' . $envName;
251
+			} elseif ($this->IsBackupDataTransfer()) {
252
+				$description = 'Automated backup of ' . $this->getModeNice() . ' from ' . $envName;
253
+			} else {
254
+				$description = 'Backup of ' . $this->getModeNice() . ' to ' . $envName;
255
+			}
256
+		} else {
257
+			$description = 'Restore ' . $this->getModeNice() . ' to ' . $envName;
258
+		}
259
+
260
+		return $description;
261
+	}
262
+
263
+	public function getModeNice()
264
+	{
265
+		if ($this->Mode == 'all') {
266
+			return 'database and assets';
267
+		} else {
268
+			return $this->Mode;
269
+		}
270
+	}
271
+
272
+	/**
273
+	 * Is this transfer an automated backup of a push transfer?
274
+	 * @return boolean
275
+	 */
276
+	public function IsBackupDataTransfer()
277
+	{
278
+		return DB::query(sprintf(
279
+			'SELECT COUNT("ID") FROM "DNDataTransfer" WHERE "BackupDataTransferID" = %d',
280
+			$this->ID
281
+		))->value();
282
+	}
283
+
284
+	/**
285
+	 * Returns the status of the resque job
286
+	 *
287
+	 * @return string
288
+	 */
289
+	public function ResqueStatus()
290
+	{
291
+		$status = new Resque_Job_Status($this->ResqueToken);
292
+		$statusCode = $status->get();
293
+		// The Resque job can no longer be found, fallback to the DNDataTransfer.Status
294
+		if ($statusCode === false) {
295
+			// Translate from the DNDataTransfer.Status to the Resque job status for UI purposes
296
+			switch ($this->Status) {
297
+				case 'Finished':
298
+					return 'Complete';
299
+				case 'Started':
300
+					return 'Running';
301
+				default:
302
+					return $this->Status;
303
+			}
304
+		}
305
+		return self::map_resque_status($statusCode);
306
+	}
307 307
 }
Please login to merge, or discard this patch.
Spacing   +8 added lines, -8 removed lines patch added patch discarded remove patch
@@ -178,11 +178,11 @@  discard block
 block discarded – undo
178 178
             'backupBeforePush' => $this->backupBeforePush
179 179
         );
180 180
 
181
-        if (!$this->AuthorID) {
181
+        if(!$this->AuthorID) {
182 182
             $this->AuthorID = Member::currentUserID();
183 183
         }
184 184
 
185
-        if ($this->AuthorID) {
185
+        if($this->AuthorID) {
186 186
             $author = $this->Author();
187 187
             $message = sprintf(
188 188
                 'Data transfer on %s (%s, %s) initiated by %s (%s), with IP address %s',
@@ -245,10 +245,10 @@  discard block
 block discarded – undo
245 245
     public function getDescription()
246 246
     {
247 247
         $envName = $this->Environment()->getFullName();
248
-        if ($this->Direction == 'get') {
249
-            if ($this->Origin == 'ManualUpload') {
248
+        if($this->Direction == 'get') {
249
+            if($this->Origin == 'ManualUpload') {
250 250
                 $description = 'Manual upload of ' . $this->getModeNice() . ' to ' . $envName;
251
-            } elseif ($this->IsBackupDataTransfer()) {
251
+            } elseif($this->IsBackupDataTransfer()) {
252 252
                 $description = 'Automated backup of ' . $this->getModeNice() . ' from ' . $envName;
253 253
             } else {
254 254
                 $description = 'Backup of ' . $this->getModeNice() . ' to ' . $envName;
@@ -262,7 +262,7 @@  discard block
 block discarded – undo
262 262
 
263 263
     public function getModeNice()
264 264
     {
265
-        if ($this->Mode == 'all') {
265
+        if($this->Mode == 'all') {
266 266
             return 'database and assets';
267 267
         } else {
268 268
             return $this->Mode;
@@ -291,9 +291,9 @@  discard block
 block discarded – undo
291 291
         $status = new Resque_Job_Status($this->ResqueToken);
292 292
         $statusCode = $status->get();
293 293
         // The Resque job can no longer be found, fallback to the DNDataTransfer.Status
294
-        if ($statusCode === false) {
294
+        if($statusCode === false) {
295 295
             // Translate from the DNDataTransfer.Status to the Resque job status for UI purposes
296
-            switch ($this->Status) {
296
+            switch($this->Status) {
297 297
                 case 'Finished':
298 298
                     return 'Complete';
299 299
                 case 'Started':
Please login to merge, or discard this patch.
Braces   +17 added lines, -34 removed lines patch added patch discarded remove patch
@@ -31,8 +31,7 @@  discard block
 block discarded – undo
31 31
  * @method DNDataTransfer BackupDataTransfer()
32 32
  * @property int BackupDataTransferID
33 33
  */
34
-class DNDataTransfer extends DataObject
35
-{
34
+class DNDataTransfer extends DataObject {
36 35
 
37 36
     private static $db = array(
38 37
         "ResqueToken" => "Varchar(255)",
@@ -94,8 +93,7 @@  discard block
 block discarded – undo
94 93
      * @param int $int
95 94
      * @return string
96 95
      */
97
-    public static function map_resque_status($int)
98
-    {
96
+    public static function map_resque_status($int) {
99 97
         $remap = array(
100 98
             Resque_Job_Status::STATUS_WAITING => "Queued",
101 99
             Resque_Job_Status::STATUS_RUNNING => "Running",
@@ -109,28 +107,23 @@  discard block
 block discarded – undo
109 107
     /**
110 108
      * @param boolean $value
111 109
      */
112
-    public function setBackupBeforePush($value)
113
-    {
110
+    public function setBackupBeforePush($value) {
114 111
         $this->backupBeforePush = $value;
115 112
     }
116 113
 
117
-    public function getTitle()
118
-    {
114
+    public function getTitle() {
119 115
         return $this->dbObject('Created')->Nice() . " (Status: {$this->Status})";
120 116
     }
121 117
 
122
-    public function Link()
123
-    {
118
+    public function Link() {
124 119
         return Controller::join_links($this->Environment()->Project()->Link(), 'transfer', $this->ID);
125 120
     }
126 121
 
127
-    public function LogLink()
128
-    {
122
+    public function LogLink() {
129 123
         return Controller::join_links($this->Link(), 'log');
130 124
     }
131 125
 
132
-    public function getDefaultSearchContext()
133
-    {
126
+    public function getDefaultSearchContext() {
134 127
         $context = parent::getDefaultSearchContext();
135 128
         $context->getFields()->dataFieldByName('Status')->setHasEmptyDefault(true);
136 129
         $context->getFields()->dataFieldByName('Origin')->setHasEmptyDefault(true);
@@ -138,8 +131,7 @@  discard block
 block discarded – undo
138 131
         return $context;
139 132
     }
140 133
 
141
-    public function getCMSFields()
142
-    {
134
+    public function getCMSFields() {
143 135
         $fields = parent::getCMSFields();
144 136
         $fields->removeByName('EnvironmentID');
145 137
         $fields->removeByName('ArchiveFile');
@@ -167,8 +159,7 @@  discard block
 block discarded – undo
167 159
     /**
168 160
      * Queue a transfer job
169 161
      */
170
-    public function start()
171
-    {
162
+    public function start() {
172 163
         $env = $this->Environment();
173 164
         $log = $this->log();
174 165
 
@@ -208,8 +199,7 @@  discard block
 block discarded – undo
208 199
      * @param Member|null $member
209 200
      * @return bool
210 201
      */
211
-    public function canView($member = null)
212
-    {
202
+    public function canView($member = null) {
213 203
         return $this->Environment()->canView($member);
214 204
     }
215 205
 
@@ -217,8 +207,7 @@  discard block
 block discarded – undo
217 207
      * Return a path to the log file.
218 208
      * @return string
219 209
      */
220
-    protected function logfile()
221
-    {
210
+    protected function logfile() {
222 211
         return sprintf(
223 212
             '%s.datatransfer.%s.log',
224 213
             $this->Environment()->getFullName('.'),
@@ -229,21 +218,18 @@  discard block
 block discarded – undo
229 218
     /**
230 219
      * @return \DeploynautLogFile
231 220
      */
232
-    public function log()
233
-    {
221
+    public function log() {
234 222
         return new DeploynautLogFile($this->logfile());
235 223
     }
236 224
 
237 225
     /**
238 226
      * @return string
239 227
      */
240
-    public function LogContent()
241
-    {
228
+    public function LogContent() {
242 229
         return $this->log()->content();
243 230
     }
244 231
 
245
-    public function getDescription()
246
-    {
232
+    public function getDescription() {
247 233
         $envName = $this->Environment()->getFullName();
248 234
         if ($this->Direction == 'get') {
249 235
             if ($this->Origin == 'ManualUpload') {
@@ -260,8 +246,7 @@  discard block
 block discarded – undo
260 246
         return $description;
261 247
     }
262 248
 
263
-    public function getModeNice()
264
-    {
249
+    public function getModeNice() {
265 250
         if ($this->Mode == 'all') {
266 251
             return 'database and assets';
267 252
         } else {
@@ -273,8 +258,7 @@  discard block
 block discarded – undo
273 258
      * Is this transfer an automated backup of a push transfer?
274 259
      * @return boolean
275 260
      */
276
-    public function IsBackupDataTransfer()
277
-    {
261
+    public function IsBackupDataTransfer() {
278 262
         return DB::query(sprintf(
279 263
             'SELECT COUNT("ID") FROM "DNDataTransfer" WHERE "BackupDataTransferID" = %d',
280 264
             $this->ID
@@ -286,8 +270,7 @@  discard block
 block discarded – undo
286 270
      *
287 271
      * @return string
288 272
      */
289
-    public function ResqueStatus()
290
-    {
273
+    public function ResqueStatus() {
291 274
         $status = new Resque_Job_Status($this->ResqueToken);
292 275
         $statusCode = $status->get();
293 276
         // The Resque job can no longer be found, fallback to the DNDataTransfer.Status
Please login to merge, or discard this patch.
code/model/jobs/DNDeployment.php 3 patches
Indentation   +340 added lines, -340 removed lines patch added patch discarded remove patch
@@ -15,344 +15,344 @@
 block discarded – undo
15 15
 class DNDeployment extends DataObject
16 16
 {
17 17
 
18
-    /**
19
-     * @var array
20
-     */
21
-    private static $db = array(
22
-        "SHA" => "GitSHA",
23
-        "ResqueToken" => "Varchar(255)",
24
-        // Observe that this is not the same as Resque status, since ResqueStatus is not persistent
25
-        // It's used for finding successful deployments and displaying that in history views in the frontend
26
-        "Status" => "Enum('Queued, Started, Finished, Failed, n/a', 'n/a')",
27
-        // JSON serialised DeploymentStrategy.
28
-        "Strategy" => "Text"
29
-    );
30
-
31
-    /**
32
-     * @var array
33
-     */
34
-    private static $has_one = array(
35
-        "Environment" => "DNEnvironment",
36
-        "Deployer" => "Member",
37
-    );
38
-
39
-    private static $default_sort = '"LastEdited" DESC';
40
-
41
-    public function getTitle()
42
-    {
43
-        return "#{$this->ID}: {$this->SHA} (Status: {$this->Status})";
44
-    }
45
-
46
-    private static $summary_fields = array(
47
-        'LastEdited' => 'Last Edited',
48
-        'SHA' => 'SHA',
49
-        'Status' => 'Status',
50
-        'Deployer.Name' => 'Deployer'
51
-    );
52
-
53
-    /**
54
-     * @param int $int
55
-     * @return string
56
-     */
57
-    public static function map_resque_status($int)
58
-    {
59
-        $remap = array(
60
-            Resque_Job_Status::STATUS_WAITING => "Queued",
61
-            Resque_Job_Status::STATUS_RUNNING => "Running",
62
-            Resque_Job_Status::STATUS_FAILED => "Failed",
63
-            Resque_Job_Status::STATUS_COMPLETE => "Complete",
64
-            false => "Invalid",
65
-        );
66
-        return $remap[$int];
67
-    }
68
-
69
-
70
-    public function Link()
71
-    {
72
-        return Controller::join_links($this->Environment()->Link(), 'deploy', $this->ID);
73
-    }
74
-
75
-    public function LogLink()
76
-    {
77
-        return $this->Link() . '/log';
78
-    }
79
-
80
-    public function canView($member = null)
81
-    {
82
-        return $this->Environment()->canView($member);
83
-    }
84
-
85
-    /**
86
-     * Return a path to the log file.
87
-     * @return string
88
-     */
89
-    protected function logfile()
90
-    {
91
-        return sprintf(
92
-            '%s.%s.log',
93
-            $this->Environment()->getFullName('.'),
94
-            $this->ID
95
-        );
96
-    }
97
-
98
-    /**
99
-     * @return DeploynautLogFile
100
-     */
101
-    public function log()
102
-    {
103
-        return Injector::inst()->createWithArgs('DeploynautLogFile', array($this->logfile()));
104
-    }
105
-
106
-    public function LogContent()
107
-    {
108
-        return $this->log()->content();
109
-    }
110
-
111
-    /**
112
-     * Returns the status of the resque job
113
-     *
114
-     * @return string
115
-     */
116
-    public function ResqueStatus()
117
-    {
118
-        $status = new Resque_Job_Status($this->ResqueToken);
119
-        $statusCode = $status->get();
120
-        // The Resque job can no longer be found, fallback to the DNDeployment.Status
121
-        if ($statusCode === false) {
122
-            // Translate from the DNDeployment.Status to the Resque job status for UI purposes
123
-            switch ($this->Status) {
124
-                case 'Finished':
125
-                    return 'Complete';
126
-                case 'Started':
127
-                    return 'Running';
128
-                default:
129
-                    return $this->Status;
130
-            }
131
-        }
132
-        return self::map_resque_status($statusCode);
133
-    }
134
-
135
-
136
-    /**
137
-     * Fetch the git repository
138
-     *
139
-     * @return \Gitonomy\Git\Repository|null
140
-     */
141
-    public function getRepository()
142
-    {
143
-        if (!$this->SHA) {
144
-            return null;
145
-        }
146
-        return $this->Environment()->Project()->getRepository();
147
-    }
148
-
149
-
150
-    /**
151
-     * Gets the commit from source. The result is cached upstream in Repository.
152
-     *
153
-     * @return \Gitonomy\Git\Commit|null
154
-     */
155
-    public function getCommit()
156
-    {
157
-        $repo = $this->getRepository();
158
-        if ($repo) {
159
-            try {
160
-                return $repo->getCommit($this->SHA);
161
-            } catch (Gitonomy\Git\Exception\ReferenceNotFoundException $ex) {
162
-                return null;
163
-            }
164
-        }
165
-
166
-        return null;
167
-    }
168
-
169
-
170
-    /**
171
-     * Gets the commit message.
172
-     *
173
-     * @return string|null
174
-     */
175
-    public function getCommitMessage()
176
-    {
177
-        $commit = $this->getCommit();
178
-        if ($commit) {
179
-            try {
180
-                return Convert::raw2xml($commit->getMessage());
181
-            } catch (Gitonomy\Git\Exception\ReferenceNotFoundException $e) {
182
-                return null;
183
-            }
184
-        }
185
-        return null;
186
-    }
187
-
188
-    /**
189
-     * Return all tags for the deployed commit.
190
-     *
191
-     * @return ArrayList
192
-     */
193
-    public function getTags()
194
-    {
195
-        $returnTags = array();
196
-        $repo = $this->getRepository();
197
-        if ($repo) {
198
-            $tags = $repo->getReferences()->resolveTags($this->SHA);
199
-            if (!empty($tags)) {
200
-                foreach ($tags as $tag) {
201
-                    $field = Varchar::create('Tag', '255');
202
-                    $field->setValue($tag->getName());
203
-                    $returnTags[] = $field;
204
-                }
205
-            }
206
-        }
207
-        return new ArrayList($returnTags);
208
-    }
209
-
210
-    /**
211
-     * Collate the list of additional flags to affix to this deployment.
212
-     * Elements of the array will be rendered literally.
213
-     *
214
-     * @return ArrayList
215
-     */
216
-    public function getFullDeployMessages()
217
-    {
218
-        $strategy = $this->getDeploymentStrategy();
219
-        if ($strategy->getActionCode()!=='full') {
220
-            return null;
221
-        }
222
-
223
-        $changes = $strategy->getChangesModificationNeeded();
224
-        $messages = [];
225
-        foreach ($changes as $change => $details) {
226
-            if ($change==='Code version') {
227
-                continue;
228
-            }
229
-
230
-            $messages[] = [
231
-                'Flag' => sprintf(
232
-                    '<span class="label label-default full-deploy-info-item">%s</span>',
233
-                    $change[0]
234
-                ),
235
-                'Text' => sprintf('%s changed', $change)
236
-            ];
237
-        }
238
-
239
-        if (empty($messages)) {
240
-            $messages[] = [
241
-                'Flag' => '',
242
-                'Text' => '<i>Environment changes have been made.</i>'
243
-            ];
244
-        }
245
-
246
-        return new ArrayList($messages);
247
-    }
248
-
249
-    /**
250
-     * Fetches the latest tag for the deployed commit
251
-     *
252
-     * @return \Varchar|null
253
-     */
254
-    public function getTag()
255
-    {
256
-        $tags = $this->getTags();
257
-        if ($tags->count() > 0) {
258
-            return $tags->last();
259
-        }
260
-        return null;
261
-    }
262
-
263
-    /**
264
-     * @return DeploymentStrategy
265
-     */
266
-    public function getDeploymentStrategy()
267
-    {
268
-        $environment = $this->Environment();
269
-        $strategy = new DeploymentStrategy($environment);
270
-        $strategy->fromJSON($this->Strategy);
271
-        return $strategy;
272
-    }
273
-
274
-    /**
275
-     * Return a list of things that are going to be deployed, such
276
-     * as the code version, and any infrastrucutral changes.
277
-     *
278
-     * @return ArrayList
279
-     */
280
-    public function getChanges()
281
-    {
282
-        $list = new ArrayList();
283
-        $strategy = $this->getDeploymentStrategy();
284
-        foreach ($strategy->getChanges() as $name => $change) {
285
-            if (empty($change['to'])) {
286
-                continue;
287
-            }
288
-
289
-            $list->push(new ArrayData([
290
-                'Name' => $name,
291
-                'From' => $change['from'],
292
-                'To' => $change['to'],
293
-                'Description' => isset($change['description']) ? $change['description'] : '',
294
-                'Changed' => $change['from'] != $change['to'],
295
-                'CompareUrl' => isset($change['compareUrl']) ? $change['compareUrl'] : ''
296
-            ]));
297
-        }
298
-
299
-        return $list;
300
-    }
301
-
302
-    /**
303
-     * Start a resque job for this deployment
304
-     *
305
-     * @return string Resque token
306
-     */
307
-    protected function enqueueDeployment()
308
-    {
309
-        $environment = $this->Environment();
310
-        $project = $environment->Project();
311
-        $log = $this->log();
312
-
313
-        $args = array(
314
-            'environmentName' => $environment->Name,
315
-            'repository' => $project->getLocalCVSPath(),
316
-            'logfile' => $this->logfile(),
317
-            'projectName' => $project->Name,
318
-            'env' => $project->getProcessEnv(),
319
-            'deploymentID' => $this->ID
320
-        );
321
-
322
-        $strategy = $this->getDeploymentStrategy();
323
-        // Inject options.
324
-        $args = array_merge($args, $strategy->getOptions());
325
-        // Make sure we use the SHA as it was written into this DNDeployment.
326
-        $args['sha'] = $this->SHA;
327
-
328
-        if (!$this->DeployerID) {
329
-            $this->DeployerID = Member::currentUserID();
330
-        }
331
-
332
-        if ($this->DeployerID) {
333
-            $deployer = $this->Deployer();
334
-            $message = sprintf(
335
-                'Deploy to %s initiated by %s (%s), with IP address %s',
336
-                $environment->getFullName(),
337
-                $deployer->getName(),
338
-                $deployer->Email,
339
-                Controller::curr()->getRequest()->getIP()
340
-            );
341
-            $log->write($message);
342
-        }
343
-
344
-        return Resque::enqueue('deploy', 'DeployJob', $args, true);
345
-    }
346
-
347
-    public function start()
348
-    {
349
-        $log = $this->log();
350
-        $token = $this->enqueueDeployment();
351
-        $this->ResqueToken = $token;
352
-        $this->Status = 'Queued';
353
-        $this->write();
354
-
355
-        $message = sprintf('Deploy queued as job %s', $token);
356
-        $log->write($message);
357
-    }
18
+	/**
19
+	 * @var array
20
+	 */
21
+	private static $db = array(
22
+		"SHA" => "GitSHA",
23
+		"ResqueToken" => "Varchar(255)",
24
+		// Observe that this is not the same as Resque status, since ResqueStatus is not persistent
25
+		// It's used for finding successful deployments and displaying that in history views in the frontend
26
+		"Status" => "Enum('Queued, Started, Finished, Failed, n/a', 'n/a')",
27
+		// JSON serialised DeploymentStrategy.
28
+		"Strategy" => "Text"
29
+	);
30
+
31
+	/**
32
+	 * @var array
33
+	 */
34
+	private static $has_one = array(
35
+		"Environment" => "DNEnvironment",
36
+		"Deployer" => "Member",
37
+	);
38
+
39
+	private static $default_sort = '"LastEdited" DESC';
40
+
41
+	public function getTitle()
42
+	{
43
+		return "#{$this->ID}: {$this->SHA} (Status: {$this->Status})";
44
+	}
45
+
46
+	private static $summary_fields = array(
47
+		'LastEdited' => 'Last Edited',
48
+		'SHA' => 'SHA',
49
+		'Status' => 'Status',
50
+		'Deployer.Name' => 'Deployer'
51
+	);
52
+
53
+	/**
54
+	 * @param int $int
55
+	 * @return string
56
+	 */
57
+	public static function map_resque_status($int)
58
+	{
59
+		$remap = array(
60
+			Resque_Job_Status::STATUS_WAITING => "Queued",
61
+			Resque_Job_Status::STATUS_RUNNING => "Running",
62
+			Resque_Job_Status::STATUS_FAILED => "Failed",
63
+			Resque_Job_Status::STATUS_COMPLETE => "Complete",
64
+			false => "Invalid",
65
+		);
66
+		return $remap[$int];
67
+	}
68
+
69
+
70
+	public function Link()
71
+	{
72
+		return Controller::join_links($this->Environment()->Link(), 'deploy', $this->ID);
73
+	}
74
+
75
+	public function LogLink()
76
+	{
77
+		return $this->Link() . '/log';
78
+	}
79
+
80
+	public function canView($member = null)
81
+	{
82
+		return $this->Environment()->canView($member);
83
+	}
84
+
85
+	/**
86
+	 * Return a path to the log file.
87
+	 * @return string
88
+	 */
89
+	protected function logfile()
90
+	{
91
+		return sprintf(
92
+			'%s.%s.log',
93
+			$this->Environment()->getFullName('.'),
94
+			$this->ID
95
+		);
96
+	}
97
+
98
+	/**
99
+	 * @return DeploynautLogFile
100
+	 */
101
+	public function log()
102
+	{
103
+		return Injector::inst()->createWithArgs('DeploynautLogFile', array($this->logfile()));
104
+	}
105
+
106
+	public function LogContent()
107
+	{
108
+		return $this->log()->content();
109
+	}
110
+
111
+	/**
112
+	 * Returns the status of the resque job
113
+	 *
114
+	 * @return string
115
+	 */
116
+	public function ResqueStatus()
117
+	{
118
+		$status = new Resque_Job_Status($this->ResqueToken);
119
+		$statusCode = $status->get();
120
+		// The Resque job can no longer be found, fallback to the DNDeployment.Status
121
+		if ($statusCode === false) {
122
+			// Translate from the DNDeployment.Status to the Resque job status for UI purposes
123
+			switch ($this->Status) {
124
+				case 'Finished':
125
+					return 'Complete';
126
+				case 'Started':
127
+					return 'Running';
128
+				default:
129
+					return $this->Status;
130
+			}
131
+		}
132
+		return self::map_resque_status($statusCode);
133
+	}
134
+
135
+
136
+	/**
137
+	 * Fetch the git repository
138
+	 *
139
+	 * @return \Gitonomy\Git\Repository|null
140
+	 */
141
+	public function getRepository()
142
+	{
143
+		if (!$this->SHA) {
144
+			return null;
145
+		}
146
+		return $this->Environment()->Project()->getRepository();
147
+	}
148
+
149
+
150
+	/**
151
+	 * Gets the commit from source. The result is cached upstream in Repository.
152
+	 *
153
+	 * @return \Gitonomy\Git\Commit|null
154
+	 */
155
+	public function getCommit()
156
+	{
157
+		$repo = $this->getRepository();
158
+		if ($repo) {
159
+			try {
160
+				return $repo->getCommit($this->SHA);
161
+			} catch (Gitonomy\Git\Exception\ReferenceNotFoundException $ex) {
162
+				return null;
163
+			}
164
+		}
165
+
166
+		return null;
167
+	}
168
+
169
+
170
+	/**
171
+	 * Gets the commit message.
172
+	 *
173
+	 * @return string|null
174
+	 */
175
+	public function getCommitMessage()
176
+	{
177
+		$commit = $this->getCommit();
178
+		if ($commit) {
179
+			try {
180
+				return Convert::raw2xml($commit->getMessage());
181
+			} catch (Gitonomy\Git\Exception\ReferenceNotFoundException $e) {
182
+				return null;
183
+			}
184
+		}
185
+		return null;
186
+	}
187
+
188
+	/**
189
+	 * Return all tags for the deployed commit.
190
+	 *
191
+	 * @return ArrayList
192
+	 */
193
+	public function getTags()
194
+	{
195
+		$returnTags = array();
196
+		$repo = $this->getRepository();
197
+		if ($repo) {
198
+			$tags = $repo->getReferences()->resolveTags($this->SHA);
199
+			if (!empty($tags)) {
200
+				foreach ($tags as $tag) {
201
+					$field = Varchar::create('Tag', '255');
202
+					$field->setValue($tag->getName());
203
+					$returnTags[] = $field;
204
+				}
205
+			}
206
+		}
207
+		return new ArrayList($returnTags);
208
+	}
209
+
210
+	/**
211
+	 * Collate the list of additional flags to affix to this deployment.
212
+	 * Elements of the array will be rendered literally.
213
+	 *
214
+	 * @return ArrayList
215
+	 */
216
+	public function getFullDeployMessages()
217
+	{
218
+		$strategy = $this->getDeploymentStrategy();
219
+		if ($strategy->getActionCode()!=='full') {
220
+			return null;
221
+		}
222
+
223
+		$changes = $strategy->getChangesModificationNeeded();
224
+		$messages = [];
225
+		foreach ($changes as $change => $details) {
226
+			if ($change==='Code version') {
227
+				continue;
228
+			}
229
+
230
+			$messages[] = [
231
+				'Flag' => sprintf(
232
+					'<span class="label label-default full-deploy-info-item">%s</span>',
233
+					$change[0]
234
+				),
235
+				'Text' => sprintf('%s changed', $change)
236
+			];
237
+		}
238
+
239
+		if (empty($messages)) {
240
+			$messages[] = [
241
+				'Flag' => '',
242
+				'Text' => '<i>Environment changes have been made.</i>'
243
+			];
244
+		}
245
+
246
+		return new ArrayList($messages);
247
+	}
248
+
249
+	/**
250
+	 * Fetches the latest tag for the deployed commit
251
+	 *
252
+	 * @return \Varchar|null
253
+	 */
254
+	public function getTag()
255
+	{
256
+		$tags = $this->getTags();
257
+		if ($tags->count() > 0) {
258
+			return $tags->last();
259
+		}
260
+		return null;
261
+	}
262
+
263
+	/**
264
+	 * @return DeploymentStrategy
265
+	 */
266
+	public function getDeploymentStrategy()
267
+	{
268
+		$environment = $this->Environment();
269
+		$strategy = new DeploymentStrategy($environment);
270
+		$strategy->fromJSON($this->Strategy);
271
+		return $strategy;
272
+	}
273
+
274
+	/**
275
+	 * Return a list of things that are going to be deployed, such
276
+	 * as the code version, and any infrastrucutral changes.
277
+	 *
278
+	 * @return ArrayList
279
+	 */
280
+	public function getChanges()
281
+	{
282
+		$list = new ArrayList();
283
+		$strategy = $this->getDeploymentStrategy();
284
+		foreach ($strategy->getChanges() as $name => $change) {
285
+			if (empty($change['to'])) {
286
+				continue;
287
+			}
288
+
289
+			$list->push(new ArrayData([
290
+				'Name' => $name,
291
+				'From' => $change['from'],
292
+				'To' => $change['to'],
293
+				'Description' => isset($change['description']) ? $change['description'] : '',
294
+				'Changed' => $change['from'] != $change['to'],
295
+				'CompareUrl' => isset($change['compareUrl']) ? $change['compareUrl'] : ''
296
+			]));
297
+		}
298
+
299
+		return $list;
300
+	}
301
+
302
+	/**
303
+	 * Start a resque job for this deployment
304
+	 *
305
+	 * @return string Resque token
306
+	 */
307
+	protected function enqueueDeployment()
308
+	{
309
+		$environment = $this->Environment();
310
+		$project = $environment->Project();
311
+		$log = $this->log();
312
+
313
+		$args = array(
314
+			'environmentName' => $environment->Name,
315
+			'repository' => $project->getLocalCVSPath(),
316
+			'logfile' => $this->logfile(),
317
+			'projectName' => $project->Name,
318
+			'env' => $project->getProcessEnv(),
319
+			'deploymentID' => $this->ID
320
+		);
321
+
322
+		$strategy = $this->getDeploymentStrategy();
323
+		// Inject options.
324
+		$args = array_merge($args, $strategy->getOptions());
325
+		// Make sure we use the SHA as it was written into this DNDeployment.
326
+		$args['sha'] = $this->SHA;
327
+
328
+		if (!$this->DeployerID) {
329
+			$this->DeployerID = Member::currentUserID();
330
+		}
331
+
332
+		if ($this->DeployerID) {
333
+			$deployer = $this->Deployer();
334
+			$message = sprintf(
335
+				'Deploy to %s initiated by %s (%s), with IP address %s',
336
+				$environment->getFullName(),
337
+				$deployer->getName(),
338
+				$deployer->Email,
339
+				Controller::curr()->getRequest()->getIP()
340
+			);
341
+			$log->write($message);
342
+		}
343
+
344
+		return Resque::enqueue('deploy', 'DeployJob', $args, true);
345
+	}
346
+
347
+	public function start()
348
+	{
349
+		$log = $this->log();
350
+		$token = $this->enqueueDeployment();
351
+		$this->ResqueToken = $token;
352
+		$this->Status = 'Queued';
353
+		$this->write();
354
+
355
+		$message = sprintf('Deploy queued as job %s', $token);
356
+		$log->write($message);
357
+	}
358 358
 }
Please login to merge, or discard this patch.
Spacing   +19 added lines, -19 removed lines patch added patch discarded remove patch
@@ -118,9 +118,9 @@  discard block
 block discarded – undo
118 118
         $status = new Resque_Job_Status($this->ResqueToken);
119 119
         $statusCode = $status->get();
120 120
         // The Resque job can no longer be found, fallback to the DNDeployment.Status
121
-        if ($statusCode === false) {
121
+        if($statusCode === false) {
122 122
             // Translate from the DNDeployment.Status to the Resque job status for UI purposes
123
-            switch ($this->Status) {
123
+            switch($this->Status) {
124 124
                 case 'Finished':
125 125
                     return 'Complete';
126 126
                 case 'Started':
@@ -140,7 +140,7 @@  discard block
 block discarded – undo
140 140
      */
141 141
     public function getRepository()
142 142
     {
143
-        if (!$this->SHA) {
143
+        if(!$this->SHA) {
144 144
             return null;
145 145
         }
146 146
         return $this->Environment()->Project()->getRepository();
@@ -155,10 +155,10 @@  discard block
 block discarded – undo
155 155
     public function getCommit()
156 156
     {
157 157
         $repo = $this->getRepository();
158
-        if ($repo) {
158
+        if($repo) {
159 159
             try {
160 160
                 return $repo->getCommit($this->SHA);
161
-            } catch (Gitonomy\Git\Exception\ReferenceNotFoundException $ex) {
161
+            } catch(Gitonomy\Git\Exception\ReferenceNotFoundException $ex) {
162 162
                 return null;
163 163
             }
164 164
         }
@@ -175,10 +175,10 @@  discard block
 block discarded – undo
175 175
     public function getCommitMessage()
176 176
     {
177 177
         $commit = $this->getCommit();
178
-        if ($commit) {
178
+        if($commit) {
179 179
             try {
180 180
                 return Convert::raw2xml($commit->getMessage());
181
-            } catch (Gitonomy\Git\Exception\ReferenceNotFoundException $e) {
181
+            } catch(Gitonomy\Git\Exception\ReferenceNotFoundException $e) {
182 182
                 return null;
183 183
             }
184 184
         }
@@ -194,10 +194,10 @@  discard block
 block discarded – undo
194 194
     {
195 195
         $returnTags = array();
196 196
         $repo = $this->getRepository();
197
-        if ($repo) {
197
+        if($repo) {
198 198
             $tags = $repo->getReferences()->resolveTags($this->SHA);
199
-            if (!empty($tags)) {
200
-                foreach ($tags as $tag) {
199
+            if(!empty($tags)) {
200
+                foreach($tags as $tag) {
201 201
                     $field = Varchar::create('Tag', '255');
202 202
                     $field->setValue($tag->getName());
203 203
                     $returnTags[] = $field;
@@ -216,14 +216,14 @@  discard block
 block discarded – undo
216 216
     public function getFullDeployMessages()
217 217
     {
218 218
         $strategy = $this->getDeploymentStrategy();
219
-        if ($strategy->getActionCode()!=='full') {
219
+        if($strategy->getActionCode() !== 'full') {
220 220
             return null;
221 221
         }
222 222
 
223 223
         $changes = $strategy->getChangesModificationNeeded();
224 224
         $messages = [];
225
-        foreach ($changes as $change => $details) {
226
-            if ($change==='Code version') {
225
+        foreach($changes as $change => $details) {
226
+            if($change === 'Code version') {
227 227
                 continue;
228 228
             }
229 229
 
@@ -236,7 +236,7 @@  discard block
 block discarded – undo
236 236
             ];
237 237
         }
238 238
 
239
-        if (empty($messages)) {
239
+        if(empty($messages)) {
240 240
             $messages[] = [
241 241
                 'Flag' => '',
242 242
                 'Text' => '<i>Environment changes have been made.</i>'
@@ -254,7 +254,7 @@  discard block
 block discarded – undo
254 254
     public function getTag()
255 255
     {
256 256
         $tags = $this->getTags();
257
-        if ($tags->count() > 0) {
257
+        if($tags->count() > 0) {
258 258
             return $tags->last();
259 259
         }
260 260
         return null;
@@ -281,8 +281,8 @@  discard block
 block discarded – undo
281 281
     {
282 282
         $list = new ArrayList();
283 283
         $strategy = $this->getDeploymentStrategy();
284
-        foreach ($strategy->getChanges() as $name => $change) {
285
-            if (empty($change['to'])) {
284
+        foreach($strategy->getChanges() as $name => $change) {
285
+            if(empty($change['to'])) {
286 286
                 continue;
287 287
             }
288 288
 
@@ -325,11 +325,11 @@  discard block
 block discarded – undo
325 325
         // Make sure we use the SHA as it was written into this DNDeployment.
326 326
         $args['sha'] = $this->SHA;
327 327
 
328
-        if (!$this->DeployerID) {
328
+        if(!$this->DeployerID) {
329 329
             $this->DeployerID = Member::currentUserID();
330 330
         }
331 331
 
332
-        if ($this->DeployerID) {
332
+        if($this->DeployerID) {
333 333
             $deployer = $this->Deployer();
334 334
             $message = sprintf(
335 335
                 'Deploy to %s initiated by %s (%s), with IP address %s',
Please login to merge, or discard this patch.
Braces   +20 added lines, -40 removed lines patch added patch discarded remove patch
@@ -12,8 +12,7 @@  discard block
 block discarded – undo
12 12
  * @method Member Deployer()
13 13
  * @property int DeployerID
14 14
  */
15
-class DNDeployment extends DataObject
16
-{
15
+class DNDeployment extends DataObject {
17 16
 
18 17
     /**
19 18
      * @var array
@@ -38,8 +37,7 @@  discard block
 block discarded – undo
38 37
 
39 38
     private static $default_sort = '"LastEdited" DESC';
40 39
 
41
-    public function getTitle()
42
-    {
40
+    public function getTitle() {
43 41
         return "#{$this->ID}: {$this->SHA} (Status: {$this->Status})";
44 42
     }
45 43
 
@@ -54,8 +52,7 @@  discard block
 block discarded – undo
54 52
      * @param int $int
55 53
      * @return string
56 54
      */
57
-    public static function map_resque_status($int)
58
-    {
55
+    public static function map_resque_status($int) {
59 56
         $remap = array(
60 57
             Resque_Job_Status::STATUS_WAITING => "Queued",
61 58
             Resque_Job_Status::STATUS_RUNNING => "Running",
@@ -67,18 +64,15 @@  discard block
 block discarded – undo
67 64
     }
68 65
 
69 66
 
70
-    public function Link()
71
-    {
67
+    public function Link() {
72 68
         return Controller::join_links($this->Environment()->Link(), 'deploy', $this->ID);
73 69
     }
74 70
 
75
-    public function LogLink()
76
-    {
71
+    public function LogLink() {
77 72
         return $this->Link() . '/log';
78 73
     }
79 74
 
80
-    public function canView($member = null)
81
-    {
75
+    public function canView($member = null) {
82 76
         return $this->Environment()->canView($member);
83 77
     }
84 78
 
@@ -86,8 +80,7 @@  discard block
 block discarded – undo
86 80
      * Return a path to the log file.
87 81
      * @return string
88 82
      */
89
-    protected function logfile()
90
-    {
83
+    protected function logfile() {
91 84
         return sprintf(
92 85
             '%s.%s.log',
93 86
             $this->Environment()->getFullName('.'),
@@ -98,13 +91,11 @@  discard block
 block discarded – undo
98 91
     /**
99 92
      * @return DeploynautLogFile
100 93
      */
101
-    public function log()
102
-    {
94
+    public function log() {
103 95
         return Injector::inst()->createWithArgs('DeploynautLogFile', array($this->logfile()));
104 96
     }
105 97
 
106
-    public function LogContent()
107
-    {
98
+    public function LogContent() {
108 99
         return $this->log()->content();
109 100
     }
110 101
 
@@ -113,8 +104,7 @@  discard block
 block discarded – undo
113 104
      *
114 105
      * @return string
115 106
      */
116
-    public function ResqueStatus()
117
-    {
107
+    public function ResqueStatus() {
118 108
         $status = new Resque_Job_Status($this->ResqueToken);
119 109
         $statusCode = $status->get();
120 110
         // The Resque job can no longer be found, fallback to the DNDeployment.Status
@@ -138,8 +128,7 @@  discard block
 block discarded – undo
138 128
      *
139 129
      * @return \Gitonomy\Git\Repository|null
140 130
      */
141
-    public function getRepository()
142
-    {
131
+    public function getRepository() {
143 132
         if (!$this->SHA) {
144 133
             return null;
145 134
         }
@@ -152,8 +141,7 @@  discard block
 block discarded – undo
152 141
      *
153 142
      * @return \Gitonomy\Git\Commit|null
154 143
      */
155
-    public function getCommit()
156
-    {
144
+    public function getCommit() {
157 145
         $repo = $this->getRepository();
158 146
         if ($repo) {
159 147
             try {
@@ -172,8 +160,7 @@  discard block
 block discarded – undo
172 160
      *
173 161
      * @return string|null
174 162
      */
175
-    public function getCommitMessage()
176
-    {
163
+    public function getCommitMessage() {
177 164
         $commit = $this->getCommit();
178 165
         if ($commit) {
179 166
             try {
@@ -190,8 +177,7 @@  discard block
 block discarded – undo
190 177
      *
191 178
      * @return ArrayList
192 179
      */
193
-    public function getTags()
194
-    {
180
+    public function getTags() {
195 181
         $returnTags = array();
196 182
         $repo = $this->getRepository();
197 183
         if ($repo) {
@@ -213,8 +199,7 @@  discard block
 block discarded – undo
213 199
      *
214 200
      * @return ArrayList
215 201
      */
216
-    public function getFullDeployMessages()
217
-    {
202
+    public function getFullDeployMessages() {
218 203
         $strategy = $this->getDeploymentStrategy();
219 204
         if ($strategy->getActionCode()!=='full') {
220 205
             return null;
@@ -251,8 +236,7 @@  discard block
 block discarded – undo
251 236
      *
252 237
      * @return \Varchar|null
253 238
      */
254
-    public function getTag()
255
-    {
239
+    public function getTag() {
256 240
         $tags = $this->getTags();
257 241
         if ($tags->count() > 0) {
258 242
             return $tags->last();
@@ -263,8 +247,7 @@  discard block
 block discarded – undo
263 247
     /**
264 248
      * @return DeploymentStrategy
265 249
      */
266
-    public function getDeploymentStrategy()
267
-    {
250
+    public function getDeploymentStrategy() {
268 251
         $environment = $this->Environment();
269 252
         $strategy = new DeploymentStrategy($environment);
270 253
         $strategy->fromJSON($this->Strategy);
@@ -277,8 +260,7 @@  discard block
 block discarded – undo
277 260
      *
278 261
      * @return ArrayList
279 262
      */
280
-    public function getChanges()
281
-    {
263
+    public function getChanges() {
282 264
         $list = new ArrayList();
283 265
         $strategy = $this->getDeploymentStrategy();
284 266
         foreach ($strategy->getChanges() as $name => $change) {
@@ -304,8 +286,7 @@  discard block
 block discarded – undo
304 286
      *
305 287
      * @return string Resque token
306 288
      */
307
-    protected function enqueueDeployment()
308
-    {
289
+    protected function enqueueDeployment() {
309 290
         $environment = $this->Environment();
310 291
         $project = $environment->Project();
311 292
         $log = $this->log();
@@ -344,8 +325,7 @@  discard block
 block discarded – undo
344 325
         return Resque::enqueue('deploy', 'DeployJob', $args, true);
345 326
     }
346 327
 
347
-    public function start()
348
-    {
328
+    public function start() {
349 329
         $log = $this->log();
350 330
         $token = $this->enqueueDeployment();
351 331
         $this->ResqueToken = $token;
Please login to merge, or discard this patch.
code/model/jobs/DNGitFetch.php 3 patches
Indentation   +138 added lines, -138 removed lines patch added patch discarded remove patch
@@ -14,142 +14,142 @@
 block discarded – undo
14 14
 class DNGitFetch extends DataObject
15 15
 {
16 16
 
17
-    /**
18
-     * @var array
19
-     */
20
-    private static $db = array(
21
-        "ResqueToken" => "Varchar(255)",
22
-        // Observe that this is not the same as Resque status, since ResqueStatus is not persistent
23
-        // It's used for finding successful deployments and displaying that in history views in the frontend
24
-        "Status" => "Enum('Queued, Started, Finished, Failed, n/a', 'n/a')",
25
-    );
26
-
27
-    /**
28
-     * @var array
29
-     */
30
-    private static $has_one = array(
31
-        "Project" => "DNProject",
32
-        "Deployer" => "Member"
33
-    );
34
-
35
-    /**
36
-     * @param int $int
37
-     * @return string
38
-     */
39
-    public static function map_resque_status($int)
40
-    {
41
-        $remap = array(
42
-            Resque_Job_Status::STATUS_WAITING => "Queued",
43
-            Resque_Job_Status::STATUS_RUNNING => "Running",
44
-            Resque_Job_Status::STATUS_FAILED => "Failed",
45
-            Resque_Job_Status::STATUS_COMPLETE => "Complete",
46
-            false => "Invalid",
47
-        );
48
-        return $remap[$int];
49
-    }
50
-
51
-    /**
52
-     * Queue a fetch job
53
-     * @param bool $forceClone Force repository to be re-cloned
54
-     */
55
-    public function start($forceClone = false)
56
-    {
57
-        $project = $this->Project();
58
-        $log = $this->log();
59
-
60
-        if (!$this->DeployerID) {
61
-            $this->DeployerID = Member::currentUserID();
62
-        }
63
-
64
-        if ($this->DeployerID) {
65
-            $deployer = $this->Deployer();
66
-            $message = sprintf(
67
-                'Update repository job for %s initiated by %s (%s)',
68
-                $project->Name,
69
-                $deployer->getName(),
70
-                $deployer->Email
71
-            );
72
-            $log->write($message);
73
-        }
74
-
75
-        // write first, so we have the ID. We have to write again
76
-        // later once we have the resque token.
77
-        $this->write();
78
-
79
-        $args = array(
80
-            'projectID' => $project->ID,
81
-            'logfile' => $this->logfile(),
82
-            'fetchID' => $this->ID,
83
-            'forceClone' => $forceClone
84
-        );
85
-
86
-        $token = Resque::enqueue('git', 'FetchJob', $args, true);
87
-        $this->ResqueToken = $token;
88
-        $this->write();
89
-
90
-        $message = sprintf('Fetch queued as job %s', $token);
91
-        $log->write($message);
92
-    }
93
-
94
-    /**
95
-     * @param Member|null $member
96
-     * @return bool
97
-     */
98
-    public function canView($member = null)
99
-    {
100
-        return $this->Project()->canView($member);
101
-    }
102
-
103
-    /**
104
-     * Return a path to the log file.
105
-     * @return string
106
-     */
107
-    protected function logfile()
108
-    {
109
-        return sprintf(
110
-            '%s.fetch.%s.log',
111
-            $this->Project()->Name,
112
-            $this->ID
113
-        );
114
-    }
115
-
116
-    /**
117
-     * @return \DeploynautLogFile
118
-     */
119
-    public function log()
120
-    {
121
-        return new DeploynautLogFile($this->logfile());
122
-    }
123
-
124
-    /**
125
-     * @return string
126
-     */
127
-    public function LogContent()
128
-    {
129
-        return $this->log()->content();
130
-    }
131
-
132
-    /**
133
-     * Returns the status of the resque job
134
-     *
135
-     * @return string
136
-     */
137
-    public function ResqueStatus()
138
-    {
139
-        $status = new Resque_Job_Status($this->ResqueToken);
140
-        $statusCode = $status->get();
141
-        // The Resque job can no longer be found, fallback to the DNDeployment.Status
142
-        if ($statusCode === false) {
143
-            // Translate from the DNDeployment.Status to the Resque job status for UI purposes
144
-            switch ($this->Status) {
145
-                case 'Finished':
146
-                    return 'Complete';
147
-                case 'Started':
148
-                    return 'Running';
149
-                default:
150
-                    return $this->Status;
151
-            }
152
-        }
153
-        return self::map_resque_status($statusCode);
154
-    }
17
+	/**
18
+	 * @var array
19
+	 */
20
+	private static $db = array(
21
+		"ResqueToken" => "Varchar(255)",
22
+		// Observe that this is not the same as Resque status, since ResqueStatus is not persistent
23
+		// It's used for finding successful deployments and displaying that in history views in the frontend
24
+		"Status" => "Enum('Queued, Started, Finished, Failed, n/a', 'n/a')",
25
+	);
26
+
27
+	/**
28
+	 * @var array
29
+	 */
30
+	private static $has_one = array(
31
+		"Project" => "DNProject",
32
+		"Deployer" => "Member"
33
+	);
34
+
35
+	/**
36
+	 * @param int $int
37
+	 * @return string
38
+	 */
39
+	public static function map_resque_status($int)
40
+	{
41
+		$remap = array(
42
+			Resque_Job_Status::STATUS_WAITING => "Queued",
43
+			Resque_Job_Status::STATUS_RUNNING => "Running",
44
+			Resque_Job_Status::STATUS_FAILED => "Failed",
45
+			Resque_Job_Status::STATUS_COMPLETE => "Complete",
46
+			false => "Invalid",
47
+		);
48
+		return $remap[$int];
49
+	}
50
+
51
+	/**
52
+	 * Queue a fetch job
53
+	 * @param bool $forceClone Force repository to be re-cloned
54
+	 */
55
+	public function start($forceClone = false)
56
+	{
57
+		$project = $this->Project();
58
+		$log = $this->log();
59
+
60
+		if (!$this->DeployerID) {
61
+			$this->DeployerID = Member::currentUserID();
62
+		}
63
+
64
+		if ($this->DeployerID) {
65
+			$deployer = $this->Deployer();
66
+			$message = sprintf(
67
+				'Update repository job for %s initiated by %s (%s)',
68
+				$project->Name,
69
+				$deployer->getName(),
70
+				$deployer->Email
71
+			);
72
+			$log->write($message);
73
+		}
74
+
75
+		// write first, so we have the ID. We have to write again
76
+		// later once we have the resque token.
77
+		$this->write();
78
+
79
+		$args = array(
80
+			'projectID' => $project->ID,
81
+			'logfile' => $this->logfile(),
82
+			'fetchID' => $this->ID,
83
+			'forceClone' => $forceClone
84
+		);
85
+
86
+		$token = Resque::enqueue('git', 'FetchJob', $args, true);
87
+		$this->ResqueToken = $token;
88
+		$this->write();
89
+
90
+		$message = sprintf('Fetch queued as job %s', $token);
91
+		$log->write($message);
92
+	}
93
+
94
+	/**
95
+	 * @param Member|null $member
96
+	 * @return bool
97
+	 */
98
+	public function canView($member = null)
99
+	{
100
+		return $this->Project()->canView($member);
101
+	}
102
+
103
+	/**
104
+	 * Return a path to the log file.
105
+	 * @return string
106
+	 */
107
+	protected function logfile()
108
+	{
109
+		return sprintf(
110
+			'%s.fetch.%s.log',
111
+			$this->Project()->Name,
112
+			$this->ID
113
+		);
114
+	}
115
+
116
+	/**
117
+	 * @return \DeploynautLogFile
118
+	 */
119
+	public function log()
120
+	{
121
+		return new DeploynautLogFile($this->logfile());
122
+	}
123
+
124
+	/**
125
+	 * @return string
126
+	 */
127
+	public function LogContent()
128
+	{
129
+		return $this->log()->content();
130
+	}
131
+
132
+	/**
133
+	 * Returns the status of the resque job
134
+	 *
135
+	 * @return string
136
+	 */
137
+	public function ResqueStatus()
138
+	{
139
+		$status = new Resque_Job_Status($this->ResqueToken);
140
+		$statusCode = $status->get();
141
+		// The Resque job can no longer be found, fallback to the DNDeployment.Status
142
+		if ($statusCode === false) {
143
+			// Translate from the DNDeployment.Status to the Resque job status for UI purposes
144
+			switch ($this->Status) {
145
+				case 'Finished':
146
+					return 'Complete';
147
+				case 'Started':
148
+					return 'Running';
149
+				default:
150
+					return $this->Status;
151
+			}
152
+		}
153
+		return self::map_resque_status($statusCode);
154
+	}
155 155
 }
Please login to merge, or discard this patch.
Spacing   +4 added lines, -4 removed lines patch added patch discarded remove patch
@@ -57,11 +57,11 @@  discard block
 block discarded – undo
57 57
         $project = $this->Project();
58 58
         $log = $this->log();
59 59
 
60
-        if (!$this->DeployerID) {
60
+        if(!$this->DeployerID) {
61 61
             $this->DeployerID = Member::currentUserID();
62 62
         }
63 63
 
64
-        if ($this->DeployerID) {
64
+        if($this->DeployerID) {
65 65
             $deployer = $this->Deployer();
66 66
             $message = sprintf(
67 67
                 'Update repository job for %s initiated by %s (%s)',
@@ -139,9 +139,9 @@  discard block
 block discarded – undo
139 139
         $status = new Resque_Job_Status($this->ResqueToken);
140 140
         $statusCode = $status->get();
141 141
         // The Resque job can no longer be found, fallback to the DNDeployment.Status
142
-        if ($statusCode === false) {
142
+        if($statusCode === false) {
143 143
             // Translate from the DNDeployment.Status to the Resque job status for UI purposes
144
-            switch ($this->Status) {
144
+            switch($this->Status) {
145 145
                 case 'Finished':
146 146
                     return 'Complete';
147 147
                 case 'Started':
Please login to merge, or discard this patch.
Braces   +8 added lines, -16 removed lines patch added patch discarded remove patch
@@ -11,8 +11,7 @@  discard block
 block discarded – undo
11 11
  * @property int $DeployerID
12 12
  *
13 13
  */
14
-class DNGitFetch extends DataObject
15
-{
14
+class DNGitFetch extends DataObject {
16 15
 
17 16
     /**
18 17
      * @var array
@@ -36,8 +35,7 @@  discard block
 block discarded – undo
36 35
      * @param int $int
37 36
      * @return string
38 37
      */
39
-    public static function map_resque_status($int)
40
-    {
38
+    public static function map_resque_status($int) {
41 39
         $remap = array(
42 40
             Resque_Job_Status::STATUS_WAITING => "Queued",
43 41
             Resque_Job_Status::STATUS_RUNNING => "Running",
@@ -52,8 +50,7 @@  discard block
 block discarded – undo
52 50
      * Queue a fetch job
53 51
      * @param bool $forceClone Force repository to be re-cloned
54 52
      */
55
-    public function start($forceClone = false)
56
-    {
53
+    public function start($forceClone = false) {
57 54
         $project = $this->Project();
58 55
         $log = $this->log();
59 56
 
@@ -95,8 +92,7 @@  discard block
 block discarded – undo
95 92
      * @param Member|null $member
96 93
      * @return bool
97 94
      */
98
-    public function canView($member = null)
99
-    {
95
+    public function canView($member = null) {
100 96
         return $this->Project()->canView($member);
101 97
     }
102 98
 
@@ -104,8 +100,7 @@  discard block
 block discarded – undo
104 100
      * Return a path to the log file.
105 101
      * @return string
106 102
      */
107
-    protected function logfile()
108
-    {
103
+    protected function logfile() {
109 104
         return sprintf(
110 105
             '%s.fetch.%s.log',
111 106
             $this->Project()->Name,
@@ -116,16 +111,14 @@  discard block
 block discarded – undo
116 111
     /**
117 112
      * @return \DeploynautLogFile
118 113
      */
119
-    public function log()
120
-    {
114
+    public function log() {
121 115
         return new DeploynautLogFile($this->logfile());
122 116
     }
123 117
 
124 118
     /**
125 119
      * @return string
126 120
      */
127
-    public function LogContent()
128
-    {
121
+    public function LogContent() {
129 122
         return $this->log()->content();
130 123
     }
131 124
 
@@ -134,8 +127,7 @@  discard block
 block discarded – undo
134 127
      *
135 128
      * @return string
136 129
      */
137
-    public function ResqueStatus()
138
-    {
130
+    public function ResqueStatus() {
139 131
         $status = new Resque_Job_Status($this->ResqueToken);
140 132
         $statusCode = $status->get();
141 133
         // The Resque job can no longer be found, fallback to the DNDeployment.Status
Please login to merge, or discard this patch.
code/model/jobs/DNPing.php 3 patches
Indentation   +134 added lines, -134 removed lines patch added patch discarded remove patch
@@ -1,140 +1,140 @@
 block discarded – undo
1 1
 <?php
2 2
 /**
3
- * This class will queue a ping job and also proxy to the log file of that output
4
- *
5
- * @property string $ResqueToken
6
- *
7
- * @method DNEnvironment Environment()
8
- * @property int EnvironmentID
9
- * @method Member Deployer()
10
- * @property int DeployerID
11
- */
3
+	 * This class will queue a ping job and also proxy to the log file of that output
4
+	 *
5
+	 * @property string $ResqueToken
6
+	 *
7
+	 * @method DNEnvironment Environment()
8
+	 * @property int EnvironmentID
9
+	 * @method Member Deployer()
10
+	 * @property int DeployerID
11
+	 */
12 12
 class DNPing extends DataObject
13 13
 {
14 14
 
15
-    /**
16
-     * @var array
17
-     */
18
-    private static $db = array(
19
-        "ResqueToken" => "Varchar(255)",
20
-    );
21
-
22
-    /**
23
-     * @var array
24
-     */
25
-    private static $has_one = array(
26
-        "Environment" => "DNEnvironment",
27
-        "Deployer" =>"Member",
28
-    );
29
-
30
-    /**
31
-     * @return string
32
-     */
33
-    public function Link()
34
-    {
35
-        return Controller::join_links($this->Environment()->Link(), 'ping', $this->ID);
36
-    }
37
-
38
-    /**
39
-     * @return string
40
-     */
41
-    public function LogLink()
42
-    {
43
-        return $this->Link() . '/log';
44
-    }
45
-
46
-    /**
47
-     * @param Member|null $member
48
-     * @return bool
49
-     */
50
-    public function canView($member = null)
51
-    {
52
-        return $this->Environment()->canView($member);
53
-    }
54
-
55
-    /**
56
-     * Return a path to the log file.
57
-     * @return string
58
-     */
59
-    protected function logfile()
60
-    {
61
-        return sprintf(
62
-            '%s.ping.%s.log',
63
-            $this->Environment()->getFullName('.'),
64
-            $this->ID
65
-        );
66
-    }
67
-
68
-    /**
69
-     * @return \DeploynautLogFile
70
-     */
71
-    public function log()
72
-    {
73
-        return new DeploynautLogFile($this->logfile());
74
-    }
75
-
76
-    /**
77
-     * @return string
78
-     */
79
-    public function LogContent()
80
-    {
81
-        return $this->log()->content();
82
-    }
83
-
84
-    /**
85
-     * @return string
86
-     */
87
-    public function ResqueStatus()
88
-    {
89
-        $status = new Resque_Job_Status($this->ResqueToken);
90
-
91
-        $remap = array(
92
-            Resque_Job_Status::STATUS_WAITING => "Queued",
93
-            Resque_Job_Status::STATUS_RUNNING => "Running",
94
-            Resque_Job_Status::STATUS_FAILED => "Failed",
95
-            Resque_Job_Status::STATUS_COMPLETE => "Complete",
96
-            false => "Invalid",
97
-        );
98
-
99
-        return $remap[$status->get()];
100
-    }
101
-
102
-    /**
103
-     * Queue a ping job
104
-     */
105
-    public function start()
106
-    {
107
-        $environment = $this->Environment();
108
-        $project = $environment->Project();
109
-        $log = $this->log();
110
-
111
-        $args = array(
112
-            'environmentName' => $environment->Name,
113
-            'logfile' => $this->logfile(),
114
-            'projectName' => $project->Name,
115
-            'env' => $project->getProcessEnv()
116
-        );
117
-
118
-        if (!$this->DeployerID) {
119
-            $this->DeployerID = Member::currentUserID();
120
-        }
121
-
122
-        if ($this->DeployerID) {
123
-            $deployer = $this->Deployer();
124
-            $message = sprintf(
125
-                'Ping to %s initiated by %s (%s)',
126
-                $environment->getFullName(),
127
-                $deployer->getName(),
128
-                $deployer->Email
129
-            );
130
-            $log->write($message);
131
-        }
132
-
133
-        $token = Resque::enqueue('deploy', 'PingJob', $args, true);
134
-        $this->ResqueToken = $token;
135
-        $this->write();
136
-
137
-        $message = sprintf('Ping queued as job %s', $token);
138
-        $log->write($message);
139
-    }
15
+	/**
16
+	 * @var array
17
+	 */
18
+	private static $db = array(
19
+		"ResqueToken" => "Varchar(255)",
20
+	);
21
+
22
+	/**
23
+	 * @var array
24
+	 */
25
+	private static $has_one = array(
26
+		"Environment" => "DNEnvironment",
27
+		"Deployer" =>"Member",
28
+	);
29
+
30
+	/**
31
+	 * @return string
32
+	 */
33
+	public function Link()
34
+	{
35
+		return Controller::join_links($this->Environment()->Link(), 'ping', $this->ID);
36
+	}
37
+
38
+	/**
39
+	 * @return string
40
+	 */
41
+	public function LogLink()
42
+	{
43
+		return $this->Link() . '/log';
44
+	}
45
+
46
+	/**
47
+	 * @param Member|null $member
48
+	 * @return bool
49
+	 */
50
+	public function canView($member = null)
51
+	{
52
+		return $this->Environment()->canView($member);
53
+	}
54
+
55
+	/**
56
+	 * Return a path to the log file.
57
+	 * @return string
58
+	 */
59
+	protected function logfile()
60
+	{
61
+		return sprintf(
62
+			'%s.ping.%s.log',
63
+			$this->Environment()->getFullName('.'),
64
+			$this->ID
65
+		);
66
+	}
67
+
68
+	/**
69
+	 * @return \DeploynautLogFile
70
+	 */
71
+	public function log()
72
+	{
73
+		return new DeploynautLogFile($this->logfile());
74
+	}
75
+
76
+	/**
77
+	 * @return string
78
+	 */
79
+	public function LogContent()
80
+	{
81
+		return $this->log()->content();
82
+	}
83
+
84
+	/**
85
+	 * @return string
86
+	 */
87
+	public function ResqueStatus()
88
+	{
89
+		$status = new Resque_Job_Status($this->ResqueToken);
90
+
91
+		$remap = array(
92
+			Resque_Job_Status::STATUS_WAITING => "Queued",
93
+			Resque_Job_Status::STATUS_RUNNING => "Running",
94
+			Resque_Job_Status::STATUS_FAILED => "Failed",
95
+			Resque_Job_Status::STATUS_COMPLETE => "Complete",
96
+			false => "Invalid",
97
+		);
98
+
99
+		return $remap[$status->get()];
100
+	}
101
+
102
+	/**
103
+	 * Queue a ping job
104
+	 */
105
+	public function start()
106
+	{
107
+		$environment = $this->Environment();
108
+		$project = $environment->Project();
109
+		$log = $this->log();
110
+
111
+		$args = array(
112
+			'environmentName' => $environment->Name,
113
+			'logfile' => $this->logfile(),
114
+			'projectName' => $project->Name,
115
+			'env' => $project->getProcessEnv()
116
+		);
117
+
118
+		if (!$this->DeployerID) {
119
+			$this->DeployerID = Member::currentUserID();
120
+		}
121
+
122
+		if ($this->DeployerID) {
123
+			$deployer = $this->Deployer();
124
+			$message = sprintf(
125
+				'Ping to %s initiated by %s (%s)',
126
+				$environment->getFullName(),
127
+				$deployer->getName(),
128
+				$deployer->Email
129
+			);
130
+			$log->write($message);
131
+		}
132
+
133
+		$token = Resque::enqueue('deploy', 'PingJob', $args, true);
134
+		$this->ResqueToken = $token;
135
+		$this->write();
136
+
137
+		$message = sprintf('Ping queued as job %s', $token);
138
+		$log->write($message);
139
+	}
140 140
 }
Please login to merge, or discard this patch.
Spacing   +2 added lines, -2 removed lines patch added patch discarded remove patch
@@ -115,11 +115,11 @@
 block discarded – undo
115 115
             'env' => $project->getProcessEnv()
116 116
         );
117 117
 
118
-        if (!$this->DeployerID) {
118
+        if(!$this->DeployerID) {
119 119
             $this->DeployerID = Member::currentUserID();
120 120
         }
121 121
 
122
-        if ($this->DeployerID) {
122
+        if($this->DeployerID) {
123 123
             $deployer = $this->Deployer();
124 124
             $message = sprintf(
125 125
                 'Ping to %s initiated by %s (%s)',
Please login to merge, or discard this patch.
Braces   +9 added lines, -18 removed lines patch added patch discarded remove patch
@@ -9,8 +9,7 @@  discard block
 block discarded – undo
9 9
  * @method Member Deployer()
10 10
  * @property int DeployerID
11 11
  */
12
-class DNPing extends DataObject
13
-{
12
+class DNPing extends DataObject {
14 13
 
15 14
     /**
16 15
      * @var array
@@ -30,16 +29,14 @@  discard block
 block discarded – undo
30 29
     /**
31 30
      * @return string
32 31
      */
33
-    public function Link()
34
-    {
32
+    public function Link() {
35 33
         return Controller::join_links($this->Environment()->Link(), 'ping', $this->ID);
36 34
     }
37 35
 
38 36
     /**
39 37
      * @return string
40 38
      */
41
-    public function LogLink()
42
-    {
39
+    public function LogLink() {
43 40
         return $this->Link() . '/log';
44 41
     }
45 42
 
@@ -47,8 +44,7 @@  discard block
 block discarded – undo
47 44
      * @param Member|null $member
48 45
      * @return bool
49 46
      */
50
-    public function canView($member = null)
51
-    {
47
+    public function canView($member = null) {
52 48
         return $this->Environment()->canView($member);
53 49
     }
54 50
 
@@ -56,8 +52,7 @@  discard block
 block discarded – undo
56 52
      * Return a path to the log file.
57 53
      * @return string
58 54
      */
59
-    protected function logfile()
60
-    {
55
+    protected function logfile() {
61 56
         return sprintf(
62 57
             '%s.ping.%s.log',
63 58
             $this->Environment()->getFullName('.'),
@@ -68,24 +63,21 @@  discard block
 block discarded – undo
68 63
     /**
69 64
      * @return \DeploynautLogFile
70 65
      */
71
-    public function log()
72
-    {
66
+    public function log() {
73 67
         return new DeploynautLogFile($this->logfile());
74 68
     }
75 69
 
76 70
     /**
77 71
      * @return string
78 72
      */
79
-    public function LogContent()
80
-    {
73
+    public function LogContent() {
81 74
         return $this->log()->content();
82 75
     }
83 76
 
84 77
     /**
85 78
      * @return string
86 79
      */
87
-    public function ResqueStatus()
88
-    {
80
+    public function ResqueStatus() {
89 81
         $status = new Resque_Job_Status($this->ResqueToken);
90 82
 
91 83
         $remap = array(
@@ -102,8 +94,7 @@  discard block
 block discarded – undo
102 94
     /**
103 95
      * Queue a ping job
104 96
      */
105
-    public function start()
106
-    {
97
+    public function start() {
107 98
         $environment = $this->Environment();
108 99
         $project = $environment->Project();
109 100
         $log = $this->log();
Please login to merge, or discard this patch.