]> scripts.mit.edu Git - autoinstalls/mediawiki.git/blob - includes/FeedUtils.php
MediaWiki 1.16.4
[autoinstalls/mediawiki.git] / includes / FeedUtils.php
1 <?php
2
3 /**
4  * Helper functions for feeds
5  *
6  * @ingroup Feed
7  */
8 class FeedUtils {
9
10         /**
11          * Check whether feed's cache should be cleared; for changes feeds
12          * If the feed should be purged; $timekey and $key will be removed from
13          * $messageMemc
14          *
15          * @param $timekey String: cache key of the timestamp of the last item
16          * @param $key String: cache key of feed's content
17          */
18         public static function checkPurge( $timekey, $key ) {
19                 global $wgRequest, $wgUser, $messageMemc;
20                 $purge = $wgRequest->getVal( 'action' ) === 'purge';
21                 if ( $purge && $wgUser->isAllowed('purge') ) {
22                         $messageMemc->delete( $timekey );
23                         $messageMemc->delete( $key );
24                 }
25         }
26
27         /**
28          * Check whether feeds can be used and that $type is a valid feed type
29          *
30          * @param $type String: feed type, as requested by the user
31          * @return Boolean
32          */
33         public static function checkFeedOutput( $type ) {
34                 global $wgFeed, $wgFeedClasses;
35
36                 if ( !$wgFeed ) {
37                         global $wgOut;
38                         $wgOut->addWikiMsg( 'feed-unavailable' );
39                         return false;
40                 }
41
42                 if( !isset( $wgFeedClasses[$type] ) ) {
43                         wfHttpError( 500, "Internal Server Error", "Unsupported feed type." );
44                         return false;
45                 }
46
47                 return true;
48         }
49
50         /**
51          * Format a diff for the newsfeed
52          *
53          * @param $row Object: row from the recentchanges table
54          * @return String
55          */
56         public static function formatDiff( $row ) {
57                 global $wgUser;
58
59                 $titleObj = Title::makeTitle( $row->rc_namespace, $row->rc_title );
60                 $timestamp = wfTimestamp( TS_MW, $row->rc_timestamp );
61                 $actiontext = '';
62                 if( $row->rc_type == RC_LOG ) {
63                         if( $row->rc_deleted & LogPage::DELETED_ACTION ) {
64                                 $actiontext = wfMsgHtml('rev-deleted-event');
65                         } else {
66                                 $actiontext = LogPage::actionText( $row->rc_log_type, $row->rc_log_action,
67                                         $titleObj, $wgUser->getSkin(), LogPage::extractParams($row->rc_params,true,true) );
68                         }
69                 }
70                 return self::formatDiffRow( $titleObj,
71                         $row->rc_last_oldid, $row->rc_this_oldid,
72                         $timestamp,
73                         ($row->rc_deleted & Revision::DELETED_COMMENT) ? wfMsgHtml('rev-deleted-comment') : $row->rc_comment,
74                         $actiontext );
75         }
76
77         /**
78          * Really format a diff for the newsfeed
79          *
80          * @param $title Title object
81          * @param $oldid Integer: old revision's id
82          * @param $newid Integer: new revision's id
83          * @param $timestamp Integer: new revision's timestamp
84          * @param $comment String: new revision's comment
85          * @param $actiontext String: text of the action; in case of log event
86          * @return String
87          */
88         public static function formatDiffRow( $title, $oldid, $newid, $timestamp, $comment, $actiontext='' ) {
89                 global $wgFeedDiffCutoff, $wgContLang, $wgUser;
90                 wfProfileIn( __METHOD__ );
91
92                 $skin = $wgUser->getSkin();
93                 # log enties
94                 $completeText = '<p>' . implode( ' ',
95                         array_filter(
96                                 array(
97                                         $actiontext,
98                                         $skin->formatComment( $comment ) ) ) ) . "</p>\n";
99
100                 //NOTE: Check permissions for anonymous users, not current user.
101                 //      No "privileged" version should end up in the cache.
102                 //      Most feed readers will not log in anway.
103                 $anon = new User();
104                 $accErrors = $title->getUserPermissionsErrors( 'read', $anon, true );
105
106                 if( $title->getNamespace() >= 0 && !$accErrors && $newid ) {
107                         if( $oldid ) {
108                                 wfProfileIn( __METHOD__."-dodiff" );
109
110                                 #$diffText = $de->getDiff( wfMsg( 'revisionasof',
111                                 #       $wgContLang->timeanddate( $timestamp ),
112                                 #       $wgContLang->date( $timestamp ),
113                                 #       $wgContLang->time( $timestamp ) ),
114                                 #       wfMsg( 'currentrev' ) );
115                                 
116                                 // Don't bother generating the diff if we won't be able to show it
117                                 if ( $wgFeedDiffCutoff > 0 ) {
118                                         $de = new DifferenceEngine( $title, $oldid, $newid );
119                                         $diffText = $de->getDiff(
120                                                 wfMsg( 'previousrevision' ), // hack
121                                                 wfMsg( 'revisionasof',
122                                                         $wgContLang->timeanddate( $timestamp ),
123                                                         $wgContLang->date( $timestamp ),
124                                                         $wgContLang->time( $timestamp ) ) );
125                                 }
126
127                                 if ( ( strlen( $diffText ) > $wgFeedDiffCutoff ) || ( $wgFeedDiffCutoff <= 0 ) ) {
128                                         // Omit large diffs
129                                         $diffLink = $title->escapeFullUrl(
130                                                 'diff=' . $newid .
131                                                 '&oldid=' . $oldid );
132                                         $diffText = '<a href="' .
133                                                 $diffLink .
134                                                 '">' .
135                                                 htmlspecialchars( wfMsgForContent( 'showdiff' ) ) .
136                                                 '</a>';
137                                 } elseif ( $diffText === false ) {
138                                         // Error in diff engine, probably a missing revision
139                                         $diffText = "<p>Can't load revision $newid</p>";
140                                 } else {
141                                         // Diff output fine, clean up any illegal UTF-8
142                                         $diffText = UtfNormal::cleanUp( $diffText );
143                                         $diffText = self::applyDiffStyle( $diffText );
144                                 }
145                                 wfProfileOut( __METHOD__."-dodiff" );
146                         } else {
147                                 $rev = Revision::newFromId( $newid );
148                                 if( is_null( $rev ) ) {
149                                         $newtext = '';
150                                 } else {
151                                         $newtext = $rev->getText();
152                                 }
153                                 $diffText = '<p><b>' . wfMsg( 'newpage' ) . '</b></p>' .
154                                         '<div>' . nl2br( htmlspecialchars( $newtext ) ) . '</div>';
155                         }
156                         $completeText .= $diffText;
157                 }
158
159                 wfProfileOut( __METHOD__ );
160                 return $completeText;
161         }
162
163         /**
164          * Hacky application of diff styles for the feeds.
165          * Might be 'cleaner' to use DOM or XSLT or something,
166          * but *gack* it's a pain in the ass.
167          *
168          * @param $text String: diff's HTML output
169          * @return String: modified HTML
170          * @private
171          */
172         public static function applyDiffStyle( $text ) {
173                 $styles = array(
174                         'diff'             => 'background-color: white; color:black;',
175                         'diff-otitle'      => 'background-color: white; color:black;',
176                         'diff-ntitle'      => 'background-color: white; color:black;',
177                         'diff-addedline'   => 'background: #cfc; color:black; font-size: smaller;',
178                         'diff-deletedline' => 'background: #ffa; color:black; font-size: smaller;',
179                         'diff-context'     => 'background: #eee; color:black; font-size: smaller;',
180                         'diffchange'       => 'color: red; font-weight: bold; text-decoration: none;',
181                 );
182
183                 foreach( $styles as $class => $style ) {
184                         $text = preg_replace( "/(<[^>]+)class=(['\"])$class\\2([^>]*>)/",
185                                 "\\1style=\"$style\"\\3", $text );
186                 }
187
188                 return $text;
189         }
190
191 }