[ Index ]

PHP Cross Reference of Akelos Framework

title

Body

[close]

/ -> AkelosInstaller.php (source)

   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  ?>


Generated: Mon Oct 27 12:43:49 2008 Cross-referenced by PHPXref 0.6