1
<?php
2
/**
3
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
4
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
5
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
6
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
7
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
8
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
9
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
10
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
11
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
12
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
13
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
14
 *
15
 * This software consists of voluntary contributions made by many individuals
16
 * and is licensed under the LGPL. For more information please see
17
 * <http://phing.info>.
18
 */
19

20
/**
21
 * Moves a file or directory to a new file or directory.
22
 *
23
 * By default, the destination file is overwritten if it
24
 * already exists.  When overwrite is turned off, then files
25
 * are only moved if the source file is newer than the
26
 * destination file, or when the destination file does not
27
 * exist.
28
 *
29
 * Source files and directories are only deleted when the file or
30
 * directory has been copied to the destination successfully.
31
 *
32
 * @package phing.tasks.system
33
 */
34
class MoveTask extends CopyTask
35
{
36 1
    public function __construct()
37
    {
38 1
        parent::__construct();
39 1
        $this->overwrite = true;
40
    }
41

42
    /**
43
     * Validates attributes coming in from XML
44
     *
45
     * @return void
46
     *
47
     * @throws BuildException
48
     */
49 1
    protected function validateAttributes()
50
    {
51 1
        if ($this->file !== null && $this->file->isDirectory()) {
52
            if (
53 1
                ($this->destFile !== null
54 1
                && $this->destDir !== null)
55 1
                || ($this->destFile === null
56 0
                && $this->destDir === null)
57
            ) {
58 0
                throw new BuildException("One and only one of tofile and todir must be set.");
59
            }
60

61 1
            if ($this->destFile === null) {
62 0
                $this->destFile = new PhingFile($this->destDir, $this->file->getName());
63
            }
64

65 1
            if ($this->destDir === null) {
66 1
                $this->destDir = $this->destFile->getParentFile();
67
            }
68

69 1
            $this->completeDirMap[$this->file->getAbsolutePath()] = $this->destFile->getAbsolutePath();
70

71 1
            $this->file = null;
72
        } else {
73 1
            parent::validateAttributes();
74
        }
75
    }
76

77 1
    protected function doWork()
78
    {
79 1
        if (count($this->completeDirMap) > 0) {
80 1
            foreach ($this->completeDirMap as $from => $to) {
81 1
                $f = new PhingFile($from);
82 1
                $d = new PhingFile($to);
83

84
                try { // try to rename
85 1
                    $this->log("Attempting to rename $from to $to", $this->verbosity);
86 1
                    if (!empty($this->filterChains)) {
87 0
                        $this->fileUtils->copyFile(
88 0
                            $f,
89
                            $d,
90 0
                            $this->getProject(),
91 0
                            $this->overwrite,
92 0
                            $this->preserveLMT,
93 0
                            $this->filterChains,
94 0
                            $this->mode,
95 0
                            $this->preservePermissions,
96 0
                            $this->granularity
97
                        );
98 0
                        $f->delete(true);
99
                    } else {
100 1
                        $this->fileUtils->renameFile($f, $d, $this->overwrite);
101
                    }
102 0
                } catch (IOException $ioe) {
103 0
                    $this->logError("Failed to rename $from to $to: " . $ioe->getMessage());
104
                }
105
            }
106
        }
107

108 1
        $copyMapSize = count($this->fileCopyMap);
109 1
        if ($copyMapSize > 0) {
110
            // files to move
111 1
            $this->log("Moving $copyMapSize files to " . $this->destDir->getAbsolutePath());
112

113 1
            foreach ($this->fileCopyMap as $from => $to) {
114 1
                if ($from == $to) {
115 0
                    $this->log("Skipping self-move of $from", $this->verbosity);
116 0
                    continue;
117
                }
118

119 1
                $f = new PhingFile($from);
120 1
                $d = new PhingFile($to);
121

122
                try { // try to move
123 1
                    $this->log("Moving $from to $to", $this->verbosity);
124

125 1
                    $this->fileUtils->copyFile(
126 1
                        $f,
127
                        $d,
128 1
                        $this->getProject(),
129 1
                        $this->overwrite,
130 1
                        $this->preserveLMT,
131 1
                        $this->filterChains,
132 1
                        $this->mode,
133 1
                        $this->preservePermissions,
134 1
                        $this->granularity
135
                    );
136

137 1
                    $f->delete();
138 0
                } catch (IOException $ioe) {
139 0
                    $this->logError("Failed to move $from to $to: " . $ioe->getMessage(), $this->getLocation());
140
                }
141
            } // foreach fileCopyMap
142
        } // if copyMapSize
143

144
        // handle empty dirs if appropriate
145 1
        if ($this->includeEmpty) {
146 1
            $count = 0;
147 1
            foreach ($this->dirCopyMap as $srcDir => $destDir) {
148 0
                $d = new PhingFile((string) $destDir);
149 0
                if (!$d->exists()) {
150 0
                    if (!$d->mkdirs()) {
151 0
                        $this->logError("Unable to create directory " . $d->getAbsolutePath());
152
                    } else {
153 0
                        $count++;
154
                    }
155
                }
156
            }
157 1
            if ($count > 0) {
158 0
                $this->log(
159 0
                    "moved $count empty director" . ($count == 1 ? "y" : "ies") . " to " . $this->destDir->getAbsolutePath(
160
                    )
161
                );
162
            }
163
        }
164

165 1
        if (count($this->filesets) > 0) {
166
            // process filesets
167 1
            foreach ($this->filesets as $fs) {
168 1
                $dir = $fs->getDir($this->project);
169 1
                if ($this->okToDelete($dir)) {
170 1
                    $this->deleteDir($dir);
171
                }
172
            }
173
        }
174

175 1
        $dirsets = $this->getDirSets();
176 1
        if (count($dirsets) > 0) {
177
            // process dirsets
178 0
            foreach ($dirsets as $ds) {
179 0
                $dir = $ds->getDir($this->project);
180 0
                if ($this->okToDelete($dir)) {
181 0
                    $this->deleteDir($dir);
182
                }
183
            }
184
        }
185
    }
186

187
    /**
188
     * Its only ok to delete a dir tree if there are no files in it.
189
     *
190
     * @param $d
191
     *
192
     * @throws IOException
193
     *
194
     * @return bool
195
     */
196 1
    private function okToDelete(PhingFile $d)
197
    {
198 1
        $list = $d->listDir();
199 1
        if ($list === null) {
200 0
            return false; // maybe io error?
201
        }
202

203 1
        foreach ($list as $s) {
204 1
            $f = new PhingFile($d, $s);
205 1
            if ($f->isDirectory()) {
206 1
                if (!$this->okToDelete($f)) {
207 0
                    return false;
208
                }
209
            } else {
210
                // found a file
211 0
                return false;
212
            }
213
        }
214

215 1
        return true;
216
    }
217

218
    /**
219
     * Go and delete the directory tree.
220
     *
221
     * @param $d
222
     *
223
     * @throws BuildException
224
     * @throws IOException
225
     */
226 1
    private function deleteDir(PhingFile $d)
227
    {
228 1
        $list = $d->listDir();
229 1
        if ($list === null) {
230 0
            return; // on an io error list() can return null
231
        }
232

233 1
        foreach ($list as $fname) {
234 1
            $f = new PhingFile($d, $fname);
235 1
            if ($f->isDirectory()) {
236 1
                $this->deleteDir($f);
237
            } else {
238 0
                throw new BuildException("UNEXPECTED ERROR - The file " . $f->getAbsolutePath() . " should not exist!");
239
            }
240
        }
241

242 1
        $this->log("Deleting directory " . $d->getPath(), $this->verbosity);
243
        try {
244 1
            $d->delete();
245 0
        } catch (Exception $e) {
246 0
            $this->logError("Unable to delete directory " . $d->__toString() . ": " . $e->getMessage());
247
        }
248
    }
249
}

Read our documentation on viewing source code .

Loading