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 / 3
CRAP
0.00% covered (danger)
0.00%
0 / 1
FlowUpdateResolvedNotifTitles
0.00% covered (danger)
0.00%
0 / 46
0.00% covered (danger)
0.00%
0 / 3
110
0.00% covered (danger)
0.00%
0 / 1
 __construct
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 1
2
 getUpdateKey
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 doDBUpdates
0.00% covered (danger)
0.00%
0 / 41
0.00% covered (danger)
0.00%
0 / 1
72
1<?php
2/**
3 * Update the titles of flow-topic-resolved events to point to boards instead of topics
4 *
5 * @ingroup Maintenance
6 */
7
8namespace Flow\Maintenance;
9
10use BatchRowIterator;
11use Exception;
12use Flow\Container;
13use Flow\WorkflowLoaderFactory;
14use LoggedUpdateMaintenance;
15use MediaWiki\Title\Title;
16use MWEchoDbFactory;
17
18$IP = getenv( 'MW_INSTALL_PATH' );
19if ( $IP === false ) {
20    $IP = __DIR__ . '/../../..';
21}
22
23require_once "$IP/maintenance/Maintenance.php";
24
25/**
26 * Maintenance script that update flow-topic-resolved events to point event_page_id to the board instead of the topic.
27 *
28 * @ingroup Maintenance
29 */
30class FlowUpdateResolvedNotifTitles extends LoggedUpdateMaintenance {
31
32    public function __construct() {
33        parent::__construct();
34
35        $this->addDescription( "Update the titles of flow-topic-resolved Echo events to point to boards instead of topics" );
36
37        $this->setBatchSize( 500 );
38
39        $this->requireExtension( 'Flow' );
40    }
41
42    public function getUpdateKey() {
43        return 'FlowUpdateResolvedNotifTitles';
44    }
45
46    public function doDBUpdates() {
47        $dbFactory = MWEchoDbFactory::newFromDefault();
48        $dbw = $dbFactory->getEchoDb( DB_PRIMARY );
49        $dbr = $dbFactory->getEchoDb( DB_REPLICA );
50        // We can't join echo_event with page, because those tables can be on different
51        // DB clusters. If we had been able to do that, we could have added
52        // wHERE page_namespace=NS_TOPIC, but instead we have to examine all rows
53        // and skip the non-NS_TOPIC ones.
54        $iterator = new BatchRowIterator(
55            $dbr,
56            'echo_event',
57            'event_id',
58            $this->getBatchSize()
59        );
60        $iterator->addConditions( [
61            'event_type' => 'flow-topic-resolved',
62            'event_page_id IS NOT NULL',
63        ] );
64        $iterator->setFetchColumns( [ 'event_page_id' ] );
65        $iterator->setCaller( __METHOD__ );
66
67        $storage = Container::get( 'storage.workflow' );
68
69        $this->output( "Retitling flow-topic-resolved events...\n" );
70
71        $processed = 0;
72        foreach ( $iterator as $batch ) {
73            foreach ( $batch as $row ) {
74                $topicTitle = Title::newFromID( $row->event_page_id );
75                if ( !$topicTitle || $topicTitle->getNamespace() !== NS_TOPIC ) {
76                    continue;
77                }
78                $boardTitle = null;
79                try {
80                    $uuid = WorkflowLoaderFactory::uuidFromTitle( $topicTitle );
81                    $workflow = $storage->get( $uuid );
82                    if ( $workflow ) {
83                        $boardTitle = $workflow->getOwnerTitle();
84                    }
85                } catch ( Exception $e ) {
86                }
87                if ( $boardTitle ) {
88                    $dbw->newUpdateQueryBuilder()
89                        ->update( 'echo_event' )
90                        ->set( [ 'event_page_id' => $boardTitle->getArticleID() ] )
91                        ->where( [ 'event_id' => $row->event_id ] )
92                        ->caller( __METHOD__ )
93                        ->execute();
94                    $processed += $dbw->affectedRows();
95                } else {
96                    $this->output( "Could not find board for topic: " . $topicTitle->getPrefixedText() . "\n" );
97                }
98            }
99
100            $this->output( "Updated $processed events.\n" );
101            $this->waitForReplication();
102        }
103
104        return true;
105    }
106}
107
108$maintClass = FlowUpdateResolvedNotifTitles::class;
109require_once RUN_MAINTENANCE_IF_MAIN;