Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 68
0.00% covered (danger)
0.00%
0 / 6
CRAP
0.00% covered (danger)
0.00%
0 / 1
LqtDeletionController
0.00% covered (danger)
0.00%
0 / 68
0.00% covered (danger)
0.00%
0 / 6
552
0.00% covered (danger)
0.00%
0 / 1
 onArticleDeleteComplete
0.00% covered (danger)
0.00%
0 / 20
0.00% covered (danger)
0.00%
0 / 1
56
 recursivelyDeleteReplies
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 1
6
 onRevisionUndeleted
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 1
6
 onArticleUndelete
0.00% covered (danger)
0.00%
0 / 27
0.00% covered (danger)
0.00%
0 / 1
42
 onArticleConfirmDelete
0.00% covered (danger)
0.00%
0 / 11
0.00% covered (danger)
0.00%
0 / 1
30
 onArticleDelete
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
2
1<?php
2
3use MediaWiki\Context\RequestContext;
4use MediaWiki\MediaWikiServices;
5use MediaWiki\Output\OutputPage;
6use MediaWiki\Revision\RevisionRecord;
7use MediaWiki\Title\Title;
8use MediaWiki\User\User;
9
10class LqtDeletionController {
11    /** @var Title[]|null */
12    public static $pageids_to_revive;
13
14    public static function onArticleDeleteComplete( WikiPage &$article, User &$user, $reason, $id ) {
15        $title = $article->getTitle();
16
17        if ( $title->getNamespace() != NS_LQT_THREAD ) {
18            return true;
19        }
20
21        $threads = Threads::where( [ 'thread_root' => $id ] );
22
23        if ( !count( $threads ) ) {
24            wfDebugLog( 'LiquidThreads', __METHOD__ . ": no threads with root $id, ignoring...\n" );
25            return true;
26        }
27
28        $thread = array_pop( $threads );
29
30        // Mark the thread as deleted
31        $thread->delete( $reason );
32
33        // Avoid orphaning subthreads, update their parentage.
34        if ( $thread->replies() && $thread->isTopmostThread() ) {
35            $reason = wfMessage( 'lqt-delete-parent-deleted', $reason )->text();
36            self::recursivelyDeleteReplies( $thread, $reason, $user );
37            $out = RequestContext::getMain()->getOutput();
38            $out->addWikiMsg( 'lqt-delete-replies-done' );
39        } elseif ( $thread->replies() ) {
40            foreach ( $thread->replies() as $reply ) {
41                $reply->setSuperthread( $thread->superthread() );
42                $reply->save();
43            }
44        }
45
46        // Synchronise the first 500 threads, in reverse order by thread id. If
47        // there are more threads to synchronise, the job queue will take over.
48        Threads::synchroniseArticleData( $article, 500, 'cascade' );
49
50        return true;
51    }
52
53    public static function recursivelyDeleteReplies( Thread $thread, $reason, User $user ) {
54        foreach ( $thread->replies() as $reply ) {
55            $reply->root()->getPage()->doDeleteArticleReal( $reason, $user );
56            $reply->delete( $reason );
57            self::recursivelyDeleteReplies( $reply, $reason, $user );
58        }
59    }
60
61    public static function onRevisionUndeleted( RevisionRecord $revisionRecord, $oldPageId ) {
62        $linkTarget = $revisionRecord->getPageAsLinkTarget();
63        if ( $linkTarget->getNamespace() == NS_LQT_THREAD ) {
64            self::$pageids_to_revive[$oldPageId] = Title::newFromLinkTarget( $linkTarget );
65        }
66
67        return true;
68    }
69
70    public static function onArticleUndelete( &$udTitle, $created, $comment = '' ) {
71        if ( !self::$pageids_to_revive ) {
72            return true;
73        }
74
75        foreach ( self::$pageids_to_revive as $pageid => $title ) {
76            if ( $pageid == 0 ) {
77                continue;
78            }
79
80            // Try to get comment for old versions where it isn't passed, hacky :(
81            if ( !$comment ) {
82                global $wgRequest;
83                $comment = $wgRequest->getText( 'wpComment' );
84            }
85
86            // TX has not been committed yet, so we must select from the master
87            $dbw = MediaWikiServices::getInstance()->getConnectionProvider()->getPrimaryDatabase();
88            $res = $dbw->newSelectQueryBuilder()
89                ->select( '*' )
90                ->from( 'thread' )
91                ->where( [ 'thread_root' => $pageid ] )
92                ->caller( __METHOD__ )
93                ->fetchResultSet();
94            $threads = Threads::loadFromResult( $res, $dbw );
95
96            if ( count( $threads ) ) {
97                $thread = array_pop( $threads );
98                $thread->setRoot( new Article( $title, 0 ) );
99                $thread->undelete( $comment );
100            } else {
101                wfDebug( __METHOD__ . ":No thread found with root set to $pageid (??)\n" );
102            }
103        }
104
105        // Synchronise the first 500 threads, in reverse order by thread id. If
106        // there are more threads to synchronise, the job queue will take over.
107        Threads::synchroniseArticleData(
108            MediaWikiServices::getInstance()->getWikiPageFactory()->newFromTitle( $udTitle ),
109            500,
110            'cascade'
111        );
112
113        return true;
114    }
115
116    /**
117     * @param Article $article
118     * @param OutputPage $out
119     * @param string &$reason
120     * @return bool
121     */
122    public static function onArticleConfirmDelete( $article, $out, &$reason ) {
123        if ( $article->getTitle()->getNamespace() != NS_LQT_THREAD ) {
124            return true;
125        }
126
127        $thread = Threads::withRoot( $article->getPage() );
128
129        if ( !$thread ) {
130            return true;
131        }
132
133        if ( $thread->isTopmostThread() && count( $thread->replies() ) ) {
134            $out->wrapWikiMsg(
135                '<strong>$1</strong>',
136                'lqt-delete-parent-warning'
137            );
138        }
139
140        return true;
141    }
142
143    public static function onArticleDelete( $wikiPage ) {
144        // Synchronise article data so that moving the article doesn't break any
145        // article association.
146        Threads::synchroniseArticleData( $wikiPage );
147
148        return true;
149    }
150}