Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 84
0.00% covered (danger)
0.00%
0 / 7
CRAP
0.00% covered (danger)
0.00%
0 / 1
Suggest
0.00% covered (danger)
0.00%
0 / 84
0.00% covered (danger)
0.00%
0 / 7
756
0.00% covered (danger)
0.00%
0 / 1
 run
0.00% covered (danger)
0.00%
0 / 8
0.00% covered (danger)
0.00%
0 / 1
6
 refresh
0.00% covered (danger)
0.00%
0 / 8
0.00% covered (danger)
0.00%
0 / 1
2
 undo
0.00% covered (danger)
0.00%
0 / 14
0.00% covered (danger)
0.00%
0 / 1
30
 clear
0.00% covered (danger)
0.00%
0 / 5
0.00% covered (danger)
0.00%
0 / 1
12
 unban
0.00% covered (danger)
0.00%
0 / 9
0.00% covered (danger)
0.00%
0 / 1
20
 getCollectionSuggestTemplate
0.00% covered (danger)
0.00%
0 / 36
0.00% covered (danger)
0.00%
0 / 1
110
 addArticlesFromName
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 1
6
1<?php
2/**
3 * Collection Extension for MediaWiki
4 *
5 * Copyright (C) 2008-2009, PediaPress GmbH
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License along
18 * with this program; if not, write to the Free Software Foundation, Inc.,
19 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20 * http://www.gnu.org/copyleft/gpl.html
21 */
22
23namespace MediaWiki\Extension\Collection;
24
25use MediaWiki\Extension\Collection\Specials\SpecialCollection;
26use MediaWiki\Extension\Collection\Templates\CollectionSuggestTemplate;
27use MediaWiki\Session\SessionManager;
28use RequestContext;
29
30/**
31 * This class contains only static methods, so there's no need for a constructor.
32 * When the page Special:Book/suggest/ is loaded the method run() is called.
33 * Ajax calls refresh().
34 * When clearing a book the method clear() should be called.
35 */
36class Suggest {
37
38    /**
39     * Main entrypoint
40     *
41     * @param string $mode
42     *        'add' => add one title to the book.
43     *        'addAll' => Add a list of titles to the book.
44     *        'ban' => Ban a title from the proposals.
45     *        'unban' => Undo a ban.
46     *        'remove' => Remove a title from the book, and ban it.
47     *        'removeOnly' => Remove a title without banning it.
48     * @param string|string[] $param Name of the article to be added, banned
49     *        or removed, or a list of article names to be added.
50     */
51    public static function run( $mode = '', $param = '' ) {
52        if ( !Session::hasSession() ) {
53            Session::startSession();
54        }
55
56        $template = self::getCollectionSuggestTemplate( $mode, $param );
57        $context = RequestContext::getMain();
58        $out = $context->getOutput();
59        $out->setPageTitleMsg( $context->msg( 'coll-suggest_title' ) );
60        $out->addModules( 'ext.collection.suggest' );
61        $out->addTemplate( $template );
62    }
63
64    /**
65     * Entrypoint for Ajax
66     *
67     * @param string $mode
68     *        'add' => add one title to the book.
69     *        'addAll' => Add a list of titles to the book.
70     *        'ban' => Ban a title from the proposals.
71     *        'unban' => Undo a ban.
72     *        'remove' => Remove a title from the book, and ban it.
73     *        'removeOnly' => Remove a title without banning it.
74     * @param string|string[] $param Name of the article to be added, banned
75     *        or removed, or a list of article names to be added.
76     * @return string[] HTML code for the proposallist and the memberlist
77     */
78    public static function refresh( $mode, $param ) {
79        $template = self::getCollectionSuggestTemplate( $mode, $param );
80        return [
81            'suggestions_html' => $template->getProposalList(),
82            'members_html' => $template->getMemberList(),
83            'num_pages' => wfMessage( 'coll-n_pages' )
84                ->numParams( Session::countArticles() )
85                ->escaped(),
86        ];
87    }
88
89    /**
90     * @param string $lastAction
91     * @param string|string[] $article
92     * @return string[] HTML
93     */
94    public static function undo( $lastAction, $article ) {
95        switch ( $lastAction ) {
96            case 'add':
97                $template = self::getCollectionSuggestTemplate( 'removeonly', $article );
98                break;
99            case 'ban':
100                $template = self::getCollectionSuggestTemplate( 'unban', $article );
101                break;
102            case 'remove':
103                $template = self::getCollectionSuggestTemplate( 'add', $article );
104                break;
105            default:
106                // FIXME: Is this even possible? Shouldn't this fail with an exception?
107                return [];
108        }
109        return [
110            'suggestions_html' => $template->getProposalList(),
111            'members_html' => $template->getMemberList(),
112        ];
113    }
114
115    /**
116     * Remove the suggestion data from the session
117     */
118    public static function clear() {
119        $session = SessionManager::getGlobalSession();
120
121        if ( isset( $session['wsCollectionSuggestBan'] ) ) {
122            unset( $session['wsCollectionSuggestBan'] );
123        }
124        if ( isset( $session['wsCollectionSuggestProp'] ) ) {
125            unset( $session['wsCollectionSuggestProp'] );
126        }
127    }
128
129    /**
130     * @param string $article
131     */
132    private static function unban( $article ) {
133        $session = SessionManager::getGlobalSession();
134
135        if ( !isset( $session['wsCollectionSuggestBan'] ) ) {
136            return;
137        }
138        $bans = $session['wsCollectionSuggestBan'];
139        $newbans = [];
140        foreach ( $bans as $ban ) {
141            if ( $ban != $article ) {
142                $newbans[] = $ban;
143            }
144        }
145        $session['wsCollectionSuggestBan'] = $newbans;
146    }
147
148    /**
149     * Update the session and return the template
150     *
151     * @param string $mode
152     *        'add' => add one title to the book.
153     *        'addAll' => Add a list of titles to the book.
154     *        'ban' => Ban a title from the proposals.
155     *        'unban' => Undo a ban.
156     *        'remove' => Remove a title from the book, and ban it.
157     *        'removeOnly' => Remove a title without banning it.
158     * @param string|string[] $param Name of the article to be added, banned
159     *        or removed, or a list of article names to be added.
160     * @return CollectionSuggestTemplate the template for the wikipage
161     */
162    private static function getCollectionSuggestTemplate( $mode, $param ) {
163        global $wgCollectionMaxSuggestions;
164
165        $session = SessionManager::getGlobalSession();
166
167        if ( !isset( $session['wsCollectionSuggestBan'] ) || $mode == 'resetbans' ) {
168            $session['wsCollectionSuggestBan'] = [];
169        }
170        if ( !isset( $session['wsCollectionSuggestProp'] ) ) {
171            $session['wsCollectionSuggestProp'] = [];
172        }
173
174        switch ( $mode ) {
175            case 'add':
176                SpecialCollection::addArticleFromName( NS_MAIN, $param );
177                self::unban( $param );
178                break;
179            case 'ban':
180                $session['wsCollectionSuggestBan'][] = $param;
181                break;
182            case 'remove':
183                SpecialCollection::removeArticleFromName( NS_MAIN, $param );
184                $session['wsCollectionSuggestBan'][] = $param;
185                break;
186            case 'removeonly': // remove w/out banning (for undo)
187                SpecialCollection::removeArticleFromName( NS_MAIN, $param );
188                break;
189            case 'unban': // for undo
190                self::unban( $param );
191                break;
192        }
193
194        $template = new CollectionSuggestTemplate();
195        $proposals = new Proposals(
196            $session['wsCollection'],
197            $session['wsCollectionSuggestBan'],
198            $session['wsCollectionSuggestProp']
199        );
200
201        if ( $mode == 'addAll' ) {
202            self::addArticlesFromName( $param, $proposals );
203        }
204
205        $template->set( 'collection', $session['wsCollection'] );
206        $template->set( 'proposals', $proposals->getProposals( $wgCollectionMaxSuggestions ) );
207        $template->set( 'hasbans', $proposals->hasBans() );
208        $template->set( 'num_pages', Session::countArticles() );
209
210        $session['wsCollectionSuggestProp'] = $proposals->getLinkList();
211
212        return $template;
213    }
214
215    /**
216     * Add some articles and update the book of the Proposal-Object
217     *
218     * @param array $articleList with the names of the articles to be added
219     * @param Proposals $prop
220     */
221    private static function addArticlesFromName( $articleList, Proposals $prop ) {
222        $session = SessionManager::getGlobalSession();
223        foreach ( $articleList as $article ) {
224            SpecialCollection::addArticleFromName( NS_MAIN, $article );
225        }
226        $prop->setCollection( $session['wsCollection'] );
227    }
228}