Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
95.92% |
47 / 49 |
|
50.00% |
2 / 4 |
CRAP | |
0.00% |
0 / 1 |
EventTopicsStore | |
95.92% |
47 / 49 |
|
50.00% |
2 / 4 |
11 | |
0.00% |
0 / 1 |
__construct | |
100.00% |
2 / 2 |
|
100.00% |
1 / 1 |
1 | |||
getEventTopics | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
getEventTopicsMulti | |
92.31% |
12 / 13 |
|
0.00% |
0 / 1 |
3.00 | |||
addOrUpdateEventTopics | |
96.97% |
32 / 33 |
|
0.00% |
0 / 1 |
6 |
1 | <?php |
2 | |
3 | declare( strict_types=1 ); |
4 | |
5 | namespace MediaWiki\Extension\CampaignEvents\Event\Store; |
6 | |
7 | use MediaWiki\Extension\CampaignEvents\Database\CampaignsDatabaseHelper; |
8 | |
9 | /** |
10 | * This class abstracts access to the ce_event_topics DB table. |
11 | * @note This class is intended to manage event and topic relationships within the CampaignEvents extension. |
12 | */ |
13 | class EventTopicsStore { |
14 | public const SERVICE_NAME = 'CampaignEventsEventTopicsStore'; |
15 | |
16 | private CampaignsDatabaseHelper $dbHelper; |
17 | private bool $featureEnabled; |
18 | |
19 | public function __construct( |
20 | CampaignsDatabaseHelper $dbHelper, |
21 | bool $featureEnabled |
22 | ) { |
23 | $this->dbHelper = $dbHelper; |
24 | $this->featureEnabled = $featureEnabled; |
25 | } |
26 | |
27 | /** |
28 | * Retrieves all topics (ceet_topics) associated with a specific event ID. |
29 | * |
30 | * @param int $eventID |
31 | * @return string[] List of topics IDs |
32 | */ |
33 | public function getEventTopics( int $eventID ) { |
34 | return $this->getEventTopicsMulti( [ $eventID ] )[$eventID]; |
35 | } |
36 | |
37 | /** |
38 | * Retrieves all topics associated with the given events. |
39 | * |
40 | * @param int[] $eventIDs |
41 | * @return array<int,string[]> Maps event ID to a list of topic IDs |
42 | */ |
43 | public function getEventTopicsMulti( array $eventIDs ): array { |
44 | $topicsByEvent = array_fill_keys( $eventIDs, [] ); |
45 | if ( !$this->featureEnabled ) { |
46 | return $topicsByEvent; |
47 | } |
48 | |
49 | $dbr = $this->dbHelper->getDBConnection( DB_REPLICA ); |
50 | $queryBuilder = $dbr->newSelectQueryBuilder(); |
51 | $res = $queryBuilder->select( [ 'ceet_event_id', 'ceet_topic' ] ) |
52 | ->from( 'ce_event_topics' ) |
53 | ->where( [ 'ceet_event_id' => $eventIDs ] ) |
54 | ->caller( __METHOD__ ) |
55 | ->fetchResultSet(); |
56 | |
57 | foreach ( $res as $row ) { |
58 | $topicsByEvent[$row->ceet_event_id][] = $row->ceet_topic; |
59 | } |
60 | return $topicsByEvent; |
61 | } |
62 | |
63 | /** |
64 | * Adds topics for a specific event ID. |
65 | * |
66 | * @param int $eventID The event ID to associate these topics with. |
67 | * @param string[] $eventTopics An array of topic IDs to add |
68 | */ |
69 | public function addOrUpdateEventTopics( int $eventID, array $eventTopics ): void { |
70 | if ( !$this->featureEnabled ) { |
71 | return; |
72 | } |
73 | $dbw = $this->dbHelper->getDBConnection( DB_PRIMARY ); |
74 | |
75 | $queryBuilder = $dbw->newSelectQueryBuilder(); |
76 | $currentTopicsRes = $queryBuilder->select( [ 'ceet_id', 'ceet_topic' ] ) |
77 | ->from( 'ce_event_topics' ) |
78 | ->where( [ 'ceet_event_id' => $eventID ] ) |
79 | ->caller( __METHOD__ ) |
80 | ->fetchResultSet(); |
81 | $currentTopicsByID = []; |
82 | foreach ( $currentTopicsRes as $row ) { |
83 | $currentTopicsByID[$row->ceet_id] = $row->ceet_topic; |
84 | } |
85 | |
86 | $rowIDsToRemove = array_keys( array_diff( $currentTopicsByID, $eventTopics ) ); |
87 | $topicsToAdd = array_diff( $eventTopics, $currentTopicsByID ); |
88 | |
89 | if ( count( $rowIDsToRemove ) > 0 ) { |
90 | $deleteQueryBuilder = $dbw->newDeleteQueryBuilder(); |
91 | $deleteQueryBuilder->delete( 'ce_event_topics' ) |
92 | ->where( [ 'ceet_id' => $rowIDsToRemove ] ) |
93 | ->caller( __METHOD__ ) |
94 | ->execute(); |
95 | } |
96 | |
97 | if ( count( $topicsToAdd ) > 0 ) { |
98 | $rows = []; |
99 | foreach ( $topicsToAdd as $topic ) { |
100 | $rows[] = [ |
101 | 'ceet_event_id' => $eventID, |
102 | 'ceet_topic' => $topic |
103 | ]; |
104 | } |
105 | |
106 | $insertQueryBuilder = $dbw->newInsertQueryBuilder(); |
107 | $insertQueryBuilder->insertInto( 'ce_event_topics' ) |
108 | ->ignore() |
109 | ->rows( $rows ) |
110 | ->caller( __METHOD__ ) |
111 | ->execute(); |
112 | } |
113 | } |
114 | } |