eZ Publish  [4.0]
ezpackageinstallationhandler.php
Go to the documentation of this file.
00001 <?php
00002 //
00003 // Definition of eZPackageInstallationHandler class
00004 //
00005 // Created on: <31-Mar-2004 10:15:36 kk>
00006 //
00007 // ## BEGIN COPYRIGHT, LICENSE AND WARRANTY NOTICE ##
00008 // SOFTWARE NAME: eZ Publish
00009 // SOFTWARE RELEASE: 4.0.x
00010 // COPYRIGHT NOTICE: Copyright (C) 1999-2008 eZ Systems AS
00011 // SOFTWARE LICENSE: GNU General Public License v2.0
00012 // NOTICE: >
00013 //   This program is free software; you can redistribute it and/or
00014 //   modify it under the terms of version 2.0  of the GNU General
00015 //   Public License as published by the Free Software Foundation.
00016 //
00017 //   This program is distributed in the hope that it will be useful,
00018 //   but WITHOUT ANY WARRANTY; without even the implied warranty of
00019 //   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00020 //   GNU General Public License for more details.
00021 //
00022 //   You should have received a copy of version 2.0 of the GNU General
00023 //   Public License along with this program; if not, write to the Free
00024 //   Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
00025 //   MA 02110-1301, USA.
00026 //
00027 //
00028 // ## END COPYRIGHT, LICENSE AND WARRANTY NOTICE ##
00029 //
00030 
00031 /*! \file ezpackageinstallationhandler.php
00032 */
00033 
00034 /*!
00035   \ingroup package
00036   \class eZPackageInstallationHandler ezpackageinstallationhandler.php
00037   \brief The class eZPackageInstallationHandler does
00038 
00039 */
00040 
00041 class eZPackageInstallationHandler
00042 {
00043     /*!
00044      Constructor
00045     */
00046     function eZPackageInstallationHandler( $package, $type, $installItem, $name = null, $steps = null )
00047     {
00048         $this->Package = $package;
00049         $this->Attributes = array( 'type' => $type,
00050                                    'name' => $name,
00051                                    'steps' => $steps,
00052                                    'step_map' => false,
00053                                    'current_steps' => $steps );
00054         $this->InitializeStepMethodMap = array();
00055         $this->ValidateStepMethodMap = array();
00056         $this->CommitStepMethodMap = array();
00057         $this->InstallItem = $installItem;
00058     }
00059 
00060     /*!
00061      Will go over the steps and make sure that:
00062      - The next and previous links are correct
00063      - Steps that aren't needed are removed
00064 
00065       It will also make sure that steps can be looked up by their ID.
00066     */
00067     function generateStepMap( $package, &$persistentData )
00068     {
00069         $steps = $this->attribute( 'steps' );
00070         $map = array();
00071         $lastStep = false;
00072         $currentSteps = array();
00073         for ( $i = 0; $i < count( $steps ); ++$i )
00074         {
00075             $step =& $steps[$i];
00076             if ( !isset( $step['previous_step'] ) )
00077             {
00078                 if ( $lastStep )
00079                     $step['previous_step'] = $lastStep['id'];
00080                 else
00081                     $step['previous_step'] = false;
00082             }
00083             if ( !isset( $step['next_step'] ) )
00084             {
00085                 if ( $i + 1 < count( $steps ) )
00086                     $step['next_step'] = $steps[$i+1]['id'];
00087                 else
00088                     $step['next_step'] = false;
00089             }
00090             if ( isset( $step['methods']['initialize'] ) )
00091                 $this->InitializeStepMethodMap[$step['id']] = $step['methods']['initialize'];
00092             if ( isset( $step['methods']['validate'] ) )
00093                 $this->ValidateStepMethodMap[$step['id']] = $step['methods']['validate'];
00094             if ( isset( $step['methods']['commit'] ) )
00095                 $this->CommitStepMethodMap[$step['id']] = $step['methods']['commit'];
00096             $isStepIncluded = true;
00097             if ( isset( $step['methods']['check'] ) )
00098             {
00099                 $checkMethod = $step['methods']['check'];
00100                 $isStepIncluded = $this->$checkMethod( $package, $persistentData );
00101             }
00102             if ( $isStepIncluded )
00103             {
00104                 $map[$step['id']] =& $step;
00105                 $lastStep =& $step;
00106                 $currentSteps[] =& $step;
00107             }
00108         }
00109         $this->StepMap = array( 'first' => &$steps[0],
00110                                 'map' => &$map,
00111                                 'steps' => &$steps );
00112         $this->Attributes['step_map'] =& $this->StepMap;
00113         $this->Attributes['current_steps'] = $currentSteps;
00114     }
00115 
00116     function attributes()
00117     {
00118         return array_keys( $this->Attributes );
00119     }
00120 
00121     function hasAttribute( $name )
00122     {
00123         return array_key_exists( $name, $this->Attributes );
00124     }
00125 
00126     function attribute( $name )
00127     {
00128         if ( array_key_exists( $name, $this->Attributes ) )
00129         {
00130             return $this->Attributes[$name];
00131         }
00132 
00133         eZDebug::writeError( "Attribute '$name' does not exist", 'eZPackageInstallationHandler::attribute' );
00134         return null;
00135     }
00136 
00137     function initializeStepMethodMap()
00138     {
00139         return $this->InitializeStepMethodMap;
00140     }
00141 
00142     function validateStepMethodMap()
00143     {
00144         return $this->ValidateStepMethodMap;
00145     }
00146 
00147     function commitStepMethodMap()
00148     {
00149         return $this->CommitStepMethodMap;
00150     }
00151 
00152     /*!
00153      \return a process step map which has proper next/previous links,
00154              method maps and allows lookup of steps by ID.
00155     */
00156     function &stepMap()
00157     {
00158         return $this->StepMap;
00159     }
00160 
00161     /*!
00162      \virtual
00163     */
00164     function stepTemplate( $package, $installItem, $step )
00165     {
00166         $stepTemplatePath = 'design:package/';
00167         $stepTemplateName = $step['template'];
00168         if ( isset( $step['use_standard_template'] ) and
00169              $step['use_standard_template'] )
00170             $stepTemplatePath .= "create";
00171         else
00172             $stepTemplatePath .= "installers/" . $this->attribute( 'type' );
00173         return array( 'name' => $stepTemplateName,
00174                       'path' => $stepTemplatePath );
00175     }
00176 
00177     /*!
00178      \virtual
00179      This is called the first time the step is entered (ie. not on validations)
00180      and can be used to fill in values in the \a $persistentData variable
00181      for use in the template or later retrieval.
00182     */
00183     function initializeStep( $package, $http, $step, &$persistentData, $tpl, $module )
00184     {
00185         $methodMap = $this->initializeStepMethodMap();
00186         if ( count( $methodMap ) > 0 )
00187         {
00188             if ( isset( $methodMap[$step['id']] ) )
00189             {
00190                 $method = $methodMap[$step['id']];
00191                 return $this->$method( $package, $http, $step, $persistentData, $tpl, $module );
00192             }
00193         }
00194     }
00195 
00196     /*!
00197      This is called after a step is finished. Reimplement this function to validate
00198      the step values and give back errors.
00199      \return \c false if the next step should not be fetched (ie. errors) or
00200              \c true if the all is OK and the next step should be fetched.
00201              It is also possible to return a step identifier, in which case
00202              this will be the next step.
00203     */
00204     function validateStep( $package, $http, $currentStepID, &$stepMap, &$persistentData, &$errorList )
00205     {
00206         $nextStep = $this->validateAndAdvanceStep( $package, $http, $currentStepID, $stepMap, $persistentData, $errorList );
00207         if ( $nextStep === true )
00208         {
00209             if ( !isset( $stepMap['map'][$currentStepID] ) )
00210             {
00211                 $nextStep = $stepMap['first']['id'];
00212             }
00213             else
00214             {
00215                 $currentStep =& $stepMap['map'][$currentStepID];
00216                 $nextStep = $currentStep['next_step'];
00217             }
00218         }
00219         else if ( $nextStep === false )
00220             $nextStep = $currentStepID;
00221         return $nextStep;
00222     }
00223 
00224     /*!
00225      \virtual
00226     */
00227     function validateAndAdvanceStep( $package, $http, $currentStepID, &$stepMap, &$persistentData, &$errorList )
00228     {
00229         $methodMap = $this->validateStepMethodMap();
00230         if ( count( $methodMap ) > 0 )
00231         {
00232             if ( isset( $methodMap[$currentStepID] ) )
00233             {
00234                 $method = $methodMap[$currentStepID];
00235                 return $this->$method( $package, $http, $currentStepID, $stepMap, $persistentData, $errorList );
00236             }
00237         }
00238         return true;
00239     }
00240 
00241     /*!
00242      \virtual
00243      This is called after a step has validated it's information. It can
00244      be used to put values in the \a $persistentData variable for later retrieval.
00245     */
00246     function commitStep( $package, $http, $step, &$persistentData, $tpl )
00247     {
00248         $methodMap = $this->commitStepMethodMap();
00249         if ( count( $methodMap ) > 0 )
00250         {
00251             if ( isset( $methodMap[$step['id']] ) )
00252             {
00253                 $method = $methodMap[$step['id']];
00254                 return $this->$method( $package, $http, $step, $persistentData, $tpl );
00255             }
00256         }
00257     }
00258 
00259     /*!
00260      \virtual
00261      Used to reset the instalation handler if needed
00262     */
00263     function reset( )
00264     {
00265     }
00266 
00267     /*!
00268      \virtual
00269      Finalizes the creation process with the gathered information.
00270      This is usually the function that creates the package and
00271      adds the proper elements.
00272     */
00273     function finalize( $package, $http, &$persistentData )
00274     {
00275     }
00276 
00277     /*!
00278      \return the package installation handler object for the handler named \a $handlerName.
00279 
00280      \param handler name'
00281      \param install Item
00282     */
00283     static function instance( $package, $handlerName, $installItem )
00284     {
00285         // if no installItem is given, then this is the whole package installer
00286         /*if ( $installItem == null )
00287         {
00288             include_once( $package->path() . '/' . $package->installerDirectory() . '/' . $package->installerFileName() );
00289             $handlerClassName = $package->installerFileName();
00290             $handler =& new $handlerClassName( $package, null, null );
00291             return $handler;
00292         }*/
00293 
00294         $handlers =& $GLOBALS['eZPackageCreationInstallers'];
00295         if ( !isset( $handlers ) )
00296             $handlers = array();
00297         $handler = false;
00298         //include_once( 'lib/ezutils/classes/ezextension.php' );
00299         if ( eZExtension::findExtensionType( array( 'ini-name' => 'package.ini',
00300                                                     'repository-group' => 'PackageSettings',
00301                                                     'repository-variable' => 'RepositoryDirectories',
00302                                                     'extension-group' => 'PackageSettings',
00303                                                     'extension-variable' => 'ExtensionDirectories',
00304                                                     'subdir' => 'packageinstallers',
00305                                                     'extension-subdir' => 'packageinstallers',
00306                                                     'suffix-name' => 'packageinstaller.php',
00307                                                     'type-directory' => true,
00308                                                     'type' => $handlerName,
00309                                                     'alias-group' => 'InstallerSettings',
00310                                                     'alias-variable' => 'HandlerAlias' ),
00311                                              $result ) )
00312         {
00313             $handlerFile = $result['found-file-path'];
00314             if ( file_exists( $handlerFile ) )
00315             {
00316                 include_once( $handlerFile );
00317                 $handlerClassName = $result['type'] . 'PackageInstaller';
00318 
00319                 if ( isset( $handlers[$result['type']] ) )
00320                 {
00321                     $handler =& $handlers[$result['type']];
00322                     $handler->reset();
00323                 }
00324                 else
00325                 {
00326                     $handler = new $handlerClassName( $package, $handlerName, $installItem );
00327                     $handlers[$result['type']] =& $handler;
00328                 }
00329 
00330                 // if custom install handler is available in the package, we use it
00331                 $customInstallHandler = $handler->customInstallHandlerInfo( $package, $installItem );
00332                 if ( $customInstallHandler )
00333                 {
00334                     unset( $handler );
00335                     $handlerClassName = $customInstallHandler['classname'];
00336                     $handlerFile = $customInstallHandler['file-path'];
00337 
00338                     include_once( $handlerFile );
00339                     $handler = new $handlerClassName( $package, $handlerName, $installItem );
00340                 }
00341             }
00342         }
00343         return $handler;
00344     }
00345 
00346     /*!
00347      \virtual
00348      \return The package type taken from \a $package if the package exists,
00349              otherwise \c false.
00350      If the creator should have a specific package type this function should be reimplemented.
00351      See eZPackage::typeList() for more information on available types.
00352 
00353      \note This function is called from createPackage and checkPackageMaintainer()
00354     */
00355     function packageType( $package, &$persistentData )
00356     {
00357         if ( $package instanceof eZPackage )
00358         {
00359             return $package->attribute( 'type' );
00360         }
00361         return false;
00362     }
00363 
00364     /*!
00365      \private
00366      Get root dom node of current install item.
00367     */
00368     function rootDOMNode()
00369     {
00370         if ( !isset( $this->InstallItem['content'] ) || !$this->InstallItem['content'] )
00371         {
00372             $filename = $this->InstallItem['filename'];
00373             $subdirectory = $this->InstallItem['sub-directory'];
00374             if ( $subdirectory )
00375                 $filepath = $subdirectory . '/' . $filename . '.xml';
00376             else
00377                 $filepath = $filename . '.xml';
00378 
00379             $filepath = $this->Package->path() . '/' . $filepath;
00380 
00381             $dom = $this->Package->fetchDOMFromFile( $filepath );
00382             if ( $dom )
00383             {
00384                 $this->InstallItem['content'] = $dom->documentElement;
00385             }
00386             else
00387             {
00388                 eZDebug::writeError( 'Failed fetching dom from file ' . $filepath,
00389                                      'eZPackageInstallationHandler::rootDOMNode()' );
00390                 exit(0);
00391             }
00392         }
00393 
00394         return $this->InstallItem['content'];
00395     }
00396 
00397     /*!
00398      \private
00399      Support for custom installers (stored within the package)
00400     */
00401     function customInstallHandlerInfo( $package, $installItem )
00402     {
00403         return false;
00404     }
00405 
00406 }
00407 ?>