[ Index ]
 

Code source de Joomla 1.0.13

Accédez au Source d'autres logiciels libres

title

Body

[fermer]

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

   1  <?php
   2  /**
   3  * @version $Id: installer.class.php 5035 2006-09-14 01:22:50Z pasamio $
   4  * @package Joomla
   5  * @subpackage Installer
   6  * @copyright Copyright (C) 2005 Open Source Matters. All rights reserved.
   7  * @license http://www.gnu.org/copyleft/gpl.html GNU/GPL, see LICENSE.php
   8  * Joomla! is free software. This version may have been modified pursuant
   9  * to the GNU General Public License, and as distributed it includes or
  10  * is derivative of works licensed under the GNU General Public License or
  11  * other free or open source software licenses.
  12  * See COPYRIGHT.php for copyright notices and details.
  13  */
  14  
  15  // no direct access
  16  defined( '_VALID_MOS' ) or die( 'Restricted access' );
  17  
  18  /**
  19  * Installer class
  20  * @package Joomla
  21  * @subpackage Installer
  22  * @abstract
  23  */
  24  class mosInstaller {
  25      // name of the XML file with installation information
  26      var $i_installfilename    = "";
  27      var $i_installarchive    = "";
  28      var $i_installdir        = "";
  29      var $i_iswin            = false;
  30      var $i_errno            = 0;
  31      var $i_error            = "";
  32      var $i_installtype        = "";
  33      var $i_unpackdir        = "";
  34      var $i_docleanup        = true;
  35  
  36      /** @var string The directory where the element is to be installed */
  37      var $i_elementdir         = '';
  38      /** @var string The name of the Joomla! element */
  39      var $i_elementname         = '';
  40      /** @var string The name of a special atttibute in a tag */
  41      var $i_elementspecial     = '';
  42      /** @var object A DOMIT XML document */
  43      var $i_xmldoc            = null;
  44      var $i_hasinstallfile     = null;
  45      var $i_installfile         = null;
  46  
  47      /**
  48      * Constructor
  49      */
  50  	function mosInstaller() {
  51          $this->i_iswin = (substr(PHP_OS, 0, 3) == 'WIN');
  52      }
  53      /**
  54      * Uploads and unpacks a file
  55      * @param string The uploaded package filename or install directory
  56      * @param boolean True if the file is an archive file
  57      * @return boolean True on success, False on error
  58      */
  59  	function upload($p_filename = null, $p_unpack = true) {
  60          $this->i_iswin = (substr(PHP_OS, 0, 3) == 'WIN');
  61          $this->installArchive( $p_filename );
  62  
  63          if ($p_unpack) {
  64              if ($this->extractArchive()) {
  65                  return $this->findInstallFile();
  66              } else {
  67                  return false;
  68              }
  69          }
  70      }
  71      /**
  72      * Extracts the package archive file
  73      * @return boolean True on success, False on error
  74      */
  75  	function extractArchive() {
  76          global $mosConfig_absolute_path;
  77  
  78          $base_Dir         = mosPathName( $mosConfig_absolute_path . '/media' );
  79  
  80          $archivename     = $base_Dir . $this->installArchive();
  81          $tmpdir         = uniqid( 'install_' );
  82  
  83          $extractdir     = mosPathName( $base_Dir . $tmpdir );
  84          $archivename     = mosPathName( $archivename, false );
  85  
  86          $this->unpackDir( $extractdir );
  87  
  88          if (eregi( '.zip$', $archivename )) {
  89              // Extract functions
  90              require_once ( $mosConfig_absolute_path . '/administrator/includes/pcl/pclzip.lib.php' );
  91              require_once ( $mosConfig_absolute_path . '/administrator/includes/pcl/pclerror.lib.php' );
  92              //require_once( $mosConfig_absolute_path . '/administrator/includes/pcl/pcltrace.lib.php' );
  93              //require_once( $mosConfig_absolute_path . '/administrator/includes/pcl/pcltar.lib.php' );
  94              $zipfile = new PclZip( $archivename );
  95              if($this->isWindows()) {
  96                  define('OS_WINDOWS',1);
  97              } else {
  98                  define('OS_WINDOWS',0);
  99              }
 100  
 101              $ret = $zipfile->extract( PCLZIP_OPT_PATH, $extractdir );
 102              if($ret == 0) {
 103                  $this->setError( 1, 'Unrecoverable error "'.$zipfile->errorName(true).'"' );
 104                  return false;
 105              }
 106          } else {
 107              require_once ( $mosConfig_absolute_path . '/includes/Archive/Tar.php' );
 108              $archive = new Archive_Tar( $archivename );
 109              $archive->setErrorHandling( PEAR_ERROR_PRINT );
 110  
 111              if (!$archive->extractModify( $extractdir, '' )) {
 112                  $this->setError( 1, 'Extract Error' );
 113                  return false;
 114              }
 115          }
 116  
 117          $this->installDir( $extractdir );
 118  
 119          // Try to find the correct install dir. in case that the package have subdirs
 120          // Save the install dir for later cleanup
 121          $filesindir = mosReadDirectory( $this->installDir(), '' );
 122  
 123          if (count( $filesindir ) == 1) {
 124              if (is_dir( $extractdir . $filesindir[0] )) {
 125                  $this->installDir( mosPathName( $extractdir . $filesindir[0] ) );
 126              }
 127          }
 128          return true;
 129      }
 130      /**
 131      * Tries to find the package XML file
 132      * @return boolean True on success, False on error
 133      */
 134  	function findInstallFile() {
 135          $found = false;
 136          // Search the install dir for an xml file
 137          $files = mosReadDirectory( $this->installDir(), '.xml$', true, true );
 138  
 139          if (count( $files ) > 0) {
 140              foreach ($files as $file) {
 141                  $packagefile = $this->isPackageFile( $file );
 142                  if (!is_null( $packagefile ) && !$found ) {
 143                      $this->xmlDoc( $packagefile );
 144                      return true;
 145                  }
 146              }
 147              $this->setError( 1, 'ERROR: Could not find a Joomla! XML setup file in the package.' );
 148              return false;
 149          } else {
 150              $this->setError( 1, 'ERROR: Could not find an XML setup file in the package.' );
 151              return false;
 152          }
 153      }
 154      /**
 155      * @param string A file path
 156      * @return object A DOMIT XML document, or null if the file failed to parse
 157      */
 158  	function isPackageFile( $p_file ) {
 159          $xmlDoc = new DOMIT_Lite_Document();
 160          $xmlDoc->resolveErrors( true );
 161  
 162          if (!$xmlDoc->loadXML( $p_file, false, true )) {
 163              return null;
 164          }
 165          $root = &$xmlDoc->documentElement;
 166  
 167          if ($root->getTagName() != 'mosinstall') {
 168              return null;
 169          }
 170          // Set the type
 171          $this->installType( $root->getAttribute( 'type' ) );
 172          $this->installFilename( $p_file );
 173          return $xmlDoc;
 174      }
 175      /**
 176      * Loads and parses the XML setup file
 177      * @return boolean True on success, False on error
 178      */
 179  	function readInstallFile() {
 180  
 181          if ($this->installFilename() == "") {
 182              $this->setError( 1, 'No filename specified' );
 183              return false;
 184          }
 185  
 186          $this->i_xmldoc = new DOMIT_Lite_Document();
 187          $this->i_xmldoc->resolveErrors( true );
 188          if (!$this->i_xmldoc->loadXML( $this->installFilename(), false, true )) {
 189              return false;
 190          }
 191          $root = &$this->i_xmldoc->documentElement;
 192  
 193          // Check that it's am installation file
 194          if ($root->getTagName() != 'mosinstall') {
 195              $this->setError( 1, 'File :"' . $this->installFilename() . '" is not a valid Joomla! installation file' );
 196              return false;
 197          }
 198  
 199          $this->installType( $root->getAttribute( 'type' ) );
 200          return true;
 201      }
 202      /**
 203      * Abstract install method
 204      */
 205  	function install() {
 206          die( 'Method "install" cannot be called by class ' . strtolower(get_class( $this )) );
 207      }
 208      /**
 209      * Abstract uninstall method
 210      */
 211  	function uninstall() {
 212          die( 'Method "uninstall" cannot be called by class ' . strtolower(get_class( $this )) );
 213      }
 214      /**
 215      * return to method
 216      */
 217  	function returnTo( $option, $element ) {
 218          return "index2.php?option=$option&element=$element";
 219      }
 220      /**
 221      * @param string Install from directory
 222      * @param string The install type
 223      * @return boolean
 224      */
 225  	function preInstallCheck( $p_fromdir, $type ) {
 226  
 227          if (!is_null($p_fromdir)) {
 228              $this->installDir($p_fromdir);
 229          }
 230  
 231          if (!$this->installfile()) {
 232              $this->findInstallFile();
 233          }
 234  
 235          if (!$this->readInstallFile()) {
 236              $this->setError( 1, 'Installation file not found:<br />' . $this->installDir() );
 237              return false;
 238          }
 239  
 240          if ($this->installType() != $type) {
 241              $this->setError( 1, 'XML setup file is not for a "'.$type.'".' );
 242              return false;
 243          }
 244  
 245          // In case there where an error doring reading or extracting the archive
 246          if ($this->errno()) {
 247              return false;
 248          }
 249  
 250          return true;
 251      }
 252      /**
 253      * @param string The tag name to parse
 254      * @param string An attribute to search for in a filename element
 255      * @param string The value of the 'special' element if found
 256      * @param boolean True for Administrator components
 257      * @return mixed Number of file or False on error
 258      */
 259  	function parseFiles( $tagName='files', $special='', $specialError='', $adminFiles=0 ) {
 260          global $mosConfig_absolute_path;
 261          // Find files to copy
 262          $xmlDoc =& $this->xmlDoc();
 263          $root =& $xmlDoc->documentElement;
 264  
 265          $files_element =& $root->getElementsByPath( $tagName, 1 );
 266          if (is_null( $files_element )) {
 267              return 0;
 268          }
 269  
 270          if (!$files_element->hasChildNodes()) {
 271              // no files
 272              return 0;
 273          }
 274          $files = $files_element->childNodes;
 275          $copyfiles = array();
 276          if (count( $files ) == 0) {
 277              // nothing more to do
 278              return 0;
 279          }
 280  
 281          if ($folder = $files_element->getAttribute( 'folder' )) {
 282              $temp = mosPathName( $this->unpackDir() . $folder );
 283              if ($temp == $this->installDir()) {
 284                  // this must be only an admin component
 285                  $installFrom = $this->installDir();
 286              } else {
 287                  $installFrom = mosPathName( $this->installDir() . $folder );
 288              }
 289          } else {
 290              $installFrom = $this->installDir();
 291          }
 292  
 293          foreach ($files as $file) {
 294              if (basename( $file->getText() ) != $file->getText()) {
 295                  $newdir = dirname( $file->getText() );
 296  
 297                  if ($adminFiles){
 298                      if (!mosMakePath( $this->componentAdminDir(), $newdir )) {
 299                          $this->setError( 1, 'Failed to create directory "' . ($this->componentAdminDir()) . $newdir . '"' );
 300                          return false;
 301                      }
 302                  } else {
 303                      if (!mosMakePath( $this->elementDir(), $newdir )) {
 304                          $this->setError( 1, 'Failed to create directory "' . ($this->elementDir()) . $newdir . '"' );
 305                          return false;
 306                      }
 307                  }
 308              }
 309              $copyfiles[] = $file->getText();
 310  
 311              // check special for attribute
 312              if ($file->getAttribute( $special )) {
 313                  $this->elementSpecial( $file->getAttribute( $special ) );
 314              }
 315          }
 316  
 317          if ($specialError) {
 318              if ($this->elementSpecial() == '') {
 319                  $this->setError( 1, $specialError );
 320                  return false;
 321              }
 322          }
 323  
 324          if ($tagName == 'media') {
 325              // media is a special tag
 326              $installTo = mosPathName( $mosConfig_absolute_path . '/images/stories' );
 327          } else if ($adminFiles) {
 328              $installTo = $this->componentAdminDir();
 329          } else {
 330              $installTo = $this->elementDir();
 331          }
 332          $result = $this->copyFiles( $installFrom, $installTo, $copyfiles );
 333  
 334          return $result;
 335      }
 336      /**
 337      * @param string Source directory
 338      * @param string Destination directory
 339      * @param array array with filenames
 340      * @param boolean True is existing files can be replaced
 341      * @return boolean True on success, False on error
 342      */
 343  	function copyFiles( $p_sourcedir, $p_destdir, $p_files, $overwrite=false ) {
 344          if (is_array( $p_files ) && count( $p_files ) > 0) {
 345              foreach($p_files as $_file) {
 346                  $filesource    = mosPathName( mosPathName( $p_sourcedir ) . $_file, false );
 347                  $filedest    = mosPathName( mosPathName( $p_destdir ) . $_file, false );
 348  
 349                  if (!file_exists( $filesource )) {
 350                      $this->setError( 1, "File $filesource does not exist!" );
 351                      return false;
 352                  } else if (file_exists( $filedest ) && !$overwrite) {
 353                      $this->setError( 1, "There is already a file called $filedest - Are you trying to install the same CMT twice?" );
 354                      return false;
 355                  } else {
 356                                          $path_info = pathinfo($_file);
 357                                          if (!is_dir( $path_info['dirname'] )){
 358                                                  mosMakePath( $p_destdir, $path_info['dirname'] );
 359                                          }
 360                      if( !( copy($filesource,$filedest) && mosChmod($filedest) ) ) {
 361                          $this->setError( 1, "Failed to copy file: $filesource to $filedest" );
 362                          return false;
 363                      }
 364                  }
 365              }
 366          } else {
 367              return false;
 368          }
 369          return count( $p_files );
 370      }
 371      /**
 372      * Copies the XML setup file to the element Admin directory
 373      * Used by Components/Modules/Mambot Installer Installer
 374      * @return boolean True on success, False on error
 375      */
 376  	function copySetupFile( $where='admin' ) {
 377          if ($where == 'admin') {
 378              return $this->copyFiles( $this->installDir(), $this->componentAdminDir(), array( basename( $this->installFilename() ) ), true );
 379          } else if ($where == 'front') {
 380              return $this->copyFiles( $this->installDir(), $this->elementDir(), array( basename( $this->installFilename() ) ), true );
 381          }
 382      }
 383  
 384      /**
 385      * @param int The error number
 386      * @param string The error message
 387      */
 388  	function setError( $p_errno, $p_error ) {
 389          $this->errno( $p_errno );
 390          $this->error( $p_error );
 391      }
 392      /**
 393      * @param boolean True to display both number and message
 394      * @param string The error message
 395      * @return string
 396      */
 397  	function getError($p_full = false) {
 398          if ($p_full) {
 399              return $this->errno() . " " . $this->error();
 400          } else {
 401              return $this->error();
 402          }
 403      }
 404      /**
 405      * @param string The name of the property to set/get
 406      * @param mixed The value of the property to set
 407      * @return The value of the property
 408      */
 409      function &setVar( $name, $value=null ) {
 410          if (!is_null( $value )) {
 411              $this->$name = $value;
 412          }
 413          return $this->$name;
 414      }
 415  
 416  	function installFilename( $p_filename = null ) {
 417          if(!is_null($p_filename)) {
 418              if($this->isWindows()) {
 419                  $this->i_installfilename = str_replace('/','\\',$p_filename);
 420              } else {
 421                  $this->i_installfilename = str_replace('\\','/',$p_filename);
 422              }
 423          }
 424          return $this->i_installfilename;
 425      }
 426  
 427  	function installType( $p_installtype = null ) {
 428          return $this->setVar( 'i_installtype', $p_installtype );
 429      }
 430  
 431  	function error( $p_error = null ) {
 432          return $this->setVar( 'i_error', $p_error );
 433      }
 434  
 435      function &xmlDoc( $p_xmldoc = null ) {
 436          return $this->setVar( 'i_xmldoc', $p_xmldoc );
 437      }
 438  
 439  	function installArchive( $p_filename = null ) {
 440          return $this->setVar( 'i_installarchive', $p_filename );
 441      }
 442  
 443  	function installDir( $p_dirname = null ) {
 444          return $this->setVar( 'i_installdir', $p_dirname );
 445      }
 446  
 447  	function unpackDir( $p_dirname = null ) {
 448          return $this->setVar( 'i_unpackdir', $p_dirname );
 449      }
 450  
 451  	function isWindows() {
 452          return $this->i_iswin;
 453      }
 454  
 455  	function errno( $p_errno = null ) {
 456          return $this->setVar( 'i_errno', $p_errno );
 457      }
 458  
 459  	function hasInstallfile( $p_hasinstallfile = null ) {
 460          return $this->setVar( 'i_hasinstallfile', $p_hasinstallfile );
 461      }
 462  
 463  	function installfile( $p_installfile = null ) {
 464          return $this->setVar( 'i_installfile', $p_installfile );
 465      }
 466  
 467  	function elementDir( $p_dirname = null )    {
 468          return $this->setVar( 'i_elementdir', $p_dirname );
 469      }
 470  
 471  	function elementName( $p_name = null )    {
 472          return $this->setVar( 'i_elementname', $p_name );
 473      }
 474  	function elementSpecial( $p_name = null )    {
 475          return $this->setVar( 'i_elementspecial', $p_name );
 476      }
 477  }
 478  
 479  function cleanupInstall( $userfile_name, $resultdir) {
 480      global $mosConfig_absolute_path;
 481  
 482      if (file_exists( $resultdir )) {
 483          deldir( $resultdir );
 484          unlink( mosPathName( $mosConfig_absolute_path . '/media/' . $userfile_name, false ) );
 485      }
 486  }
 487  
 488  function deldir( $dir ) {
 489      $current_dir = opendir( $dir );
 490      $old_umask = umask(0);
 491      while ($entryname = readdir( $current_dir )) {
 492          if ($entryname != '.' and $entryname != '..') {
 493              if (is_dir( $dir . $entryname )) {
 494                  deldir( mosPathName( $dir . $entryname ) );
 495              } else {
 496                  @chmod($dir . $entryname, 0777);
 497                  unlink( $dir . $entryname );
 498              }
 499          }
 500      }
 501      umask($old_umask);
 502      closedir( $current_dir );
 503      return rmdir( $dir );
 504  }
 505  ?>


Généré le : Wed Nov 21 14:43:32 2007 par Balluche grâce à PHPXref 0.7
  Clicky Web Analytics