Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 92
0.00% covered (danger)
0.00%
0 / 11
CRAP
0.00% covered (danger)
0.00%
0 / 1
EchoPageLinkedPresentationModel
0.00% covered (danger)
0.00%
0 / 92
0.00% covered (danger)
0.00%
0 / 11
600
0.00% covered (danger)
0.00%
0 / 1
 getIconType
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 canRender
0.00% covered (danger)
0.00%
0 / 3
0.00% covered (danger)
0.00%
0 / 1
6
 getPrimaryLink
0.00% covered (danger)
0.00%
0 / 12
0.00% covered (danger)
0.00%
0 / 1
12
 getSecondaryLinks
0.00% covered (danger)
0.00%
0 / 9
0.00% covered (danger)
0.00%
0 / 1
2
 getMuteLink
0.00% covered (danger)
0.00%
0 / 42
0.00% covered (danger)
0.00%
0 / 1
30
 getHeaderMessageKey
0.00% covered (danger)
0.00%
0 / 3
0.00% covered (danger)
0.00%
0 / 1
6
 getHeaderMessage
0.00% covered (danger)
0.00%
0 / 7
0.00% covered (danger)
0.00%
0 / 1
2
 getCompactHeaderMessage
0.00% covered (danger)
0.00%
0 / 3
0.00% covered (danger)
0.00%
0 / 1
2
 getLinkedPageId
0.00% covered (danger)
0.00%
0 / 8
0.00% covered (danger)
0.00%
0 / 1
30
 getPageFrom
