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