Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
0.00% |
0 / 109 |
|
0.00% |
0 / 15 |
CRAP | |
0.00% |
0 / 1 |
ThreadRevision | |
0.00% |
0 / 109 |
|
0.00% |
0 / 15 |
930 | |
0.00% |
0 / 1 |
loadFromId | |
0.00% |
0 / 10 |
|
0.00% |
0 / 1 |
6 | |||
loadFromRow | |
0.00% |
0 / 8 |
|
0.00% |
0 / 1 |
12 | |||
create | |
0.00% |
0 / 23 |
|
0.00% |
0 / 1 |
20 | |||
insert | |
0.00% |
0 / 8 |
|
0.00% |
0 / 1 |
2 | |||
save | |
0.00% |
0 / 8 |
|
0.00% |
0 / 1 |
2 | |||
getRow | |
0.00% |
0 / 6 |
|
0.00% |
0 / 1 |
6 | |||
getTimestamp | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
getUser | |
0.00% |
0 / 3 |
|
0.00% |
0 / 1 |
6 | |||
getChangeType | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
getChangeObject | |
0.00% |
0 / 8 |
|
0.00% |
0 / 1 |
30 | |||
getChangeComment | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
getId | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
getThreadObj | |
0.00% |
0 / 9 |
|
0.00% |
0 / 1 |
20 | |||
prev | |
0.00% |
0 / 11 |
|
0.00% |
0 / 1 |
2 | |||
next | |
0.00% |
0 / 11 |
|
0.00% |
0 / 1 |
2 |
1 | <?php |
2 | |
3 | use MediaWiki\MediaWikiServices; |
4 | use MediaWiki\User\User; |
5 | |
6 | class ThreadRevision { |
7 | /** @var string[] */ |
8 | public static $load = |
9 | [ |
10 | 'th_id' => 'mId', |
11 | 'th_thread' => 'mThreadId', |
12 | |
13 | 'th_timestamp' => 'mTimestamp', |
14 | |
15 | 'th_user' => 'mUserId', |
16 | 'th_user_text' => 'mUserText', |
17 | |
18 | 'th_change_type' => 'mChangeType', |
19 | 'th_change_object' => 'mChangeObjectId', |
20 | 'th_change_comment' => 'mChangeComment', |
21 | 'th_content' => 'mObjSer', |
22 | ]; |
23 | |
24 | /** @var int */ |
25 | protected $mId; |
26 | /** @var int */ |
27 | protected $mThreadId; |
28 | /** @var string */ |
29 | protected $mTimestamp; |
30 | /** @var User */ |
31 | protected $mUser; |
32 | /** @var int */ |
33 | protected $mUserId; |
34 | /** @var string */ |
35 | protected $mUserText; |
36 | /** @var int */ |
37 | protected $mChangeType; |
38 | /** @var int */ |
39 | protected $mChangeObjectId; |
40 | /** @var Thread|null|false */ |
41 | protected $mChangeObject; |
42 | /** @var string */ |
43 | protected $mChangeComment; |
44 | /** @var string|null */ |
45 | protected $mObjSer; |
46 | /** @var Thread|false|null */ |
47 | protected $mThreadObj; |
48 | |
49 | public static function loadFromId( $id ) { |
50 | $dbr = MediaWikiServices::getInstance()->getConnectionProvider()->getReplicaDatabase(); |
51 | $row = $dbr->newSelectQueryBuilder() |
52 | ->select( '*' ) |
53 | ->from( 'thread_history' ) |
54 | ->where( [ 'th_id' => $id ] ) |
55 | ->caller( __METHOD__ ) |
56 | ->fetchRow(); |
57 | |
58 | if ( !$row ) { |
59 | return null; |
60 | } |
61 | |
62 | return self::loadFromRow( $row ); |
63 | } |
64 | |
65 | public static function loadFromRow( $row ) { |
66 | if ( !$row ) { |
67 | return null; |
68 | } |
69 | |
70 | $rev = new ThreadRevision; |
71 | |
72 | foreach ( self::$load as $col => $field ) { |
73 | $rev->$field = $row->$col; |
74 | } |
75 | |
76 | $rev->mUser = User::newFromName( $rev->mUserText, /* Don't validate */ false ); |
77 | $rev->mThreadObj = unserialize( $rev->mObjSer ); |
78 | |
79 | return $rev; |
80 | } |
81 | |
82 | public static function create( |
83 | Thread $thread, |
84 | $change_type, |
85 | User $user, |
86 | $change_object = null, |
87 | $comment = '' |
88 | ) { |
89 | $timestamp = wfTimestampNow(); |
90 | |
91 | if ( $comment === null ) { |
92 | $comment = ''; |
93 | } |
94 | |
95 | $rev = new ThreadRevision; |
96 | |
97 | $rev->mThreadId = $thread->topmostThread()->id(); |
98 | $rev->mTimestamp = $timestamp; |
99 | |
100 | $rev->mUser = $user; |
101 | $rev->mUserId = $user->getId(); |
102 | $rev->mUserText = $user->getName(); |
103 | |
104 | $rev->mChangeType = $change_type; |
105 | |
106 | if ( $change_object instanceof Thread ) { |
107 | $rev->mChangeObjectId = $change_object->id(); |
108 | $rev->mChangeObject = $change_object; |
109 | } elseif ( $change_object === null ) { |
110 | $rev->mChangeObjectId = $thread->id(); |
111 | $rev->mChangeObject = $thread; |
112 | } else { |
113 | $rev->mChangeObjectId = $change_object; |
114 | } |
115 | |
116 | // This field is TINYTEXT so it can only fit 255 bytes. |
117 | $rev->mChangeComment = MediaWikiServices::getInstance()->getContentLanguage() |
118 | ->truncateForDatabase( $comment, 255 ); |
119 | |
120 | $rev->mThreadObj = $thread->topmostThread(); |
121 | $rev->mObjSer = serialize( $rev->mThreadObj ); |
122 | |
123 | $rev->insert(); |
124 | |
125 | return $rev; |
126 | } |
127 | |
128 | public function insert() { |
129 | $dbw = MediaWikiServices::getInstance()->getConnectionProvider()->getPrimaryDatabase(); |
130 | |
131 | $row = $this->getRow(); |
132 | |
133 | $dbw->newInsertQueryBuilder() |
134 | ->insertInto( 'thread_history' ) |
135 | ->row( $row ) |
136 | ->caller( __METHOD__ ) |
137 | ->execute(); |
138 | |
139 | $this->mId = $dbw->insertId(); |
140 | } |
141 | |
142 | public function save() { |
143 | $row = $this->getRow(); |
144 | |
145 | $dbw = MediaWikiServices::getInstance()->getConnectionProvider()->getPrimaryDatabase(); |
146 | |
147 | $dbw->newReplaceQueryBuilder() |
148 | ->replaceInto( 'thread_history' ) |
149 | ->uniqueIndexFields( 'th_thread' ) |
150 | ->row( $row ) |
151 | ->caller( __METHOD__ ) |
152 | ->execute(); |
153 | } |
154 | |
155 | public function getRow() { |
156 | $row = []; |
157 | |
158 | // First, prep the data for insertion |
159 | $dbw = MediaWikiServices::getInstance()->getConnectionProvider()->getPrimaryDatabase(); |
160 | $this->mTimestamp = $dbw->timestamp( $this->mTimestamp ); |
161 | |
162 | foreach ( self::$load as $col => $field ) { |
163 | $row[$col] = $this->$field; |
164 | } |
165 | |
166 | return $row; |
167 | } |
168 | |
169 | public function getTimestamp() { |
170 | return wfTimestamp( TS_MW, $this->mTimestamp ); |
171 | } |
172 | |
173 | public function getUser() { |
174 | if ( $this->mUserId ) { |
175 | return User::newFromId( $this->mUserId ); |
176 | } |
177 | |
178 | return User::newFromName( $this->mUserText, /* No validation */ false ); |
179 | } |
180 | |
181 | public function getChangeType() { |
182 | return $this->mChangeType; |
183 | } |
184 | |
185 | public function getChangeObject() { |
186 | if ( $this->mChangeObject === null && $this->mChangeObjectId ) { |
187 | $threadObj = $this->getThreadObj(); |
188 | |
189 | if ( $threadObj instanceof Thread ) { |
190 | $objectId = $this->mChangeObjectId; |
191 | $this->mChangeObject = $threadObj->replyWithId( $objectId ); |
192 | } |
193 | |
194 | if ( !$this->mChangeObject ) { |
195 | $this->mChangeObject = false; |
196 | } |
197 | } |
198 | |
199 | return $this->mChangeObject; |
200 | } |
201 | |
202 | public function getChangeComment() { |
203 | return $this->mChangeComment; |
204 | } |
205 | |
206 | public function getId() { |
207 | return $this->mId; |
208 | } |
209 | |
210 | public function getThreadObj() { |
211 | if ( $this->mThreadObj === null ) { |
212 | if ( $this->mObjSer !== null ) { |
213 | $this->mThreadObj = unserialize( $this->mObjSer ); |
214 | } else { |
215 | throw new LogicException( "Missing mObjSer" ); |
216 | } |
217 | } |
218 | |
219 | if ( !( $this->mThreadObj instanceof Thread ) ) { |
220 | $this->mThreadObj = false; |
221 | return false; |
222 | } |
223 | |
224 | $this->mThreadObj->threadRevision = $this; |
225 | |
226 | return $this->mThreadObj; |
227 | } |
228 | |
229 | public function prev() { |
230 | $dbr = MediaWikiServices::getInstance()->getConnectionProvider()->getReplicaDatabase(); |
231 | |
232 | $row = $dbr->newSelectQueryBuilder() |
233 | ->select( '*' ) |
234 | ->from( 'thread_history' ) |
235 | ->where( [ |
236 | $dbr->expr( 'th_id', '<', intval( $this->getId() ) ), |
237 | 'th_thread' => $this->mThreadId |
238 | ] ) |
239 | ->caller( __METHOD__ ) |
240 | ->fetchRow(); |
241 | |
242 | return self::loadFromRow( $row ); |
243 | } |
244 | |
245 | public function next() { |
246 | $dbr = MediaWikiServices::getInstance()->getConnectionProvider()->getReplicaDatabase(); |
247 | |
248 | $row = $dbr->newSelectQueryBuilder() |
249 | ->select( '*' ) |
250 | ->from( 'thread_history' ) |
251 | ->where( [ |
252 | $dbr->expr( 'th_id', '>', intval( $this->getId() ) ), |
253 | 'th_thread' => $this->mThreadId |
254 | ] ) |
255 | ->caller( __METHOD__ ) |
256 | ->fetchRow(); |
257 | |
258 | return self::loadFromRow( $row ); |
259 | } |
260 | } |