0.00% covered (danger)
0.00%
0 / 3
0.00% covered (danger)
0.00%
0 / 1
6
 getSubjectMessageKey
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
1<?php
2
3namespace MediaWiki\Extension\Notifications\Formatters;
4
5use MediaWiki\Extension\Notifications\Controller\NotificationController;
6use MediaWiki\Extension\Notifications\Model\Event;
7use MediaWiki\MediaWikiServices;
8use MediaWiki\SpecialPage\SpecialPage;
9use MediaWiki\Title\Title;
10
11class EchoPageLinkedPresentationModel extends EchoEventPresentationModel {
12
13    /** @var Title|null */
14    private $pageFrom;
15
16    public function getIconType() {
17        return 'linked';
18    }
19
20    /**
21     * The page containing the link may be a new page
22     * that is not yet replicated.
23     * This event won't be rendered unless/until
24     * both pages are available.
25     * @return bool
26     */
27    public function canRender() {
28        $pageTo = $this->event->getTitle();
29        $pageFrom = $this->getPageFrom();
30        return (bool)$pageTo && (bool)$pageFrom;
31    }
32
33    public function getPrimaryLink() {
34        if ( $this->isBundled() ) {
35            return false;
36        } else {
37            $params = [];
38            if ( $this->event->getExtraParam( 'revid' ) ) {
39                $params = [
40                    'oldid' => 'prev',
41                    'diff' => $this->event->getExtraParam( 'revid' )
42                ];
43            }
44
45            return [
46                'url' => $this->getPageFrom()->getFullURL( $params ),
47                'label' => $this->msg( 'notification-link-text-view-page' )->text(),
48            ];
49        }
50    }
51
52    public function getSecondaryLinks() {
53        $whatLinksHereLink = [
54            'url' => SpecialPage::getTitleFor( 'Whatlinkshere', $this->event->getTitle()->getPrefixedText() )
55                ->getFullURL(),
56            'label' => $this->msg( 'notification-link-text-what-links-here' )->text(),
57            'description' => '',
58            'icon' => 'linked',
59            'prioritized' => true
60        ];
61
62        return [ $whatLinksHereLink, $this->getMuteLink() ];
63    }
64
65    protected function getMuteLink() {
66        if ( !MediaWikiServices::getInstance()->getMainConfig()->get( 'EchoPerUserBlacklist' ) ) {
67            return null;
68        }
69        $title = $this->event->getTitle();
70        $isPageMuted = NotificationController::isPageLinkedTitleMutedByUser( $title, $this->getUser() );
71        $action = $isPageMuted ? 'unmute' : 'mute';
72        $prefTitle = SpecialPage::getTitleFor( 'Preferences', false, 'mw-prefsection-echo-mutedpageslist' );
73        $data = [
74            'tokenType' => 'csrf',
75            'params' => [
76                'action' => 'echomute',
77                'type' => 'page-linked-title',
78            ],
79            'messages' => [
80                'confirmation' => [
81                    // notification-dynamic-actions-mute-page-linked-confirmation
82                    // notification-dynamic-actions-unmute-page-linked-confirmation
83                    'title' => $this
84                        ->msg( 'notification-dynamic-actions-' . $action . '-page-linked-confirmation' )
85                        ->params(
86                            $this->getTruncatedTitleText( $title ),
87                            $this->getViewingUserForGender()
88                        ),
89                    // notification-dynamic-actions-mute-page-linked-confirmation-description
90                    // notification-dynamic-actions-unmute-page-linked-confirmation-description
91                    'description' => $this
92                        ->msg( 'notification-dynamic-actions-' . $action . '-page-linked-confirmation-description' )
93                        ->params(
94                            $prefTitle->getFullURL(),
95                            $this->getViewingUserForGender()
96                        )
97                ]
98            ]
99        ];
100        $data['params'][$isPageMuted ? 'unmute' : 'mute'] = $title->getPrefixedText();
101
102        return $this->getDynamicActionLink(
103            $prefTitle,
104            $isPageMuted ? 'bell' : 'unbell',
105            // notification-dynamic-actions-mute-page-linked
106            // notification-dynamic-actions-unmute-page-linked
107            $this->msg( 'notification-dynamic-actions-' . $action . '-page-linked' )
108                ->params(
109                    $this->getTruncatedTitleText( $title ),
110                    $this->getViewingUserForGender()
111                )->text(),
112            null,
113            $data,
114            []
115        );
116    }
117
118    protected function getHeaderMessageKey() {
119        if ( $this->getBundleCount( true, [ $this, 'getLinkedPageId' ] ) > 1 ) {
120            return 'notification-bundle-header-page-linked';
121        }
122        return 'notification-header-page-linked';
123    }
124
125    public function getHeaderMessage() {
126        $msg = parent::getHeaderMessage();
127        $msg->params( $this->getTruncatedTitleText( $this->event->getTitle(), true ) );
128        $msg->params( $this->getTruncatedTitleText( $this->getPageFrom(), true ) );
129        $count =
130            $this->getNotificationCountForOutput( true, [ $this, 'getLinkedPageId' ] );
131
132        // Repeat is B/C until unused parameter is removed from translations
133        $msg->numParams( $count, $count );
134        return $msg;
135    }
136
137    public function getCompactHeaderMessage() {
138        $msg = $this->msg( parent::getCompactHeaderMessageKey() );
139        $msg->params( $this->getTruncatedTitleText( $this->getPageFrom(), true ) );
140        return $msg;
141    }
142
143    /**
144     * Get the page ID of the linked-from page for a given event.
145     * @param Event $event page-linked event
146     * @return int Page ID, or 0 if the page doesn't exist
147     */
148    public function getLinkedPageId( Event $event ) {
149        $extra = $event->getExtra();
150        if ( isset( $extra['link-from-page-id'] ) ) {
151            return $extra['link-from-page-id'];
152        }
153        // Backwards compatibility for events from before https://gerrit.wikimedia.org/r/#/c/63076
154        if ( isset( $extra['link-from-namespace'] ) && isset( $extra['link-from-title'] ) ) {
155            $title = Title::makeTitleSafe( $extra['link-from-namespace'], $extra['link-from-title'] );
156            if ( $title ) {
157                return $title->getArticleID();
158            }
159        }
160        return 0;
161    }
162
163    private function getPageFrom() {
164        if ( !$this->pageFrom ) {
165            $this->pageFrom = Title::newFromID( $this->getLinkedPageId( $this->event ) );
166        }
167        return $this->pageFrom;
168    }
169
170    protected function getSubjectMessageKey() {
171        return 'notification-page-linked-email-subject';
172    }
173}