TaskGenerator::setLogger()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 4
ccs 2
cts 2
cp 1
rs 10
cc 1
eloc 2
nc 1
nop 1
crap 1
1
<?php
2
namespace AppBundle\Sync;
3
4
use AppBundle\Exception\TaskException;
5
use AppBundle\Sync\Entity\FileCollection;
6
use AppBundle\Sync\Entity\Task;
7
use AppBundle\Sync\Entity\Task\Add;
8
use AppBundle\Sync\Entity\Task\Delete;
9
use AppBundle\Sync\Entity\Task\Update;
10
use AppBundle\Sync\Entity\TaskCollection;
11
use AppBundle\Sync\Entity\File;
12
use Psr\Log\NullLogger;
13
use Psr\Log\LoggerInterface;
14
15
/**
16
 * Compare two FileCollections and generate tasks
17
 *
18
 * @author Sergey Sadovoi <[email protected]>
19
 */
20
class TaskGenerator
21
{
22
    /**
23
     * @var string Path for slave file
24
     */
25
    protected $slavePathTpl;
26
    /**
27
     * @var LoggerInterface
28
     */
29
    protected $logger;
30
31
    /**
32
     * @param string $path
33 2
     */
34
    public function setSlavePathTpl($path)
35 2
    {
36 2
        $this->slavePathTpl = $path;
37
    }
38
39
    /**
40
     * @return string
41
     *
42
     * @throws TaskException
43 3
     */
44
    public function getSlavePathTpl()
45 3
    {
46 1
        if ($this->slavePathTpl == '') {
47 1
            throw new TaskException(
48
                '[TaskGenerator] You must set the Slave Path template',
49 1
                TaskException::SLAVE_PATH_NOT_SET
50
            );
51
        }
52 2
53
        return $this->slavePathTpl;
54
    }
55
56
    /**
57
     * Get the slave path form template
58
     *
59
     * @param string $uid  File uid
60
     *
61
     * @return string  Path to file
62 2
     */
63
    public function getSlavePath($uid)
64 2
    {
65 2
        $path = $this->getSlavePathTpl();
66 2
        $path = str_replace('__uid__', $uid, $path);
67
        $path = str_replace('__program__', substr($uid, 0, 4), $path);
68 2
69
        return $path;
70
    }
71
72
    /**
73
     * Compare collections and create tasks
74
     *
75
     * @param FileCollection $master
76
     * @param FileCollection $slave
77
     *
78
     * @return TaskCollection
79 2
     */
80
    public function handle(FileCollection $master, FileCollection $slave)
81 2
    {
82 2
        $masterHash = $this->getHash($master);
83
        $slaveHash  = $this->getHash($slave);
84 2
85 2
        $tasks = new TaskCollection();
86 2
        $createTaskCounter = 0;
87
        $deleteTaskCounter = 0;
88 2
89
        $logger = $this->getLogger();
90
91
        /**
92
         * Add and Update
93
         *
94
         * @var File $masterFile
95
         * @var File $slaveFile
96 2
         */
97
        $diff = array_diff_assoc($masterHash, $slaveHash);
98 2
99 2
        foreach ($diff as $uid => $hash) {
100 2
            $masterFile = $master->getByUid($uid);
101
            $slaveFile  = $slave->getByUid($uid);
102 2
103 2
            $new = !isset($slaveHash[$uid]);
104 2
            if ($new) {
105 2
                $task = new Add();
106 2
            } else {
107
                $task = new Update();
108
            }
109 2
110 2
            $task->setSourcePath($masterFile->getPath());
111
            $task->setDestPath($this->getSlavePath($uid));
112 2
113
            $tasks->addTask($task);
114 2
115 2
            $logger->info(
116 2
                sprintf(
117 2
                    '[TaskGenerator] Generated "%s" task based on files: S[%s] D[%s]',
118 2
                    $task->getName(),
119
                    $masterFile,
120 2
                    $slaveFile
121 2
                )
122
            );
123 2
124 2
            $createTaskCounter++;
125
        }
126
127 2
        // Delete
128
        $diff = array_diff_assoc($slaveHash, $masterHash);
129 2
130
        foreach ($diff as $uid => $hash) {
131 2
            // Skip changed files
132 2
            if (isset($masterHash[$uid])) {
133
                continue;
134
            }
135
136 2
            // Delete task
137
            $slaveFile = $slave->getByUid($uid);
138 2
139 2
            $task = new Delete();
140
            $task->setDestPath($slaveFile->getPath());
141 2
142
            $tasks->addTask($task);
143 2
144 2
            $logger->info(
145 2
                sprintf(
146 2
                    '[TaskGenerator] Generated "%s" task based on file: D[%s]',
147
                    $task->getName(),
148 2
                    $slaveFile
149 2
                )
150
            );
151 2
152 2
            $deleteTaskCounter++;
153
        }
154
155
        // Halt on huge delete action
156 2
        if ($deleteTaskCounter > 50) {
157
            throw new TaskException(
158
                'Huge amount of DELETE tasks. Exiting.',
159
                TaskException::HUGE_AMOUNT_TO_DELETE
160
            );
161
        }
162 2
163
        return $tasks;
164
    }
165
166
    /**
167
     * Calculates hashes for FileCollection
168
     *
169
     * @param FileCollection $files
170
     *
171
     * @return array  of hashes
172 2
     */
173
    private function getHash(FileCollection $files)
174 2
    {
175
        $hash = [];
176
177
        /**
178
         * @var File $file
179 2
         */
180 2
        foreach ($files as $file) {
181 2
            $hash[$file->getUid()] = md5($file->getUid() . $file->getSize());
182
        }
183 2
184
        return $hash;
185
    }
186
187
    /**
188
     * @return LoggerInterface
189 2
     */
190
    protected function getLogger()
191 2
    {
192 1
        if (is_null($this->logger)) {
193
            return new NullLogger();
194
        }
195 1
196
        return $this->logger;
197
    }
198
199
    /**
200
     * @param LoggerInterface $logger
201 1
     */
202
    public function setLogger(LoggerInterface $logger)
203 1
    {
204 1
        $this->logger = $logger;
205
    }
206
}
207