Completed
Push — master ( 27b3cb...f1c80d )
by Nikola
02:33
created

Workflow::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

Changes 4
Bugs 0 Features 1
Metric Value
c 4
b 0
f 1
dl 0
loc 4
ccs 3
cts 3
cp 1
rs 10
cc 1
eloc 2
nc 1
nop 1
crap 1
1
<?php
2
/*
3
 * This file is part of the Backup package, an RunOpenCode project.
4
 *
5
 * (c) 2015 RunOpenCode
6
 *
7
 * For the full copyright and license information, please view the LICENSE
8
 * file that was distributed with this source code.
9
 *
10
 * This project is fork of "kbond/php-backup", for full credits info, please
11
 * view CREDITS file that was distributed with this source code.
12
 */
13
namespace RunOpenCode\Backup\Workflow;
14
15
use Psr\Log\LoggerInterface;
16
use RunOpenCode\Backup\Backup\Backup;
17
use RunOpenCode\Backup\Contract\BackupInterface;
18
use RunOpenCode\Backup\Contract\EventDispatcherAwareInterface;
19
use RunOpenCode\Backup\Contract\LoggerAwareInterface;
20
use RunOpenCode\Backup\Contract\ProfileInterface;
21
use RunOpenCode\Backup\Contract\WorkflowActivityInterface;
22
use RunOpenCode\Backup\Contract\WorkflowInterface;
23
use RunOpenCode\Backup\Event\BackupEvent;
24
use RunOpenCode\Backup\Event\BackupEvents;
25
use RunOpenCode\Backup\Event\EventDispatcherAwareTrait;
26
use RunOpenCode\Backup\Exception\EmptySourceException;
27
use RunOpenCode\Backup\Log\LoggerAwareTrait;
28
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
29
30
/**
31
 * Class Workflow
32
 *
33
 * Workflow is entry point of backup workflow that executes workflow activities in given sequence.
34
 *
35
 * @package RunOpenCode\Backup\Workflow
36
 */
37
class Workflow implements WorkflowInterface
38
{
39
    use EventDispatcherAwareTrait;
40
    use LoggerAwareTrait;
41
42
    /**
43
     * @var WorkflowActivityInterface[]
44
     */
45
    private $activities;
46
47 26
    public function __construct(array $activities)
48
    {
49 26
        $this->activities = $activities;
50 26
    }
51
52
    /**
53
     * {@inheritdoc}
54
     */
55 4
    public function execute(ProfileInterface $profile)
56
    {
57 4
        if (empty($this->eventDispatcher) || empty($this->logger)) {
58
            throw new \LogicException('Workflow can not be executed without provided Logger and EventDispatcher.');
59
        }
60
61 4
        $backup = new Backup($profile->getName());
62
63 4
        $this->logger->info(sprintf('About to execute backup for profile: "%s".', $profile->getName()));
64 4
        $this->eventDispatcher->dispatch(BackupEvents::BEGIN, new BackupEvent($this, $profile, $backup));
65
66 4
        $terminate = function() use ($profile) {
67
68
            try {
69
70 4
                $this->eventDispatcher->dispatch(BackupEvents::TERMINATE, new BackupEvent($profile));
71 2
                $this->logger->info(sprintf('Backup for profile "%s" successfully terminated.', $profile->getName()));
72
73 4
            } catch (\Exception $e) {
74
75 2
                $this->logger->alert(sprintf('Could not terminate backup process for profile "%s".', $profile->getName()));
76
77
            }
78 4
        };
79
80 4
        \Closure::bind($terminate, $this);
81
82
        try {
83
84
            /**
85
             * @var WorkflowActivityInterface $activity
86
             */
87 4
            foreach ($this->activities as $activity) {
88 4
                $this->executeActivity($activity, $profile, $backup);
89
            }
90
91
            $terminate();
92
93 4
        } catch (EmptySourceException $e) {
94
95 2
            $this->logger->info(sprintf('Backup for profile "%s" didn\'t yield any file for backup.', $profile->getName()));
96
97 2
            $terminate();
98
99 4
        } catch (\Exception $e) {
100
101 2
            $this->eventDispatcher->dispatch(BackupEvents::ERROR, new BackupEvent($this, $profile));
102 2
            $this->logger->critical(sprintf('There has been an error while executing backup profile "%s".', $profile->getName()), array(
103 2
                'message' => $e->getMessage(),
104 2
                'code' => $e->getCode(),
105 2
                'file' => $e->getFile(),
106 2
                'line' => $e->getLine(),
107 2
                'trace' => $e->getTrace()
108 2
            ));
109
110 2
            $terminate();
111
        }
112 4
    }
113
114
    /**
115
     * Execute workflow activity.
116
     *
117
     * @param WorkflowActivityInterface $activity Activity to execute.
118
     * @param ProfileInterface $profile Profile for which activity is being executed.
119
     * @param BackupInterface $backup Backup for which activity is being executed.
120
     *
121
     * @throws \Exception
122
     */
123 4
    protected function executeActivity(WorkflowActivityInterface $activity, ProfileInterface $profile, BackupInterface $backup)
124
    {
125
        $activity
126 4
            ->setBackup($backup)
127 4
            ->setProfile($profile);
128
129
        /**
130
         * @var LoggerAwareInterface $activity
131
         */
132 4
        if ($activity instanceof LoggerAwareInterface) {
133 4
            $activity->setLogger($this->logger);
134 4
        }
135
136
        /**
137
         * @var EventDispatcherAwareInterface $activity
138
         */
139 4
        if ($activity instanceof EventDispatcherAwareInterface) {
140 4
            $activity->setEventDispatcher($this->eventDispatcher);
141 4
        }
142
143
        try {
144
            /**
145
             * @var WorkflowActivityInterface $activity
146
             */
147 4
            $activity->execute();
148
149 4
        } catch (\Exception $e) {
150
151 4
            $this->eventDispatcher->dispatch(BackupEvents::ERROR, new BackupEvent($this, $profile, $backup, $activity));
152
153 4
            throw $e;
154
        }
155
    }
156
157
    /**
158
     * Builds default workflow.
159
     *
160
     * @return Workflow
161
     */
162 26
    public static function build()
163
    {
164 26
        return new Workflow(array(
165 26
            new Fetch(),
166 26
            new Process(),
167 26
            new Name(),
168 26
            new PreRotate(),
169 26
            new Push(),
170 26
            new PostRotate()
171 26
        ));
172
    }
173
}
174