1<?php
2/*
3 *  $Id: abac916657e9962cdb09fcb6bbcaa7963be25e96 $
4 *
5 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
6 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
7 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
8 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
9 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
10 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
11 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
12 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
13 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
14 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
15 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
16 *
17 * This software consists of voluntary contributions made by many individuals
18 * and is licensed under the LGPL. For more information please see
19 * <http://phing.info>.
20 */
21
22require_once 'phing/Task.php';
23include_once 'phing/system/io/FileSystem.php';
24include_once 'phing/tasks/system/condition/ConditionBase.php';
25
26/**
27 * <available> task.
28 *
29 * Note: implements condition interface (see condition/Condition.php)
30 *
31 * @author    Andreas Aderhold <andi@binarycloud.com>
32 * @copyright 2001,2002 THYRELL. All rights reserved
33 * @version   $Id: abac916657e9962cdb09fcb6bbcaa7963be25e96 $
34 * @package   phing.tasks.system
35 */
36class AvailableTask extends Task {
37
38    /** Property to check for. */
39    private $property;
40
41    /** Value property should be set to. */
42    private $value = "true";
43
44    /** File/directory to check existence */
45    private $file;
46
47    /** Resource to check for */
48    private $resource;
49
50    /** Extension to check if is loaded */
51    private $extension;
52
53    private $type = null;
54    private $filepath = null;
55
56    private $followSymlinks = false;
57
58    function setProperty($property) {
59        $this->property = (string) $property;
60    }
61
62    function setValue($value) {
63        $this->value = (string) $value;
64    }
65
66    function setFile(PhingFile $file) {
67        $this->file = $file;
68    }
69
70    function setResource($resource) {
71        $this->resource = (string) $resource;
72    }
73
74    function setExtension($extension) {
75        $this->extension = (string) $extension;
76    }
77
78    function setType($type) {
79        $this->type = (string) strtolower($type);
80    }
81
82    public function setFollowSymlinks($followSymlinks)
83    {
84        $this->followSymlinks = (bool) $followSymlinks;
85    }
86
87    /**
88     * Set the path to use when looking for a file.
89     *
90     * @param Path $filepath a Path instance containing the search path for files.
91     */
92    public function setFilepath(Path $filepath) {
93        if ($this->filepath === null) {
94            $this->filepath = $filepath;
95        } else {
96            $this->filepath->append($filepath);
97        }
98    }
99
100    /**
101     * Creates a path to be configured
102     *
103     * @return Path
104     */
105    public function createFilepath() {
106        if ($this->filepath === null) {
107            $this->filepath = new Path($this->project);
108        }
109        return $this->filepath->createPath();
110    }
111
112    function main() {
113        if ($this->property === null) {
114            throw new BuildException("property attribute is required", $this->location);
115        }
116        if ($this->evaluate()) {
117            $this->project->setProperty($this->property, $this->value);
118        }
119    }
120
121    function evaluate() {
122        if ($this->file === null && $this->resource === null && $this->extension === null) {
123            throw new BuildException("At least one of (file|resource|extension) is required", $this->location);
124        }
125
126        if ($this->type !== null && ($this->type !== "file" && $this->type !== "dir")) {
127            throw new BuildException("Type must be one of either dir or file", $this->location);
128        }
129
130        if (($this->file !== null) && !$this->_checkFile()) {
131            $this->log("Unable to find " . $this->file->__toString() . " to set property " . $this->property, Project::MSG_VERBOSE);
132            return false;
133        }
134
135        if (($this->resource !== null) && !$this->_checkResource($this->resource)) {
136            $this->log("Unable to load resource " . $this->resource . " to set property " . $this->property, Project::MSG_VERBOSE);
137            return false;
138        }
139
140        if ($this->extension !== null && !extension_loaded($this->extension)) {
141            $this->log("Unable to load extension " . $this->extension . " to set property " . $this->property, Project::MSG_VERBOSE);
142            return false;
143        }
144
145        return true;
146    }
147
148    // this is prepared for the path type
149    private function _checkFile() {
150        if ($this->filepath === null) {
151            return $this->_checkFile1($this->file);
152        } else {
153            $paths = $this->filepath->listPaths();
154            for($i=0,$pcnt=count($paths); $i < $pcnt; $i++) {
155                $this->log("Searching " . $paths[$i], Project::MSG_VERBOSE);
156                $tmp = new PhingFile($paths[$i], $this->file->getName());
157                if($tmp->isFile()) {
158                    return true;
159                }
160            }
161        }
162        return false;
163    }
164
165    private function _checkFile1(PhingFile $file) {
166        // Resolve symbolic links
167        if ($this->followSymlinks && $file->isLink()) {
168            $linkTarget = new PhingFile($file->getLinkTarget());
169            if ($linkTarget->isAbsolute()) {
170                $file = $linkTarget;
171            }
172            else {
173                $fs = FileSystem::getFileSystem();
174                $file = new PhingFile(
175                    $fs->resolve(
176                        $fs->normalize($file->getParent()),
177                        $fs->normalize($file->getLinkTarget())
178                    )
179                );
180            }
181        }
182
183        if ($this->type !== null) {
184            if ($this->type === "dir") {
185                return $file->isDirectory();
186            } else if ($this->type === "file") {
187                return $file->isFile();
188            }
189        }
190        return $file->exists();
191    }
192
193    private function _checkResource($resource) {
194        if (null != ($resourcePath = Phing::getResourcePath($resource))) {
195            return $this->_checkFile1(new PhingFile($resourcePath));
196        } else {
197            return false;
198        }
199    }
200}
201