[ Index ]

PHP Cross Reference of Mambo 4.6.5

[ Variables ]     [ Functions ]     [ Classes ]     [ Constants ]     [ Statistics ]

title

Body

[close]

/administrator/components/com_installer/ -> installer.class.php (source)

   1  <?php
   2  /**
   3  * @package Mambo
   4  * @subpackage Installer
   5  * @author Mambo Foundation Inc see README.php
   6  * @copyright (C) 2000 - 2009 Mambo Foundation Inc.
   7  * See COPYRIGHT.php for copyright notices and details.
   8  * @license GNU/GPL Version 2, see LICENSE.php
   9  *
  10  * Redistributions of files must retain the above copyright notice.
  11  *
  12  * Mambo is free software; you can redistribute it and/or
  13  * modify it under the terms of the GNU General Public License
  14  * as published by the Free Software Foundation; version 2 of the License.
  15  */
  16  
  17  /** ensure this file is being included by a parent file */
  18  defined( '_VALID_MOS' ) or die( 'Direct Access to this location is not allowed.' );
  19  
  20  class mosCommonInstallXML extends mosXMLDescription {
  21      var $type = '';
  22      var $name = '';
  23      var $special_attr = '';
  24      var $group = '';
  25      var $userdir = '';
  26      var $admindir = '';
  27      var $files = array();
  28      var $rem_files = array();
  29      var $images = array();
  30      var $admin_files = array();
  31      var $admin_images = array();
  32      var $queryid = 0;
  33      var $queries = array();
  34      var $mainmenu = '';
  35      var $subact = '';
  36      var $submenus = array();
  37      var $submenuordering = 0;
  38      var $special_filetitle = '';
  39      var $isspecial = false;
  40      var $special_file = null;
  41      var $installfile = '';
  42      var $uninstallfile = '';
  43      var $client = '';
  44      var $media = array();
  45      var $css = array();
  46      var $language_attrs = '';
  47  
  48      var $user_dir = '';
  49      var $admin_dir = '';
  50  
  51      function tagNestIs ($next, $last=null) {
  52          if ($next == $this->opentags[1] AND ($last == null OR $last == $this->opentags[2])) return true;
  53          else return false;
  54      }
  55  
  56      function element_mosinstall ($attrs) {
  57          if (isset($attrs['TYPE'])) {
  58              $this->type = $attrs['TYPE'];
  59              $method = 'init_'.$attrs['TYPE'];
  60              $setup = array (&$this, $method);
  61              if (is_callable($setup)) $this->$method($attrs);
  62              else $this->errors->addErrorDetails(sprintf(T_('XML error in %s: no handler %s'), $this->xmlfile, $method), _MOS_ERROR_FATAL);
  63          }
  64          else $this->errors->addErrorDetails(sprintf(T_('XML error in %s: mosinstall has no type'), $this->xmlfile), _MOS_ERROR_FATAL);
  65      }
  66  
  67      function end_element_mosinstall () {
  68          if ($this->name = $this->getName($this->type));
  69          elseif ($this->type != 'params') $this->errors->addErrorDetails(sprintf(T_('XML Error in %s: install has no name'), $this->xmlfile), _MOS_ERROR_FATAL);
  70      }
  71  
  72      function element_filename ($attrs) {
  73          if ($this->type == 'language') $this->language_attrs = $attrs;
  74          elseif (isset($attrs[$this->special_attr])) $this->special_filetitle = $attrs[$this->special_attr];
  75      }
  76  
  77      function end_element_filename () {
  78          if ($this->special_filetitle) $this->special_file = array($this->special_filetitle, $this->chardata);
  79          $this->special_filetitle = '';
  80          if ($this->type == 'language') $this->files[] = array($this->language_attrs, $this->chardata);
  81          elseif ($this->tagNestIs('FILES', 'MOSINSTALL')) $this->files[] = $this->chardata;
  82          elseif ($this->tagNestIs('REMOVE_FILES', 'MOSINSTALL')) $this->rem_files[] = $this->chardata;
  83          elseif ($this->tagNestIs('IMAGES', 'MOSINSTALL')) $this->images[] = $this->chardata;
  84          elseif ($this->tagNestIs('FILES', 'ADMINISTRATION')) $this->admin_files[] = $this->chardata;
  85          elseif ($this->tagNestIs('IMAGES', 'ADMINISTRATION')) $this->admin_images[] = $this->chardata;
  86          elseif ($this->tagNestIs('MEDIA', 'MOSINSTALL')) $this->media[] = $this->chardata;
  87          elseif ($this->tagNestIs('CSS', 'MOSINSTALL')) $this->css[] = $this->chardata;
  88      }
  89  
  90      function element_query ($attrs) {
  91          if (isset($attrs['ID'])) $this->queryid = $attrs['ID'];
  92      }
  93  
  94      function element_menu ($attrs) {
  95          if ($this->type != 'component') {
  96              $this->errors->addErrorDetails(sprintf(T_('XML error in %s: MENU found, but this is not component XML'), $this->xmlfile), _MOS_ERROR_WARNING);
  97              return;
  98          }
  99          if ($this->tagNestIs('SUBMENU', 'ADMINISTRATION')) {
 100              if (isset($attrs['ACT'])) $this->subact = '&act='.$attrs['ACT'];
 101              elseif (isset($attrs['TASK'])) $this->subact = '&task='.$attrs['TASK'];
 102              elseif (isset($attrs['LINK'])) $this->subact = $attrs['LINK'];
 103          }
 104      }
 105  
 106      function end_element_menu (){
 107          if ($this->tagNestIs('ADMINISTRATION')) $this->mainmenu = $this->chardata;
 108          elseif ($this->tagNestIs('SUBMENU', 'ADMINISTRATION')) $this->submenus[] = array ($this->chardata, $this->subact);
 109          $this->subact = '';
 110      }
 111  
 112      function end_element_installfile () {
 113          $this->installfile = $this->chardata;
 114      }
 115  
 116      function end_element_uninstallfile (){
 117          $this->uninstallfile = $this->chardata;
 118      }
 119  
 120      function init_component ($attrs) {
 121      }
 122  
 123      function init_module ($attrs) {
 124          $this->special_attr = 'MODULE';
 125          if (isset($attrs['CLIENT'])) $this->client = $attrs['CLIENT'];
 126      }
 127  
 128      function init_mambot ($attrs) {
 129          $this->special_attr = 'MAMBOT';
 130          if (isset($attrs['GROUP'])) {
 131              $this->group = $attrs['GROUP'];
 132          }
 133          else $this->errors->addErrorDetails(sprintf(T_('XML Error in %s: Mambot does not have a group specified'), $this->xmlfile), _MOS_ERROR_FATAL);
 134      }
 135  
 136      function init_template ($attrs) {
 137          if (isset($attrs['CLIENT'])) $this->client = $attrs['CLIENT'];
 138      }
 139  
 140      function init_language ($attrs) {
 141      }
 142  
 143      function init_params ($attrs) {
 144      }
 145  
 146      function init_include($attrs) {
 147      }
 148  
 149      function init_parameter($attrs) {
 150      }
 151  
 152      function init_patch ($attrs) {
 153      }
 154  
 155  }
 156  
 157  class mosInstallXML extends mosCommonInstallXML {
 158  
 159      function install () {
 160          if (ini_get('safe_mode')) {
 161              $this->errors->addErrorDetails(sprintf(T_('Your system is running in Safe Mode component install is aborting!')), _MOS_ERROR_FATAL);
 162              return;
 163          }
 164          if ($this->errors->getMaxLevel() >= _MOS_ERROR_FATAL) return;
 165          $method = 'install_'.$this->type;
 166          $setup = array (&$this, $method);
 167          if (is_callable($setup)) $this->$method();
 168          else $this->errors->addErrorDetails(sprintf(T_('XML error in %s: no installer %s'), $this->xmlfile, $method), _MOS_ERROR_FATAL);
 169          if ($this->errors->getMaxLevel() >= _MOS_ERROR_FATAL) {
 170              $killmethod = 'kill_'.$this->type;
 171              $killer = array (&$this, $killmethod);
 172              if (is_callable($killer)) $this->$killmethod();
 173          }
 174      }
 175  
 176      function end_element_query () {
 177          if ($this->tagNestIs('QUERIES', 'INSTALL')) $this->queries[] = array ($this->chardata, $this->queryid);
 178          $this->queryid = 0;
 179      }
 180  
 181      function createDirectories ($name) {
 182          if ($this->admin_dir) {
 183              $adirectory = new mosDirectory ($this->admin_dir);
 184              $type = $this->type;
 185              if (!$adirectory->createFresh()) {
 186                  $this->errors->addErrorDetails(sprintf(T_('Installer error with %s: unable to create admin directory for %s %s'), $this->xmlfile, $type, $name), _MOS_ERROR_SEVERE);
 187                  return false;
 188              }
 189          }
 190          if ($this->user_dir) {
 191              $udirectory = new mosDirectory ($this->user_dir);
 192              if (!$udirectory->createFresh()) {
 193                  $this->errors->addErrorDetails(sprintf(T_('Installer error with %s: unable to create user directory for %s %s'), $this->xmlfile, $type, $name), _MOS_ERROR_SEVERE);
 194                  return false;
 195              }
 196              return true;
 197          }
 198      }
 199  
 200      function createComponentMenu ($item, $name, $toplevel=0) {
 201          $text = $item[0];
 202          $database =& mamboDatabase::getInstance();
 203          $component =& new mosComponent($database);
 204          $component->name = $component->admin_menu_alt = $text;
 205          if ($toplevel == 0) $component->link = "option=$name";
 206          $component->menuid = 0;
 207          $component->parent = $toplevel;
 208          $component->iscore = 0;
 209          $component->admin_menu_link = "option=$name";
 210          if ($toplevel AND ($linkdetail = $item[1])) {
 211              if ($linkdetail[0] == '&') $component->admin_menu_link .= $linkdetail;
 212              else $component->admin_menu_link = $linkdetail;
 213          }
 214          $component->option = $name;
 215          $component->ordering = $toplevel ? $this->submenuordering++ : 0;
 216          $component->admin_menu_img = 'js/ThemeOffice/component.png';
 217          $component->params = '';
 218          if ($component->store()) return $component->id;
 219          $this->errors->addErrorDetails(sprintf(T_('Installer error with %s: writing component menu SQL error %s'), $this->xmlfile, $database->stderr(true)), _MOS_ERROR_FATAL);
 220          return 0;
 221      }
 222  
 223      function install_component (){
 224          $com_name = 'com_'.str_replace(' ', '', strtolower($this->name));
 225          $this->user_dir = mosPathName(mamboCore::get('mosConfig_absolute_path').'/components/'.$com_name);
 226          $this->admin_dir = mosPathName(mamboCore::get('mosConfig_absolute_path').'/administrator/components/'.$com_name);
 227          $database =& mamboDatabase::getInstance();
 228          // @RawSQLUse, trivial_implementation, SELECT
 229          $sql = "SELECT COUNT(id) FROM #__components WHERE `option`='$com_name'";
 230          $database->setQuery($sql);
 231          if ($count = $database->loadResult()) {
 232              $this->errors->addErrorDetails(sprintf(T_('Installer error with %s: %s %s already installed'), $this->xmlfile, 'component', $com_name), _MOS_ERROR_WARN);
 233              return;
 234          }
 235          if (!$this->createDirectories($com_name)) return;
 236          $fmanager =& mosFileManager::getInstance();
 237          $here = mosPathName(dirname($this->xmlfile));
 238          $fmanager->forceCopy($this->xmlfile, $this->admin_dir.basename($this->xmlfile));
 239          foreach ($this->files as $ufile) $fmanager->forceCopy($here.$ufile, $this->user_dir.$ufile);
 240          foreach ($this->images as $uimage) $fmanager->forceCopy($here.$uimage, $this->user_dir.$uimage);
 241          foreach ($this->admin_files as $afile) $fmanager->forceCopy($here.$afile, $this->admin_dir.$afile);
 242          foreach ($this->admin_images as $aimage) $fmanager->forceCopy($here.$aimage, $this->admin_dir.$aimage);
 243          if ($this->installfile) $fmanager->forceCopy($here.$this->installfile, $this->admin_dir.$this->installfile);
 244          if ($this->uninstallfile) $fmanager->forceCopy($here.$this->uninstallfile, $this->admin_dir.$this->uninstallfile);
 245          foreach ($this->queries as $query) {
 246              $database->setQuery($query[0]);
 247              if (!$database->query()) {
 248                  $this->errors->addErrorDetails(sprintf(T_('Installer error with %s: %s %s SQL error %s'), $this->xmlfile, 'component', $com_name, $database->stderr(true)), _MOS_ERROR_FATAL);
 249              }
 250          }
 251          if ($this->mainmenu) {
 252              $topid = $this->createComponentMenu (array($this->mainmenu), $com_name);
 253              foreach ($this->submenus as $submenu) {
 254                  $this->createComponentMenu ($submenu, $com_name, $topid);
 255              }
 256          } else {
 257              $database =& mamboDatabase::getInstance();
 258              $component =& new mosComponent($database);
 259              $component->name = $this->name;
 260              $component->option = $com_name;    
 261              $component->params = '';  
 262              if (!$component->store()) $this->errors->addErrorDetails(sprintf(T_('Installer error with %s: writing component SQL error %s'), $this->xmlfile, $database->stderr(true)), _MOS_ERROR_FATAL);
 263          } 
 264          if ($this->installfile) {
 265              $ifile = mosPathName($this->admin_dir).$this->installfile;
 266              if (is_file($ifile)) {
 267                  global $mosConfig_absolute_path, $mosConfig_live_site, $acl, $database;
 268                  require_once($ifile);
 269                  $_ret = com_install();
 270                  if ($_ret) {
 271                      // convert the first character of the returned string to be represented by an integer
 272                      $_type = intval(bin2hex($_ret{0}))-intval(bin2hex(_MOS_ERROR_INFORM));
 273                      switch ($_type) {
 274                      case _MOS_ERROR_INFORM:
 275                      case _MOS_ERROR_WARN:
 276                      case _MOS_ERROR_SEVERE:
 277                      case _MOS_ERROR_FATAL:
 278                          //strip off the first character
 279                          $_ret = substr($_ret, 1);
 280                          break;
 281                      default:
 282                          $_type = _MOS_ERROR_INFORM;
 283                          break;
 284                      }
 285                      if ($_type < _MOS_ERROR_FATAL) {
 286                          $this->errors->addErrorDetails(sprintf(T_('%s'), $_ret), $_type);
 287                      }else {
 288                          $this->errors->addErrorDetails(sprintf(T_('The com_install() function for component "%s" aborted with: %s'), $com_name, $_ret), $_type);
 289                      }
 290                  }
 291              }
 292          }
 293          $this->errors->addErrorDetails($this->getDescription('component'), _MOS_ERROR_INFORM);
 294      }
 295  
 296      function install_module () {
 297          if (!is_array($this->special_file)) {
 298              $this->errors->addErrorDetails(sprintf(T_('Installer error with %s: no file identified as the %s'), $this->xmlfile, 'module'), _MOS_ERROR_FATAL);
 299              return;
 300          }
 301          $special = $this->special_file[0];
 302          $database =& mamboDatabase::getInstance();
 303          $client_id = $this->client == 'administrator' ? 1 : 0;
 304          // @RawSQLUse, trivial_implementation, SELECT
 305          $sql = "SELECT COUNT(id) FROM #__modules WHERE module='$special' AND client_id='$client_id'";
 306          $database->setQuery($sql);
 307          if ($database->loadResult()) {
 308              $this->errors->addErrorDetails(sprintf(T_('Installer error with %s: %s %s already installed'), $this->xmlfile, 'module', $this->name),  _MOS_ERROR_WARN);
 309              return;
 310          }
 311          if ($client_id) $this->user_dir = mosPathName(mamboCore::get('mosConfig_absolute_path').'/administrator/modules/');
 312          else $this->user_dir = mosPathName(mamboCore::get('mosConfig_absolute_path').'/modules');
 313          $fmanager =& mosFileManager::getInstance();
 314          $here = mosPathName(dirname($this->xmlfile));
 315          $fmanager->forceCopy($this->xmlfile, $this->user_dir.basename($this->xmlfile));
 316          foreach ($this->files as $ufile) $fmanager->forceCopy($here.$ufile, $this->user_dir.$ufile);
 317          foreach ($this->images as $uimage) $fmanager->forceCopy($here.$uimage, $this->user_dir.$uimage);
 318          $module =& new mosModule($database);
 319          $module->title = $this->name;
 320          $module->ordering = 99;
 321          $module->position = 'left';
 322          $module->showtitle = 1;
 323          $module->iscore = 0;
 324          $module->access = $client_id ? 99 : 0;
 325          $module->client_id = $client_id;
 326          $module->module = $special;
 327          $module->content = '';   // double check the last chance at wush to be here at SG new SVN
 328          $module->params = '';
 329          $module->store();
 330          if ($module->store()) $this->errors->addErrorDetails($this->getDescription('module'), _MOS_ERROR_INFORM);
 331          else {
 332              $this->errors->addErrorDetails(sprintf(T_('Installer error with %s: %s %s SQL error %s'), $this->xmlfile, 'mambot', $this->name, $database->stderr(true)), _MOS_ERROR_FATAL);
 333          }
 334          
 335          // @RawSQLUse, trivial_implementation, INSERT
 336          $database->setQuery("INSERT INTO #__modules_menu VALUES ('$module->id', 0)");
 337          if (!$database->query()) {
 338              $this->errors->addErrorDetails(sprintf(T_('Installer error with %s: %s %s SQL error %s'), $this->xmlfile, 'module', $this->name, $database->stderr(true)), _MOS_ERROR_FATAL);
 339          }
 340          //$this->errors->addErrorDetails($this->getDescription('module'), _MOS_ERROR_INFORM);
 341      }
 342  
 343      function install_mambot () {
 344          if (!is_array($this->special_file)) {
 345              $this->errors->addErrorDetails(sprintf(T_('Installer error with %s: no file identified as the %s'), $this->xmlfile, 'mambot'), _MOS_ERROR_FATAL);
 346              return;
 347          }
 348          $database =& mamboDatabase::getInstance();
 349          $name = $this->name;
 350          // @RawSQLUse, trivial_implementation, SELECT
 351          $sql = "SELECT COUNT(id) FROM #__mambots WHERE element='$name'";
 352          $database->setQuery($sql);
 353          if ($database->loadResult()) {
 354              $this->errors->addErrorDetails(sprintf(T_('Installer error with %s: %s %s already installed'), $this->xmlfile, 'mambot', $this->name),  _MOS_ERROR_WARN);
 355              return;
 356          }
 357          $this->user_dir = mosPathName(mamboCore::get('mosConfig_absolute_path').'/mambots/'.$this->group);
 358          $fmanager =& mosFileManager::getInstance();
 359          $here = mosPathName(dirname($this->xmlfile));
 360          $fmanager->forceCopy($this->xmlfile, $this->user_dir.basename($this->xmlfile));
 361          foreach ($this->files as $ufile) $fmanager->forceCopy($here.$ufile, $this->user_dir.$ufile);
 362          foreach ($this->images as $uimage) $fmanager->forceCopy($here.$uimage, $this->user_dir.$uimage);
 363          $mambot =& new mosMambot($database);
 364          $mambot->name = $this->name;
 365          $mambot->ordering = 0;
 366          $mambot->folder = $this->group;
 367          $mambot->iscore = 0;
 368          $mambot->access = 0;
 369          $mambot->client_id = 0;
 370          $mambot->element = $this->special_file[0];
 371          $mambot->params = '';
 372          if ($mambot->store()) $this->errors->addErrorDetails($this->getDescription('mambot'), _MOS_ERROR_INFORM);
 373          else {
 374              $this->errors->addErrorDetails(sprintf(T_('Installer error with %s: %s %s SQL error %s'), $this->xmlfile, 'mambot', $this->name, $database->stderr(true)), _MOS_ERROR_FATAL);
 375          }
 376      }
 377  
 378      function install_template () {
 379          $client_id = $this->client == 'administrator' ? 1 : 0;
 380          if ($client_id) $this->user_dir = mosPathName(mamboCore::get('mosConfig_absolute_path').'/administrator/templates/'.str_replace(' ', '_', strtolower($this->name)));
 381          else $this->user_dir = mosPathName(mamboCore::get('mosConfig_absolute_path').'/templates/'.str_replace(' ', '_', strtolower($this->name)));
 382          if (file_exists($this->user_dir)) {
 383              $this->errors->addErrorDetails(sprintf(T_('Installer error with %s: %s %s already installed'), $this->xmlfile, 'template', $this->name),  _MOS_ERROR_WARN);
 384              return;
 385          }
 386          $fmanager =& mosFileManager::getInstance();
 387          $here = mosPathName(dirname($this->xmlfile));
 388          $fmanager->forceCopy($this->xmlfile, $this->user_dir.basename($this->xmlfile));
 389          foreach ($this->files as $ufile) $fmanager->forceCopy($here.$ufile, $this->user_dir.$ufile);
 390          foreach ($this->images as $uimage) $fmanager->forceCopy($here.$uimage, $this->user_dir.$uimage);
 391          foreach ($this->css as $acss) $fmanager->forceCopy($here.$acss, $this->user_dir.$acss);
 392          $mediadir = mamboCore::get('mosConfig_absolute_path').'/images/stories/';
 393          foreach ($this->media as $simage) $fmanager->forceCopy($here.$simage, $mediadir.$simage);
 394          $this->errors->addErrorDetails($this->getDescription('template'), _MOS_ERROR_INFORM);
 395      }
 396  
 397      function install_language () {
 398          $this->user_dir = mosPathName(mamboCore::get('mosConfig_absolute_path').'/language');
 399          $fmanager =& mosFileManager::getInstance();
 400          $here = mosPathName(dirname($this->xmlfile));
 401          $fmanager->forceCopy($this->xmlfile, $this->user_dir.basename($this->xmlfile));
 402          $lang =  substr(basename($this->xmlfile), 0, -4);
 403          foreach ($this->files as $ufile) {
 404              $file = str_replace('language/', '/', $ufile[1]);
 405              $fmanager->forceCopy($here.$file, $this->user_dir.$file);
 406          }
 407          $this->errors->addErrorDetails($this->getDescription('language'), _MOS_ERROR_INFORM);
 408      }
 409  
 410      function install_include () {
 411          $this->user_dir = mosPathName(mamboCore::get('mosConfig_absolute_path').'/includes');
 412          $this->admin_dir = mosPathName(mamboCore::get('mosConfig_absolute_path').'/administrator/includes');
 413          $fmanager =& mosFileManager::getInstance();
 414          $here = mosPathName(dirname($this->xmlfile));
 415          foreach ($this->files as $ufile) $fmanager->lightCopy($here.$ufile, $this->user_dir.$ufile);
 416          foreach ($this->admin_files as $afile) $fmanager->lightCopy($here.$afile, $this->admin_dir.$afile);
 417      }
 418  
 419      function install_parameter () {
 420          $database =& mamboDatabase::getInstance();
 421          $name = $this->name;
 422          // @RawSQLUse, trivial_implementation, SELECT
 423          $sql = "SELECT COUNT(id) FROM #__parameters WHERE param_name='$name'";
 424          $database->setQuery($sql);
 425          if ($database->loadResult()) {
 426              $this->errors->addErrorDetails(sprintf(T_('Installer error with %s: %s %s already installed'), $this->xmlfile, 'parameter', $this->name),  _MOS_ERROR_WARN);
 427              return;
 428          }
 429          $this->user_dir = mosPathName(mamboCore::get('mosConfig_absolute_path').'/parameters/');
 430          $fmanager =& mosFileManager::getInstance();
 431          $xmlfile = $this->xmlfile;
 432          $filexmlfile = basename($xmlfile);
 433          $fmanager->forceCopy($xmlfile, $this->user_dir.basename($filexmlfile));
 434          // @RawSQLUse, trivial_implementation, INSERT
 435          $sql = "INSERT INTO #__parameters (param_name, param_file, param_version, params) VALUES ('$name', '$filexmlfile', '', '')";
 436          $database->setQuery($sql);
 437          if (!$database->query()) {
 438              $this->errors->addErrorDetails(sprintf(T_('Installer error with %s: %s %s SQL error %s'), $xmlfile, 'parameter', $name, $database->stderr(true)), _MOS_ERROR_FATAL);
 439          }
 440          $this->errors->addErrorDetails($this->getDescription('parameter'), _MOS_ERROR_INFORM);
 441      }
 442  
 443      function install_patch () {
 444          $permit_problem = false;
 445          $fmanager =& mosFileManager::getInstance();
 446          $here = mosPathName(dirname($this->xmlfile));
 447          $basedir = mosPathName(mamboCore::get('mosConfig_absolute_path'));
 448          foreach ($this->files as $file) {
 449              if (!$fmanager->acceptCopy($basedir.$file) OR (file_exists($basedir.$file) AND !is_writable($basedir.$file))) {
 450                  $this->errors->addErrorDetails(sprintf(T_('Patch install error with %s: cannot write %s'), $this->xmlfile, $basedir.$file), _MOS_ERROR_WARN);
 451                  $permit_problem = true;
 452              }
 453          }
 454          foreach ($this->rem_files as $file) {
 455              if (!is_writable($basedir.$file)) {
 456                  $this->errors->addErrorDetails(sprintf(T_('Patch install error with %s: cannot delete %s'), $this->xmlfile, $basedir.$file), _MOS_ERROR_WARN);
 457                  $permit_problem = true;
 458              }
 459          }
 460          if ($permit_problem) {
 461              $this->errors->addErrorDetails(sprintf(T_('Patch install error with %s: file permissions prevent patch application'), $this->xmlfile), _MOS_ERROR_FATAL);
 462              return;
 463          }
 464          foreach ($this->rem_files as $file) {
 465              if (!@unlink($basedir.$file)) {
 466                  $this->errors->addErrorDetails(sprintf(T_('Patch install error with %s: failed to delete %s'), $this->xmlfile, $basedir.$file), _MOS_ERROR_WARN);
 467                  $permit_problem = true;
 468              }
 469          }
 470          foreach ($this->files as $file) {
 471              if (!$fmanager->forceCopy($here.$file, $basedir.$file)) {
 472                  $this->errors->addErrorDetails(sprintf(T_('Patch install error with %s: failed to write %s'), $this->xmlfile, $basedir.$file), _MOS_ERROR_WARN);
 473                  $permit_problem = true;
 474              }
 475          }
 476          if ($permit_problem) $this->errors->addErrorDetails(sprintf(T_('Patch install error with %s: check was OK, but application failed'), $this->xmlfile), _MOS_ERROR_FATAL);
 477          else $this->errors->addErrorDetails(sprintf(T_('Patch install %s: completed successfully'), $this->xmlfile), _MOS_ERROR_INFORM);
 478      }
 479  
 480      function kill_component () {
 481          if (isset($this->user_dir)) {
 482              $dir = new mosDirectory($this->user_dir);
 483              $dir->deleteAll();
 484          }
 485          if (isset($this->admin_dir)) {
 486              $dir = new mosDirectory($this->admin_dir);
 487              $dir->deleteAll();
 488          }
 489          $com_name = 'com_'.strtolower($this->name);
 490          // @RawSQLUse, trivial_implementation, DELETE
 491          $sql = "DELETE FROM #__components WHERE `option`='$com_name'";
 492          $database =& mamboDatabase::getInstance();
 493          $database->setQuery($sql);
 494          $database->query();
 495      }
 496  
 497      function kill_module () {
 498          $name = $this->name;
 499          // @RawSQLUse, trivial_implementation, DELETE
 500          $sql = "DELETE FROM #__modules WHERE title='$name'";
 501          $database =& mamboDatabase::getInstance();
 502          $database->setQuery($sql);
 503          $database->query();
 504      }
 505  
 506      function kill_mambot () {
 507          $name = $this->name;
 508          // @RawSQLUse, trivial_implementation, DELETE
 509          $sql = "DELETE FROM #__mambots WHERE name='$name'";
 510          $database =& mamboDatabase::getInstance();
 511          $database->setQuery($sql);
 512          $database->query();
 513      }
 514  
 515      function kill_template () {
 516          if (isset($this->user_dir)) {
 517              $dir = new mosDirectory($this->user_dir);
 518              $dir->deleteAll();
 519          }
 520      }
 521  
 522      function kill_language () {
 523      }
 524  
 525      function kill_include () {
 526      }
 527  
 528      function kill_parameter () {
 529          $database =& mamboDatabase::getInstance();
 530          $name = $this->name;
 531          // @RawSQLUse, trivial_implementation, DELETE
 532          $sql = "DELETE FROM #__parameters WHERE param_name='$name'";
 533          $database->setQuery($sql);
 534          $database->query();
 535      }
 536  
 537      function kill_patch () {
 538      }
 539  
 540  }
 541  
 542  
 543  class mosUninstallXML extends mosCommonInstallXML {
 544  
 545      function uninstall () {
 546          $method = 'uninstall_'.$this->type;
 547          $setup = array (&$this, $method);
 548          if (is_callable($setup)) $this->$method();
 549          else $this->errors->addErrorDetails(sprintf(T_('Uninstaller error with %s: no uninstaller %s'), $this->xmlfile, $method), _MOS_ERROR_FATAL);
 550          if ($this->errors->getMaxLevel() >= _MOS_ERROR_FATAL) return false;
 551          return true;
 552      }
 553  
 554      function end_element_query () {
 555          if ($this->tagNestIs('QUERIES', 'UNINSTALL')) $this->queries[] = array ($this->chardata, $this->queryid);
 556          $this->queryid = 0;
 557      }
 558  
 559      function deleteFileSet ($files, $rootdir) {
 560          $dirs = array();
 561          $fmanager =& mosFileManager::getInstance();
 562          foreach ($files as $file) {
 563              $parts = split ('/', $file);
 564              if (count($parts) > 1 AND !in_array($parts[0], $dirs)) $dirs[] = $parts[0];
 565              $fmanager->deleteFile($rootdir.'/'.$file);
 566          }
 567          foreach ($dirs as $dir) {
 568              $dirobj = new mosDirectory($rootdir.'/'.$dir);
 569              $dirobj->deleteAll();
 570          }
 571      }
 572  
 573  
 574      function uninstall_component (){
 575          $com_name = 'com_'.str_replace(' ', '', strtolower($this->getName('component')));
 576          $this->user_dir = mosPathName(mamboCore::get('mosConfig_absolute_path').'/components/'.$com_name);
 577          $this->admin_dir = mosPathName(mamboCore::get('mosConfig_absolute_path').'/administrator/components/'.$com_name);
 578          if ($this->uninstallfile) {
 579              $ufile = mosPathName($this->admin_dir).$this->uninstallfile;
 580              if (is_file($ufile)) {
 581                  require_once($ufile);
 582                  com_uninstall();
 583              }
 584          }
 585          $database =& mamboDatabase::getInstance();
 586          foreach ($this->queries as $query) {
 587              $database->setQuery($query[0]);
 588              if (!$database->query()) {
 589                  $this->errors->addErrorDetails(sprintf(T_('Uninstaller error with %s: %s %s SQL error %s'), $this->xmlfile, 'component', $com_name, $database->stderr(true)), _MOS_ERROR_SEVERE);
 590              }
 591          }
 592          $udir = new mosDirectory($this->user_dir);
 593          $udir->deleteAll();
 594          $adir = new mosDirectory($this->admin_dir);
 595          $adir->deleteAll();
 596          // @RawSQLUse, trivial_implementation, DELETE
 597          $sql = "DELETE FROM #__components WHERE `option`='$com_name'";
 598          $database->setQuery($sql);
 599          if (!$database->query()) {
 600              $this->errors->addErrorDetails(sprintf(T_('Uninstaller error with %s: %s %s not fully deleted from database'), $this->xmlfile, 'component', $com_name), _MOS_ERROR_SEVERE);
 601              return;
 602          }
 603          $this->errors->addErrorDetails($this->getDescription('component'), _MOS_ERROR_INFORM);
 604      }
 605  
 606      function uninstall_module () {
 607          $client_id = $this->client == 'administrator' ? 1 : 0;
 608          if ($client_id) $this->user_dir = mosPathName(mamboCore::get('mosConfig_absolute_path').'/administrator/modules/');
 609          else $this->user_dir = mosPathName(mamboCore::get('mosConfig_absolute_path').'/modules');
 610          $this->deleteFileSet($this->files, $this->user_dir);
 611          $this->deleteFileSet($this->images, $this->user_dir);
 612          if (!is_array($this->special_file)) {
 613              $this->errors->addErrorDetails(sprintf(T_('Uninstaller error with %s: no file identified as the %s'), $this->xmlfile, 'module'), _MOS_ERROR_FATAL);
 614              return;
 615          }
 616          $special = $this->special_file[0];
 617          $database =& mamboDatabase::getInstance();
 618          $name = $this->getName('module');
 619          // @RawSQLUse, trivial_implementation, DELETE
 620          $sql = "DELETE FROM #__modules WHERE module='$special' AND client_id='$client_id'";
 621          $database->setQuery($sql);
 622          if (!$database->query()) {
 623              $this->errors->addErrorDetails(sprintf(T_('Uninstaller error with %s: %s %s not fully deleted from database'), $this->xmlfile, 'module', $name), _MOS_ERROR_SEVERE);
 624              return;
 625          }
 626          $fmanager =& mosFileManager::getInstance();
 627          $fmanager->deleteFile($this->xmlfile);
 628          $this->errors->addErrorDetails($this->getDescription('module'), _MOS_ERROR_INFORM);
 629      }
 630  
 631      function uninstall_mambot () {
 632          $this->user_dir = mosPathName(mamboCore::get('mosConfig_absolute_path').'/mambots/'.$this->group);
 633          $this->deleteFileSet($this->files, $this->user_dir);
 634          $this->deleteFileSet($this->images, $this->user_dir);
 635          $database =& mamboDatabase::getInstance();
 636          $name = $this->getName('mambot');
 637          $element = $this->special_file[0];
 638          $group = $this->group;
 639          // @RawSQLUse, trivial_implementation, DELETE
 640          $sql = "DELETE FROM #__mambots WHERE element='$element' AND folder='$group'";
 641          $database->setQuery($sql);
 642          if (!$database->query()) {
 643              $this->errors->addErrorDetails(sprintf(T_('Uninstaller error with %s: %s %s not fully deleted from database'), $this->xmlfile, 'mambot', $name), _MOS_ERROR_SEVERE);
 644              return;
 645          }
 646          $fmanager =& mosFileManager::getInstance();
 647          $fmanager->deleteFile($this->xmlfile);
 648          $this->errors->addErrorDetails($this->getDescription('mambot'), _MOS_ERROR_INFORM);
 649      }
 650  
 651      /**
 652      * This routine is not called - uninstalling templates is done by just deleting
 653      * the whole directory.  It might be better to manage the uninstall via the XML.
 654      * Just deleting the template leaves all the files in the "media" directory.
 655      * But the following code has never been tested.
 656      **/
 657      function uninstall_template () {
 658          $name = str_replace(' ', '_', strtolower($this->getName('template')));
 659          $client_id = $this->client == 'administrator' ? 1 : 0;
 660          if ($client_id) $this->user_dir = mosPathName(mamboCore::get('mosConfig_absolute_path').'/administrator/templates/');
 661          else $this->user_dir = mosPathName(mamboCore::get('mosConfig_absolute_path').'/templates/'.$name);
 662          $userdir = new mosDirectory($this->user_dir);
 663          $userdir->deleteAll();
 664          $mediadir = mamboCore::get('mosConfig_absolute_path').'/images/stories/';
 665          $this->deleteFileSet($this->media, $mediadir);
 666          $fmanager =& mosFileManager::getInstance();
 667          $fmanager->deleteFile($this->xmlfile);
 668          $this->errors->addErrorDetails($this->getDescription('template'), _MOS_ERROR_INFORM);
 669      }
 670  
 671      function uninstall_language () {
 672          $this->user_dir = mosPathName(mamboCore::get('mosConfig_absolute_path').'/language/');
 673          $fmanager =& mosFileManager::getInstance();
 674          $here = mosPathName(dirname($this->xmlfile));
 675          $fmanager->deleteFile($this->user_dir.basename($this->xmlfile));
 676          foreach ($this->files as $ufile) $fmanager->deleteFile($this->user_dir.$ufile);
 677          $this->errors->addErrorDetails($this->getDescription('language'), _MOS_ERROR_INFORM);
 678      }
 679  
 680      function uninstall_params () {
 681      }
 682  
 683  }
 684  
 685  /**
 686  * Installer class
 687  * @package Mambo
 688  * @subpackage Installer
 689  * @abstract
 690  */
 691  class mosInstaller {
 692      var $archiveName = '';
 693      var $extractDir = '';
 694      var $cleanDir = '';
 695      var $errors = '';
 696  
 697      function mosInstaller () {
 698          $this->errors = new mosErrorSet();
 699      }
 700  
 701      /**
 702      * Extracts the package archive file
 703      * @return boolean True on success, False on error
 704      */
 705      function extractArchive($filename) {
 706          $mosConfig_absolute_path = mamboCore::get('mosConfig_absolute_path');
 707          $base_Dir = mosPathName($mosConfig_absolute_path.'/media');
 708          $this->archiveName = $base_Dir.$filename;
 709          $tmpdir = uniqid('install_');
 710          $this->extractDir = $this->cleanDir = mosPathName($base_Dir.uniqid('install_'));
 711          if (eregi( '.zip$', $filename )) {
 712              // Extract functions
 713              require_once ( $mosConfig_absolute_path . '/administrator/includes/pcl/pclzip.lib.php' );
 714              require_once ( $mosConfig_absolute_path . '/administrator/includes/pcl/pclerror.lib.php' );
 715              //require_once( $mosConfig_absolute_path . '/administrator/includes/pcl/pcltrace.lib.php' );
 716              //require_once( $mosConfig_absolute_path . '/administrator/includes/pcl/pcltar.lib.php' );
 717              $zipfile = new PclZip( $this->archiveName );
 718              $ret = $zipfile->extract( PCLZIP_OPT_PATH, $this->extractDir );
 719              if($ret == 0) {
 720                  $this->errors->addErrorDetails(sprintf(T_('Installer unrecoverable ZIP error %s in %s'), $zipfile->errorName(true), $this->archiveName), _MOS_ERROR_FATAL);
 721                  return false;
 722              }
 723          } else {
 724              require_once ( $mosConfig_absolute_path . '/includes/Archive/Tar.php' );
 725              $archive =& new Archive_Tar( $this->archiveName );
 726              $archive->setErrorHandling( PEAR_ERROR_PRINT );
 727  
 728              if (!$archive->extractModify( $this->extractDir, '' )) {
 729                  $this->errors->addErrorDetails(sprintf(T_('Installer unrecoverable TAR error in %s'), $this->archiveName), _MOS_ERROR_FATAL);
 730                  return false;
 731              }
 732          }
 733          // Try to find the correct install dir. in case that the package have subdirs
 734          // Save the install dir for later cleanup
 735          $dir =& new mosDirectory($this->extractDir);
 736          $singledir = $dir->soleDir();
 737          if ($singledir) $this->extractDir = mosPathName($this->extractDir.$singledir);
 738          return true;
 739      }
 740      /**
 741      * Custom install method
 742      * @param boolean True if installing from directory
 743      */
 744      function install($p_fromdir = null) {
 745          if (!is_null($p_fromdir)) $this->extractDir = $p_fromdir;
 746          $here = $this->extractDir;
 747          $installdir =& new mosDirectory($here);
 748          $xmlfiles =& $installdir->listFiles('.xml$');
 749          foreach ($xmlfiles as $file) {
 750              $parser = new mosInstallXML ($here.$file);
 751              $parser->install();
 752              $this->errors->mergeAnother($parser->errors);
 753              if ($parser->errors->getMaxLevel() >= _MOS_ERROR_WARN) return false;
 754          }
 755          return true;
 756      }
 757  
 758      function cleanUpInstall () {
 759          if ($this->archiveName) {
 760              $fmanager =& mosFileManager::getInstance();
 761              $fmanager->deleteFile($this->archiveName);
 762          }
 763          if ($this->cleanDir) {
 764              $edir =& new mosDirectory ($this->cleanDir);
 765              $edir->deleteAll();
 766          }
 767      }
 768  
 769      function getErrors () {
 770          return $this->errors->getErrors();
 771      }
 772  
 773  }
 774  
 775  ?>