Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 78
0.00% covered (danger)
0.00%
0 / 11
CRAP
0.00% covered (danger)
0.00%
0 / 1
EchoCoreThanksPresentationModel
0.00% covered (danger)
0.00%
0 / 78
0.00% covered (danger)
0.00%
0 / 11
992
0.00% covered (danger)
0.00%
0 / 1
 canRender
0.00% covered (danger)
0.00%
0 / 7
0.00% covered (danger)
0.00%
0 / 1
20
 getIconType
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getHeaderMessage
0.00% covered (danger)
0.00%
0 / 13
0.00% covered (danger)
0.00%
0 / 1
12
 getCompactHeaderMessage
0.00% covered (danger)
0.00%
0 / 3
0.00% covered (danger)
0.00%
0 / 1
2
 getBodyMessage
0.00% covered (danger)
0.00%
0 / 6
0.00% covered (danger)
0.00%
0 / 1
6
 getRevisionEditSummary
0.00% covered (danger)
0.00%
0 / 7
0.00% covered (danger)
0.00%
0 / 1
20
 getRevOrLogComment
0.00% covered (danger)
0.00%
0 / 15
0.00% covered (danger)
0.00%
0 / 1
42
 getPrimaryLink
0.00% covered (danger)
0.00%
0 / 13
0.00% covered (danger)
0.00%
0 / 1
6
 getSecondaryLinks
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 1
6
 getLogEntry
