1<?php 2/* 3 * $Id: fad30caf32ff1ee9ff98f63849d61053ab88f645 $ 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/types/FileSet.php'; 24 25/** 26 * Task that changes the permissions on a file/directory. 27 * 28 * @author Manuel Holtgrewe <grin@gmx.net> 29 * @author Hans Lellelid <hans@xmpl.org> 30 * @version $Id: fad30caf32ff1ee9ff98f63849d61053ab88f645 $ 31 * @package phing.tasks.system 32 */ 33class ChmodTask extends Task { 34 35 private $file; 36 37 private $mode; 38 39 private $filesets = array(); 40 41 private $filesystem; 42 43 private $quiet = false; 44 private $failonerror = true; 45 private $verbose = true; 46 47 /** 48 * This flag means 'note errors to the output, but keep going' 49 * @see setQuiet() 50 */ 51 function setFailonerror($bool) { 52 $this->failonerror = $bool; 53 } 54 55 /** 56 * Set quiet mode, which suppresses warnings if chmod() fails. 57 * @see setFailonerror() 58 */ 59 function setQuiet($bool) { 60 $this->quiet = $bool; 61 if ($this->quiet) { 62 $this->failonerror = false; 63 } 64 } 65 66 /** 67 * Set verbosity, which if set to false surpresses all but an overview 68 * of what happened. 69 */ 70 function setVerbose($bool) { 71 $this->verbose = (bool)$bool; 72 } 73 74 /** 75 * Sets a single source file to touch. If the file does not exist 76 * an empty file will be created. 77 */ 78 function setFile(PhingFile $file) { 79 $this->file = $file; 80 } 81 82 function setMode($str) { 83 $this->mode = $str; 84 } 85 86 /** 87 * Nested creator, adds a set of files (nested fileset attribute). 88 */ 89 function createFileSet() { 90 $num = array_push($this->filesets, new FileSet()); 91 return $this->filesets[$num-1]; 92 } 93 94 /** 95 * Execute the touch operation. 96 * @return void 97 */ 98 function main() { 99 // Check Parameters 100 $this->checkParams(); 101 $this->chmod(); 102 } 103 104 /** 105 * Ensure that correct parameters were passed in. 106 * @return void 107 */ 108 private function checkParams() { 109 110 if ($this->file === null && empty($this->filesets)) { 111 throw new BuildException("Specify at least one source - a file or a fileset."); 112 } 113 114 if ($this->mode === null) { 115 throw new BuildException("You have to specify an octal mode for chmod."); 116 } 117 118 // check for mode to be in the correct format 119 if (!preg_match('/^([0-7]){3,4}$/', $this->mode)) { 120 throw new BuildException("You have specified an invalid mode."); 121 } 122 123 } 124 125 /** 126 * Does the actual work. 127 * @return void 128 */ 129 private function chmod() { 130 131 if (strlen($this->mode) === 4) { 132 $mode = octdec($this->mode); 133 } else { 134 // we need to prepend the 0 before converting 135 $mode = octdec("0". $this->mode); 136 } 137 138 // counters for non-verbose output 139 $total_files = 0; 140 $total_dirs = 0; 141 142 // one file 143 if ($this->file !== null) { 144 $total_files = 1; 145 $this->chmodFile($this->file, $mode); 146 } 147 148 // filesets 149 foreach($this->filesets as $fs) { 150 151 $ds = $fs->getDirectoryScanner($this->project); 152 $fromDir = $fs->getDir($this->project); 153 154 $srcFiles = $ds->getIncludedFiles(); 155 $srcDirs = $ds->getIncludedDirectories(); 156 157 $filecount = count($srcFiles); 158 $total_files = $total_files + $filecount; 159 for ($j = 0; $j < $filecount; $j++) { 160 $this->chmodFile(new PhingFile($fromDir, $srcFiles[$j]), $mode); 161 } 162 163 $dircount = count($srcDirs); 164 $total_dirs = $total_dirs + $dircount; 165 for ($j = 0; $j < $dircount; $j++) { 166 $this->chmodFile(new PhingFile($fromDir, $srcDirs[$j]), $mode); 167 } 168 } 169 170 if (!$this->verbose) { 171 $this->log('Total files changed to ' . vsprintf('%o', $mode) . ': ' . $total_files); 172 $this->log('Total directories changed to ' . vsprintf('%o', $mode) . ': ' . $total_dirs); 173 } 174 175 } 176 177 /** 178 * Actually change the mode for the file. 179 * @param PhingFile $file 180 * @param int $mode 181 */ 182 private function chmodFile(PhingFile $file, $mode) { 183 if ( !$file->exists() ) { 184 throw new BuildException("The file " . $file->__toString() . " does not exist"); 185 } 186 187 try { 188 $file->setMode($mode); 189 if ($this->verbose) { 190 $this->log("Changed file mode on '" . $file->__toString() ."' to " . vsprintf("%o", $mode)); 191 } 192 } catch (Exception $e) { 193 if($this->failonerror) { 194 throw $e; 195 } else { 196 $this->log($e->getMessage(), $this->quiet ? Project::MSG_VERBOSE : Project::MSG_WARN); 197 } 198 } 199 } 200 201} 202 203 204