Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 104
0.00% covered (danger)
0.00%
0 / 2
CRAP
0.00% covered (danger)
0.00%
0 / 1
CampaignPageFormatter
0.00% covered (danger)
0.00%
0 / 104
0.00% covered (danger)
0.00%
0 / 2
42
0.00% covered (danger)
0.00%
0 / 1
 __construct
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 1
2
 fillParserOutput
0.00% covered (danger)
0.00%
0 / 100
0.00% covered (danger)
0.00%
0 / 1
30
1<?php
2
3namespace MediaWiki\Extension\MediaUploader\Campaign;
4
5use Html;
6use ImageGalleryBase;
7use MediaWiki\Extension\MediaUploader\Config\CampaignParsedConfig;
8use MediaWiki\Extension\MediaUploader\MediaUploaderServices;
9use MWException;
10use ParserOutput;
11use RequestContext;
12use Skin;
13use Title;
14
15/**
16 * Helper class to produce formatted HTML output for campaigns
17 */
18class CampaignPageFormatter {
19
20    /** @var CampaignRecord */
21    private $record;
22
23    /** @var CampaignParsedConfig */
24    private $config;
25
26    /** @var CampaignStats */
27    private $campaignStats;
28
29    /** @var RequestContext */
30    private $context;
31
32    public function __construct(
33        CampaignRecord $campaignRecord,
34        CampaignParsedConfig $config
35    ) {
36        $this->record = $campaignRecord;
37        $this->config = $config;
38
39        // TODO: use DI
40        $this->campaignStats = MediaUploaderServices::getCampaignStats();
41        // No way to get rid of this for now.
42        // Blockers: ImageGalleryBase and message localization.
43        $this->context = RequestContext::getMain();
44    }
45
46    /**
47     * @param ParserOutput $output
48     *
49     * @return void
50     * @throws MWException
51     */
52    public function fillParserOutput( ParserOutput $output ): void {
53        $campaignTitle = Title::makeTitle(
54            NS_CAMPAIGN,
55            $this->record->getPage()->getDBkey()
56        );
57        $campaignName = $this->config->getSetting(
58            'title',
59            $campaignTitle->getText()
60        );
61
62        $campaignDescription = $this->config->getSetting( 'description', '' );
63        $trackingCat = Title::newFromText(
64            $this->record->getTrackingCategoryName( $this->config ),
65            NS_CATEGORY
66        );
67        $campaignViewMoreLink = $trackingCat ? $trackingCat->getFullURL() : '';
68
69        $outputPage = $this->context->getOutput();
70        $outputPage->setCdnMaxage(
71            $this->config->getSetting( 'campaignCdnMaxAge' )
72        );
73        $outputPage->enableOOUI();
74
75        $stats = $this->campaignStats->getStatsForRecord( $this->record ) ?? [];
76        $images = $stats['uploadedMedia'] ?? [];
77
78        if ( $this->context->getUser()->isAnon() ) {
79            $urlParams = [ 'returnto' => $campaignTitle->getPrefixedText() ];
80            $createAccountUrl = Skin::makeSpecialUrlSubpage( 'Userlogin', 'signup', $urlParams );
81            $uploadLink = new \OOUI\ButtonWidget( [
82                'label' => $this->context->msg( 'mediauploader-campaign-create-account-button' )->text(),
83                'flags' => [ 'progressive', 'primary' ],
84                'href' => $createAccountUrl
85            ] );
86        } else {
87            $uploadUrl = Skin::makeSpecialUrl(
88                'MediaUploader', [ 'campaign' => $this->record->getPage()->getDBkey() ]
89            );
90            $uploadLink = new \OOUI\ButtonWidget( [
91                'label' => $this->context->msg( 'mediauploader-campaign-upload-button' )->text(),
92                'flags' => [ 'progressive', 'primary' ],
93                'href' => $uploadUrl
94            ] );
95        }
96
97        if ( $images === [] ) {
98            $body = Html::element(
99                'div',
100                [ 'id' => 'mw-campaign-no-uploads-yet' ],
101                $this->context->msg( 'mediauploader-campaign-no-uploads-yet' )->plain()
102            );
103        } else {
104            $gallery = ImageGalleryBase::factory( 'packed-hover', $this->context );
105            $gallery->setShowBytes( false );
106
107            foreach ( $images as $image ) {
108                $gallery->add( Title::newFromText( $image, NS_FILE ) );
109            }
110
111            $body =
112                Html::rawElement( 'div', [ 'id' => 'mw-campaign-images' ], $gallery->toHTML() ) .
113                Html::rawElement( 'a',
114                    [ 'id' => 'mw-campaign-view-all', 'href' => $campaignViewMoreLink ],
115                    Html::rawElement(
116                        'span',
117                        [ 'class' => 'mw-campaign-chevron mw-campaign-float-left' ], '&nbsp;'
118                    ) .
119                    $this->context->msg( 'mediauploader-campaign-view-all-media' )->escaped() .
120                    Html::rawElement(
121                        'span',
122                        [ 'class' => 'mw-campaign-chevron mw-campaign-float-right' ], '&nbsp;'
123                    )
124                );
125        }
126
127        $contributorsCount = $stats['contributorsCount'] ?? 0;
128        $campaignExpensiveStats =
129            Html::rawElement( 'div', [ 'class' => 'mw-campaign-number-container' ],
130                Html::element( 'div', [ 'class' => 'mw-campaign-number' ],
131                    $this->context->getLanguage()->formatNum( $contributorsCount ) ) .
132                Html::element( 'span',
133                    [ 'class' => 'mw-campaign-number-desc' ],
134                    $this->context->msg( 'mediauploader-campaign-contributors-count-desc' )
135                    ->numParams( $contributorsCount )
136                    ->text()
137                )
138            );
139
140        $uploadCount = $stats['uploadedMediaCount'] ?? 0;
141        $result =
142            Html::rawElement( 'div', [ 'id' => 'mw-campaign-container' ],
143                Html::rawElement( 'div', [ 'id' => 'mw-campaign-header' ],
144                    Html::rawElement( 'div', [ 'id' => 'mw-campaign-primary-info' ],
145                        // No need to escape these, since they are just parsed wikitext
146                        // Any stripping that needed to be done should've been done by the parser
147                        Html::rawElement( 'p', [ 'id' => 'mw-campaign-title' ], $campaignName ) .
148                        Html::rawElement( 'p', [ 'id' => 'mw-campaign-description' ], $campaignDescription ) .
149                    $uploadLink
150                    ) .
151                    Html::rawElement( 'div', [ 'id' => 'mw-campaign-numbers' ],
152                        $campaignExpensiveStats .
153                        Html::rawElement( 'div', [ 'class' => 'mw-campaign-number-container' ],
154                            Html::element( 'div', [ 'class' => 'mw-campaign-number' ],
155                                $this->context->getLanguage()->formatNum( $uploadCount )
156                            ) .
157                            Html::element( 'span',
158                                [ 'class' => 'mw-campaign-number-desc' ],
159                                $this->context->msg( 'mediauploader-campaign-media-count-desc' )
160                                ->numParams( $uploadCount )
161                                ->text()
162                            )
163                        )
164                    )
165                ) .
166                $body
167            );
168        $output->setText( $result );
169    }
170}