0.00% covered (danger)
0.00%
0 / 8
0.00% covered (danger)
0.00%
0 / 1
20
 getThankType
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
6
1<?php
2
3namespace MediaWiki\Extension\Thanks;
4
5use DatabaseLogEntry;
6use LogEntry;
7use LogPage;
8use MediaWiki\Extension\Notifications\Formatters\EchoEventPresentationModel;
9use MediaWiki\Language\RawMessage;
10use MediaWiki\MediaWikiServices;
11use MediaWiki\Parser\Sanitizer;
12use MediaWiki\Revision\RevisionRecord;
13use MediaWiki\SpecialPage\SpecialPage;
14
15class EchoCoreThanksPresentationModel extends EchoEventPresentationModel {
16    /** @var LogEntry|bool|null */
17    private $logEntry;
18
19    /** @inheritDoc */
20    public function canRender() {
21        $hasTitle = (bool)$this->event->getTitle();
22        if ( $hasTitle && $this->getThankType() === 'log' ) {
23            $logEntry = $this->getLogEntry();
24            return $logEntry && !(
25                // the notification renders the message on Special:Log without the comment,
26                // so check $logEntry is not deleted, or only its comment is deleted
27                $logEntry->getDeleted() & ~LogPage::DELETED_COMMENT
28            );
29        }
30        return $hasTitle;
31    }
32
33    /** @inheritDoc */
34    public function getIconType() {
35        return 'thanks';
36    }
37
38    /** @inheritDoc */
39    public function getHeaderMessage() {
40        $type = $this->getThankType();
41        if ( $this->isBundled() ) {
42            // Message is either notification-bundle-header-rev-thank
43            // or notification-bundle-header-log-thank.
44            $msg = $this->msg( "notification-bundle-header-$type-thank" );
45            $msg->params( $this->getBundleCount() );
46            $msg->params( $this->getTruncatedTitleText( $this->event->getTitle(), true ) );
47            $msg->params( $this->getViewingUserForGender() );
48            return $msg;
49        } else {
50            if ( $this->event->getExtraParam( 'revcreation', null ) ) {
51                // This is a thank on a page creation revision.
52                $msg = $this->getMessageWithAgent( "notification-header-creation-thank" );
53            } else {
54                // Message is either notification-header-rev-thank or notification-header-log-thank.
55                $msg = $this->getMessageWithAgent( "notification-header-$type-thank" );
56            }
57            $msg->params( $this->getTruncatedTitleText( $this->event->getTitle(), true ) );
58            $msg->params( $this->getViewingUserForGender() );
59            return $msg;
60        }
61    }
62
63    /** @inheritDoc */
64    public function getCompactHeaderMessage() {
65        // The following message is used here:
66        // * notification-compact-header-edit-thank
67        $msg = parent::getCompactHeaderMessage();
68        $msg->params( $this->getViewingUserForGender() );
69        return $msg;
70    }
71
72    /** @inheritDoc */
73    public function getBodyMessage() {
74        $comment = $this->getRevOrLogComment();
75        if ( $comment !== '' ) {
76            $msg = new RawMessage( '$1' );
77            $msg->plaintextParams( $comment );
78            return $msg;
79        }
80        return false;
81    }
82
83    /**
84     * @return string|bool The comment or false if it could not be retrieved.
85     */
86    private function getRevisionEditSummary() {
87        if ( !$this->userCan( RevisionRecord::DELETED_COMMENT ) ) {
88            return false;
89        }
90
91        $revision = $this->event->getRevision();
92        if ( !$revision ) {
93            return false;
94        }
95
96        $summary = $revision->getComment( RevisionRecord::RAW );
97        return $summary ? $summary->text : false;
98    }
99
100    /**
101     * Get the comment/summary/excerpt of the log entry or revision,
102     * for use in the notification body.
103     * @return string
104     */
105    protected function getRevOrLogComment(): string {
106        if ( $this->event->getExtraParam( 'logid' ) ) {
107            $logEntry = $this->getLogEntry();
108            if ( !$logEntry ) {
109                return '';
110            }
111            $services = MediaWikiServices::getInstance();
112            $formatter = $services->getLogFormatterFactory()->newFromEntry( $logEntry );
113            $excerpt = $formatter->getPlainActionText();
114            // Turn wikitext into plaintext
115            $excerpt = $services->getCommentFormatter()->format( $excerpt );
116            return Sanitizer::stripAllTags( $excerpt );
117        } else {
118            // Try to get edit summary.
119            $summary = $this->getRevisionEditSummary();
120            if ( $summary !== false && $summary !== '' ) {
121                return $summary;
122            }
123            // Fallback on edit excerpt.
124            if ( $this->userCan( RevisionRecord::DELETED_TEXT ) ) {
125                return $this->event->getExtraParam( 'excerpt', '' );
126            }
127            return '';
128        }
129    }
130
131    /** @inheritDoc */
132    public function getPrimaryLink() {
133        $logId = $this->event->getExtraParam( 'logid' );
134        if ( $logId ) {
135            $url = SpecialPage::getTitleFor( 'Log' )->getLocalURL( [ 'logid' => $logId ] );
136            $label = 'notification-link-text-view-logentry';
137        } else {
138            $url = $this->event->getTitle()->getLocalURL( [
139                'oldid' => 'prev',
140                'diff' => $this->event->getExtraParam( 'revid' )
141            ] );
142            $label = 'notification-link-text-view-edit';
143        }
144        return [
145            'url' => $url,
146            // Label is only used for non-JS clients.
147            'label' => $this->msg( $label )->text(),
148        ];
149    }
150
151    /** @inheritDoc */
152    public function getSecondaryLinks() {
153        $pageLink = $this->getPageLink( $this->event->getTitle(), '', true );
154        if ( $this->isBundled() ) {
155            return [ $pageLink ];
156        } else {
157            return [ $this->getAgentLink(), $pageLink ];
158        }
159    }
160
161    /**
162     * @return LogEntry|false
163     */
164    private function getLogEntry() {
165        if ( $this->logEntry !== null ) {
166            return $this->logEntry;
167        }
168        $logId = $this->event->getExtraParam( 'logid' );
169        if ( !$logId ) {
170            $this->logEntry = false;
171        } else {
172            $dbr = MediaWikiServices::getInstance()->getConnectionProvider()->getReplicaDatabase();
173            $this->logEntry = DatabaseLogEntry::newFromId( $logId, $dbr ) ?: false;
174        }
175        return $this->logEntry;
176    }
177
178    /**
179     * Returns thank type
180     *
181     * @return string 'log' or 'rev'
182     */
183    private function getThankType() {
184        return $this->event->getExtraParam( 'logid' ) ? 'log' : 'rev';
185    }
186}