eZ Publish  [trunk]
ezclusterfilehandler.php
Go to the documentation of this file.
00001 <?php
00002 /**
00003  * File containing the eZClusterFileHandler 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 class eZClusterFileHandler
00011 {
00012     /**
00013      * Returns the configured instance of an eZClusterFileHandlerInterface
00014      * See ClusteringSettings.FileHandler in file.ini
00015      *
00016      * @param string|bool $filename
00017      *        Optional filename the handler should be initialized with
00018      *
00019      * @return eZClusterFileHandlerInterface
00020      */
00021     static function instance( $filename = false )
00022     {
00023         if ( self::$isShutdownFunctionRegistered !== true )
00024         {
00025             eZExecution::addCleanupHandler( array( __CLASS__, 'cleanupGeneratingFiles' ) );
00026             self::$isShutdownFunctionRegistered = true;
00027         }
00028 
00029         if( $filename !== false )
00030         {
00031             $optionArray = array( 'iniFile'      => 'file.ini',
00032                                   'iniSection'   => 'ClusteringSettings',
00033                                   'iniVariable'  => 'FileHandler',
00034                                   'handlerParams'=> array( $filename ) );
00035 
00036             $options = new ezpExtensionOptions( $optionArray );
00037 
00038             $handler = eZExtension::getHandlerClass( $options );
00039 
00040             return $handler;
00041         }
00042         else
00043         {
00044             // return Filehandler from GLOBALS based on ini setting.
00045             if ( self::$globalHandler === null )
00046             {
00047                 $optionArray = array( 'iniFile'      => 'file.ini',
00048                                       'iniSection'   => 'ClusteringSettings',
00049                                       'iniVariable'  => 'FileHandler' );
00050 
00051                 $options = new ezpExtensionOptions( $optionArray );
00052 
00053                 $handler = eZExtension::getHandlerClass( $options );
00054 
00055                 self::$globalHandler = $handler;
00056             }
00057             else
00058                 $handler = self::$globalHandler;
00059 
00060             return $handler;
00061         }
00062     }
00063 
00064     /**
00065       * Resets the handler so that a new one can be loaded
00066       */
00067     public static function resetHandler()
00068     {
00069         self::cleanupGeneratingFiles();
00070         self::$globalHandler = null;
00071     }
00072 
00073     /**
00074      * @deprecated 4.3 No longer used as we rely on ezpExtension & autoloads
00075      * @return array list of directories used to search cluster file handlers for
00076      */
00077     static function searchPathArray()
00078     {
00079         if ( !isset( $GLOBALS['eZClusterFileHandler_search_path_array'] ) )
00080         {
00081             $fileINI = eZINI::instance( 'file.ini' );
00082             $searchPathArray = array( 'kernel/classes/clusterfilehandlers',
00083                                       'kernel/private/classes/clusterfilehandlers' );
00084             if ( $fileINI->hasVariable( 'ClusteringSettings', 'ExtensionDirectories' ) )
00085             {
00086                 $extensionDirectories = $fileINI->variable( 'ClusteringSettings', 'ExtensionDirectories' );
00087                 $baseDirectory = eZExtension::baseDirectory();
00088                 foreach ( $extensionDirectories as $extensionDirectory )
00089                 {
00090                     $customSearchPath = $baseDirectory . '/' . $extensionDirectory . '/clusterfilehandlers';
00091                     if ( file_exists( $customSearchPath ) )
00092                         $searchPathArray[] = $customSearchPath;
00093                 }
00094             }
00095 
00096             $GLOBALS['eZClusterFileHandler_search_path_array'] = $searchPathArray;
00097         }
00098 
00099         return $GLOBALS['eZClusterFileHandler_search_path_array'];
00100     }
00101 
00102     /**
00103      * Cluster shutdown handler. Terminates generation for unterminated files.
00104      * This situation doesn't happen by default, but may with custom code that doesn't follow recommendations.
00105      */
00106     static function cleanupGeneratingFiles()
00107     {
00108         if ( count( self::$generatingFiles ) === 0 )
00109         {
00110             return false;
00111         }
00112         else
00113         {
00114             eZDebug::writeWarning( "Execution was stopped while one or more files were generating. This should not happen.", __METHOD__ );
00115             foreach( self::$generatingFiles as $generatingFile )
00116             {
00117                 $generatingFile->abortCacheGeneration();
00118                 self::removeGeneratingFile( $generatingFile );
00119             }
00120             return true;
00121         }
00122     }
00123 
00124     /**
00125      * Goes trough the directory path and removes empty directories, starting at
00126      * the leaf and deleting down until a non empty directory is reached.
00127      * If the path is not a directory, nothing will happen.
00128      *
00129      * @param string $path
00130      */
00131     public static function cleanupEmptyDirectories( $path )
00132     {
00133         $dirpath = eZDir::dirpath( $path );
00134 
00135         eZDebugSetting::writeDebug( 'kernel-clustering', "eZClusterFileHandler::cleanupEmptyDirectories( '{$dirpath}' )" );
00136 
00137         if ( is_dir( $dirpath ) )
00138         {
00139             eZDir::cleanupEmptyDirectories( $dirpath );
00140         }
00141     }
00142 
00143     /**
00144      * Adds a file to the generating list
00145      *
00146      * @param eZDFSFileHandler|eZDFSFileHandler $file
00147      *        Cluster file handler instance
00148      *        Note that this method expect a version of the handler where the filePath is the REAL one, not the .generating
00149      */
00150     public static function addGeneratingFile( $file )
00151     {
00152         if ( !( $file instanceof eZDBFileHandler )
00153                 && !( $file instanceof eZDFSFileHandler )
00154                 && !( $file instanceof eZFS2FileHandler ) )
00155             return false; // @todo Exception
00156 
00157         self::$generatingFiles[$file->filePath] = $file;
00158     }
00159 
00160     /**
00161      * Removes a file from the generating list
00162      * @param eZDBFileHandler|eZDFSFileHandler $file
00163      *        Cluster file handler instance
00164      *        Note that this method expect a version of the handler where the filePath is the REAL one, not the .generating
00165      *
00166      * @todo Clustering: apply the eZClusterFileHandlerInterface to all cluster handlers
00167      */
00168     public static function removeGeneratingFile( $file )
00169     {
00170         if ( !( $file instanceof eZDBFileHandler )
00171                 && !( $file instanceof eZDFSFileHandler )
00172                 && !( $file instanceof eZFS2FileHandler ) )
00173             return false; // @todo Exception
00174 
00175         if ( isset( self::$generatingFiles[$file->filePath] ) )
00176             unset( self::$generatingFiles[$file->filePath] );
00177     }
00178 
00179     /**
00180      * Performs required operations before forking a process
00181      *
00182      * - disconnects DB based cluster handlers from the database
00183      */
00184     public static function preFork()
00185     {
00186         $clusterHandler = self::instance();
00187 
00188         // disconnect DB based cluster handlers from the database
00189         if ( $clusterHandler instanceof ezpDatabaseBasedClusterFileHandler )
00190         {
00191             $clusterHandler->disconnect();
00192 
00193             // destroy the current handler so that it reconnects when instanciated again
00194             self::$globalHandler = null;
00195         }
00196     }
00197 
00198     /**
00199      * Global list of currently generating files. Used by handlers that support stalecache.
00200      * @var array(filename => eZClusterFileHandlerInterface)
00201      */
00202     private static $generatingFiles = array();
00203 
00204     /**
00205      * Shutdown registration check variable
00206      * @var bool
00207      */
00208     private static $isShutdownFunctionRegistered = false;
00209 
00210     /**
00211      * Global, generic (e.g. not linked to a file) cluster handler, used for caching
00212      * @var eZClusterFileHandlerInterface
00213      */
00214     public static $globalHandler;
00215 }
00216 
00217 ?>