RsyncClient::getOptionsString()   B
last analyzed

Complexity

Conditions 5
Paths 5

Size

Total Lines 19
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 12
CRAP Score 5.0729

Importance

Changes 0
Metric Value
dl 0
loc 19
ccs 12
cts 14
cp 0.8571
rs 8.8571
c 0
b 0
f 0
cc 5
eloc 11
nc 5
nop 0
crap 5.0729
1
<?php
2
3
namespace SyncFS\Client;
4
5
use Symfony\Component\Process\Process;
6
use SyncFS\Event;
7
8
/**
9
 * Class RsyncClient
10
 *
11
 * @package SyncFS\Client
12
 * @author  Matej Velikonja <[email protected]>
13
 */
14
class RsyncClient implements ClientInterface
15
{
16
    /**
17
     * @var array
18
     */
19
    private $options;
20
21
    /**
22
     * @var string
23
     */
24
    private $executable;
25
26
    /**
27
     * @param array $options Use options from rSync manual page
28
     *
29
     * @link http://linux.die.net/man/1/rsync
30
     */
31 3
    public function __construct(array $options = array())
32
    {
33
        $defaultOptions = array(
34
            'rsync' => array(
35 3
                'archive'        => true,
36 3
                'verbose'        => true,
37 3
                'compress'       => true,
38 3
                'human-readable' => true,
39 3
                'delete'         => false,
40 3
                'progress'       => true,
41 3
            ),
42
            'timeout' => 60
43 3
        );
44
45 3
        $this->options    = array_replace_recursive($defaultOptions, $options);
46 3
        $this->executable = '/usr/bin/rsync';
47 3
    }
48
49
    /**
50
     * Sync $origin directory with $target one.
51
     * If SSH was configured, you must use absolute path
52
     * in the target directory
53
     *
54
     * @param string   $src
55
     * @param string   $dst
56
     * @param Callable $callback
57
     *
58
     * @throws ClientException
59
     *
60
     * @return int|null
61
     */
62 3
    public function sync($src, $dst, $callback = null)
63
    {
64 3
        if (! strlen($dst)) {
65
            throw new ClientException('Destination parameter missing.');
66
        }
67
68 3
        if (! strlen($src)) {
69
            throw new ClientException('Source parameter missing.');
70
        }
71
72 3
        if ($callback !== null && !is_callable($callback)) {
73 1
            throw new ClientException(sprintf('%s is not callable.', $callback));
74
        }
75
76 2
        $options = $this->getOptionsString();
77 2
        $command = implode(' ', array($this->executable, $options, $src, $dst));
78 2
        $process = new Process($command);
79 2
        $process->setTimeout($this->options['timeout']);
80
81 2
        $process->run(
82 2
            function ($type, $buffer) use ($callback) {
83 2
                if (Process::ERR === $type) {
84
                    return;
85
                }
86
87 2
                if ($callback) {
88 2
                    $event = new Event(
89 2
                        $buffer,
90
                        null //TODO
91 2
                    );
92
93 2
                    call_user_func($callback, $event);
94 2
                }
95 2
            }
96 2
        );
97
98 2
        if (! $process->isSuccessful()) {
99
            throw new ClientException($process->getErrorOutput());
100
        }
101
102 2
        return $process->getExitCode();
103
    }
104
105
    /**
106
     * @return string
107
     */
108 2
    private function getOptionsString()
109
    {
110 2
        $options   = array_filter($this->options['rsync']); // remove all options with false value
111 2
        $arguments = '';
112
113 2
        foreach ($options as $name => $value) {
114 2
            $prefix = ' -';
115 2
            if (strlen($name) > 1) {
116 2
                $prefix = ' --';
117 2
            }
118
119 2
            $arguments .= $prefix . $name;
120 2
            if ($value && !is_bool($value)) {
121
                $arguments .= '=' . $value;
122
            }
123 2
        }
124
125 2
        return trim($arguments);
126
    }
127
}
128