| [ Index ] |
PHP Cross Reference of Akelos Framework |
[Summary view] [Print] [Text view]
1 <?php 2 /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */ 3 4 // +----------------------------------------------------------------------+ 5 // | Akelos Framework - http://www.akelos.org | 6 // +----------------------------------------------------------------------+ 7 // | Copyright (c) 2002-2006, Akelos Media, S.L. & Bermi Ferrer Martinez | 8 // | Released under the GNU Lesser General Public License, see LICENSE.txt| 9 // +----------------------------------------------------------------------+ 10 11 /** 12 * @package AkelosFramework 13 * @subpackage Installer 14 * @author Bermi Ferrer <bermi a.t akelos c.om> 15 * @copyright Copyright (c) 2002-2006, Akelos Media, S.L. http://www.akelos.org 16 * @license GNU Lesser General Public License <http://www.gnu.org/copyleft/lesser.html> 17 */ 18 19 class AkelosInstaller 20 { 21 var $options = array(); 22 var $errors = array(); 23 24 function AkelosInstaller($options) 25 { 26 $default_options = array( 27 'source' => $this->_absolutePath(dirname(__FILE__).DIRECTORY_SEPARATOR.'..'), 28 'force' => false, 29 'skip' => false, 30 'quiet' => false, 31 'public_html' => false, 32 'dependencies' => false, 33 'version'=>false 34 ); 35 $this->options = array_merge($default_options, $options); 36 if (isset($this->options['version']) && $this->options['version']!==false) { 37 die(file_get_contents('version.txt')."\n"); 38 } 39 $this->options['directory'] = $this->_absolutePath(@$this->options['directory']); 40 41 if(empty($this->options['directory'])){ 42 trigger_error('You must supply a valid destination path', E_USER_ERROR); 43 } 44 45 $this->source_tree = Ak::dir($this->options['source'],array('dirs'=>true,'recurse'=>true)); 46 47 if(empty($this->options['dependencies'])){ 48 $this->framework_dirs = array('lib', 'vendor', 'test'); 49 50 foreach ($this->framework_dirs as $framework_dir){ 51 foreach ($this->source_tree as $k => $v){ 52 if(isset($v[$framework_dir])){ 53 unset($this->source_tree[$k]) ; 54 } 55 } 56 } 57 } 58 59 $this->destination_tree = Ak::dir($this->options['directory'],array('dirs'=>true,'recurse'=>true)); 60 } 61 62 function install() 63 { 64 if(empty($this->destination_tree) || !empty($this->options['force'])){ 65 if(!is_dir($this->options['directory'])){ 66 if(!$this->_makeDir($this->options['directory'])){ 67 $this->addError("Can't create directory: " . $this->options['directory']); 68 return false; 69 } 70 } 71 72 $this->_copyFrameworkFiles($this->source_tree, $this->options['source']); 73 74 if(empty($this->options['dependencies'])){ 75 $this->_setupApplicationTestingEnvironment(); 76 $this->_linkDependencies(); 77 } 78 79 $this->runEvironmentSpecificTasks(); 80 81 $this->_linkPublicHtmlFolder(); 82 83 }else{ 84 $this->addError('Installation directory is not empty. Add --force if you want to override existing files'); 85 } 86 87 88 } 89 90 91 function _setupApplicationTestingEnvironment() 92 { 93 $source_test_dir = $this->options['source'].DS.'test'; 94 $test_dir = $this->options['directory'].DS.'test'; 95 96 $this->_makeDir($test_dir); 97 $this->_copyFile($source_test_dir.DS.'app.php'); 98 99 $this->_makeDir($test_dir.DS.'fixtures'); 100 $this->_makeDir($test_dir.DS.'fixtures'.DS.'app'); 101 102 $this->_copyFile($source_test_dir.DS.'fixtures'.DS.'app'.DS.'application_controller.php'); 103 $this->_copyFile($source_test_dir.DS.'fixtures'.DS.'app'.DS.'base_action_controller.php'); 104 $this->_copyFile($source_test_dir.DS.'fixtures'.DS.'app'.DS.'shared_model.php'); 105 $this->_copyFile($source_test_dir.DS.'fixtures'.DS.'app'.DS.'base_active_record.php'); 106 107 $this->_makeDir($test_dir.DS.'fixtures'.DS.'config'); 108 $this->_copyFile($source_test_dir.DS.'fixtures'.DS.'config'.DS.'config.php'); 109 110 $this->_makeDir($test_dir.DS.'fixtures'.DS.'data'); 111 $this->_makeDir($test_dir.DS.'fixtures'.DS.'public'); 112 $this->_copyFile($source_test_dir.DS.'fixtures'.DS.'public'.DS.'.htaccess'); 113 $this->_copyFile($source_test_dir.DS.'fixtures'.DS.'public'.DS.'index.php'); 114 } 115 116 117 function _linkPublicHtmlFolder() 118 { 119 if(!empty($this->options['public_html'])){ 120 if(function_exists('symlink')){ 121 $this->options['public_html'] = $this->_absolutePath($this->options['public_html']); 122 $link_info = @linkinfo($this->options['public_html']); 123 if(!is_numeric($link_info) || $link_info < 0){ 124 $this->yield("\n Adding symbolic link ".$this->options['public_html'].' to the public web server.'); 125 if(@symlink($this->options['directory'].DS.'public',$this->options['public_html'])){ 126 return true; 127 } 128 } 129 } 130 $this->yield("\n Could not create a symbolic link of ".$this->options['directory'].DS.'public'.' at '.$this->options['public_html']); 131 132 }else{ 133 $this->_addRootLevelDispatcher(); 134 $this->_addHtaccessDirectoryProtection(); 135 } 136 return false; 137 } 138 139 function _linkDependencies() 140 { 141 $this->yield("\n Linking the application with the framework at ".$this->options['source'])."\n"; 142 foreach (array( 143 'config'.DS.'DEFAULT-config.php', 144 'app'.DS.'controllers'.DS.'framework_setup_controller.php') as $file){ 145 if(file_exists($this->options['directory'].DS.$file)){ 146 $file_contents = str_replace("// defined('AK_FRAMEWORK_DIR') ? null : define('AK_FRAMEWORK_DIR', '/path/to/the/framework');", 147 "defined('AK_FRAMEWORK_DIR') ? null : define('AK_FRAMEWORK_DIR', '".addcslashes($this->options['source'],'\\')."');", 148 file_get_contents($this->options['directory'].DS.$file)); 149 file_put_contents($this->options['directory'].DS.$file, $file_contents); 150 } 151 } 152 } 153 154 function _addRootLevelDispatcher() 155 { 156 $this->_copyFile($this->options['source'].DS.'index.php'); 157 $this->_copyFile($this->options['source'].DS.'.htaccess'); 158 } 159 160 function _addHtaccessDirectoryProtection() 161 { 162 foreach($this->source_tree as $k=>$node){ 163 if (is_array($node)){ 164 $folder = array_shift(array_keys($node)); 165 $path = $this->options['directory'].DS.$folder; 166 if(is_dir($path) && !file_exists($path.DS.'.htaccess') && $folder != 'public'){ 167 file_put_contents($path.DS.'.htaccess', "order allow,deny\ndeny from all"); 168 } 169 } 170 } 171 } 172 173 function _copyFrameworkFiles($directory_structure, $base_path = '.') 174 { 175 foreach ($directory_structure as $k=>$node){ 176 177 $path = $base_path.DS.$node; 178 if(is_dir($path)){ 179 $this->_makeDir($path); 180 }elseif(is_file($path)){ 181 $this->_copyFile($path); 182 }elseif(is_array($node)){ 183 foreach ($node as $dir=>$items){ 184 $path = $base_path.DS.$dir; 185 if(is_dir($path)){ 186 $this->_makeDir($path); 187 $this->_copyFrameworkFiles($items, $path); 188 } 189 } 190 } 191 192 } 193 } 194 195 function _makeDir($path) 196 { 197 $dir = $this->_getDestinationPath($path); 198 199 if($this->_canUsePath($dir)){ 200 if(!is_dir($dir)){ 201 $this->yield(" Creating directory: ".$dir); 202 if(!@mkdir($dir)) 203 return false; 204 } 205 } 206 return true; 207 } 208 209 function _copyFile($path) 210 { 211 $destination_file = $this->_getDestinationPath($path); 212 213 if($this->_canUsePath($destination_file)){ 214 if(!file_exists($destination_file)){ 215 $this->yield(" Creating file: ".$destination_file); 216 copy($path, $destination_file); 217 }elseif(md5_file($path) != md5_file($destination_file)){ 218 $this->yield(" Modifying file: ".$destination_file); 219 copy($path, $destination_file); 220 } 221 222 $source_file_mode = fileperms($path); 223 $target_file_mode = fileperms($destination_file); 224 if($source_file_mode != $target_file_mode){ 225 $this->yield(" Setting $destination_file permissions to: ".(sprintf("%o",$source_file_mode))); 226 chmod($destination_file,$source_file_mode); 227 } 228 } 229 } 230 231 /** 232 * Computes the destination path 233 * 234 * Gicing /path/to/the_framework/lib/Ak.php will rerturn /my/project/path/lib/Ak.php 235 * 236 */ 237 function _getDestinationPath($path) 238 { 239 return str_replace($this->options['source'].DS, $this->options['directory'].DS, $path); 240 } 241 242 /** 243 * Returns false if operating on the path is not allowed 244 */ 245 function _canUsePath($path) 246 { 247 if(is_file($path) || is_dir($path)){ 248 return !empty($this->options['skip']) ? false : !empty($this->options['force']); 249 } 250 251 return true; 252 } 253 254 function _absolutePath($path) 255 { 256 $_path = $path; 257 if (!preg_match((AK_OS == 'WINDOWS' ? "/^\w+:/" : "/^\//"), $path )) { 258 $current_dir = AK_OS == 'WINDOWS' ? str_replace("\\", DS, realpath('.').DS) : realpath('.').DS; 259 $_path = $current_dir . $_path; 260 } 261 $start = ''; 262 if(AK_OS == 'WINDOWS'){ 263 list($start, $_path) = explode(':', $_path, 2); 264 $start .= ':'; 265 } 266 $real_parts = array(); 267 $parts = explode(DS, $_path); 268 for ($i = 0; $i < count($parts); $i++ ) { 269 if (strlen($parts[$i]) == 0 || $parts[$i] == "."){ 270 continue; 271 } 272 if ($parts[$i] == '..'){ 273 if(count($real_parts) > 0){ 274 array_pop($real_parts); 275 } 276 }else{ 277 array_push($real_parts, $parts[$i]); 278 } 279 } 280 return $start.DS.implode(DS,$real_parts ); 281 } 282 283 function yield($message) 284 { 285 if(empty($this->options['quiet'])){ 286 echo $message."\n"; 287 } 288 } 289 290 function addError($error) 291 { 292 $this->errors[$error] = ''; 293 } 294 295 function getErrors() 296 { 297 return array_keys($this->errors); 298 } 299 300 function hasErrors() 301 { 302 return !empty($this->errors); 303 } 304 305 306 function runEvironmentSpecificTasks() 307 { 308 if($evironment = $this->guessEnvironment()){ 309 $method_name = 'run'.$evironment.'Tasks'; 310 if(method_exists($this, $method_name)){ 311 $this->$method_name(); 312 } 313 } 314 } 315 316 // Environment specific tasks 317 318 function guessEnvironment() 319 { 320 if(AK_OS == 'WINDOWS'){ 321 if(file_exists('C:/xampp/apache/conf/httpd.conf')){ 322 return 'DefaultXamppOnWindows'; 323 } 324 } 325 return false; 326 } 327 328 function runDefaultXamppOnWindowsTasks() 329 { 330 // XAMPP has mod_rewrite disabled by default so we will try to enable it. 331 $http_conf = file_get_contents('C:/xampp/apache/conf/httpd.conf'); 332 if(strstr($http_conf, '#LoadModule rewrite_module')){ 333 $this->yield('Enabling mod_rewrite'); 334 file_put_contents('C:/xampp/apache/conf/httpd.conf.akelos', $http_conf); 335 file_put_contents('C:/xampp/apache/conf/httpd.conf', 336 str_replace( 337 '#LoadModule rewrite_module', 338 'LoadModule rewrite_module', 339 $http_conf 340 )); 341 342 $this->yield('Restarting Apache'); 343 // Stop apache 344 exec('C:\xampp\apache\bin\pv -f -k apache.exe -q'); 345 exec('rm C:\xampp\apache\logs\httpd.pid'); 346 347 // Start Apache in the background 348 $shell = new COM('WScript.Shell'); 349 $shell->Run('C:\xampp\apache\bin\apache.exe', 0, false); 350 } 351 352 $my_cnf = @file_get_contents('C:/xampp/mysql/bin/my.cnf'); 353 // InnoDB engine is not enabled by default on XAMPP we need it enabled in order to use transactions 354 if(strstr($my_cnf, '#innodb_')){ 355 $this->yield('Enabling InnoDB MySQL engine.'); 356 file_put_contents('C:/xampp/mysql/bin/my.cnf.akelos', $my_cnf); 357 file_put_contents('C:/xampp/mysql/bin/my.cnf', 358 str_replace( 359 array('skip-innodb', '#innodb_', '#set-variable = innodb'), 360 array('#skip-innodb', 'innodb_', 'set-variable = innodb') 361 ,$my_cnf)); 362 363 $this->yield('Restarting MySQL server.'); 364 $shell = new COM('WScript.Shell'); 365 $shell->Run('C:\xampp\mysql\bin\mysqladmin --user=pma --password= shutdown', 0, false); 366 $shell = new COM('WScript.Shell'); 367 $shell->Run('C:\xampp\mysql\bin\mysqld --defaults-file=C:\xampp\mysql\bin\my.cnf --standalone --console', 0, false); 368 } 369 } 370 371 } 372 ?>
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
| Generated: Mon Oct 27 12:43:49 2008 | Cross-referenced by PHPXref 0.6 |