MediaWiki REL1_34
rebuildFileCache.php
Go to the documentation of this file.
1<?php
25
26require_once __DIR__ . '/Maintenance.php';
27
34 private $enabled = true;
35
36 public function __construct() {
37 parent::__construct();
38 $this->addDescription( 'Build file cache for content pages' );
39 $this->addOption( 'start', 'Page_id to start from', false, true );
40 $this->addOption( 'end', 'Page_id to end on', false, true );
41 $this->addOption( 'overwrite', 'Refresh page cache' );
42 $this->setBatchSize( 100 );
43 }
44
45 public function finalSetup() {
46 global $wgUseFileCache;
47
48 $this->enabled = $wgUseFileCache;
49 // Script will handle capturing output and saving it itself
50 $wgUseFileCache = false;
51 // Avoid DB writes (like enotif/counters)
52 MediaWiki\MediaWikiServices::getInstance()->getReadOnlyMode()
53 ->setReason( 'Building cache' );
54
55 // Ensure no debug-specific logic ends up in the cache (must be after Setup.php)
56 MWDebug::deinit();
57
58 parent::finalSetup();
59 }
60
61 public function execute() {
62 if ( !$this->enabled ) {
63 $this->fatalError( "Nothing to do -- \$wgUseFileCache is disabled." );
64 }
65
66 $start = $this->getOption( 'start', "0" );
67 if ( !ctype_digit( $start ) ) {
68 $this->fatalError( "Invalid value for start parameter." );
69 }
70 $start = intval( $start );
71
72 $end = $this->getOption( 'end', "0" );
73 if ( !ctype_digit( $end ) ) {
74 $this->fatalError( "Invalid value for end parameter." );
75 }
76 $end = intval( $end );
77
78 $this->output( "Building content page file cache from page {$start}!\n" );
79
80 $dbr = $this->getDB( DB_REPLICA );
81 $batchSize = $this->getBatchSize();
82 $overwrite = $this->hasOption( 'overwrite' );
83 $start = ( $start > 0 )
84 ? $start
85 : $dbr->selectField( 'page', 'MIN(page_id)', '', __METHOD__ );
86 $end = ( $end > 0 )
87 ? $end
88 : $dbr->selectField( 'page', 'MAX(page_id)', '', __METHOD__ );
89 if ( !$start ) {
90 $this->fatalError( "Nothing to do." );
91 }
92
93 // Mock request (hack, no real client)
94 $_SERVER['HTTP_ACCEPT_ENCODING'] = 'bgzip';
95
96 # Do remaining chunk
97 $end += $batchSize - 1;
98 $blockStart = $start;
99 $blockEnd = $start + $batchSize - 1;
100
101 $dbw = $this->getDB( DB_MASTER );
102 // Go through each page and save the output
103 while ( $blockEnd <= $end ) {
104 // Get the pages
105 $res = $dbr->select( 'page',
106 [ 'page_namespace', 'page_title', 'page_id' ],
107 [ 'page_namespace' => MediaWikiServices::getInstance()->getNamespaceInfo()->
108 getContentNamespaces(),
109 "page_id BETWEEN " . (int)$blockStart . " AND " . (int)$blockEnd ],
110 __METHOD__,
111 [ 'ORDER BY' => 'page_id ASC', 'USE INDEX' => 'PRIMARY' ]
112 );
113
114 $this->beginTransaction( $dbw, __METHOD__ ); // for any changes
115 foreach ( $res as $row ) {
116 $rebuilt = false;
117
118 $title = Title::makeTitleSafe( $row->page_namespace, $row->page_title );
119 if ( $title === null ) {
120 $this->output( "Page {$row->page_id} has bad title\n" );
121 continue; // broken title?
122 }
123
124 $context = new RequestContext();
125 $context->setTitle( $title );
127 $context->setWikiPage( $article->getPage() );
128
129 // Some extensions like FlaggedRevs while error out if this is unset
130 RequestContext::getMain()->setTitle( $title );
131
132 // If the article is cacheable, then load it
133 if ( $article->isFileCacheable( HTMLFileCache::MODE_REBUILD ) ) {
134 $viewCache = new HTMLFileCache( $title, 'view' );
135 $historyCache = new HTMLFileCache( $title, 'history' );
136 if ( $viewCache->isCacheGood() && $historyCache->isCacheGood() ) {
137 if ( $overwrite ) {
138 $rebuilt = true;
139 } else {
140 $this->output( "Page '$title' (id {$row->page_id}) already cached\n" );
141 continue; // done already!
142 }
143 }
144
145 Wikimedia\suppressWarnings(); // header notices
146
147 // 1. Cache ?action=view
148 // Be sure to reset the mocked request time (T24852)
149 $_SERVER['REQUEST_TIME_FLOAT'] = microtime( true );
150 ob_start();
151 $article->view();
152 $context->getOutput()->output();
153 $context->getOutput()->clearHTML();
154 $viewHtml = ob_get_clean();
155 $viewCache->saveToFileCache( $viewHtml );
156
157 // 2. Cache ?action=history
158 // Be sure to reset the mocked request time (T24852)
159 $_SERVER['REQUEST_TIME_FLOAT'] = microtime( true );
160 ob_start();
161 Action::factory( 'history', $article, $context )->show();
162 $context->getOutput()->output();
163 $context->getOutput()->clearHTML();
164 $historyHtml = ob_get_clean();
165 $historyCache->saveToFileCache( $historyHtml );
166
167 Wikimedia\restoreWarnings();
168
169 if ( $rebuilt ) {
170 $this->output( "Re-cached page '$title' (id {$row->page_id})..." );
171 } else {
172 $this->output( "Cached page '$title' (id {$row->page_id})..." );
173 }
174 $this->output( "[view: " . strlen( $viewHtml ) . " bytes; " .
175 "history: " . strlen( $historyHtml ) . " bytes]\n" );
176 } else {
177 $this->output( "Page '$title' (id {$row->page_id}) not cacheable\n" );
178 }
179 }
180 $this->commitTransaction( $dbw, __METHOD__ ); // commit any changes (just for sanity)
181
182 $blockStart += $batchSize;
183 $blockEnd += $batchSize;
184 }
185 $this->output( "Done!\n" );
186 }
187}
188
189$maintClass = RebuildFileCache::class;
190require_once RUN_MAINTENANCE_IF_MAIN;
getDB()
$wgUseFileCache
This will cache static pages for non-logged-in users to reduce database traffic on public sites.
const RUN_MAINTENANCE_IF_MAIN
static newFromTitle( $title, IContextSource $context)
Create an Article object of the appropriate class for the given page.
Definition Article.php:160
Page view caching in the file system.
Abstract maintenance class for quickly writing and churning out maintenance scripts with minimal effo...
beginTransaction(IDatabase $dbw, $fname)
Begin a transcation on a DB.
commitTransaction(IDatabase $dbw, $fname)
Commit the transcation on a DB handle and wait for replica DBs to catch up.
output( $out, $channel=null)
Throw some output to the user.
hasOption( $name)
Checks to see if a particular option exists.
getBatchSize()
Returns batch size.
addDescription( $text)
Set the description text.
addOption( $name, $description, $required=false, $withArg=false, $shortName=false, $multiOccurrence=false)
Add a parameter to the script.
getOption( $name, $default=null)
Get an option, or return the default.
setBatchSize( $s=0)
Set the batch size.
fatalError( $msg, $exitCode=1)
Output a message and terminate the current script.
MediaWikiServices is the service locator for the application scope of MediaWiki.
Maintenance script that builds file cache for content pages.
execute()
Do the actual work.
__construct()
Default constructor.
finalSetup()
Handle some last-minute setup here.
Group all the pieces relevant to the context of a request into one instance.
$context
Definition load.php:45
const DB_REPLICA
Definition defines.php:25
const DB_MASTER
Definition defines.php:26