eZ Publish  [4.0]
ezscript.php
Go to the documentation of this file.
00001 <?php
00002 //
00003 // Definition of eZScript class
00004 //
00005 // Created on: <06-Aug-2003 11:06:35 amos>
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 ezscript.php
00032 */
00033 
00034 /*!
00035   \class eZScript ezscript.php
00036   \brief Handles the basics of script execution
00037 
00038   By using this class for script execution startup, initializing
00039   and shutdown the amount code required to write a new script is
00040   reduced significantly.
00041 
00042   It is also recommended to use the eZCLI class in addition to this
00043   class.
00044 
00045   What this class will handle is:
00046   - Startup of database
00047   - Startup/shutdown of session
00048   - Debug initialize and display
00049   - Text codec initialize
00050 
00051   This class consists of the static functions startup(), initialize()
00052   and shutdown().
00053 
00054   A typical usage:
00055 \code
00056 $script = eZScript::instance();
00057 
00058 $script->startup();
00059 
00060 // Read arguments and modify script accordingly
00061 
00062 $script->initialize();
00063 
00064 // Do the actual script here
00065 
00066 $script->shutdown(); // Finish execution
00067 
00068 \endcode
00069 
00070 */
00071 
00072 //include_once( 'lib/ezutils/classes/ezcli.php' );
00073 //include_once( 'lib/ezdb/classes/ezdb.php' );
00074 require_once( 'access.php' );
00075 
00076 class eZScript
00077 {
00078     /*!
00079      Constructor
00080     */
00081     function eZScript( $settings = array() )
00082     {
00083         $settings = array_merge( array( 'debug-message' => false,
00084                                         'debug-output' => false,
00085                                         'debug-include' => false,
00086                                         'debug-levels' => false,
00087                                         'debug-accumulator' => false,
00088                                         'debug-timing' => false,
00089                                         'use-session' => false,
00090                                         'use-extensions' => false,
00091                                         'use-modules' => false,
00092                                         'user' => false,
00093                                         'description' => 'eZ Publish script',
00094                                         'site-access' => false,
00095                                         'min_version' => false,
00096                                         'max_version' => false ),
00097                                  $settings );
00098         $this->DebugMessage = $settings['debug-message'];
00099         $this->UseDebugOutput = $settings['debug-output'];
00100         $this->AllowedDebugLevels = $settings['debug-levels'];
00101         $this->UseDebugAccumulators = $settings['debug-accumulator'];
00102         $this->UseDebugTimingPoints = $settings['debug-timing'];
00103         $this->UseIncludeFiles = $settings['debug-include'];
00104         $this->UseSession = $settings['use-session'];
00105         $this->UseModules = $settings['use-modules'];
00106         $this->UseExtensions = $settings['use-extensions'];
00107         $this->User = $settings['user'];
00108         $this->SiteAccess = $settings['site-access'];
00109         $this->Description = $settings['description'];
00110         $this->MinVersion = $settings['min_version'];
00111         $this->MaxVersion = $settings['max_version'];
00112         $this->ExitCode = false;
00113         $this->IsQuiet = false;
00114         $this->ShowVerbose = false;
00115         $this->IsInitialized = false;
00116         $this->CurrentOptions = false;
00117         $this->CurrentOptionConfig = false;
00118         $this->CurrentStandardOptions = false;
00119         $this->CurrentExcludeOptions = false;
00120         $this->CurrentOptionHelp = false;
00121 
00122         $this->IterationTrueString = '.';
00123         $this->IterationFalseString = '~';
00124         $this->IterationNumericStrings = false;
00125         $this->IterationWrapNumeric = false;
00126         $this->IterationIndex = 0;
00127         $this->IterationColumn = 0;
00128         $this->IterationColumnMax = 70;
00129         $this->IterationMax = false;
00130         $this->InitializationErrorMessage = 'unknown error';
00131     }
00132 
00133     /*!
00134      Checks if the script is run on correct eZ Publish version.
00135     */
00136     function validateVersion()
00137     {
00138         //include_once( 'lib/version.php' );
00139         $versionValidated = false;
00140         $ezversion = eZPublishSDK::version();
00141         if ( $this->MinVersion !== false )
00142         {
00143             if ( $this->MaxVersion !== false )
00144             {
00145                 if ( version_compare( $this->MinVersion, $ezversion , 'le' ) &&
00146                      version_compare( $this->MaxVersion, $ezversion , 'ge' ) )
00147                 {
00148                     return true;
00149                 }
00150                 return false;
00151             }
00152             if ( version_compare( $this->MinVersion, $ezversion , 'le' ) )
00153             {
00154                 return true;
00155             }
00156             return false;
00157         }
00158         else
00159         {
00160             if ( version_compare( $this->MaxVersion, $ezversion , 'ge' ) )
00161             {
00162                 return true;
00163             }
00164             return false;
00165         }
00166     }
00167 
00168     /*!
00169      Checks if the script is run in CLI mode, if not it exits with a warning.
00170      The PHP local is also initialized if it is used.
00171 
00172      Call this at the very start of your script and always before getOptions() and initialize().
00173     */
00174     function startup()
00175     {
00176         error_reporting( E_ALL );
00177 
00178         eZDebug::setHandleType( eZDebug::HANDLE_TO_PHP );
00179 
00180         if ( php_sapi_name() != 'cli' )
00181         {
00182             $cli = eZCLI::instance();
00183             $cli->output( "PHP is currently using the '" . php_sapi_name() . "' interface. Make sure it is using the 'cli' interface." );
00184             exit( 1 );
00185         }
00186 
00187         //include_once( "lib/ezutils/classes/ezini.php" );
00188         $ini = eZINI::instance();
00189         $phpLocale = trim( $ini->variable( 'RegionalSettings', 'SystemLocale' ) );
00190         if ( $phpLocale != '' )
00191         {
00192             setlocale( LC_ALL, explode( ',', $phpLocale ) );
00193         }
00194 
00195         // Set correct site timezone
00196         $timezone = $ini->variable( "TimeZoneSettings", "TimeZone" );
00197         if ( $timezone )
00198         {
00199             putenv( "TZ=$timezone" );
00200         }
00201     }
00202 
00203     /*!
00204      Initializes all settings which are required for the script to run,
00205      must be called after startup() and getOptions().
00206 
00207      If you modify the eZScript object using the set* functions you must make sure that
00208      is done before this function is called.
00209     */
00210     function initialize()
00211     {
00212         if( ob_get_length() != 0 )
00213             ob_end_clean();
00214         //include_once( "lib/ezutils/classes/ezdebugsetting.php" );
00215 
00216         $debugINI = eZINI::instance( 'debug.ini' );
00217         eZDebugSetting::setDebugINI( $debugINI );
00218 
00219         // Initialize text codec settings
00220         $this->updateTextCodecSettings();
00221 
00222         // Initialize debug settings
00223         $this->updateDebugSettings( $this->UseDebugOutput );
00224 
00225         // Set the different permissions/settings.
00226         //include_once( 'lib/ezi18n/classes/ezcodepage.php' );
00227         $ini = eZINI::instance();
00228         $iniFilePermission = $ini->variable( 'FileSettings', 'StorageFilePermissions' );
00229         $iniDirPermission = $ini->variable( 'FileSettings', 'StorageDirPermissions' );
00230         $iniVarDirectory = eZSys::cacheDirectory() ;
00231 
00232         eZCodePage::setPermissionSetting( array( 'file_permission' => octdec( $iniFilePermission ),
00233                                                  'dir_permission'  => octdec( $iniDirPermission ),
00234                                                  'var_directory'   => $iniVarDirectory ) );
00235 
00236         require_once( 'lib/ezutils/classes/ezexecution.php' );
00237 
00238         eZExecution::addCleanupHandler( 'eZDBCleanup' );
00239         eZExecution::addFatalErrorHandler( 'eZFatalError' );
00240 
00241         eZDebug::setHandleType( eZDebug::HANDLE_FROM_PHP );
00242 
00243         if ( $this->UseExtensions )
00244         {
00245             // Check for extension
00246             //include_once( 'lib/ezutils/classes/ezextension.php' );
00247             require_once( 'kernel/common/ezincludefunctions.php' );
00248             eZExtension::activateExtensions( 'default' );
00249             // Extension check end
00250         }
00251 
00252         require_once( "access.php" );
00253         $siteaccess = $this->SiteAccess;
00254         if ( $siteaccess )
00255         {
00256             $access = array( 'name' => $siteaccess,
00257                              'type' => EZ_ACCESS_TYPE_STATIC );
00258         }
00259         else
00260         {
00261             $ini = eZINI::instance();
00262             $siteaccess = $ini->variable( 'SiteSettings', 'DefaultAccess' );
00263             $access = array( 'name' => $siteaccess,
00264                              'type' => EZ_ACCESS_TYPE_DEFAULT );
00265         }
00266 
00267         $access = changeAccess( $access );
00268         require_once( 'kernel/common/i18n.php' );
00269 
00270         if ( $this->UseExtensions )
00271         {
00272             // Check for siteaccess extension
00273             eZExtension::activateExtensions( 'access' );
00274             // Extension check end
00275         }
00276 
00277         // Set the global setting which is read by the session lib
00278         $GLOBALS['eZSiteBasics']['session-required'] = $this->UseSession;
00279 
00280         if ( $this->UseSession )
00281         {
00282             // include ezsession override implementation
00283             require_once( "lib/ezutils/classes/ezsession.php" );
00284             //include_once( 'lib/ezdb/classes/ezdb.php' );
00285             $db = eZDB::instance();
00286             if ( $db->isConnected() )
00287             {
00288                 eZSessionStart();
00289             }
00290             else
00291             {
00292                 $this->IsInitialized = false;
00293                 $this->InitializationErrorMessage = 'database error: ' . $db->errorMessage();
00294                 return;
00295             }
00296         }
00297 
00298         if ( $this->User )
00299         {
00300             $userLogin = $this->User['login'];
00301             $userPassword = $this->User['password'];
00302             //include_once( 'kernel/classes/datatypes/ezuser/ezuser.php' );
00303 
00304             if ( $userLogin and $userPassword )
00305             {
00306                 $userID = eZUser::loginUser( $userLogin, $userPassword );
00307                 if ( !$userID )
00308                 {
00309                     $cli = eZCLI::instance();
00310                     if ( $this->isLoud() )
00311                         $cli->warning( 'Failed to login with user ' . $userLogin );
00312                     require_once( 'lib/ezutils/classes/ezexecution.php' );
00313                     eZExecution::cleanup();
00314                     eZExecution::setCleanExit();
00315                 }
00316             }
00317         }
00318 
00319         // Initialize module handling
00320         if ( $this->UseModules )
00321         {
00322             //include_once( 'lib/ezutils/classes/ezmodule.php' );
00323             $moduleRepositories = eZModule::activeModuleRepositories( $this->UseExtensions );
00324             eZModule::setGlobalPathList( $moduleRepositories );
00325         }
00326         $this->IsInitialized = true;
00327     }
00328 
00329     function isInitialized()
00330     {
00331         return $this->IsInitialized;
00332     }
00333 
00334     function initializationError()
00335     {
00336         return $this->InitializationErrorMessage;
00337     }
00338 
00339     /*!
00340      Shuts down the currently running script, the following things will be done:
00341      - Remove current session (if sessions are used)
00342      - Print debug messages (if debug is enabled)
00343      - Call cleanup function using eZExecution
00344      - Sets the clean exit flag, that way an exit, die or other stops will not issue an error
00345 
00346      If an exit code is set, PHP will exit with that code set (this means that this function never returns),
00347      otherwise this function returns normally.
00348     */
00349     function shutdown( $exitCode = false, $exitText = false )
00350     {
00351         $cli = eZCLI::instance();
00352         if ( class_exists( 'eZDB' )
00353              and eZDB::hasInstance() )
00354         {
00355             $db = eZDB::instance( false, array( 'show_errors' => false ) );
00356             // Perform transaction check
00357             $transactionCounterCheck = eZDB::checkTransactionCounter();
00358             if ( isset( $transactionCounterCheck['error'] ) )
00359                 $cli->error( $transactionCounterCheck['error'] );
00360 
00361             if ( $this->UseSession and
00362                  $db->isConnected() )
00363             {
00364                 //include_once( 'kernel/classes/datatypes/ezuser/ezuser.php' );
00365                 eZUser::logoutCurrent();
00366                 eZSessionRemove();
00367             }
00368         }
00369 
00370         $webOutput = $cli->isWebOutput();
00371 
00372         if ( $this->UseDebugOutput or
00373              eZDebug::isDebugEnabled() )
00374         {
00375             if ( $this->DebugMessage )
00376                 fputs( STDERR, $this->DebugMessage );
00377             fputs( STDERR, eZDebug::printReport( false, $webOutput, true,
00378                                                  $this->AllowedDebugLevels, $this->UseDebugAccumulators,
00379                                                  $this->UseDebugTimingPoints, $this->UseIncludeFiles ) );
00380         }
00381 
00382         require_once( 'lib/ezutils/classes/ezexecution.php' );
00383         eZExecution::cleanup();
00384         eZExecution::setCleanExit();
00385         $this->IsInitialized = false;
00386         if ( $exitCode !== false )
00387             $this->ExitCode = $exitCode;
00388         if ( $this->ExitCode !== false )
00389         {
00390             if ( $exitText !== false )
00391                 $cli->output( $exitText );
00392             exit( $this->ExitCode );
00393         }
00394     }
00395 
00396     /*!
00397      Sets the text message which is shown before the debug list.
00398      There will be a default message which should suit most scripts.
00399      \note This requires that setUseDebugOutput is set to true or that
00400            the user has enabled debug in the arguments.
00401     */
00402     function setDebugMessage( $message )
00403     {
00404         $this->DebugMessage = $message;
00405     }
00406 
00407     /*!
00408      Sets whether debug output should be enabled or not.
00409      \note This can also be called by the argument parser if the user specifies to show debug.
00410     */
00411     function setUseDebugOutput( $useDebug )
00412     {
00413         $this->UseDebugOutput = $useDebug;
00414     }
00415 
00416     /*!
00417      Sets whether accumulators should be shown on debug output or not.
00418      \note This requires that setUseDebugOutput is set to true or that
00419            the user has enabled debug in the arguments.
00420     */
00421     function setUseDebugAccumulators( $useAccumulators )
00422     {
00423         $this->UseDebugAccumulators = $useAccumulators;
00424     }
00425 
00426     /*!
00427      Sets whether timing points should be shown on debug output or not.
00428      \note This requires that setUseDebugOutput is set to true or that
00429            the user has enabled debug in the arguments.
00430     */
00431     function setUseDebugTimingPoints( $useTimingPoints )
00432     {
00433         $this->UseDebugTimingPoints = $useTimingPoints;
00434     }
00435 
00436     /*!
00437      Sets whether include files should be shown on debug output or not.
00438      \note This requires that setUseDebugOutput is set to true or that
00439            the user has enabled debug in the arguments.
00440     */
00441     function setUseIncludeFiles( $useIncludeFiles )
00442     {
00443         $this->UseIncludeFiles = $useIncludeFiles;
00444     }
00445 
00446     /*!
00447      Sets which debug levels are to be shown on debug output, this must be an array
00448      with EZ_LEVEL_* definitions taken from eZDebug.
00449      \note This requires that setUseDebugOutput is set to true or that
00450            the user has enabled debug in the arguments.
00451     */
00452     function setAllowedDebugLevels( $allowedDebugLevels )
00453     {
00454         $this->AllowedDebugLevels = $allowedDebugLevels;
00455     }
00456 
00457     /*!
00458      Sets whether session is to be used or not.
00459      \note This will only work if it is set before initialized() is called.
00460      \note If session is enabled the current session data will be removed on shutdown().
00461     */
00462     function setUseSession( $useSession )
00463     {
00464         $this->UseSession = $useSession;
00465     }
00466 
00467     /*!
00468      Sets whether extension support is to be added or not.
00469      \note This will only work if it is set before initialized() is called.
00470     */
00471     function setUseExtensions( $useExtensions )
00472     {
00473         $this->UseExtensions = $useExtensions;
00474     }
00475 
00476     /*!
00477      Sets the current site access to \a $siteAccess.
00478      \note This will only work if it is set before initialized() is called.
00479      \note This will be filled in if getOptions() is used and the user specifices it in the arguments.
00480     */
00481     function setUseSiteAccess( $siteAccess )
00482     {
00483         $this->SiteAccess = $siteAccess;
00484     }
00485 
00486     /*!
00487      \return the currently set siteaccess or \c false if none is set.
00488     */
00489     function usedSiteAccess()
00490     {
00491         return $this->SiteAccess;
00492     }
00493 
00494     function setUseModules( $useModules )
00495     {
00496         $this->UseModules = $useModules;
00497     }
00498 
00499     function setUser( $userLogin, $userPassword )
00500     {
00501         $this->User = array( 'login' => $userLogin,
00502                              'password' => $userPassword );
00503     }
00504 
00505     /*!
00506      Controls whether verbose output is used or not, use \c false to turn it off,
00507      \c true to turn it on or a number to select the verbose level (\c true == 1).
00508      The actual behaviour of verbose output depends on the script, however enabling
00509      it will make sure iteration looping displays the iteration name instead of a dot.
00510     */
00511     function setShowVerboseOutput( $verbose )
00512     {
00513         if ( $verbose === true )
00514             $verbose = 1;
00515         $this->ShowVerbose = $verbose;
00516     }
00517 
00518     /*!
00519      \return the verbosity level for the script, will be \c false or a number in the range 1 and up.
00520     */
00521     function verboseOutputLevel()
00522     {
00523         return $this->ShowVerbose;
00524     }
00525 
00526     /*!
00527      \return the currently set options if getOptions() has been run or \c false if no options are set.
00528     */
00529     function currentOptions()
00530     {
00531         return $this->CurrentOptions;
00532     }
00533 
00534     /*!
00535      \return the current option configuration, this will be a mix of the standard options and script specified.
00536     */
00537     function currentOptionConfig()
00538     {
00539         return $this->CurrentOptionConfig;
00540     }
00541 
00542     /*!
00543      Sets the current exit code which will be set with an exit() call in shutdown().
00544      If you don't want shutdown() to exit automatically set it to \c false.
00545     */
00546     function setExitCode( $code = false )
00547     {
00548         $this->ExitCode = $code;
00549     }
00550 
00551     function exitCode()
00552     {
00553         return $this->ExitCode;
00554     }
00555 
00556     /*!
00557      Sets whether any output should be used or not.
00558      \sa isQuiet, isLoud
00559      \note it will also call eZCLI::setIsQuiet()
00560     */
00561     function setIsQuiet( $isQuiet )
00562     {
00563         $cli = eZCLI::instance();
00564         $this->IsQuiet = $isQuiet;
00565         $cli->setIsQuiet( $isQuiet );
00566     }
00567 
00568     /*!
00569      \return \c true if output is not allowed.
00570      \sa isLoud
00571     */
00572     function isQuiet()
00573     {
00574         return $this->IsQuiet;
00575     }
00576 
00577     /*!
00578      \return \c true if output is allowed.
00579      \sa isQuiet
00580     */
00581     function isLoud()
00582     {
00583         return !$this->IsQuiet;
00584     }
00585 
00586     function setIterationData( $trueString, $falseString,
00587                                $numericStrings = false, $wrapNumeric = false )
00588     {
00589         $this->IterationTrueString = $trueString;
00590         $this->IterationFalseString = $falseString;
00591         $this->IterationNumericStrings = $numericStrings;
00592         $this->IterationWrapNumeric = $wrapNumeric;
00593     }
00594 
00595     function resetIteration( $iterationMax = false, $startIndex = 0 )
00596     {
00597         $this->IterationIndex = $startIndex;
00598         $this->IterationColumn = 0;
00599         $this->IterationMax = $iterationMax;
00600     }
00601 
00602     function iterate( $cli, $status, $text = false )
00603     {
00604         if ( !$this->IterationNumericStrings )
00605             $status = (bool)$status;
00606         if ( $this->verboseOutputLevel() === false or
00607              $text === false )
00608         {
00609             if ( is_bool( $status ) )
00610             {
00611                 $statusText = $status ? $this->IterationTrueString : $this->IterationFalseString;
00612             }
00613             else
00614             {
00615                 if ( $this->IterationWrapNumeric )
00616                     $status = $status % count( $this->IterationNumericStrings );
00617                 if ( $status < count( $this->IterationNumericStrings ) )
00618                     $statusText = $this->IterationNumericStrings[$status];
00619                 else
00620                     $statusText = ' ';
00621             }
00622             $endLine = false;
00623             $changeLine = false;
00624             ++$this->IterationIndex;
00625             ++$this->IterationColumn;
00626             $iterationColumn = $this->IterationColumn;
00627             if ( $this->IterationColumn >= $this->IterationColumnMax )
00628             {
00629                 $this->IterationColumn = 0;
00630                 $changeLine = true;
00631             }
00632             if ( $this->IterationMax !== false )
00633             {
00634                 if ( $this->IterationIndex >= $this->IterationMax )
00635                 {
00636                     $this->IterationColumn = 0;
00637                     $changeLine = true;
00638                 }
00639             }
00640             if ( $changeLine )
00641             {
00642                 if ( $this->IterationMax !== false )
00643                 {
00644                     $spacing = $this->IterationColumnMax - $iterationColumn;
00645                     $percent = ( $this->IterationIndex * 100 ) / $this->IterationMax;
00646                     if ( $percent > 100.0 )
00647                         $percent = 100;
00648                     else
00649                         $spacing += 1;
00650                     $percentText = number_format( $percent, 2 ) . '%';
00651                     $statusText .= str_repeat( ' ', $spacing );
00652                     $statusText .= $percentText;
00653                 }
00654                 $endLine = true;
00655             }
00656             $cli->output( $statusText, $endLine );
00657         }
00658         else
00659         {
00660             $statusLevel = $status;
00661             if ( is_bool( $status ) )
00662                 $statusLevel = $status ? 0 : 1;
00663             if ( $statusLevel > 0 )
00664             {
00665                 --$statusLevel;
00666                 $statusLevels = array( 'warning', 'failure' );
00667                 if ( $statusLevel > count( $statusLevels ) )
00668                     $statusLevel = count( $statusLevels ) - 1;
00669                 $levelText = $statusLevels[$statusLevel];
00670                 $cli->output( $cli->stylize( $levelText, $text ) );
00671             }
00672             else
00673             {
00674                 $cli->output( $text );
00675             }
00676         }
00677     }
00678 
00679     function showHelp( $useStandardOptions = false, $optionConfig = false, $optionHelp = false, $argumentConfig = false, $arguments = false )
00680     {
00681         if ( $useStandardOptions === false )
00682         {
00683             $useStandardOptions = $this->CurrentStandardOptions;
00684         }
00685         if ( $optionConfig === false )
00686         {
00687             $optionConfig = $this->CurrentOptionConfig;
00688         }
00689         if ( $optionHelp === false )
00690         {
00691             $optionHelp = $this->CurrentOptionHelp;
00692         }
00693         if ( $argumentConfig === false )
00694         {
00695             $argumentConfig = $this->ArgumentConfig;
00696         }
00697         $optionList = array();
00698         foreach ( $optionConfig['list'] as $configItem )
00699         {
00700             if ( in_array( $configItem['name'], $this->CurrentExcludeOptions ) )
00701                 continue;
00702             $optionText = '-';
00703             if ( $configItem['is-long-option'] )
00704                 $optionText .= '-';
00705             $optionText .= $configItem['name'];
00706             if ( $configItem['has-value'] and $configItem['is-long-option'] )
00707                 $optionText .= "=VALUE";
00708             $hasMultipleValues = ( $configItem['quantifier']['min'] > 1 or
00709                                    $configItem['quantifier']['max'] === false or
00710                                    $configItem['quantifier']['max'] > 1 );
00711             if ( $hasMultipleValues )
00712                 $optionText .= "...";
00713             $optionDescription = '';
00714             if ( isset( $optionHelp[$configItem['name']] ) )
00715                 $optionDescription = $optionHelp[$configItem['name']];
00716             $optionList[] = array( $optionText, $optionDescription );
00717         }
00718         if ( $arguments === false )
00719         {
00720             $arguments = $_SERVER['argv'];
00721             $program = $arguments[0];
00722         }
00723         $cli = eZCLI::instance();
00724         $generalOptionList = array();
00725         $generalOptionList = array();
00726         if ( $useStandardOptions )
00727         {
00728             $generalOptionList[] = array( '-h,--help', 'display this help and exit');
00729             $generalOptionList[] = array( '-q,--quiet', 'do not give any output except when errors occur' );
00730             if ( $useStandardOptions['siteaccess'] )
00731                 $generalOptionList[] = array( '-s,--siteaccess', "selected siteaccess for operations,\nif not specified default siteaccess is used" );
00732             if ( $useStandardOptions['debug'] )
00733                 $generalOptionList[] = array( '-d,--debug...', ( "display debug output at end of execution,\n" .
00734                                                                  "the following debug items can be controlled: \n" .
00735                                                                  "all, accumulator, include, timing, error, warning, debug, notice or strict." ) );
00736             if ( $useStandardOptions['colors'] )
00737             {
00738                 $generalOptionList[] = array( '-c,--colors', 'display output using ANSI colors (default)' );
00739                 $generalOptionList[] = array( '--no-colors', 'do not use ANSI coloring' );
00740             }
00741             if ( $useStandardOptions['user'] )
00742             {
00743                 $generalOptionList[] = array( '-l,--login USER', 'login with USER and use it for all operations' );
00744                 $generalOptionList[] = array( '-p,--password PWD', 'use PWD as password for USER' );
00745             }
00746             if ( $useStandardOptions['log'] )
00747             {
00748                 $generalOptionList[] = array( '--logfiles', 'create log files' );
00749                 $generalOptionList[] = array( '--no-logfiles', 'do not create log files (default)' );
00750             }
00751             if ( $useStandardOptions['verbose'] )
00752             {
00753                 $generalOptionList[] = array( '-v,--verbose...', "display more information, \nused multiple times will increase amount of information" );
00754             }
00755         }
00756         $description = $this->Description;
00757         $helpText =  "Usage: " . $program;
00758         if ( count( $optionList ) > 0 or count( $generalOptionList ) > 0 )
00759         {
00760             $helpText .= " [OPTION]...";
00761         }
00762         if ( $argumentConfig && isset( $argumentConfig['list'] ) && is_array( $argumentConfig['list'] ) )
00763         {
00764             foreach ( $argumentConfig['list'] as $argumentItem )
00765             {
00766                 $argumentName = strtoupper( $argumentItem['name'] );
00767                 $quantifier = $argumentItem['quantifier'];
00768                 if ( $quantifier['min'] > 1 or $quantifier['max'] === false or $quantifier['max'] > 1 )
00769                     $helpText .= " [$argumentName]...";
00770                 else
00771                     $helpText .= " [$argumentName]";
00772             }
00773         }
00774         if ( $description )
00775             $helpText .= "\n" . $description . "\n";
00776         if ( count( $generalOptionList ) > 0 )
00777         {
00778             $helpText .= "\nGeneral options:\n";
00779             $maxLength = 0;
00780             foreach ( $generalOptionList as $optionItem )
00781             {
00782                 $maxLength = max( strlen( $optionItem[0] ), $maxLength );
00783             }
00784             $spacingLength = $maxLength + 2;
00785             foreach ( $generalOptionList as $optionItem )
00786             {
00787                 $option = $optionItem[0];
00788                 $optionDescription = $optionItem[1];
00789                 $optionLines = explode( "\n", $option );
00790                 $optionDescriptionLines = explode( "\n", $optionDescription );
00791                 $count = max( count( $optionLines ), count( $optionDescriptionLines ) );
00792                 for ( $i = 0; $i < $count; ++$i )
00793                 {
00794                     $optionText = '';
00795                     if ( isset( $optionLines[$i] ) )
00796                         $optionText = $optionLines[$i];
00797                     $optionDescriptionText = '';
00798                     if ( isset( $optionDescriptionLines[$i] ) )
00799                         $optionDescriptionText = $optionDescriptionLines[$i];
00800                     $spacing = $spacingLength - strlen( $optionText );
00801                     if ( $optionText or $optionDescriptionText )
00802                         $helpText .= '  ';
00803                     $helpText .= $optionText;
00804                     if ( $i > 0 )
00805                         $spacing += 2;
00806                     if ( $optionDescriptionText )
00807                         $helpText .= str_repeat( ' ', $spacing ) . $optionDescriptionText;
00808                     $helpText .= "\n";
00809                 }
00810             }
00811         }
00812         if ( count( $optionList ) > 0 )
00813         {
00814             $helpText .= "\nOptions:\n";
00815             $maxLength = 0;
00816             foreach ( $optionList as $optionItem )
00817             {
00818                 $maxLength = max( strlen( $optionItem[0] ), $maxLength );
00819             }
00820             $spacingLength = $maxLength + 2;
00821             foreach ( $optionList as $optionItem )
00822             {
00823                 $option = $optionItem[0];
00824                 $optionDescription = $optionItem[1];
00825                 $optionLines = explode( "\n", $option );
00826                 $optionDescriptionLines = explode( "\n", $optionDescription );
00827                 $count = max( count( $optionLines ), count( $optionDescriptionLines ) );
00828                 for ( $i = 0; $i < $count; ++$i )
00829                 {
00830                     $optionText = '';
00831                     if ( isset( $optionLines[$i] ) )
00832                         $optionText = $optionLines[$i];
00833                     $optionDescriptionText = '';
00834                     if ( isset( $optionDescriptionLines[$i] ) )
00835                         $optionDescriptionText = $optionDescriptionLines[$i];
00836                     $spacing = $spacingLength - strlen( $optionText );
00837                     if ( $optionText or $optionDescriptionText )
00838                         $helpText .= '  ';
00839                     $helpText .= $optionText;
00840                     if ( $i > 0 )
00841                         $spacing += 2;
00842                     if ( $optionDescriptionText )
00843                         $helpText .= str_repeat( ' ', $spacing ) . $optionDescriptionText;
00844                     $helpText .= "\n";
00845                 }
00846             }
00847         }
00848         $cli->output( $helpText );
00849     }
00850 
00851     function getOptions( $config = '', $argumentConfig = '', $optionHelp = false,
00852                          $arguments = false, $useStandardOptions = true )
00853     {
00854         if ( is_string( $config ) )
00855             $config = eZCLI::parseOptionString( $config, $optionConfig );
00856         if ( is_string( $argumentConfig ) )
00857             $argumentConfig = eZCLI::parseOptionString( $argumentConfig, $tmpArgumentConfig );
00858 
00859         if ( $useStandardOptions )
00860         {
00861             if ( !is_array( $useStandardOptions ) )
00862                 $useStandardOptions = array();
00863             $useStandardOptions = array_merge( array( 'debug' => true,
00864                                                       'colors' => true,
00865                                                       'log' => true,
00866                                                       'siteaccess' => true,
00867                                                       'verbose' => true,
00868                                                       'user' => false ),
00869                                                $useStandardOptions );
00870         }
00871 
00872         if ( $useStandardOptions )
00873         {
00874             $optionConfig = $config;
00875             $excludeOptions = array();
00876             $optionString = "[h|help][q|quiet]";
00877             $excludeOptions[] = 'h';
00878             $excludeOptions[] = 'help';
00879             $excludeOptions[] = 'q';
00880             $excludeOptions[] = 'quiet';
00881             if ( $useStandardOptions['debug'] )
00882             {
00883                 $optionString .= "[d;*|debug;*]";
00884                 $excludeOptions[] = 'd';
00885                 $excludeOptions[] = 'debug';
00886             }
00887             if ( $useStandardOptions['colors'] )
00888             {
00889                 $optionString .= "[c|colors][no-colors]";
00890                 $excludeOptions[] = 'c';
00891                 $excludeOptions[] = 'colors';
00892                 $excludeOptions[] = 'no-colors';
00893             }
00894             if ( $useStandardOptions['log'] )
00895             {
00896                 $optionString .= "[logfiles][no-logfiles]";
00897                 $excludeOptions[] = 'logfiles';
00898                 $excludeOptions[] = 'no-logfiles';
00899             }
00900             if ( $useStandardOptions['siteaccess'] )
00901             {
00902                 $optionString .= "[s:|siteaccess:]";
00903                 $excludeOptions[] = 's';
00904                 $excludeOptions[] = 'siteaccess';
00905             }
00906             if ( $useStandardOptions['user'] )
00907             {
00908                 $optionString .= "[l:|login:][p:|password:]";
00909                 $excludeOptions[] = 'l';
00910                 $excludeOptions[] = 'login';
00911                 $excludeOptions[] = 'p';
00912                 $excludeOptions[] = 'password';
00913             }
00914             if ( $useStandardOptions['verbose'] )
00915             {
00916                 $optionString .= "[v*|verbose*]";
00917                 $excludeOptions[] = 'v';
00918                 $excludeOptions[] = 'verbose';
00919             }
00920             $config = eZCLI::parseOptionString( $optionString, $optionConfig );
00921         }
00922         $cli = eZCLI::instance();
00923         $options = $cli->getOptions( $config, $argumentConfig, $arguments );
00924         $this->CurrentOptionConfig = $config;
00925         $this->CurrentOptions = $options;
00926         $this->CurrentStandardOptions = $useStandardOptions;
00927         $this->CurrentExcludeOptions = $excludeOptions;
00928         $this->CurrentOptionHelp = $optionHelp;
00929         $this->ArgumentConfig = $argumentConfig;
00930         if ( !$options )
00931         {
00932             if ( !$this->IsInitialized )
00933                 $this->initialize();
00934             $this->shutdown( 1 );
00935         }
00936         if ( $useStandardOptions )
00937         {
00938             if ( $options['quiet'] )
00939                 $this->setIsQuiet( true );
00940             $useColors = true;
00941             if ( $options['colors'] )
00942                 $useColors = true;
00943             if ( $options['no-colors'] )
00944                 $useColors = false;
00945             $cli->setUseStyles( $useColors );
00946             if ( $options['debug'] )
00947             {
00948                 $levels = array();
00949                 foreach ( $options['debug'] as $debugOption )
00950                 {
00951                     $levels = array_merge( $levels, explode( ',', $debugOption ) );
00952                 }
00953                 $allowedDebugLevels = array();
00954                 $useDebugAccumulators = false;
00955                 $useDebugTimingpoints = false;
00956                 $useIncludeFiles = false;
00957                 foreach ( $levels as $level )
00958                 {
00959                     if ( $level == 'all' )
00960                     {
00961                         $useDebugAccumulators = true;
00962                         $allowedDebugLevels = false;
00963                         $useDebugTimingpoints = true;
00964                         break;
00965                     }
00966                     if ( $level == 'accumulator' )
00967                     {
00968                         $useDebugAccumulators = true;
00969                         continue;
00970                     }
00971                     if ( $level == 'timing' )
00972                     {
00973                         $useDebugTimingpoints = true;
00974                         continue;
00975                     }
00976                     if ( $level == 'include' )
00977                     {
00978                         $useIncludeFiles = true;
00979                     }
00980                     if ( $level == 'strict' )
00981                         $level = eZDebug::LEVEL_STRICT;
00982                     else if ( $level == 'error' )
00983                         $level = eZDebug::LEVEL_ERROR;
00984                     else if ( $level == 'warning' )
00985                         $level = eZDebug::LEVEL_WARNING;
00986                     else if ( $level == 'debug' )
00987                         $level = eZDebug::LEVEL_DEBUG;
00988                     else if ( $level == 'notice' )
00989                         $level = eZDebug::LEVEL_NOTICE;
00990                     else if ( $level == 'timing' )
00991                         $level = eZDebug::EZ_LEVEL_TIMING;
00992                     $allowedDebugLevels[] = $level;
00993                 }
00994                 $this->setUseDebugOutput( true );
00995                 $this->setAllowedDebugLevels( $allowedDebugLevels );
00996                 $this->setUseDebugAccumulators( $useDebugAccumulators );
00997                 $this->setUseDebugTimingPoints( $useDebugTimingpoints );
00998                 $this->setUseIncludeFiles( $useIncludeFiles );
00999                 $this->setDebugMessage( "\n\n" . str_repeat( '#', 36 ) . $cli->style( 'emphasize' ) . " DEBUG " . $cli->style( 'emphasize-end' )  . str_repeat( '#', 36 ) . "\n" );
01000             }
01001             if ( count( $options['verbose'] ) > 0 )
01002             {
01003                 $this->setShowVerboseOutput( count( $options['verbose'] ) );
01004             }
01005             if ( $options['help'] )
01006             {
01007                 if ( !$this->IsInitialized )
01008                     $this->initialize();
01009                 $this->showHelp();
01010                 $this->shutdown( 0 );
01011             }
01012             if ( isset( $options['siteaccess'] ) and $options['siteaccess'] )
01013                 $this->setUseSiteAccess( $options['siteaccess'] );
01014 
01015             if ( isset( $options['login'] ) and $options['login'] )
01016                 $this->setUser( $options['login'], isset( $options['password'] ) ? $options['password'] : false );
01017         }
01018         return $options;
01019     }
01020 
01021     static function instance( $settings = array() )
01022     {
01023         if ( !isset( $GLOBALS['eZScriptInstance'] ) or
01024              !( $GLOBALS['eZScriptInstance'] instanceof eZScript ) )
01025         {
01026             $GLOBALS['eZScriptInstance'] = new eZScript( $settings );
01027         }
01028         return $GLOBALS['eZScriptInstance'];
01029     }
01030 
01031     /*!
01032      \static
01033      Reads settings from site.ini and passes them to eZDebug.
01034     */
01035     function updateDebugSettings( $useDebug = null )
01036     {
01037         global $debugOutput;
01038         global $useLogFiles;
01039         $ini = eZINI::instance();
01040         $cli = eZCLI::instance();
01041         $debugSettings = array();
01042         $debugSettings['debug-enabled'] = ( $ini->variable( 'DebugSettings', 'DebugOutput' ) == 'enabled' and
01043                                             $ini->variable( 'DebugSettings', 'ScriptDebugOutput' ) == 'enabled' );
01044         if ( $useDebug !== null )
01045             $debugSettings['debug-enabled'] = $useDebug;
01046         $debugSettings['debug-by-ip'] = $ini->variable( 'DebugSettings', 'DebugByIP' ) == 'enabled';
01047         $debugSettings['debug-ip-list'] = $ini->variable( 'DebugSettings', 'DebugIPList' );
01048         if ( isset( $debugOutput ) )
01049             $debugSettings['debug-enabled'] = $debugOutput;
01050         $debugSettings['debug-log-files-enabled'] = $useLogFiles;
01051         if ( $cli->useStyles() and
01052              !$cli->isWebOutput() )
01053         {
01054             $debugSettings['debug-styles'] = $cli->terminalStyles();
01055         }
01056         $logList = $ini->variable( 'DebugSettings', 'AlwaysLog' );
01057         $logMap = array( 'notice' => eZDebug::LEVEL_NOTICE,
01058                          'warning' => eZDebug::LEVEL_WARNING,
01059                          'error' => eZDebug::LEVEL_ERROR,
01060                          'debug' => eZDebug::LEVEL_DEBUG,
01061                          'strict' => eZDebug::LEVEL_STRICT );
01062         $debugSettings['always-log'] = array();
01063         foreach ( $logMap as $name => $level )
01064         {
01065             $debugSettings['always-log'][$level] = in_array( $name, $logList );
01066         }
01067         eZDebug::updateSettings( $debugSettings );
01068     }
01069 
01070     /*!
01071      \static
01072      Reads settings from i18n.ini and passes them to eZTextCodec.
01073     */
01074     function updateTextCodecSettings()
01075     {
01076         $ini = eZINI::instance( 'i18n.ini' );
01077         $i18nSettings = array();
01078         $i18nSettings['internal-charset'] = $ini->variable( 'CharacterSettings', 'Charset' );
01079         $i18nSettings['http-charset'] = $ini->variable( 'CharacterSettings', 'HTTPCharset' );
01080         $i18nSettings['mbstring-extension'] = $ini->variable( 'CharacterSettings', 'MBStringExtension' ) == 'enabled';
01081         //include_once( 'lib/ezi18n/classes/eztextcodec.php' );
01082         eZTextCodec::updateSettings( $i18nSettings );
01083     }
01084 
01085     /// \privatesection
01086     public $InitializationErrorMessage;
01087     public $DebugMessage;
01088     public $UseDebugOutput;
01089     public $UseSession;
01090     public $UseExtensions;
01091     public $UseModules;
01092     public $User;
01093     public $SiteAccess;
01094     public $ExitCode;
01095     public $IsQuiet;
01096     public $ShowVerbose;
01097 }
01098 
01099 function eZDBCleanup()
01100 {
01101     if ( class_exists( 'ezdb' )
01102          and eZDB::hasInstance() )
01103     {
01104         $db = eZDB::instance();
01105         $db->setIsSQLOutputEnabled( false );
01106     }
01107 //     session_write_close();
01108 }
01109 
01110 function eZFatalError()
01111 {
01112     $cli = eZCLI::instance();
01113     $endl = $cli->endlineString();
01114     $webOutput = $cli->isWebOutput();
01115     $bold = $cli->style( 'bold' );
01116     $unbold = $cli->style( 'bold-end' );
01117     $par = $cli->style( 'paragraph' );
01118     $unpar = $cli->style( 'paragraph-end' );
01119 
01120     $allowedDebugLevels = true;
01121     $useDebugAccumulators = true;
01122     $useDebugTimingpoints = true;
01123 
01124     eZDebug::setHandleType( eZDebug::HANDLE_NONE );
01125     if ( !$webOutput )
01126         fputs( STDERR, $endl );
01127     fputs( STDERR, $bold . "Fatal error" . $unbold . ": eZ Publish did not finish its request$endl" );
01128     fputs( STDERR, $par . "The execution of eZ Publish was abruptly ended, the debug output is present below." . $unpar . $endl );
01129     fputs( STDERR, eZDebug::printReport( false, $webOutput, true ) );
01130 }
01131 
01132 /*!
01133   Dummy function, required by some scripts in eZ Publish.
01134 */
01135 function eZUpdateDebugSettings( $useDebug = null )
01136 {
01137 }
01138 
01139 /*!
01140   Dummy function, required by some scripts in eZ Publish.
01141 */
01142 function eZUpdateTextCodecSettings()
01143 {
01144 }
01145 
01146 ?>