getHtmlCacheUpdater() */ public function __construct( HookContainer $hookContainer, $reboundDelay, $useFileCache, $cdnMaxAge ) { $this->hookRunner = new HookRunner( $hookContainer ); $this->reboundDelay = $reboundDelay; $this->useFileCache = $useFileCache; $this->cdnMaxAge = $cdnMaxAge; } /** * @param int $flags Bit field * @param int $flag Constant to check for * @return bool If $flags contains $flag */ private function fieldHasFlag( $flags, $flag ) { return ( ( $flags & $flag ) === $flag ); } /** * Purge the CDN for a URL or list of URLs * * @param string[]|string $urls URL or list of URLs * @param int $flags Bit field of class PURGE_* constants * [Default: HtmlCacheUpdater::PURGE_PRESEND] * @param mixed[] $unless Optional map of (HtmlCacheUpdater::UNLESS_* constant => value) */ public function purgeUrls( $urls, $flags = self::PURGE_PRESEND, array $unless = [] ) { $minFreshCacheMtime = $unless[self::UNLESS_CACHE_MTIME_AFTER] ?? null; if ( $minFreshCacheMtime && time() > ( $minFreshCacheMtime + $this->cdnMaxAge ) ) { return; } $urls = is_string( $urls ) ? [ $urls ] : $urls; $reboundDelay = $this->fieldHasFlag( $flags, self::PURGE_REBOUND ) ? $this->reboundDelay : 0; // no second purge $update = new CdnCacheUpdate( $urls, [ 'reboundDelay' => $reboundDelay ] ); if ( $this->fieldHasFlag( $flags, self::PURGE_PRESEND ) ) { DeferredUpdates::addUpdate( $update, DeferredUpdates::PRESEND ); } else { $update->doUpdate(); } } /** * Purge the CDN/HTMLFileCache for a title or the titles yielded by an iterator * * All cacheable canonical URLs associated with the titles will be purged from CDN. * All cacheable actions associated with the titles will be purged from HTMLFileCache. * * @param Traversable|Title[]|Title $titles Title or iterator yielding Title instances * @param int $flags Bit field of class PURGE_* constants * [Default: HtmlCacheUpdater::PURGE_PRESEND] * @param mixed[] $unless Optional map of (HtmlCacheUpdater::UNLESS_* constant => value) */ public function purgeTitleUrls( $titles, $flags = self::PURGE_PRESEND, array $unless = [] ) { $titles = $titles instanceof Title ? [ $titles ] : $titles; if ( $this->useFileCache ) { $update = HtmlFileCacheUpdate::newFromTitles( $titles ); if ( $this->fieldHasFlag( $flags, self::PURGE_PRESEND ) ) { DeferredUpdates::addUpdate( $update, DeferredUpdates::PRESEND ); } else { $update->doUpdate(); } } $minFreshCacheMtime = $unless[self::UNLESS_CACHE_MTIME_AFTER] ?? null; if ( !$minFreshCacheMtime || time() <= ( $minFreshCacheMtime + $this->cdnMaxAge ) ) { $urls = []; foreach ( $titles as $title ) { /** @var Title $title */ $urls = array_merge( $urls, $this->getUrls( $title, $flags ) ); } $this->purgeUrls( $urls, $flags ); } } /** * Get a list of URLs to purge from the CDN cache when this page changes. * * @param Title $title * @param int $flags Bit field of `PURGE_URLS_*` class constants (optional). * @return string[] URLs */ public function getUrls( Title $title, int $flags = 0 ) : array { // These urls are affected both by direct revisions as well, // as re-rendering of the same content during a LinksUpdate. $urls = [ $title->getInternalURL() ]; // Language variant page views are currently not cached // and thus not purged (T250511). // These urls are only affected by direct revisions, and do not require // purging when a LinksUpdate merely rerenders the same content. // This exists to avoid large amounts of redundant PURGE traffic (T250261). if ( !$this->fieldHasFlag( $flags, self::PURGE_URLS_LINKSUPDATE_ONLY ) ) { $urls[] = $title->getInternalURL( 'action=history' ); // Canonical action=raw URLs for user config pages if ( $title->isUserJsConfigPage() ) { $urls[] = $title->getInternalURL( 'action=raw&ctype=text/javascript' ); } elseif ( $title->isUserJsonConfigPage() ) { $urls[] = $title->getInternalURL( 'action=raw&ctype=application/json' ); } elseif ( $title->isUserCssConfigPage() ) { $urls[] = $title->getInternalURL( 'action=raw&ctype=text/css' ); } } // Extensions may add novel ways to access this content $append = []; $mode = $flags & self::PURGE_URLS_LINKSUPDATE_ONLY; $this->hookRunner->onHtmlCacheUpdaterAppendUrls( $title, $mode, $append ); $urls = array_merge( $urls, $append ); // Extensions may add novel ways to access the site overall $append = []; $this->hookRunner->onHtmlCacheUpdaterVaryUrls( $urls, $append ); $urls = array_merge( $urls, $append ); // Legacy. TODO: Deprecate this $this->hookRunner->onTitleSquidURLs( $title, $urls ); return $urls; } }