PageRenderTime 52ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 0ms

/bin/php/ezcache.php

https://bitbucket.org/crevillo/enetcall
PHP | 344 lines | 310 code | 23 blank | 11 comment | 32 complexity | cb3e681f8b2aad073d7eb62e51b8aade MD5 | raw file
Possible License(s): GPL-2.0, BSD-3-Clause, LGPL-2.1
  1. #!/usr/bin/env php
  2. <?php
  3. /**
  4. * File containing the ezcache.php script.
  5. *
  6. * @copyright Copyright (C) 1999-2012 eZ Systems AS. All rights reserved.
  7. * @license http://www.gnu.org/licenses/gpl-2.0.txt GNU General Public License v2
  8. * @version 2012.4
  9. * @package kernel
  10. */
  11. require 'autoload.php';
  12. $cli = eZCLI::instance();
  13. $script = eZScript::instance( array( 'description' => ( "eZ Publish Cache Handler\n" .
  14. "Allows for easy clearing of Cache files\n" .
  15. "\n" .
  16. "./bin/php/ezcache.php --clear-tag=content" ),
  17. 'use-session' => false,
  18. 'use-modules' => false,
  19. 'use-extensions' => true ) );
  20. $script->startup();
  21. $options = $script->getOptions( "[clear-tag:][clear-id:][clear-all]" . /*[purge-tag:][purge-id:][purge-all]*/ "[iteration-sleep:][iteration-max:][expiry:][list-tags][list-ids][purge]",
  22. "",
  23. array( 'clear-tag' => 'Clears all caches related to a given tag',
  24. 'clear-id' => 'Clears all caches related to a given id, separate multiple ids with a comma',
  25. 'clear-all' => 'Clears all caches',
  26. 'purge' => 'Enforces purging of cache items which ensures that specified entries are physically removed (Useful for saving diskspace). Used together with the clear-* options.',
  27. 'iteration-sleep' => 'Amount of seconds to sleep between each iteration when performing a purge operation, can be a float.',
  28. 'iteration-max' => 'Amount of items to remove in each iteration when performing a purge operation.',
  29. 'expiry' => 'Date or relative time which specifies when cache items are to be considered expired, e.g \'now\', \'-2 days\' or \'last monday\'',
  30. 'list-tags' => 'Lists all available tags',
  31. 'list-ids' => 'Lists all available ids' ) );
  32. $sys = eZSys::instance();
  33. $script->initialize();
  34. $purgeSleep = false;
  35. if ( $options['iteration-sleep'] )
  36. {
  37. $purgeSleep = (int)($options['iteration-sleep']*1000000); // Turn into microseconds
  38. }
  39. $purgeMax = false;
  40. if ( $options['iteration-max'] )
  41. {
  42. $purgeMax = (int)$options['iteration-max'];
  43. }
  44. $purgeExpiry = false;
  45. if ( $options['expiry'] )
  46. {
  47. $expiryText = trim( $options['expiry'] );
  48. $purgeExpiry = strtotime( $expiryText );
  49. if ( $purgeExpiry == -1 || $purgeExpiry === false )
  50. {
  51. $cli->error( "Invalid date supplied to --expiry, '$expiryText'" );
  52. $script->shutdown( 1 );
  53. }
  54. }
  55. $purge = false;
  56. if ( $options['purge'] )
  57. {
  58. if ( !$options['expiry'] ) // If --expiry is not specified, purge everything
  59. $purgeExpiry = time();
  60. $purge = true;
  61. }
  62. $noAction = true;
  63. $cacheList = eZCache::fetchList();
  64. if ( $options['list-tags'] )
  65. {
  66. $noAction = false;
  67. $tagList = eZCache::fetchTagList( $cacheList );
  68. if ( $script->verboseOutputLevel() > 0 )
  69. {
  70. $cli->output( "The following tags are defined:" );
  71. $column = 0;
  72. foreach ( $tagList as $tagName )
  73. {
  74. $len = strlen( $tagName );
  75. if ( $len > $column )
  76. $column = $len;
  77. }
  78. $column += 2;
  79. foreach ( $tagList as $tagName )
  80. {
  81. $cacheEntries = eZCache::fetchByTag( $tagName, $cacheList );
  82. $cli->output( $cli->stylize( 'emphasize', $tagName ) . ':', false );
  83. $i = 0;
  84. foreach ( $cacheEntries as $cacheEntry )
  85. {
  86. if ( $i > 0 )
  87. $cli->output( str_repeat( ' ', $column ), false );
  88. else
  89. $cli->output( str_repeat( ' ', $column - strlen( $tagName ) - 1 ), false );
  90. $cli->output( $cacheEntry['name'] );
  91. ++$i;
  92. }
  93. }
  94. }
  95. else
  96. {
  97. $cli->output( "The following tags are defined: (use --verbose for more details)" );
  98. $cli->output( $cli->stylize( 'emphasize', implode( ', ', $tagList ) ) );
  99. }
  100. $script->shutdown( 0 );
  101. }
  102. if ( $options['list-ids'] )
  103. {
  104. $noAction = false;
  105. if ( $script->verboseOutputLevel() > 0 )
  106. {
  107. $cli->output( "The following ids are defined:" );
  108. $column = 0;
  109. foreach ( $cacheList as $cacheInfo )
  110. {
  111. $len = strlen( $cacheInfo['id'] );
  112. if ( $len > $column )
  113. $column = $len;
  114. }
  115. $column += 2;
  116. foreach ( $cacheList as $cacheInfo )
  117. {
  118. $cli->output( $cli->stylize( 'emphasize', $cacheInfo['id'] ) . ':', false );
  119. $cli->output( str_repeat( ' ', $column - strlen( $cacheInfo['id'] ) - 1 ), false );
  120. $cli->output( $cacheInfo['name'] );
  121. }
  122. }
  123. else
  124. {
  125. $idList = eZCache::fetchIDList( $cacheList );
  126. $cli->output( "The following ids are defined: (use --verbose for more details)" );
  127. $cli->output( $cli->stylize( 'emphasize', implode( ', ', $idList ) ) );
  128. }
  129. $script->shutdown( 0 );
  130. }
  131. function clearItems( $cacheEntries, $cli, $name )
  132. {
  133. if ( !$name )
  134. $name = 'All cache';
  135. $name = $cli->stylize( 'emphasize', $name );
  136. $cli->output( 'Clearing ' . $name . ': ' );
  137. checkPaths( $cacheEntries, false );
  138. $i = 0;
  139. foreach ( $cacheEntries as $cacheEntry )
  140. {
  141. if ( $i > 0 )
  142. $cli->output( ', ', false );
  143. $cli->output( $cli->stylize( 'emphasize', $cacheEntry['name'] ), false );
  144. eZCache::clearItem( $cacheEntry );
  145. ++$i;
  146. }
  147. $cli->output();
  148. }
  149. function purgeItems( $cacheEntries, $cli, $name )
  150. {
  151. global $purgeSleep, $purgeMax, $purgeExpiry;
  152. if ( !$name )
  153. $name = 'All cache';
  154. $name = $cli->stylize( 'emphasize', $name );
  155. $cli->output( 'Purging ' . $name . ': ' );
  156. checkPaths( $cacheEntries, true );
  157. $i = 0;
  158. foreach ( $cacheEntries as $cacheEntry )
  159. {
  160. if ( $i > 0 )
  161. $cli->output( ', ', false );
  162. $cli->output( $cli->stylize( 'emphasize', $cacheEntry['name'] ), false );
  163. eZCache::clearItem( $cacheEntry, true, 'reportProgress', $purgeSleep, $purgeMax, $purgeExpiry );
  164. ++$i;
  165. }
  166. $cli->output();
  167. }
  168. function checkPaths( $cacheEntries, $purge )
  169. {
  170. global $cli, $script;
  171. $warnPaths = array();
  172. foreach ( $cacheEntries as $cacheEntry )
  173. {
  174. $absPath = realpath( eZSys::cacheDirectory() . DIRECTORY_SEPARATOR . $cacheEntry['path'] );
  175. $absPathElementCount = count( explode( DIRECTORY_SEPARATOR, rtrim( $absPath, DIRECTORY_SEPARATOR ) ) );
  176. // Refuse to delete root directory ('/' or 'C:\')
  177. if ( $absPath &&
  178. $absPathElementCount < 2 ) // 2, since one path element ('/foo') produces two exploded elements
  179. {
  180. $cli->error( 'Refusing to delete root directory! Please check your cache settings. Path: ' . $absPath );
  181. $script->shutdown( 1 );
  182. exit();
  183. }
  184. // Warn if the cache entry is not function based, and the path is outside ezp root, and the path has less than 2 elements
  185. if ( $absPath &&
  186. ( !$purge || !isset( $cacheEntry['purge-function'] ) ) &&
  187. !isset( $cacheEntry['function'] ) &&
  188. $absPathElementCount < 3 && /* 3, since two path elements ('/foo/bar') produce three exploded elements */
  189. strpos( dirname( $absPath ) . DIRECTORY_SEPARATOR, realpath( eZSys::rootDir() ) . DIRECTORY_SEPARATOR ) === false )
  190. {
  191. $warnPaths[] = $absPath;
  192. }
  193. }
  194. if ( count( $warnPaths ) > 0 )
  195. {
  196. $cli->warning( 'The following cache paths are outside of the eZ Publish root directory, and have less than 2 path elements. ' .
  197. 'Are you sure you want to ' . ( $purge ? 'purge' : 'clear' ) . ' them?' );
  198. foreach ( $warnPaths as $warnPath )
  199. {
  200. $cli->output( $warnPath );
  201. }
  202. $input = getUserInput( ( $purge ? 'Purge' : 'Clear' ) . '? yes/no:', array( 'yes', 'no' ) );
  203. if ( $input == 'no' )
  204. {
  205. $script->shutdown();
  206. exit();
  207. }
  208. }
  209. }
  210. if ( !function_exists( 'readline' ) )
  211. {
  212. function readline( $prompt = '' )
  213. {
  214. echo $prompt . ' ';
  215. return trim( fgets( STDIN ) );
  216. }
  217. }
  218. if ( !function_exists( 'getUserInput' ) )
  219. {
  220. function getUserInput( $query, $acceptValues )
  221. {
  222. $validInput = false;
  223. while( !$validInput )
  224. {
  225. $input = readline( $query );
  226. if ( $acceptValues === false ||
  227. in_array( $input, $acceptValues ) )
  228. {
  229. $validInput = true;
  230. }
  231. }
  232. return $input;
  233. }
  234. }
  235. function reportProgress( $filename, $count )
  236. {
  237. global $cli;
  238. static $progress = array( '|', '/', '-', '\\' );
  239. if ( $count == 0 )
  240. {
  241. $cli->output( $cli->storePosition() . " " . $cli->restorePosition(), false );
  242. }
  243. else
  244. {
  245. $text = array_shift( $progress );
  246. $cli->output( $cli->storePosition() . $text . $cli->restorePosition(), false );
  247. $progress[] = $text;
  248. }
  249. }
  250. if ( $options['clear-all'] )
  251. {
  252. $noAction = false;
  253. if ( $purge )
  254. purgeItems( $cacheList, $cli, false );
  255. else
  256. clearItems( $cacheList, $cli, false );
  257. $script->shutdown( 0 );
  258. }
  259. if ( $options['clear-tag'] )
  260. {
  261. $noAction = false;
  262. $tagName = $options['clear-tag'];
  263. $cacheEntries = eZCache::fetchByTag( $tagName, $cacheList );
  264. if ( $purge )
  265. purgeItems( $cacheEntries, $cli, $tagName );
  266. else
  267. clearItems( $cacheEntries, $cli, $tagName );
  268. }
  269. $idName = false;
  270. if ( $options['clear-id'] )
  271. {
  272. $noAction = false;
  273. $idName = $options['clear-id'];
  274. }
  275. if ( $idName )
  276. {
  277. $idList = explode( ',', $idName );
  278. $missingIDList = array();
  279. $cacheEntries = array();
  280. foreach ( $idList as $id )
  281. {
  282. $cacheEntry = eZCache::fetchByID( $id, $cacheList );
  283. if ( $cacheEntry )
  284. {
  285. $cacheEntries[] = $cacheEntry;
  286. }
  287. else
  288. {
  289. $missingIDList[] = $id;
  290. }
  291. }
  292. if ( count( $missingIDList ) > 0 )
  293. {
  294. $cli->warning( 'No such cache ID: ' . $cli->stylize( 'emphasize', implode( ', ', $missingIDList ) ) );
  295. $script->shutdown( 1 );
  296. }
  297. if ( $options['clear-id'] )
  298. {
  299. if ( $purge )
  300. purgeItems( $cacheEntries, $cli, $idName );
  301. else
  302. clearItems( $cacheEntries, $cli, $idName );
  303. }
  304. else
  305. {
  306. $script->shutdown( 1, "Internal error" );
  307. }
  308. }
  309. if ( $noAction )
  310. {
  311. $cli->warning( "To clear caches use one of the options --clear-id, --clear-tag or --clear-all. Use --help option for more details." );
  312. }
  313. $script->shutdown();
  314. ?>