Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
96.55% covered (success)
96.55%
56 / 58
50.00% covered (danger)
50.00%
2 / 4
CRAP
0.00% covered (danger)
0.00%
0 / 1
EventWikisStore
96.55% covered (success)
96.55%
56 / 58
50.00% covered (danger)
50.00%
2 / 4
14
0.00% covered (danger)
0.00%
0 / 1
 __construct
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 getEventWikis
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getEventWikisMulti
94.12% covered (success)
94.12%
16 / 17
0.00% covered (danger)
0.00%
0 / 1
4.00
 addOrUpdateEventWikis
97.37% covered (success)
97.37%
37 / 38
0.00% covered (danger)
0.00%
0 / 1
8
1<?php
2
3declare( strict_types=1 );
4
5namespace MediaWiki\Extension\CampaignEvents\Event\Store;
6
7use MediaWiki\Extension\CampaignEvents\Database\CampaignsDatabaseHelper;
8use MediaWiki\Extension\CampaignEvents\Event\EventRegistration;
9
10/**
11 * This class abstracts access to the ce_event_wikis DB table.
12 * @note This class is intended to manage event and wiki relationships within the CampaignEvents extension.
13 */
14class EventWikisStore {
15    public const SERVICE_NAME = 'CampaignEventsEventWikisStore';
16    public const ALL_WIKIS_DB_VALUE = '*all*';
17
18    private CampaignsDatabaseHelper $dbHelper;
19    private bool $featureEnabled;
20
21    public function __construct(
22        CampaignsDatabaseHelper $dbHelper,
23        bool $featureEnabled
24    ) {
25        $this->dbHelper = $dbHelper;
26        $this->featureEnabled = $featureEnabled;
27    }
28
29    /**
30     * Retrieves all wikis (ceew_wiki) associated with a specific event ID.
31     *
32     * @param int $eventID
33     * @return string[]|true List of wiki IDs or {@see EventRegistration::ALL_WIKIS}
34     */
35    public function getEventWikis( int $eventID ) {
36        return $this->getEventWikisMulti( [ $eventID ] )[$eventID];
37    }
38
39    /**
40     * Retrieves all wikis associated with the given events.
41     *
42     * @param int[] $eventIDs
43     * @return array<int,string[]|true> Maps event ID to a list of wiki IDs or {@see EventRegistration::ALL_WIKIS}
44     */
45    public function getEventWikisMulti( array $eventIDs ): array {
46        $wikisByEvent = array_fill_keys( $eventIDs, [] );
47        if ( !$this->featureEnabled ) {
48            return $wikisByEvent;
49        }
50
51        $dbr = $this->dbHelper->getDBConnection( DB_REPLICA );
52        $queryBuilder = $dbr->newSelectQueryBuilder();
53        $res = $queryBuilder->select( [ 'ceew_event_id', 'ceew_wiki' ] )
54            ->from( 'ce_event_wikis' )
55            ->where( [ 'ceew_event_id' => $eventIDs ] )
56            ->caller( __METHOD__ )
57            ->fetchResultSet();
58
59        foreach ( $res as $row ) {
60            $curEvent = $row->ceew_event_id;
61            $storedWiki = $row->ceew_wiki;
62            if ( $storedWiki === self::ALL_WIKIS_DB_VALUE ) {
63                $wikisByEvent[$curEvent] = EventRegistration::ALL_WIKIS;
64            } else {
65                $wikisByEvent[$curEvent][] = $storedWiki;
66            }
67        }
68        return $wikisByEvent;
69    }
70
71    /**
72     * Adds wikis for a specific event ID.
73     *
74     * @param int $eventID The event ID to associate these wikis with.
75     * @param string[]|true $eventWikis An array of wiki IDs to add, or {@see EventRegistration::ALL_WIKIS}
76     */
77    public function addOrUpdateEventWikis( int $eventID, $eventWikis ): void {
78        if ( !$this->featureEnabled ) {
79            return;
80        }
81        $dbw = $this->dbHelper->getDBConnection( DB_PRIMARY );
82
83        $queryBuilder = $dbw->newSelectQueryBuilder();
84        $currentWikisRes = $queryBuilder->select( [ 'ceew_id', 'ceew_wiki' ] )
85            ->from( 'ce_event_wikis' )
86            ->where( [ 'ceew_event_id' => $eventID ] )
87            ->caller( __METHOD__ )
88            ->fetchResultSet();
89        $currentWikisByID = [];
90        foreach ( $currentWikisRes as $row ) {
91            $currentWikisByID[$row->ceew_id] = $row->ceew_wiki;
92        }
93
94        if ( $eventWikis === EventRegistration::ALL_WIKIS ) {
95            if ( array_values( $currentWikisByID ) === [ self::ALL_WIKIS_DB_VALUE ] ) {
96                // Already in the desired state, no need to make changes.
97                $rowIDsToRemove = $wikisToAdd = [];
98            } else {
99                $rowIDsToRemove = array_keys( $currentWikisByID );
100                $wikisToAdd = [ self::ALL_WIKIS_DB_VALUE ];
101            }
102        } else {
103            $rowIDsToRemove = array_keys( array_diff( $currentWikisByID, $eventWikis ) );
104            $wikisToAdd = array_diff( $eventWikis, $currentWikisByID );
105        }
106
107        if ( count( $rowIDsToRemove ) > 0 ) {
108            $deleteQueryBuilder = $dbw->newDeleteQueryBuilder();
109            $deleteQueryBuilder->delete( 'ce_event_wikis' )
110                ->where( [ 'ceew_id' => $rowIDsToRemove ] )
111                ->caller( __METHOD__ )
112                ->execute();
113        }
114
115        if ( count( $wikisToAdd ) > 0 ) {
116            $rows = [];
117            foreach ( $wikisToAdd as $wiki ) {
118                $rows[] = [
119                    'ceew_event_id' => $eventID,
120                    'ceew_wiki' => $wiki
121                ];
122            }
123
124            $insertQueryBuilder = $dbw->newInsertQueryBuilder();
125            $insertQueryBuilder->insertInto( 'ce_event_wikis' )
126                ->ignore()
127                ->rows( $rows )
128                ->caller( __METHOD__ )
129                ->execute();
130        }
131    }
132}