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