Completed
Pull Request — master (#590)
by Greg
03:12
created

CopyDir::simplifyForCompare()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 4
rs 10
cc 1
eloc 2
nc 1
nop 1
1
<?php
2
namespace Robo\Task\Filesystem;
3
4
use Robo\Common\ResourceExistenceChecker;
5
use Robo\Result;
6
use Robo\Exception\TaskException;
7
8
/**
9
 * Copies one dir into another
10
 *
11
 * ``` php
12
 * <?php
13
 * $this->taskCopyDir(['dist/config' => 'config'])->run();
14
 * // as shortcut
15
 * $this->_copyDir('dist/config', 'config');
16
 * ?>
17
 * ```
18
 */
19
class CopyDir extends BaseDir
20
{
21
    use ResourceExistenceChecker;
22
23
    /**
24
     * @var int
25
     */
26
    protected $chmod = 0755;
27
28
    /**
29
     * Files to exclude on copying.
30
     *
31
     * @var string[]
32
     */
33
    protected $exclude = [];
34
35
    /**
36
     * Overwrite destination files newer than source files.
37
     */
38
    protected $overwrite = true;
39
40
    /**
41
     * {@inheritdoc}
42
     */
43
    public function run()
44
    {
45
        if (!$this->checkResources($this->dirs, 'dir')) {
46
            return Result::error($this, 'Source directories are missing!');
47
        }
48
        foreach ($this->dirs as $src => $dst) {
49
            $this->copyDir($src, $dst);
50
            $this->printTaskInfo('Copied from {source} to {destination}', ['source' => $src, 'destination' => $dst]);
51
        }
52
        return Result::success($this);
53
    }
54
55
    /**
56
     * Sets the default folder permissions for the destination if it doesn't exist
57
     *
58
     * @link http://en.wikipedia.org/wiki/Chmod
59
     * @link http://php.net/manual/en/function.mkdir.php
60
     * @link http://php.net/manual/en/function.chmod.php
61
     *
62
     * @param int $value
63
     *
64
     * @return $this
65
     */
66
    public function dirPermissions($value)
67
    {
68
        $this->chmod = (int)$value;
69
        return $this;
70
    }
71
72
    /**
73
     * List files to exclude.
74
     *
75
     * @param string[] $exclude
76
     *
77
     * @return $this
78
     */
79
    public function exclude($exclude = [])
80
    {
81
        $this->exclude = $this->simplifyForCompare($exclude);
82
        return $this;
83
    }
84
85
    /**
86
     * Destination files newer than source files are overwritten.
87
     *
88
     * @param bool $overwrite
89
     *
90
     * @return $this
91
     */
92
    public function overwrite($overwrite)
93
    {
94
        $this->overwrite = $overwrite;
95
        return $this;
96
    }
97
98
    /**
99
     * Copies a directory to another location.
100
     *
101
     * @param string $src Source directory
102
     * @param string $dst Destination directory
103
     * @param string $parent Parent directory
104
     *
105
     * @throws \Robo\Exception\TaskException
106
     */
107
    protected function copyDir($src, $dst, $parent = '')
0 ignored issues
show
Coding Style Best Practice introduced by
Please use __construct() instead of a PHP4-style constructor that is named after the class.
Loading history...
108
    {
109
        $dir = @opendir($src);
110
        if (false === $dir) {
111
            throw new TaskException($this, "Cannot open source directory '" . $src . "'");
112
        }
113
        if (!is_dir($dst)) {
114
            mkdir($dst, $this->chmod, true);
115
        }
116
        while (false !== ($file = readdir($dir))) {
117
            // Support basename and full path exclusion.
118
            if (in_array($file, $this->exclude) || in_array($this->simplifyForCompare($parent . $file), $this->exclude) || in_array($this->simplifyForCompare($src . DIRECTORY_SEPARATOR . $file), $this->exclude)) {
119
                continue;
120
            }
121
            if (($file !== '.') && ($file !== '..')) {
122
                $srcFile = $src . '/' . $file;
123
                $destFile = $dst . '/' . $file;
124
                if (is_dir($srcFile)) {
125
                    $this->copyDir($srcFile, $destFile, $parent . $file . DIRECTORY_SEPARATOR);
126
                } else {
127
                    $this->fs->copy($srcFile, $destFile, $this->overwrite);
128
                }
129
            }
130
        }
131
        closedir($dir);
132
    }
133
134
    /**
135
     * Avoid problems comparing paths on Windows that may have a
136
     * combination of DIRECTORY_SEPARATOR and /.
137
     */
138
    protected function simplifyForCompare($item)
139
    {
140
        return str_replace(DIRECTORY_SEPARATOR, '/', $item);
141
    }
142
}
143