Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
96.67% |
29 / 30 |
|
83.33% |
5 / 6 |
CRAP | |
0.00% |
0 / 1 |
SuppressionRowUpdateGenerator | |
96.67% |
29 / 30 |
|
83.33% |
5 / 6 |
16 | |
0.00% |
0 / 1 |
update | |
100.00% |
4 / 4 |
|
100.00% |
1 / 1 |
3 | |||
setNewTitleFromNsAndText | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
newTitleFromNsAndText | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
updatePageIdFromTitle | |
100.00% |
11 / 11 |
|
100.00% |
1 / 1 |
3 | |||
updatePageLinkedExtraData | |
100.00% |
8 / 8 |
|
100.00% |
1 / 1 |
5 | |||
extra | |
80.00% |
4 / 5 |
|
0.00% |
0 / 1 |
3.07 |
1 | <?php |
2 | |
3 | namespace MediaWiki\Extension\Notifications; |
4 | |
5 | use MediaWiki\Title\Title; |
6 | use RowUpdateGenerator; |
7 | use stdClass; |
8 | |
9 | /** |
10 | * Performs updates required for respecting suppression within echo: |
11 | * Updates event_page_id based on event_page_title and event_page_namespace |
12 | * Updates extra data for page-linked events to contain page id's |
13 | */ |
14 | class SuppressionRowUpdateGenerator implements RowUpdateGenerator { |
15 | /** |
16 | * @var callable Hack to allow replacing Title::makeTitleSafe in tests |
17 | */ |
18 | protected $newTitleFromNsAndText = [ 'Title', 'makeTitleSafe' ]; |
19 | |
20 | /** |
21 | * @inheritDoc |
22 | */ |
23 | public function update( $row ) { |
24 | $update = $this->updatePageIdFromTitle( $row ); |
25 | if ( $row->event_extra !== null && $row->event_type === 'page-linked' ) { |
26 | $update = $this->updatePageLinkedExtraData( $row, $update ); |
27 | } |
28 | |
29 | return $update; |
30 | } |
31 | |
32 | /** |
33 | * Hackish method of mocking Title::newFromText for tests |
34 | * |
35 | * @param callable $callable |
36 | */ |
37 | public function setNewTitleFromNsAndText( $callable ) { |
38 | $this->newTitleFromNsAndText = $callable; |
39 | } |
40 | |
41 | /** |
42 | * Hackish method of mocking Title::makeTitleSafe for tests |
43 | * |
44 | * @param int $namespace The namespace of the page to look up |
45 | * @param string $text The page name to look up |
46 | * @return Title|null The title located for the namespace + text, or null if invalid |
47 | */ |
48 | protected function newTitleFromNsAndText( $namespace, $text ) { |
49 | return call_user_func( $this->newTitleFromNsAndText, $namespace, $text ); |
50 | } |
51 | |
52 | /** |
53 | * Migrates all echo events from having page title and namespace as rows in the table |
54 | * to having only a page id in the table. Any event from a page that doesn't have an |
55 | * article id gets the title+namespace moved to the event extra data |
56 | * |
57 | * @param stdClass $row A row from the database |
58 | * @return array All updates required for this row |
59 | */ |
60 | protected function updatePageIdFromTitle( $row ) { |
61 | $update = []; |
62 | $title = $this->newTitleFromNsAndText( $row->event_page_namespace, $row->event_page_title ); |
63 | if ( $title !== null ) { |
64 | $pageId = $title->getArticleID(); |
65 | if ( $pageId ) { |
66 | // If the title has a proper id from the database, store it |
67 | $update['event_page_id'] = $pageId; |
68 | } else { |
69 | // For titles that do not refer to a WikiPage stored in the database |
70 | // move the title/namespace into event_extra |
71 | $extra = $this->extra( $row ); |
72 | $extra['page_title'] = $row->event_page_title; |
73 | $extra['page_namespace'] = $row->event_page_namespace; |
74 | |
75 | $update['event_extra'] = serialize( $extra ); |
76 | } |
77 | } |
78 | |
79 | return $update; |
80 | } |
81 | |
82 | /** |
83 | * Updates the extra data for page-linked events to point to the id of the article |
84 | * rather than the namespace+title combo. |
85 | * |
86 | * @param stdClass $row A row from the database |
87 | * @param array $update |
88 | * |
89 | * @return array All updates required for this row |
90 | */ |
91 | protected function updatePageLinkedExtraData( $row, array $update ) { |
92 | $extra = $this->extra( $row, $update ); |
93 | |
94 | if ( isset( $extra['link-from-title'] ) && isset( $extra['link-from-namespace'] ) ) { |
95 | $title = $this->newTitleFromNsAndText( $extra['link-from-namespace'], $extra['link-from-title'] ); |
96 | unset( $extra['link-from-title'], $extra['link-from-namespace'] ); |
97 | // Link from page is always from a content page, if null or no article id it was |
98 | // somehow invalid |
99 | if ( $title !== null && $title->getArticleID() ) { |
100 | $extra['link-from-page-id'] = $title->getArticleID(); |
101 | } |
102 | |
103 | $update['event_extra'] = serialize( $extra ); |
104 | } |
105 | |
106 | return $update; |
107 | } |
108 | |
109 | /** |
110 | * Return the extra data for a row, if an update wants to change the |
111 | * extra data returns that updated data rather than the original. If |
112 | * no extra data exists returns [] |
113 | * |
114 | * @param stdClass $row The database row being updated |
115 | * @param array $update Updates that need to be applied to the database row |
116 | * @return array The event extra data |
117 | */ |
118 | protected function extra( $row, array $update = [] ) { |
119 | if ( isset( $update['event_extra'] ) ) { |
120 | return unserialize( $update['event_extra'] ); |
121 | } |
122 | |
123 | if ( $row->event_extra ) { |
124 | return unserialize( $row->event_extra ); |
125 | } |
126 | |
127 | return []; |
128 | } |
129 | |
130 | } |