00001 <?php
00024 require_once( dirname(__FILE__) . '/Maintenance.php' );
00025
00026 class UpdateSpecialPages extends Maintenance {
00027 public function __construct() {
00028 parent::__construct();
00029 $this->addOption( 'list', 'List special page names' );
00030 $this->addOption( 'only', 'Only update "page". Ex: --only=BrokenRedirects', false, true );
00031 $this->addOption( 'override', 'Also update pages that have updates disabled' );
00032 }
00033
00034 public function execute() {
00035 global $IP, $wgOut, $wgSpecialPageCacheUpdates, $wgQueryPages, $wgQueryCacheLimit, $wgDisableQueryPageUpdate;
00036 $wgOut->disable();
00037 $dbw = wfGetDB( DB_MASTER );
00038
00039 foreach( $wgSpecialPageCacheUpdates as $special => $call ) {
00040 if( !is_callable($call) ) {
00041 $this->error( "Uncallable function $call!" );
00042 continue;
00043 }
00044 $t1 = explode( ' ', microtime() );
00045 call_user_func( $call, $dbw );
00046 $t2 = explode( ' ', microtime() );
00047 $this->output( sprintf( '%-30s ', $special ) );
00048 $elapsed = ($t2[0] - $t1[0]) + ($t2[1] - $t1[1]);
00049 $hours = intval( $elapsed / 3600 );
00050 $minutes = intval( $elapsed % 3600 / 60 );
00051 $seconds = $elapsed - $hours * 3600 - $minutes * 60;
00052 if ( $hours ) {
00053 $this->output( $hours . 'h ' );
00054 }
00055 if ( $minutes ) {
00056 $this->output( $minutes . 'm ' );
00057 }
00058 $this->output( sprintf( "completed in %.2fs\n", $seconds ) );
00059 # Wait for the slave to catch up
00060 wfWaitForSlaves( 5 );
00061 }
00062
00063
00064 require_once( "$IP/includes/QueryPage.php" );
00065
00066 foreach( $wgQueryPages as $page ) {
00067 @list( $class, $special, $limit ) = $page;
00068
00069 # --list : just show the name of pages
00070 if( $this->hasOption('list') ) {
00071 $this->output( "$special\n" );
00072 continue;
00073 }
00074
00075 if ( !$this->hasOption('override') && $wgDisableQueryPageUpdate && in_array( $special, $wgDisableQueryPageUpdate ) ) {
00076 $this->output( sprintf( "%-30s disabled\n", $special ) );
00077 continue;
00078 }
00079
00080 $specialObj = SpecialPage::getPage( $special );
00081 if ( !$specialObj ) {
00082 $this->output( "No such special page: $special\n" );
00083 exit;
00084 }
00085 if ( !class_exists( $class ) ) {
00086 $file = $specialObj->getFile();
00087 require_once( $file );
00088 }
00089 $queryPage = new $class;
00090
00091 if( !$this->hasOption('only') || $this->getOption('only') == $queryPage->getName() ) {
00092 $this->output( sprintf( '%-30s ', $special ) );
00093 if ( $queryPage->isExpensive() ) {
00094 $t1 = explode( ' ', microtime() );
00095 # Do the query
00096 $num = $queryPage->recache( $limit === null ? $wgQueryCacheLimit : $limit );
00097 $t2 = explode( ' ', microtime() );
00098 if ( $num === false ) {
00099 $this->output( "FAILED: database error\n" );
00100 } else {
00101 $this->output( "got $num rows in " );
00102
00103 $elapsed = ($t2[0] - $t1[0]) + ($t2[1] - $t1[1]);
00104 $hours = intval( $elapsed / 3600 );
00105 $minutes = intval( $elapsed % 3600 / 60 );
00106 $seconds = $elapsed - $hours * 3600 - $minutes * 60;
00107 if ( $hours ) {
00108 $this->output( $hours . 'h ' );
00109 }
00110 if ( $minutes ) {
00111 $this->output( $minutes . 'm ' );
00112 }
00113 $this->output( sprintf( "%.2fs\n", $seconds ) );
00114 }
00115 # Reopen any connections that have closed
00116 if ( !wfGetLB()->pingAll()) {
00117 $this->output( "\n" );
00118 do {
00119 $this->error( "Connection failed, reconnecting in 10 seconds..." );
00120 sleep( 10 );
00121 } while ( !wfGetLB()->pingAll() );
00122 $this->output( "Reconnected\n\n" );
00123 } else {
00124 # Commit the results
00125 $dbw->commit();
00126 }
00127 # Wait for the slave to catch up
00128 wfWaitForSlaves( 5 );
00129 } else {
00130 $this->output( "cheap, skipped\n" );
00131 }
00132 }
00133 }
00134 }
00135 }
00136
00137 $maintClass = "UpdateSpecialPages";
00138 require_once( DO_MAINTENANCE );