eZ Publish  [trunk]
ezstep_site_types.php
Go to the documentation of this file.
00001 <?php
00002 /**
00003  * File containing the eZStepSiteTypes class.
00004  *
00005  * @copyright Copyright (C) 1999-2012 eZ Systems AS. All rights reserved.
00006  * @license http://www.gnu.org/licenses/gpl-2.0.txt GNU General Public License v2
00007  * @version //autogentag//
00008  * @package kernel
00009  */
00010 
00011 /*!
00012   \class eZStepSiteTypes ezstep_site_types.php
00013   \brief The class eZStepSiteTypes does
00014 
00015 */
00016 
00017 class eZStepSiteTypes extends eZStepInstaller
00018 {
00019     /*!
00020      Constructor
00021     */
00022     function eZStepSiteTypes( $tpl, $http, $ini, &$persistenceList )
00023     {
00024         $ini = eZINI::instance( 'package.ini' );
00025         $indexURL = trim( $ini->variable( 'RepositorySettings', 'RemotePackagesIndexURL' ) );
00026         if ( $indexURL === '' )
00027         {
00028             $indexURL = trim( $ini->variable( 'RepositorySettings', 'RemotePackagesIndexURLBase' ) );
00029             if ( substr( $indexURL, -1, 1 ) !== '/' )
00030             {
00031                 $indexURL .= '/';
00032             }
00033             $indexURL .= eZPublishSDK::version( false, false, false ) . '/' . eZPublishSDK::version() . '/';
00034         }
00035         $this->IndexURL = $indexURL;
00036 
00037         if ( substr( $this->IndexURL, -1, 1 ) == '/' )
00038             $this->XMLIndexURL = $this->IndexURL . 'index.xml';
00039         else
00040             $this->XMLIndexURL = $this->IndexURL . '/index.xml';
00041 
00042         $this->eZStepInstaller( $tpl, $http, $ini, $persistenceList,
00043                                 'site_types', 'Site types' );
00044     }
00045 
00046     /**
00047      * Downloads file.
00048      *
00049      * Sets $this->ErrorMsg in case of an error.
00050      *
00051      * \private
00052      * \param $url            URL.
00053      * \param $outDir         Directory where to put downloaded file to.
00054      * \param $forcedFileName Force saving downloaded file under this name.
00055      * \return false on error, path to downloaded package otherwise.
00056      */
00057     function downloadFile( $url, $outDir, $forcedFileName = false )
00058     {
00059         $fileName = $outDir . "/" . ( $forcedFileName ? $forcedFileName : basename( $url ) );
00060 
00061         eZDebug::writeNotice( "Downloading file '$fileName' from $url" );
00062 
00063         // Create the out directory if not exists.
00064         if ( !file_exists( $outDir ) )
00065             eZDir::mkdir( $outDir, false, true );
00066 
00067         // First try CURL
00068         if ( extension_loaded( 'curl' ) )
00069         {
00070             $ch = curl_init( $url );
00071             $fp = eZStepSiteTypes::fopen( $fileName, 'wb' );
00072 
00073             if ( $fp === false )
00074             {
00075                 $this->ErrorMsg = ezpI18n::tr( 'design/standard/setup/init', 'Cannot write to file' ) .
00076                     ': ' . $this->FileOpenErrorMsg;
00077                 return false;
00078             }
00079 
00080             curl_setopt( $ch, CURLOPT_FILE, $fp );
00081             curl_setopt( $ch, CURLOPT_HEADER, 0 );
00082             curl_setopt( $ch, CURLOPT_FAILONERROR, 1 );
00083             curl_setopt( $ch, CURLOPT_CONNECTTIMEOUT, 3 );
00084             // Get proxy
00085             $ini = eZINI::instance();
00086             $proxy = $ini->hasVariable( 'ProxySettings', 'ProxyServer' ) ? $ini->variable( 'ProxySettings', 'ProxyServer' ) : false;
00087             if ( $proxy )
00088             {
00089                 curl_setopt ( $ch, CURLOPT_PROXY , $proxy );
00090                 $userName = $ini->hasVariable( 'ProxySettings', 'User' ) ? $ini->variable( 'ProxySettings', 'User' ) : false;
00091                 $password = $ini->hasVariable( 'ProxySettings', 'Password' ) ? $ini->variable( 'ProxySettings', 'Password' ) : false;
00092                 if ( $userName )
00093                 {
00094                     curl_setopt ( $ch, CURLOPT_PROXYUSERPWD, "$userName:$password" );
00095                 }
00096             }
00097 
00098             if ( !curl_exec( $ch ) )
00099             {
00100                 $this->ErrorMsg = curl_error( $ch );
00101                 return false;
00102             }
00103 
00104             curl_close( $ch );
00105             fclose( $fp );
00106         }
00107         else
00108         {
00109             $parsedUrl = parse_url( $url );
00110             $checkIP = isset( $parsedUrl[ 'host' ] ) ? ip2long( gethostbyname( $parsedUrl[ 'host' ] ) ) : false;
00111             if ( $checkIP === false )
00112             {
00113                 return false;
00114             }
00115 
00116             // If we don't have CURL installed we used standard fopen urlwrappers
00117             // Note: Could be blocked by not allowing remote calls.
00118             if ( !copy( $url, $fileName ) )
00119             {
00120                 $buf = eZHTTPTool::sendHTTPRequest( $url, 80, false, 'eZ Publish', false );
00121 
00122                 $header = false;
00123                 $body = false;
00124                 if ( eZHTTPTool::parseHTTPResponse( $buf, $header, $body ) )
00125                 {
00126                     eZFile::create( $fileName, false, $body );
00127                 }
00128                 else
00129                 {
00130                     $this->ErrorMsg = ezpI18n::tr( 'design/standard/setup/init', 'Failed to copy %url to local file %filename', null,
00131                                               array( "%url" => $url,
00132                                                      "%filename" => $fileName ) );
00133                     return false;
00134                 }
00135             }
00136         }
00137 
00138         return $fileName;
00139     }
00140 
00141     /**
00142      * Downloads and imports package.
00143      *
00144      * Sets $this->ErrorMsg in case of an error.
00145      *
00146      * \param $forceDownload  download even if this package already exists.
00147      * \private
00148      * \return false on error, package object otherwise.
00149      */
00150     function downloadAndImportPackage( $packageName, $packageUrl, $forceDownload = false )
00151     {
00152         $package = eZPackage::fetch( $packageName, false, false, false );
00153 
00154         if ( is_object( $package ) )
00155         {
00156             if ( $forceDownload )
00157             {
00158                 $package->remove();
00159             }
00160             else
00161             {
00162                 eZDebug::writeNotice( "Skipping download of package '$packageName': package already exists." );
00163                 return $package;
00164             }
00165         }
00166 
00167         $archiveName = $this->downloadFile( $packageUrl, /* $outDir = */ eZStepSiteTypes::tempDir() );
00168         if ( $archiveName === false )
00169         {
00170             eZDebug::writeWarning( "Download of package '$packageName' from '$packageUrl' failed: $this->ErrorMsg" );
00171             $this->ErrorMsg = ezpI18n::tr( 'design/standard/setup/init',
00172                                       'Download of package \'%pkg\' failed. You may upload the package manually.',
00173                                       false, array( '%pkg' => $packageName ) );
00174 
00175             return false;
00176         }
00177 
00178         $package = eZPackage::import( $archiveName, $packageName, false );
00179 
00180         // Remove downloaded ezpkg file
00181         $ezFileHandler = new eZFileHandler();
00182         $ezFileHandler->unlink( $archiveName );
00183 
00184         if ( !$package instanceof eZPackage )
00185         {
00186             if ( $package == eZPackage::STATUS_INVALID_NAME )
00187             {
00188                 eZDebug::writeNotice( "The package name $packageName is invalid" );
00189             }
00190             else
00191             {
00192                 eZDebug::writeNotice( "Invalid package" );
00193             }
00194 
00195             $this->ErrorMsg = ezpI18n::tr( 'design/standard/setup/init', 'Invalid package' );
00196             return false;
00197         }
00198 
00199         return $package;
00200     }
00201 
00202 
00203     /*!
00204      * Download packages required by the given package.
00205      *
00206      * \private
00207      */
00208     function downloadDependantPackages( $sitePackage )
00209     {
00210         $dependencies = $sitePackage->attribute( 'dependencies' );
00211         $requirements = $dependencies['requires'];
00212         $remotePackagesInfo = $this->retrieveRemotePackagesList();
00213 
00214         foreach ( $requirements as $req )
00215         {
00216             $requiredPackageName = $req['name'];
00217 
00218             if ( isset( $req['min-version'] ) )
00219                 $requiredPackageVersion = $req['min-version'];
00220             else
00221                 $requiredPackageVersion = 0;
00222 
00223             $downloadNewPackage   = false;
00224             $removeCurrentPackage = false;
00225 
00226             // try to fetch the required package
00227             $package = eZPackage::fetch( $requiredPackageName, false, false, false );
00228 
00229             // if it already exists
00230             if ( is_object( $package ) )
00231             {
00232                 // check its version
00233                 $currentPackageVersion = $package->getVersion();
00234 
00235                 // if existing package's version is less than required one
00236                 // we remove the package and download newer one.
00237 
00238                 if ( version_compare( $currentPackageVersion, $requiredPackageVersion ) < 0 )
00239                 {
00240                     $downloadNewPackage   = true;
00241                     $removeCurrentPackage = true;
00242                 }
00243 
00244                 // else (if the version is greater or equal to the required one)
00245                 // then do nothing (skip downloading)
00246             }
00247             else
00248                 // if the package does not exist, we download it.
00249                 $downloadNewPackage   = true;
00250 
00251             if ( $removeCurrentPackage )
00252             {
00253                 $package->remove();
00254                 unset( $package );
00255             }
00256 
00257             if ( $downloadNewPackage )
00258             {
00259                 if ( !isset( $remotePackagesInfo[$requiredPackageName]['url'] ) )
00260                 {
00261                     eZDebug::writeWarning( "Download of package '$requiredPackageName' failed: the URL is unknown." );
00262                     $this->ErrorMsg = ezpI18n::tr( 'design/standard/setup/init',
00263                                               'Download of package \'%pkg\' failed. You may upload the package manually.',
00264                                               false, array( '%pkg' => $requiredPackageName ) );
00265                     $this->ShowURL = true;
00266 
00267                     return false;
00268                 }
00269 
00270                 $requiredPackageURL = $remotePackagesInfo[$requiredPackageName]['url'];
00271                 $rc = $this->downloadAndImportPackage( $requiredPackageName, $requiredPackageURL );
00272                 if( !is_object( $rc ) )
00273                 {
00274                     return false;
00275                 }
00276             }
00277         }
00278 
00279         return true;
00280     }
00281 
00282     /**
00283      * Upload local package.
00284      *
00285      * \private
00286      */
00287     function uploadPackage()
00288     {
00289 
00290         if ( !eZHTTPFile::canFetch( 'PackageBinaryFile' ) )
00291         {
00292             $this->ErrorMsg = ezpI18n::tr( 'design/standard/setup/init',
00293                                       'No package selected for upload' ) . '.';
00294             return;
00295         }
00296 
00297         $file = eZHTTPFile::fetch( 'PackageBinaryFile' );
00298         if ( !$file )
00299         {
00300             $this->ErrorMsg = ezpI18n::tr( 'design/standard/setup/init',
00301                                       'Failed fetching upload package file' );
00302             return;
00303         }
00304 
00305         $packageFilename = $file->attribute( 'filename' );
00306         $packageName = $file->attribute( 'original_filename' );
00307         if ( preg_match( "#^(.+)-[0-9](\.[0-9]+)-[0-9].ezpkg$#", $packageName, $matches ) )
00308             $packageName = $matches[1];
00309         $packageName = preg_replace( array( "#[^a-zA-Z0-9]+#",
00310                                             "#_+#",
00311                                             "#(^_)|(_$)#" ),
00312                                      array( '_',
00313                                             '_',
00314                                             '' ), $packageName );
00315         $package = eZPackage::import( $packageFilename, $packageName, false );
00316 
00317         if ( is_object( $package ) )
00318         {
00319             // package successfully imported
00320             return;
00321         }
00322         elseif ( $package == eZPackage::STATUS_ALREADY_EXISTS )
00323         {
00324             eZDebug::writeWarning( "Package '$packageName' already exists." );
00325         }
00326         else
00327         {
00328             $this->ErrorMsg = ezpI18n::tr( 'design/standard/setup/init',
00329                                   'Uploaded file is not an eZ Publish package' );
00330         }
00331     }
00332 
00333     /**
00334      * Process POST data.
00335      *
00336      * \reimp
00337      */
00338     function processPostData()
00339     {
00340         if ( $this->Http->hasPostVariable( 'UploadPackageButton' ) )
00341         {
00342             $this->uploadPackage();
00343             return false; // force displaying the same step.
00344         }
00345 
00346         if ( !$this->Http->hasPostVariable( 'eZSetup_site_type' ) )
00347         {
00348             $this->ErrorMsg = ezpI18n::tr( 'design/standard/setup/init',
00349                                       'No site package chosen.' );
00350             return false;
00351         }
00352 
00353         $sitePackageInfo = $this->Http->postVariable( 'eZSetup_site_type' );
00354         $downloaded = false; // true - if $sitePackageName package has been downloaded.
00355         if ( preg_match( '/^(\w+)\|(.+)$/', $sitePackageInfo, $matches ) )
00356         {
00357             // remote site package chosen: download it.
00358             $sitePackageName = $matches[1];
00359             $sitePackageURL  = $matches[2];
00360 
00361             // we already know that we should download the package anyway as it has newer version
00362             // so use force download mode
00363             $package = $this->downloadAndImportPackage( $sitePackageName, $sitePackageURL, true );
00364             if ( is_object( $package ) )
00365             {
00366                 $downloaded = true;
00367                 $this->Message = ezpI18n::tr( 'design/standard/setup/init', 'Package \'%packageName\' and it\'s dependencies have been downloaded successfully. Press \'Next\' to continue.', false, array( '%packageName' => $sitePackageName ) );
00368             }
00369         }
00370         else
00371         {
00372             // local (already imported) site package chosen: just fetch it.
00373             $sitePackageName = $sitePackageInfo;
00374 
00375             $package = eZPackage::fetch( $sitePackageName, false, false, false );
00376             $this->ErrorMsg = ezpI18n::tr( 'design/standard/setup/init', 'Invalid package' ) . '.';
00377         }
00378 
00379         // Verify package.
00380         if ( !is_object( $package ) || !$this->selectSiteType( $sitePackageName ) )
00381             return false;
00382 
00383         // Download packages that the site package requires.
00384         $downloadDependandPackagesResult = $this->downloadDependantPackages( $package );
00385         return $downloadDependandPackagesResult == false ? false : !$downloaded;
00386     }
00387 
00388     function init()
00389     {
00390         if ( $this->hasKickstartData() )
00391         {
00392             $data = $this->kickstartData();
00393             $remoteSitePackages = $this->retrieveRemoteSitePackagesList();
00394             $importedSitePackages = $this->fetchAvailableSitePackages();
00395             $dependenciesStatus = array();
00396 
00397             // check site package dependencies to show their status in the template
00398             foreach ( $importedSitePackages as $sitePackage )
00399             {
00400                 $sitePackageName = $sitePackage->attribute( 'name' );
00401                 $dependencies = $sitePackage->attribute( 'dependencies' );
00402                 $requirements = $dependencies['requires'];
00403 
00404                 foreach ( $requirements as $req )
00405                 {
00406                     $requiredPackageName    = $req['name'];
00407                     $requiredPackageVersion = $req['min-version'];
00408                     $packageOK = false;
00409 
00410                     $package = eZPackage::fetch( $requiredPackageName, false, false, false );
00411                     if ( is_object( $package ) )
00412                     {
00413                         $currentPackageVersion = $package->getVersion();
00414                         if ( version_compare( $currentPackageVersion, $requiredPackageVersion ) >= 0 )
00415                             $packageOK = true;
00416                     }
00417 
00418                     $dependenciesStatus[$sitePackageName][$requiredPackageName] = array( 'version' => $requiredPackageVersion,
00419                                                                                      'status'  => $packageOK );
00420                 }
00421             }
00422 
00423             $sitePackages = $this->createSitePackagesList( $remoteSitePackages, $importedSitePackages, $dependenciesStatus );
00424             $chosenSitePackage = $data['Site_package'];
00425             $downloaded = false;
00426             foreach( $sitePackages as $sitePackagesInfo )
00427             {
00428                 if( $sitePackagesInfo['name'] == $chosenSitePackage )
00429                 {
00430                     $sitePackagesInfoChoosen = $sitePackagesInfo;
00431                 }
00432             }
00433             if ( isset( $sitePackagesInfoChoosen ) and array_key_exists( 'url', $sitePackagesInfoChoosen ) )
00434             {
00435                 // we already know that we should download the package anyway as it has newer version
00436                 // so use force download mode
00437                 $package = $this->downloadAndImportPackage( $chosenSitePackage, $sitePackagesInfoChoosen['url'], true );
00438                 if ( is_object( $package ) )
00439                 {
00440 
00441                     $downloadDependandPackagesResult = $this->downloadDependantPackages( $package );
00442                     if ( $downloadDependandPackagesResult != false )
00443                     {
00444                         $downloaded = true;
00445                     }
00446                 }
00447             }
00448             else if ( isset( $sitePackagesInfoChoosen ) and !isset( $sitePackagesInfoChoosen['url'] ) )
00449             {
00450                 // Site package found locally. Checking if all requiremens are downloaded.
00451                 // This would be the case for offline installations with manually downloaded packages.
00452                 $chosenRequirements = $sitePackagesInfoChoosen['requires'];
00453                 $reqsDownloaded = true;
00454                 foreach( $chosenRequirements as $creq )
00455                 {
00456                     if( !$creq['status'] )
00457                     {
00458                         // Required packages missing. Stalling on this step.
00459                         $reqsDownloaded = false;
00460                         break;
00461                     }
00462                 }
00463                 $downloaded = $reqsDownloaded;
00464                 // Template should show Site_package set in kickstart.ini
00465                 $this->selectSiteType( $chosenSitePackage );
00466             }
00467 
00468             if ( $downloaded and $this->selectSiteType( $chosenSitePackage ) )
00469             {
00470                 return $this->kickstartContinueNextStep();
00471             }
00472         }
00473 
00474         if ( !isset( $this->ErrorMsg ) )
00475             $this->ErrorMsg = false;
00476 
00477         return false; // Always show site template selection
00478     }
00479 
00480     /**
00481      * \private
00482      */
00483     function createSitePackagesList( $remoteSitePackages, $importedSitePackages, $dependenciesStatus )
00484     {
00485         $sitePackages = array();
00486 
00487         if ( is_array( $remoteSitePackages ) )
00488         {
00489             foreach ( $remoteSitePackages as $packageInfo )
00490             {
00491                 $packageName = $packageInfo['name'];
00492                 $sitePackages[$packageName] = $packageInfo;
00493             }
00494         }
00495 
00496         foreach ( $importedSitePackages as $package )
00497         {
00498             $packageName = $package->attribute( 'name' );
00499             $packageVersion = $package->getVersion();
00500 
00501             if ( isset( $sitePackages[$packageName] ) )
00502             {
00503                 $remoteVersion = $sitePackages[$packageName]['version'];
00504                 $localVersion = $packageVersion;
00505 
00506                 if ( version_compare( $remoteVersion, $localVersion ) > 0 )
00507                     continue;
00508             }
00509 
00510             $thumbnails = $package->attribute( 'thumbnail-list' );
00511 
00512             $thumbnailPath = false;
00513             if ( $thumbnails )
00514             {
00515                 $thumbnailFile = $thumbnails[0];
00516                 $thumbnailPath = $package->fileItemPath( $thumbnailFile, 'default' );
00517             }
00518 
00519             $dependencies = $package->attribute( 'dependencies' );
00520             $requirements = $dependencies['requires'];
00521 
00522             $requiresPackageInfo = isset( $dependenciesStatus[$packageName] ) ? $dependenciesStatus[$packageName] : null;
00523             $packageInfo = array(
00524                 'name' => $packageName,
00525                 'version' => $package->getVersion(),
00526                 'type' => $package->attribute( 'type' ),
00527                 'summary' => $package->attribute( 'summary' ),
00528                 'description' => $package->attribute( 'description' ),
00529                 'requires' => $requiresPackageInfo,
00530                 );
00531 
00532             if ( $thumbnailPath )
00533                 $packageInfo['thumbnail_path'] = $thumbnailPath;
00534 
00535             $sitePackages[$packageName] = $packageInfo;
00536         }
00537 
00538         // Set availability status for each package.
00539         foreach ( $sitePackages as $idx => $packageInfo )
00540             $sitePackages[$idx]['status'] = !isset( $packageInfo['url'] );
00541 
00542         $sortBySummary = create_function('$x,$y', "return \$x['summary'] < \$y['summary'] ? -1 : 1;");
00543         usort( $sitePackages, $sortBySummary );
00544 
00545         return $sitePackages;
00546     }
00547 
00548     function display()
00549     {
00550         $remoteSitePackages = $this->retrieveRemoteSitePackagesList();
00551         $importedSitePackages = $this->fetchAvailableSitePackages();
00552         $dependenciesStatus = array();
00553 
00554         // check site package dependencies to show their status in the template
00555         foreach ( $importedSitePackages as $sitePackage )
00556         {
00557             $sitePackageName = $sitePackage->attribute( 'name' );
00558             $dependencies = $sitePackage->attribute( 'dependencies' );
00559             $requirements = $dependencies['requires'];
00560 
00561             foreach ( $requirements as $req )
00562             {
00563                 $requiredPackageName    = $req['name'];
00564                 $requiredPackageVersion = $req['min-version'];
00565                 $packageOK = false;
00566 
00567                 $package = eZPackage::fetch( $requiredPackageName, false, false, false );
00568                 if ( is_object( $package ) )
00569                 {
00570                     $currentPackageVersion = $package->getVersion();
00571                     if ( version_compare( $currentPackageVersion, $requiredPackageVersion ) >= 0 )
00572                         $packageOK = true;
00573                 }
00574 
00575                 $dependenciesStatus[$sitePackageName][$requiredPackageName] = array( 'version' => $requiredPackageVersion,
00576                                                                                      'status'  => $packageOK );
00577             }
00578         }
00579 
00580         $sitePackages = $this->createSitePackagesList( $remoteSitePackages, $importedSitePackages, $dependenciesStatus );
00581 
00582         $chosenSitePackage = $this->chosenSitePackage();
00583 
00584         $this->Tpl->setVariable( 'site_packages', $sitePackages );
00585         $this->Tpl->setVariable( 'dependencies_status', $dependenciesStatus );
00586         $this->Tpl->setVariable( 'chosen_package', $chosenSitePackage );
00587         $this->Tpl->setVariable( 'error', $this->ErrorMsg );
00588         $this->Tpl->setVariable( 'index_url', $this->IndexURL );
00589         $this->Tpl->setVariable( 'message', $this->Message );
00590 
00591         // Return template and data to be shown
00592         $result = array();
00593         // Display template
00594         $result['content'] = $this->Tpl->fetch( 'design:setup/init/site_types.tpl' );
00595         $result['path'] = array( array( 'text' => ezpI18n::tr( 'design/standard/setup/init',
00596                                                           'Site selection' ),
00597                                         'url' => false ) );
00598         return $result;
00599     }
00600 
00601     /**
00602      * Fetches list of site packages already available locally.
00603      *
00604      * \private
00605      */
00606     function fetchAvailableSitePackages()
00607     {
00608         $packageList = eZPackage::fetchPackages( array( 'db_available' => false ), array( 'type' => 'site' ) );
00609 
00610         return $packageList;
00611     }
00612 
00613     /**
00614      * Fetches list of packages already available locally.
00615      *
00616      * \private
00617      */
00618     function fetchAvailablePackages( $type = false )
00619     {
00620         $typeArray  = array();
00621         if ( $type )
00622             $typeArray['type'] = $type;
00623 
00624         $packageList = eZPackage::fetchPackages( array( 'db_available' => false ), $typeArray );
00625 
00626         return $packageList;
00627     }
00628 
00629 
00630     /**
00631      * Retrieve list of packages available to download.
00632      *
00633      * Example of return value:
00634      * array(
00635      *  'packages' => array(
00636      *                      '<package_name1>' => array( "name" =>... , "version" =>... , "summary" => ... "url" =>... ),
00637      *                      '<package_name2>' => array( "name" =>... , "version" =>... , "summary" => ... "url" =>... )
00638      *                     )
00639      *      );
00640      *
00641      */
00642     function retrieveRemotePackagesList( $onlySitePackages = false )
00643     {
00644         // Download index file.
00645         $idxFileName = $this->downloadFile( $this->XMLIndexURL, /* $outDir = */ eZStepSiteTypes::tempDir(), 'index.xml' );
00646 
00647         if ( $idxFileName === false )
00648         {
00649             // Searching for a local index.xml file to use for offline installation
00650             $destIndexPath = eZStepSiteTypes::tempDir() . DIRECTORY_SEPARATOR . 'index.xml';
00651             $repo = eZPackage::systemRepositoryInformation();
00652 
00653             if ( $repo )
00654             {
00655                 $sourceIndexPath = $repo['path'] . DIRECTORY_SEPARATOR . 'index.xml';
00656                 if ( file_exists( $sourceIndexPath ) )
00657                 {
00658                     eZFileHandler::copy( $sourceIndexPath, $destIndexPath );
00659                     $idxFileName = $destIndexPath;
00660                     // Removing error message from downloadFile
00661                     $this->ErrorMsg = false;
00662                 }
00663             }
00664         }
00665 
00666         if ( $idxFileName === false )
00667         {
00668             $this->ErrorMsg = ezpI18n::tr( 'design/standard/setup/init',
00669                                       'Retrieving remote site packages list failed. ' .
00670                                       'You may upload packages manually.' );
00671 
00672             eZDebug::writeNotice( "Cannot download remote packages index file from '$this->XMLIndexURL'." );
00673             return false;
00674         }
00675 
00676         // Parse it.
00677         $dom = new DOMDocument( '1.0', 'utf-8' );
00678         $dom->preserveWhiteSpace = false;
00679         $success = $dom->load( realpath( $idxFileName ) );
00680 
00681         @unlink( $idxFileName );
00682 
00683         if ( !$success )
00684         {
00685             eZDebug::writeError( "Unable to open index file." );
00686             return false;
00687         }
00688 
00689         $root = $dom->documentElement;
00690 
00691         if ( $root->localName != 'packages' )
00692         {
00693             eZDebug::writeError( "Malformed index file." );
00694             return false;
00695         }
00696 
00697         $packageList = array();
00698         foreach ( $root->childNodes as $packageNode )
00699         {
00700             if ( $packageNode->localName != 'package' ) // skip unwanted chilren
00701                 continue;
00702             if ( $onlySitePackages && $packageNode->getAttribute( 'type' ) != 'site' )  // skip non-site packages
00703                 continue;
00704             $packageAttributes = array();
00705             foreach ( $packageNode->attributes as $attributeNode )
00706             {
00707                 $packageAttributes[$attributeNode->localName] = $attributeNode->value;
00708             }
00709             $packageList[$packageAttributes['name']] = $packageAttributes;
00710         }
00711 
00712         return $packageList;
00713     }
00714 
00715     /**
00716      * Retrieve list of site packages available to download.
00717      * \private
00718      */
00719     function retrieveRemoteSitePackagesList()
00720     {
00721         return $this->retrieveRemotePackagesList( true );
00722     }
00723 
00724     /**
00725      * Wrapper for standard fopen() doing error checking.
00726      *
00727      * \private
00728      * \static
00729      */
00730     function fopen( $fileName, $mode )
00731     {
00732         $savedTrackErrorsFlag = ini_get( 'track_errors' );
00733         ini_set( 'track_errors', 1 );
00734 
00735         if ( ( $handle = @fopen( $fileName, 'wb' ) ) === false )
00736             $this->FileOpenErrorMsg = $php_errormsg;
00737 
00738         ini_set( 'track_errors', $savedTrackErrorsFlag );
00739 
00740         return $handle;
00741     }
00742 
00743     /**
00744      * Returns temporary directory used to download files to.
00745      *
00746      * \static
00747      */
00748     function tempDir()
00749     {
00750         return eZDir::path( array( eZSys::cacheDirectory(),
00751                                     'packages' ) );
00752     }
00753 
00754     // current repository URL
00755     public $IndexURL;
00756     public $XMLIndexURL;
00757 
00758     public $Error = 0;
00759     public $ErrorMsg = false;
00760     public $FileOpenErrorMsg = false;
00761     public $Message = false;
00762 }
00763 
00764 ?>