eZ Publish  [trunk]
ezpackageinstallationhandler.php
Go to the documentation of this file.
00001 <?php
00002 /**
00003  * File containing the eZPackageInstallationHandler 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   \ingroup package
00013   \class eZPackageInstallationHandler ezpackageinstallationhandler.php
00014   \brief The class eZPackageInstallationHandler does
00015 
00016 */
00017 
00018 class eZPackageInstallationHandler
00019 {
00020     /*!
00021      Constructor
00022     */
00023     function eZPackageInstallationHandler( $package, $type, $installItem, $name = null, $steps = null )
00024     {
00025         $this->Package = $package;
00026         $this->Attributes = array( 'type' => $type,
00027                                    'name' => $name,
00028                                    'steps' => $steps,
00029                                    'step_map' => false,
00030                                    'current_steps' => $steps );
00031         $this->InitializeStepMethodMap = array();
00032         $this->ValidateStepMethodMap = array();
00033         $this->CommitStepMethodMap = array();
00034         $this->InstallItem = $installItem;
00035     }
00036 
00037     /*!
00038      Will go over the steps and make sure that:
00039      - The next and previous links are correct
00040      - Steps that aren't needed are removed
00041 
00042       It will also make sure that steps can be looked up by their ID.
00043     */
00044     function generateStepMap( $package, &$persistentData )
00045     {
00046         $steps = $this->attribute( 'steps' );
00047         $map = array();
00048         $lastStep = false;
00049         $currentSteps = array();
00050         for ( $i = 0; $i < count( $steps ); ++$i )
00051         {
00052             $step =& $steps[$i];
00053             if ( !isset( $step['previous_step'] ) )
00054             {
00055                 if ( $lastStep )
00056                     $step['previous_step'] = $lastStep['id'];
00057                 else
00058                     $step['previous_step'] = false;
00059             }
00060             if ( !isset( $step['next_step'] ) )
00061             {
00062                 if ( $i + 1 < count( $steps ) )
00063                     $step['next_step'] = $steps[$i+1]['id'];
00064                 else
00065                     $step['next_step'] = false;
00066             }
00067             if ( isset( $step['methods']['initialize'] ) )
00068                 $this->InitializeStepMethodMap[$step['id']] = $step['methods']['initialize'];
00069             if ( isset( $step['methods']['validate'] ) )
00070                 $this->ValidateStepMethodMap[$step['id']] = $step['methods']['validate'];
00071             if ( isset( $step['methods']['commit'] ) )
00072                 $this->CommitStepMethodMap[$step['id']] = $step['methods']['commit'];
00073             $isStepIncluded = true;
00074             if ( isset( $step['methods']['check'] ) )
00075             {
00076                 $checkMethod = $step['methods']['check'];
00077                 $isStepIncluded = $this->$checkMethod( $package, $persistentData );
00078             }
00079             if ( $isStepIncluded )
00080             {
00081                 $map[$step['id']] =& $step;
00082                 $lastStep =& $step;
00083                 $currentSteps[] =& $step;
00084             }
00085         }
00086         $this->StepMap = array( 'first' => &$steps[0],
00087                                 'map' => &$map,
00088                                 'steps' => &$steps );
00089         $this->Attributes['step_map'] =& $this->StepMap;
00090         $this->Attributes['current_steps'] = $currentSteps;
00091     }
00092 
00093     function attributes()
00094     {
00095         return array_keys( $this->Attributes );
00096     }
00097 
00098     function hasAttribute( $name )
00099     {
00100         return array_key_exists( $name, $this->Attributes );
00101     }
00102 
00103     function attribute( $name )
00104     {
00105         if ( array_key_exists( $name, $this->Attributes ) )
00106         {
00107             return $this->Attributes[$name];
00108         }
00109 
00110         eZDebug::writeError( "Attribute '$name' does not exist", __METHOD__ );
00111         return null;
00112     }
00113 
00114     function initializeStepMethodMap()
00115     {
00116         return $this->InitializeStepMethodMap;
00117     }
00118 
00119     function validateStepMethodMap()
00120     {
00121         return $this->ValidateStepMethodMap;
00122     }
00123 
00124     function commitStepMethodMap()
00125     {
00126         return $this->CommitStepMethodMap;
00127     }
00128 
00129     /*!
00130      \return a process step map which has proper next/previous links,
00131              method maps and allows lookup of steps by ID.
00132     */
00133     function &stepMap()
00134     {
00135         return $this->StepMap;
00136     }
00137 
00138     function stepTemplate( $package, $installItem, $step )
00139     {
00140         $stepTemplatePath = 'design:package/';
00141         $stepTemplateName = $step['template'];
00142         if ( isset( $step['use_standard_template'] ) and
00143              $step['use_standard_template'] )
00144             $stepTemplatePath .= "create";
00145         else
00146             $stepTemplatePath .= "installers/" . $this->attribute( 'type' );
00147         return array( 'name' => $stepTemplateName,
00148                       'path' => $stepTemplatePath );
00149     }
00150 
00151     /*!
00152      This is called the first time the step is entered (ie. not on validations)
00153      and can be used to fill in values in the \a $persistentData variable
00154      for use in the template or later retrieval.
00155     */
00156     function initializeStep( $package, $http, $step, &$persistentData, $tpl, $module )
00157     {
00158         $methodMap = $this->initializeStepMethodMap();
00159         if ( count( $methodMap ) > 0 )
00160         {
00161             if ( isset( $methodMap[$step['id']] ) )
00162             {
00163                 $method = $methodMap[$step['id']];
00164                 return $this->$method( $package, $http, $step, $persistentData, $tpl, $module );
00165             }
00166         }
00167     }
00168 
00169     /*!
00170      This is called after a step is finished. Reimplement this function to validate
00171      the step values and give back errors.
00172      \return \c false if the next step should not be fetched (ie. errors) or
00173              \c true if the all is OK and the next step should be fetched.
00174              It is also possible to return a step identifier, in which case
00175              this will be the next step.
00176     */
00177     function validateStep( $package, $http, $currentStepID, &$stepMap, &$persistentData, &$errorList )
00178     {
00179         $nextStep = $this->validateAndAdvanceStep( $package, $http, $currentStepID, $stepMap, $persistentData, $errorList );
00180         if ( $nextStep === true )
00181         {
00182             if ( !isset( $stepMap['map'][$currentStepID] ) )
00183             {
00184                 $nextStep = $stepMap['first']['id'];
00185             }
00186             else
00187             {
00188                 $currentStep =& $stepMap['map'][$currentStepID];
00189                 $nextStep = $currentStep['next_step'];
00190             }
00191         }
00192         else if ( $nextStep === false )
00193             $nextStep = $currentStepID;
00194         return $nextStep;
00195     }
00196 
00197     function validateAndAdvanceStep( $package, $http, $currentStepID, &$stepMap, &$persistentData, &$errorList )
00198     {
00199         $methodMap = $this->validateStepMethodMap();
00200         if ( count( $methodMap ) > 0 )
00201         {
00202             if ( isset( $methodMap[$currentStepID] ) )
00203             {
00204                 $method = $methodMap[$currentStepID];
00205                 return $this->$method( $package, $http, $currentStepID, $stepMap, $persistentData, $errorList );
00206             }
00207         }
00208         return true;
00209     }
00210 
00211     /*!
00212      This is called after a step has validated it's information. It can
00213      be used to put values in the \a $persistentData variable for later retrieval.
00214     */
00215     function commitStep( $package, $http, $step, &$persistentData, $tpl )
00216     {
00217         $methodMap = $this->commitStepMethodMap();
00218         if ( count( $methodMap ) > 0 )
00219         {
00220             if ( isset( $methodMap[$step['id']] ) )
00221             {
00222                 $method = $methodMap[$step['id']];
00223                 return $this->$method( $package, $http, $step, $persistentData, $tpl );
00224             }
00225         }
00226     }
00227 
00228     /*!
00229      Used to reset the instalation handler if needed
00230     */
00231     function reset( )
00232     {
00233     }
00234 
00235 
00236     /*!
00237      Finalizes the creation process with the gathered information.
00238      This is usually the function that creates the package and
00239      adds the proper elements.
00240     */
00241     function finalize( $package, $http, &$persistentData )
00242     {
00243     }
00244 
00245     /*!
00246      \return the package installation handler object for the handler named \a $handlerName.
00247 
00248      \param handler name'
00249      \param install Item
00250     */
00251     static function instance( $package, $handlerName, $installItem )
00252     {
00253         // if no installItem is given, then this is the whole package installer
00254         /*if ( $installItem == null )
00255         {
00256             include_once( $package->path() . '/' . $package->installerDirectory() . '/' . $package->installerFileName() );
00257             $handlerClassName = $package->installerFileName();
00258             $handler =& new $handlerClassName( $package, null, null );
00259             return $handler;
00260         }*/
00261 
00262         $handlers =& $GLOBALS['eZPackageCreationInstallers'];
00263         if ( !isset( $handlers ) )
00264             $handlers = array();
00265         $handler = false;
00266 
00267         if( isset( $handlers[$handlerName] ) )
00268         {
00269             $handler =& $handlers[$handlerName];
00270             $handler->reset();
00271         }
00272         else
00273         {
00274             $optionArray = array( 'iniFile'       => 'package.ini',
00275                                   'iniSection'    => 'InstallerSettings',
00276                                   'iniVariable'   => 'HandlerAlias',
00277                                   'handlerIndex'  => $handlerName,
00278                                   'handlerParams' => array( $package, $handlerName, $installItem ) );
00279 
00280             $options = new ezpExtensionOptions( $optionArray );
00281 
00282             $handler = eZExtension::getHandlerClass( $options );
00283 
00284             if( $handler !== null and $handler !== false )
00285             {
00286                 $handlers[$handlerName] =& $handler;
00287                 // if custom install handler is available in the package, we use it
00288                 $customInstallHandler = $handler->customInstallHandlerInfo( $package, $installItem );
00289                 if ( $customInstallHandler )
00290                 {
00291                     unset( $handler );
00292                     $handlerClassName = $customInstallHandler['classname'];
00293                     $handlerFile = $customInstallHandler['file-path'];
00294 
00295                     include_once( $handlerFile );
00296                     $handler = new $handlerClassName( $package, $handlerName, $installItem );
00297                 }
00298             }
00299         }
00300 
00301         return $handler;
00302     }
00303 
00304     /*!
00305      \return The package type taken from \a $package if the package exists,
00306              otherwise \c false.
00307      If the creator should have a specific package type this function should be reimplemented.
00308      See eZPackage::typeList() for more information on available types.
00309 
00310      \note This function is called from createPackage and checkPackageMaintainer()
00311     */
00312     function packageType( $package, &$persistentData )
00313     {
00314         if ( $package instanceof eZPackage )
00315         {
00316             return $package->attribute( 'type' );
00317         }
00318         return false;
00319     }
00320 
00321     /*!
00322      \private
00323      Get root dom node of current install item.
00324     */
00325     function rootDOMNode()
00326     {
00327         if ( !isset( $this->InstallItem['content'] ) || !$this->InstallItem['content'] )
00328         {
00329             $filename = $this->InstallItem['filename'];
00330             $subdirectory = $this->InstallItem['sub-directory'];
00331             if ( $subdirectory )
00332                 $filepath = $subdirectory . '/' . $filename . '.xml';
00333             else
00334                 $filepath = $filename . '.xml';
00335 
00336             $filepath = $this->Package->path() . '/' . $filepath;
00337 
00338             $dom = $this->Package->fetchDOMFromFile( $filepath );
00339             if ( $dom )
00340             {
00341                 $this->InstallItem['content'] = $dom->documentElement;
00342             }
00343             else
00344             {
00345                 eZDebug::writeError( 'Failed fetching dom from file ' . $filepath, __METHOD__ );
00346                 exit(0);
00347             }
00348         }
00349 
00350         return $this->InstallItem['content'];
00351     }
00352 
00353     /*!
00354      \private
00355      Support for custom installers (stored within the package)
00356     */
00357     function customInstallHandlerInfo( $package, $installItem )
00358     {
00359         return false;
00360     }
00361 
00362 }
00363 ?>