Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 79
0.00% covered (danger)
0.00%
0 / 5
CRAP
0.00% covered (danger)
0.00%
0 / 1
Campaigns
0.00% covered (danger)
0.00%
0 / 79
0.00% covered (danger)
0.00%
0 / 5
132
0.00% covered (danger)
0.00%
0 / 1
 __construct
0.00% covered (danger)
0.00%
0 / 3
0.00% covered (danger)
0.00%
0 / 1
2
 execute
0.00% covered (danger)
0.00%
0 / 28
0.00% covered (danger)
0.00%
0 / 1
30
 getHtmlForCampaign
0.00% covered (danger)
0.00%
0 / 39
0.00% covered (danger)
0.00%
0 / 1
12
 getHtmlForPagination
0.00% covered (danger)
0.00%
0 / 8
0.00% covered (danger)
0.00%
0 / 1
2
 getGroupName
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
1<?php
2
3namespace MediaWiki\Extension\MediaUploader\Special;
4
5use Html;
6use LogicException;
7use MediaWiki\Extension\MediaUploader\Campaign\CampaignRecord;
8use MediaWiki\Extension\MediaUploader\Campaign\CampaignStore;
9use MediaWiki\Extension\MediaUploader\Campaign\Exception\BaseCampaignException;
10use MediaWiki\Extension\MediaUploader\Config\ConfigFactory;
11use ParserOptions;
12use SpecialPage;
13use Title;
14
15class Campaigns extends SpecialPage {
16
17    /** @var CampaignStore */
18    private $campaignStore;
19
20    /** @var ConfigFactory */
21    private $configFactory;
22
23    public function __construct(
24        CampaignStore $campaignStore,
25        ConfigFactory $configFactory
26    ) {
27        parent::__construct( 'Campaigns' );
28
29        $this->campaignStore = $campaignStore;
30        $this->configFactory = $configFactory;
31    }
32
33    /**
34     * @param string|null $subPage
35     */
36    public function execute( $subPage ) {
37        $request = $this->getRequest();
38        $start = $request->getIntOrNull( 'start' );
39        $limit = 50;
40
41        $queryBuilder = $this->campaignStore->newSelectQueryBuilder()
42            // TODO: we show all campaigns, add an option to filter by enabled.
43            //  Also display whether the campaign is enabled or not.
44            //->whereEnabled( true )
45            ->orderByIdAsc()
46            ->option( 'LIMIT', $limit + 1 );
47
48        if ( $start !== null ) {
49            $queryBuilder->where( "campaign_page_id > $start" );
50        }
51
52        $this->getOutput()->setPageTitle( $this->msg( 'mediauploader-campaigns-list-title' ) );
53        $this->getOutput()->addModules( 'ext.uploadWizard.uploadCampaign.list' );
54        $this->getOutput()->addHTML( '<dl>' );
55
56        $curCount = 0;
57        $lastId = null;
58        $records = $queryBuilder->fetchCampaignRecords(
59            CampaignStore::SELECT_TITLE | CampaignStore::SELECT_CONTENT
60        );
61
62        foreach ( $records as $record ) {
63            $curCount++;
64
65            if ( $curCount > $limit ) {
66                // We've got an extra element. Paginate!
67                $lastId = $record->getPageId();
68                break;
69            }
70
71            $this->getOutput()->addHTML( $this->getHtmlForCampaign( $record ) );
72        }
73        $this->getOutput()->addHTML( '</dl>' );
74
75        // Pagination links!
76        if ( $lastId !== null ) {
77            $this->getOutput()->addHTML( $this->getHtmlForPagination( $lastId ) );
78        }
79    }
80
81    /**
82     * @param CampaignRecord $record
83     *
84     * @return string
85     */
86    private function getHtmlForCampaign( CampaignRecord $record ): string {
87        $pageRef = $record->getPage();
88        if ( $pageRef === null ) {
89            // Should never happen. The 'if' is here to make Phan happy.
90            throw new LogicException( 'Title for Campaign was expected to be set.' );
91        }
92        $title = Title::makeTitle( NS_CAMPAIGN, $pageRef->getDBkey() );
93
94        try {
95            $campaignConfig = $this->configFactory->newCampaignConfig(
96                ParserOptions::newFromUserAndLang(
97                    $this->getUser(),
98                    $this->getLanguage()
99                ),
100                $record,
101                $title
102            );
103        } catch ( BaseCampaignException $ex ) {
104            // Display an error
105            return Html::rawElement(
106                'dt',
107                [],
108                Html::Element(
109                    'a',
110                    [ 'href' => $title->getLocalURL() ],
111                    $ex->getMessage()
112                )
113            );
114        }
115
116        return Html::rawElement(
117            'dt',
118            [],
119            Html::rawElement(
120                'a',
121                [ 'href' => $title->getLocalURL() ],
122                $campaignConfig->getSetting(
123                    'title',
124                    // Escape the raw title
125                    htmlspecialchars( $title->getText() )
126                )
127            )
128        ) .
129        Html::rawElement(
130            'dd',
131            [],
132            $campaignConfig->getSetting( 'description', '' )
133        );
134    }
135
136    /**
137     * @param int $firstId
138     *
139     * @return string
140     */
141    private function getHtmlForPagination( $firstId ) {
142        $nextHref = $this->getPageTitle()->getLocalURL( [ 'start' => $firstId ] );
143        return Html::rawElement( 'div',
144            [ 'id' => 'mediauploader-campaigns-pagination' ],
145            Html::element( 'a',
146                [ 'href' => $nextHref ],
147                $this->msg( 'mediauploader-campaigns-pagination-next' )->text()
148            )
149        );
150    }
151
152    /**
153     * @inheritDoc
154     */
155    protected function getGroupName() {
156        return 'media';
157    }
158}