[ Index ]

PHP Cross Reference of MediaWiki-1.24.0

title

Body

[close]

/includes/ -> FeedUtils.php (source)

   1  <?php
   2  /**
   3   * Helper functions for feeds.
   4   *
   5   * This program is free software; you can redistribute it and/or modify
   6   * it under the terms of the GNU General Public License as published by
   7   * the Free Software Foundation; either version 2 of the License, or
   8   * (at your option) any later version.
   9   *
  10   * This program is distributed in the hope that it will be useful,
  11   * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13   * GNU General Public License for more details.
  14   *
  15   * You should have received a copy of the GNU General Public License along
  16   * with this program; if not, write to the Free Software Foundation, Inc.,
  17   * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  18   * http://www.gnu.org/copyleft/gpl.html
  19   *
  20   * @file
  21   * @ingroup Feed
  22   */
  23  
  24  /**
  25   * Helper functions for feeds
  26   *
  27   * @ingroup Feed
  28   */
  29  class FeedUtils {
  30  
  31      /**
  32       * Check whether feed's cache should be cleared; for changes feeds
  33       * If the feed should be purged; $timekey and $key will be removed from
  34       * $messageMemc
  35       *
  36       * @param string $timekey Cache key of the timestamp of the last item
  37       * @param string $key Cache key of feed's content
  38       */
  39  	public static function checkPurge( $timekey, $key ) {
  40          global $wgRequest, $wgUser, $messageMemc;
  41          $purge = $wgRequest->getVal( 'action' ) === 'purge';
  42          if ( $purge && $wgUser->isAllowed( 'purge' ) ) {
  43              $messageMemc->delete( $timekey );
  44              $messageMemc->delete( $key );
  45          }
  46      }
  47  
  48      /**
  49       * Check whether feeds can be used and that $type is a valid feed type
  50       *
  51       * @param string $type Feed type, as requested by the user
  52       * @return bool
  53       */
  54  	public static function checkFeedOutput( $type ) {
  55          global $wgOut, $wgFeed, $wgFeedClasses;
  56  
  57          if ( !$wgFeed ) {
  58              $wgOut->addWikiMsg( 'feed-unavailable' );
  59              return false;
  60          }
  61  
  62          if ( !isset( $wgFeedClasses[$type] ) ) {
  63              $wgOut->addWikiMsg( 'feed-invalid' );
  64              return false;
  65          }
  66  
  67          return true;
  68      }
  69  
  70      /**
  71       * Format a diff for the newsfeed
  72       *
  73       * @param object $row Row from the recentchanges table
  74       * @return string
  75       */
  76  	public static function formatDiff( $row ) {
  77          $titleObj = Title::makeTitle( $row->rc_namespace, $row->rc_title );
  78          $timestamp = wfTimestamp( TS_MW, $row->rc_timestamp );
  79          $actiontext = '';
  80          if ( $row->rc_type == RC_LOG ) {
  81              $rcRow = (array)$row; // newFromRow() only accepts arrays for RC rows
  82              $actiontext = LogFormatter::newFromRow( $rcRow )->getActionText();
  83          }
  84          return self::formatDiffRow( $titleObj,
  85              $row->rc_last_oldid, $row->rc_this_oldid,
  86              $timestamp,
  87              $row->rc_deleted & Revision::DELETED_COMMENT
  88                  ? wfMessage( 'rev-deleted-comment' )->escaped()
  89                  : $row->rc_comment,
  90              $actiontext
  91          );
  92      }
  93  
  94      /**
  95       * Really format a diff for the newsfeed
  96       *
  97       * @param Title $title Title object
  98       * @param int $oldid Old revision's id
  99       * @param int $newid New revision's id
 100       * @param int $timestamp New revision's timestamp
 101       * @param string $comment New revision's comment
 102       * @param string $actiontext Text of the action; in case of log event
 103       * @return string
 104       */
 105  	public static function formatDiffRow( $title, $oldid, $newid, $timestamp,
 106          $comment, $actiontext = ''
 107      ) {
 108          global $wgFeedDiffCutoff, $wgLang;
 109          wfProfileIn( __METHOD__ );
 110  
 111          // log entries
 112          $completeText = '<p>' . implode( ' ',
 113              array_filter(
 114                  array(
 115                      $actiontext,
 116                      Linker::formatComment( $comment ) ) ) ) . "</p>\n";
 117  
 118          // NOTE: Check permissions for anonymous users, not current user.
 119          //       No "privileged" version should end up in the cache.
 120          //       Most feed readers will not log in anyway.
 121          $anon = new User();
 122          $accErrors = $title->getUserPermissionsErrors( 'read', $anon, true );
 123  
 124          // Can't diff special pages, unreadable pages or pages with no new revision
 125          // to compare against: just return the text.
 126          if ( $title->getNamespace() < 0 || $accErrors || !$newid ) {
 127              wfProfileOut( __METHOD__ );
 128              return $completeText;
 129          }
 130  
 131          if ( $oldid ) {
 132              wfProfileIn( __METHOD__ . "-dodiff" );
 133  
 134              #$diffText = $de->getDiff( wfMessage( 'revisionasof',
 135              #    $wgLang->timeanddate( $timestamp ),
 136              #    $wgLang->date( $timestamp ),
 137              #    $wgLang->time( $timestamp ) )->text(),
 138              #    wfMessage( 'currentrev' )->text() );
 139  
 140              $diffText = '';
 141              // Don't bother generating the diff if we won't be able to show it
 142              if ( $wgFeedDiffCutoff > 0 ) {
 143                  $rev = Revision::newFromId( $oldid );
 144  
 145                  if ( !$rev ) {
 146                      $diffText = false;
 147                  } else {
 148                      $context = clone RequestContext::getMain();
 149                      $context->setTitle( $title );
 150  
 151                      $contentHandler = $rev->getContentHandler();
 152                      $de = $contentHandler->createDifferenceEngine( $context, $oldid, $newid );
 153                      $diffText = $de->getDiff(
 154                          wfMessage( 'previousrevision' )->text(), // hack
 155                          wfMessage( 'revisionasof',
 156                              $wgLang->timeanddate( $timestamp ),
 157                              $wgLang->date( $timestamp ),
 158                              $wgLang->time( $timestamp ) )->text() );
 159                  }
 160              }
 161  
 162              if ( $wgFeedDiffCutoff <= 0 || ( strlen( $diffText ) > $wgFeedDiffCutoff ) ) {
 163                  // Omit large diffs
 164                  $diffText = self::getDiffLink( $title, $newid, $oldid );
 165              } elseif ( $diffText === false ) {
 166                  // Error in diff engine, probably a missing revision
 167                  $diffText = "<p>Can't load revision $newid</p>";
 168              } else {
 169                  // Diff output fine, clean up any illegal UTF-8
 170                  $diffText = UtfNormal::cleanUp( $diffText );
 171                  $diffText = self::applyDiffStyle( $diffText );
 172              }
 173              wfProfileOut( __METHOD__ . "-dodiff" );
 174          } else {
 175              $rev = Revision::newFromId( $newid );
 176              if ( $wgFeedDiffCutoff <= 0 || is_null( $rev ) ) {
 177                  $newContent = ContentHandler::getForTitle( $title )->makeEmptyContent();
 178              } else {
 179                  $newContent = $rev->getContent();
 180              }
 181  
 182              if ( $newContent instanceof TextContent ) {
 183                  // only textual content has a "source view".
 184                  $text = $newContent->getNativeData();
 185  
 186                  if ( $wgFeedDiffCutoff <= 0 || strlen( $text ) > $wgFeedDiffCutoff ) {
 187                      $html = null;
 188                  } else {
 189                      $html = nl2br( htmlspecialchars( $text ) );
 190                  }
 191              } else {
 192                  //XXX: we could get an HTML representation of the content via getParserOutput, but that may
 193                  //     contain JS magic and generally may not be suitable for inclusion in a feed.
 194                  //     Perhaps Content should have a getDescriptiveHtml method and/or a getSourceText method.
 195                  //Compare also ApiFeedContributions::feedItemDesc
 196                  $html = null;
 197              }
 198  
 199              if ( $html === null ) {
 200  
 201                  // Omit large new page diffs, bug 29110
 202                  // Also use diff link for non-textual content
 203                  $diffText = self::getDiffLink( $title, $newid );
 204              } else {
 205                  $diffText = '<p><b>' . wfMessage( 'newpage' )->text() . '</b></p>' .
 206                      '<div>' . $html . '</div>';
 207              }
 208          }
 209          $completeText .= $diffText;
 210  
 211          wfProfileOut( __METHOD__ );
 212          return $completeText;
 213      }
 214  
 215      /**
 216       * Generates a diff link. Used when the full diff is not wanted for example
 217       * when $wgFeedDiffCutoff is 0.
 218       *
 219       * @param Title $title Title object: used to generate the diff URL
 220       * @param int $newid Newid for this diff
 221       * @param int|null $oldid Oldid for the diff. Null means it is a new article
 222       * @return string
 223       */
 224  	protected static function getDiffLink( Title $title, $newid, $oldid = null ) {
 225          $queryParameters = array( 'diff' => $newid );
 226          if ( $oldid != null ) {
 227              $queryParameters['oldid'] = $oldid;
 228          }
 229          $diffUrl = $title->getFullURL( $queryParameters );
 230  
 231          $diffLink = Html::element( 'a', array( 'href' => $diffUrl ),
 232              wfMessage( 'showdiff' )->inContentLanguage()->text() );
 233  
 234          return $diffLink;
 235      }
 236  
 237      /**
 238       * Hacky application of diff styles for the feeds.
 239       * Might be 'cleaner' to use DOM or XSLT or something,
 240       * but *gack* it's a pain in the ass.
 241       *
 242       * @param string $text Diff's HTML output
 243       * @return string Modified HTML
 244       */
 245  	public static function applyDiffStyle( $text ) {
 246          $styles = array(
 247              'diff'             => 'background-color: white; color:black;',
 248              'diff-otitle'      => 'background-color: white; color:black; text-align: center;',
 249              'diff-ntitle'      => 'background-color: white; color:black; text-align: center;',
 250              'diff-addedline'   => 'color:black; font-size: 88%; border-style: solid; '
 251                  . 'border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; '
 252                  . 'vertical-align: top; white-space: pre-wrap;',
 253              'diff-deletedline' => 'color:black; font-size: 88%; border-style: solid; '
 254                  . 'border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; '
 255                  . 'vertical-align: top; white-space: pre-wrap;',
 256              'diff-context'     => 'background-color: #f9f9f9; color: #333333; font-size: 88%; '
 257                  . 'border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; '
 258                  . 'border-color: #e6e6e6; vertical-align: top; white-space: pre-wrap;',
 259              'diffchange'       => 'font-weight: bold; text-decoration: none;',
 260          );
 261  
 262          foreach ( $styles as $class => $style ) {
 263              $text = preg_replace( "/(<[^>]+)class=(['\"])$class\\2([^>]*>)/",
 264                  "\\1style=\"$style\"\\3", $text );
 265          }
 266  
 267          return $text;
 268      }
 269  
 270  }


Generated: Fri Nov 28 14:03:12 2014 Cross-referenced by PHPXref 0.7.1