Workflow::__construct()   A
last analyzed

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 0
Metric Value
dl 0
loc 4
ccs 3
cts 3
cp 1
rs 10
c 0
b 0
f 0
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 28
    public function __construct(array $activities)
48
    {
49 28
        $this->activities = $activities;
50 28
    }
51
52
    /**
53
     * {@inheritdoc}
54
     */
55 6
    public function execute(ProfileInterface $profile)
56
    {
57 6
        if (null === $this->eventDispatcher || null === $this->logger) {
58
            throw new \LogicException('Workflow can not be executed without provided Logger and EventDispatcher.');
59
        }
60
61 6
        $backup = new Backup($profile->getName());
62
63 6
        $this->logger->info(sprintf('About to execute backup for profile: "%s".', $profile->getName()));
64 6
        $this->eventDispatcher->dispatch(BackupEvents::BEGIN, new BackupEvent($this, $profile, $backup));
65
66 6
        $terminate = function() use ($profile) {
67
68
            try {
69
70 6
                $this->eventDispatcher->dispatch(BackupEvents::TERMINATE, new BackupEvent($profile));
71 6
                $this->logger->info(sprintf('Backup for profile "%s" successfully terminated.', $profile->getName()));
72
73 3
            } catch (\Exception $e) {
74
75
                $this->logger->alert(sprintf('Could not terminate backup process for profile "%s".', $profile->getName()));
76
77
            }
78 6
        };
79
80 6
        \Closure::bind($terminate, $this);
81
82
        try {
83
84
            /**
85
             * @var WorkflowActivityInterface $activity
86
             */
87 6
            foreach ($this->activities as $activity) {
88 6
                $this->executeActivity($activity, $profile, $backup);
89 2
            }
90
91 4
            $terminate();
92
93 4
        } catch (EmptySourceException $e) {
94
95
            $this->logger->info(sprintf('Backup for profile "%s" didn\'t yield any file for backup.', $profile->getName()));
96
97
            $terminate();
98
99 2
        } 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 1
            ));
109
110 2
            $terminate();
111
        }
112 6
    }
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 6
    protected function executeActivity(WorkflowActivityInterface $activity, ProfileInterface $profile, BackupInterface $backup)
124
    {
125
        $activity
126 6
            ->setBackup($backup)
127 6
            ->setProfile($profile);
128
129
        /**
130
         * @var LoggerAwareInterface $activity
131
         */
132 6
        if ($activity instanceof LoggerAwareInterface) {
133 6
            $activity->setLogger($this->logger);
134 3
        }
135
136
        /**
137
         * @var EventDispatcherAwareInterface $activity
138
         */
139 6
        if ($activity instanceof EventDispatcherAwareInterface) {
140 6
            $activity->setEventDispatcher($this->eventDispatcher);
141 3
        }
142
143
        try {
144
            /**
145
             * @var WorkflowActivityInterface $activity
146
             */
147 6
            $activity->execute();
148
149 4
        } catch (\Exception $e) {
150
151 2
            $this->eventDispatcher->dispatch(BackupEvents::ERROR, new BackupEvent($this, $profile, $backup, $activity));
152
153 2
            throw $e;
154
        }
155 4
    }
156
157
    /**
158
     * Builds default workflow.
159
     *
160
     * @return Workflow
161
     */
162 28
    public static function build()
163
    {
164 28
        return new Workflow(array(
165 28
            new Fetch(),
166 28
            new Process(),
167 28
            new Name(),
168 28
            new PreRotate(),
169 28
            new Push(),
170 28
            new PostRotate()
171 14
        ));
172
    }
173
}
174