Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 52
0.00% covered (danger)
0.00%
0 / 5
CRAP
0.00% covered (danger)
0.00%
0 / 1
FRExtraCacheUpdate
0.00% covered (danger)
0.00%
0 / 52
0.00% covered (danger)
0.00%
0 / 5
210
0.00% covered (danger)
0.00%
0 / 1
 __construct
0.00% covered (danger)
0.00%
0 / 3
0.00% covered (danger)
0.00%
0 / 1
2
 doUpdate
0.00% covered (danger)
0.00%
0 / 11
0.00% covered (danger)
0.00%
0 / 1
12
 insertJobs
0.00% covered (danger)
0.00%
0 / 15
0.00% covered (danger)
0.00%
0 / 1
42
 getToCondition
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 1
2
 invalidateIDs
0.00% covered (danger)
0.00%
0 / 19
0.00% covered (danger)
0.00%
0 / 1
12
1<?php
2
3use MediaWiki\Deferred\DeferrableUpdate;
4use MediaWiki\MediaWikiServices;
5use MediaWiki\Title\Title;
6
7/**
8 * Class containing cache update methods and job construction
9 * for the special case of purging pages due to dependencies
10 * contained only in the stable version of pages.
11 *
12 * These dependencies should be limited in number as most pages should
13 * have a stable version synced with the current version.
14 */
15class FRExtraCacheUpdate implements DeferrableUpdate {
16    /** @var Title */
17    private $mTitle;
18
19    /** @var int Copy of $wgUpdateRowsPerJob */
20    private $mRowsPerJob;
21    /** @var int Copy of $wgUpdateRowsPerQuery */
22    private $mRowsPerQuery;
23
24    /**
25     * @param Title $titleTo
26     */
27    public function __construct( Title $titleTo ) {
28        global $wgUpdateRowsPerJob, $wgUpdateRowsPerQuery;
29        $this->mTitle = $titleTo;
30        $this->mRowsPerJob = $wgUpdateRowsPerJob;
31        $this->mRowsPerQuery = $wgUpdateRowsPerQuery;
32    }
33
34    /**
35     * @inheritDoc
36     */
37    public function doUpdate() {
38        # Fetch the IDs
39        $dbr = MediaWikiServices::getInstance()->getConnectionProvider()->getReplicaDatabase();
40
41        $pageIds = $dbr->newSelectQueryBuilder()
42            ->select( 'ftr_from' )
43            ->from( 'flaggedrevs_tracking' )
44            ->where( $this->getToCondition() )
45            ->caller( __METHOD__ )
46            ->fetchFieldValues();
47        # Check if there is anything to do...
48        if ( $pageIds ) {
49            # Do it right now?
50            if ( count( $pageIds ) <= $this->mRowsPerJob ) {
51                $this->invalidateIDs( $pageIds );
52            # Defer to job queue...
53            } else {
54                $this->insertJobs( $pageIds );
55            }
56        }
57    }
58
59    /**
60     * @param int[] $pageIds
61     */
62    private function insertJobs( array $pageIds ) {
63        if ( !$pageIds ) {
64            return; // sanity check
65        }
66        $jobs = [];
67        sort( $pageIds );
68        $start = reset( $pageIds );
69        foreach ( $pageIds as $i => $id ) {
70            $next = $pageIds[$i + 1] ?? null;
71            if ( !$next || $next > $id + 1 || $next - $start >= $this->mRowsPerJob ) {
72                $jobs[] = new FRExtraCacheUpdateJob( $this->mTitle, [
73                    'type' => 'purge',
74                    'start' => $start,
75                    'end' => $id,
76                ] );
77                $start = $next;
78            }
79        }
80
81        MediaWikiServices::getInstance()->getJobQueueGroup()->push( $jobs );
82    }
83
84    /**
85     * @return array
86     */
87    public function getToCondition() {
88        return [
89            'ftr_namespace' => $this->mTitle->getNamespace(),
90            'ftr_title' => $this->mTitle->getDBkey(),
91        ];
92    }
93
94    /**
95     * Invalidate a set of IDs, right now
96     * @param int[] $pageIds
97     */
98    public function invalidateIDs( array $pageIds ) {
99        if ( !$pageIds ) {
100            return; // sanity check
101        }
102
103        $dbw = MediaWikiServices::getInstance()->getConnectionProvider()->getPrimaryDatabase();
104
105        $timestamp = $dbw->timestamp();
106
107        $hcu = MediaWikiServices::getInstance()->getHtmlCacheUpdater();
108
109        foreach ( array_chunk( $pageIds, $this->mRowsPerQuery ) as $ids ) {
110            # Update page_touched
111            $dbw->newUpdateQueryBuilder()
112                ->update( 'page' )
113                ->set( [ 'page_touched' => $timestamp ] )
114                ->where( [ 'page_id' => $ids ] )
115                ->caller( __METHOD__ )
116                ->execute();
117
118            # Update CDN
119            $titles = MediaWikiServices::getInstance()
120                ->getPageStore()
121                ->newSelectQueryBuilder()
122                ->wherePageIds( $ids )
123                ->caller( __METHOD__ )
124                ->fetchPageRecords();
125            $hcu->purgeTitleUrls( $titles, $hcu::PURGE_INTENT_TXROUND_REFLECTED );
126        }
127    }
128}