[ Index ]

PHP Cross Reference of MediaWiki-1.24.0

title

Body

[close]

/includes/api/ -> ApiEditPage.php (source)

   1  <?php
   2  /**
   3   *
   4   *
   5   * Created on August 16, 2007
   6   *
   7   * Copyright © 2007 Iker Labarga "<Firstname><Lastname>@gmail.com"
   8   *
   9   * This program is free software; you can redistribute it and/or modify
  10   * it under the terms of the GNU General Public License as published by
  11   * the Free Software Foundation; either version 2 of the License, or
  12   * (at your option) any later version.
  13   *
  14   * This program is distributed in the hope that it will be useful,
  15   * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  17   * GNU General Public License for more details.
  18   *
  19   * You should have received a copy of the GNU General Public License along
  20   * with this program; if not, write to the Free Software Foundation, Inc.,
  21   * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  22   * http://www.gnu.org/copyleft/gpl.html
  23   *
  24   * @file
  25   */
  26  
  27  /**
  28   * A module that allows for editing and creating pages.
  29   *
  30   * Currently, this wraps around the EditPage class in an ugly way,
  31   * EditPage.php should be rewritten to provide a cleaner interface
  32   * @ingroup API
  33   */
  34  class ApiEditPage extends ApiBase {
  35  	public function execute() {
  36          $user = $this->getUser();
  37          $params = $this->extractRequestParams();
  38  
  39          if ( is_null( $params['text'] ) && is_null( $params['appendtext'] ) &&
  40              is_null( $params['prependtext'] ) &&
  41              $params['undo'] == 0
  42          ) {
  43              $this->dieUsageMsg( 'missingtext' );
  44          }
  45  
  46          $pageObj = $this->getTitleOrPageId( $params );
  47          $titleObj = $pageObj->getTitle();
  48          $apiResult = $this->getResult();
  49  
  50          if ( $params['redirect'] ) {
  51              if ( $params['prependtext'] === null && $params['appendtext'] === null && $params['section'] !== 'new' ) {
  52                  $this->dieUsage( 'You have attempted to edit using the "redirect"-following mode, which must be used in conjuction with section=new, prependtext, or appendtext.', 'redirect-appendonly' );
  53              }
  54              if ( $titleObj->isRedirect() ) {
  55                  $oldTitle = $titleObj;
  56  
  57                  $titles = Revision::newFromTitle( $oldTitle, false, Revision::READ_LATEST )
  58                      ->getContent( Revision::FOR_THIS_USER, $user )
  59                      ->getRedirectChain();
  60                  // array_shift( $titles );
  61  
  62                  $redirValues = array();
  63  
  64                  /** @var $newTitle Title */
  65                  foreach ( $titles as $id => $newTitle ) {
  66  
  67                      if ( !isset( $titles[$id - 1] ) ) {
  68                          $titles[$id - 1] = $oldTitle;
  69                      }
  70  
  71                      $redirValues[] = array(
  72                          'from' => $titles[$id - 1]->getPrefixedText(),
  73                          'to' => $newTitle->getPrefixedText()
  74                      );
  75  
  76                      $titleObj = $newTitle;
  77                  }
  78  
  79                  $apiResult->setIndexedTagName( $redirValues, 'r' );
  80                  $apiResult->addValue( null, 'redirects', $redirValues );
  81  
  82                  // Since the page changed, update $pageObj
  83                  $pageObj = WikiPage::factory( $titleObj );
  84              }
  85          }
  86  
  87          if ( !isset( $params['contentmodel'] ) || $params['contentmodel'] == '' ) {
  88              $contentHandler = $pageObj->getContentHandler();
  89          } else {
  90              $contentHandler = ContentHandler::getForModelID( $params['contentmodel'] );
  91          }
  92  
  93          // @todo Ask handler whether direct editing is supported at all! make
  94          // allowFlatEdit() method or some such
  95  
  96          if ( !isset( $params['contentformat'] ) || $params['contentformat'] == '' ) {
  97              $params['contentformat'] = $contentHandler->getDefaultFormat();
  98          }
  99  
 100          $contentFormat = $params['contentformat'];
 101  
 102          if ( !$contentHandler->isSupportedFormat( $contentFormat ) ) {
 103              $name = $titleObj->getPrefixedDBkey();
 104              $model = $contentHandler->getModelID();
 105  
 106              $this->dieUsage( "The requested format $contentFormat is not supported for content model " .
 107                  " $model used by $name", 'badformat' );
 108          }
 109  
 110          if ( $params['createonly'] && $titleObj->exists() ) {
 111              $this->dieUsageMsg( 'createonly-exists' );
 112          }
 113          if ( $params['nocreate'] && !$titleObj->exists() ) {
 114              $this->dieUsageMsg( 'nocreate-missing' );
 115          }
 116  
 117          // Now let's check whether we're even allowed to do this
 118          $errors = $titleObj->getUserPermissionsErrors( 'edit', $user );
 119          if ( !$titleObj->exists() ) {
 120              $errors = array_merge( $errors, $titleObj->getUserPermissionsErrors( 'create', $user ) );
 121          }
 122          if ( count( $errors ) ) {
 123              $this->dieUsageMsg( $errors[0] );
 124          }
 125  
 126          $toMD5 = $params['text'];
 127          if ( !is_null( $params['appendtext'] ) || !is_null( $params['prependtext'] ) ) {
 128              $content = $pageObj->getContent();
 129  
 130              if ( !$content ) {
 131                  if ( $titleObj->getNamespace() == NS_MEDIAWIKI ) {
 132                      # If this is a MediaWiki:x message, then load the messages
 133                      # and return the message value for x.
 134                      $text = $titleObj->getDefaultMessageText();
 135                      if ( $text === false ) {
 136                          $text = '';
 137                      }
 138  
 139                      try {
 140                          $content = ContentHandler::makeContent( $text, $this->getTitle() );
 141                      } catch ( MWContentSerializationException $ex ) {
 142                          $this->dieUsage( $ex->getMessage(), 'parseerror' );
 143  
 144                          return;
 145                      }
 146                  } else {
 147                      # Otherwise, make a new empty content.
 148                      $content = $contentHandler->makeEmptyContent();
 149                  }
 150              }
 151  
 152              // @todo Add support for appending/prepending to the Content interface
 153  
 154              if ( !( $content instanceof TextContent ) ) {
 155                  $mode = $contentHandler->getModelID();
 156                  $this->dieUsage( "Can't append to pages using content model $mode", 'appendnotsupported' );
 157              }
 158  
 159              if ( !is_null( $params['section'] ) ) {
 160                  if ( !$contentHandler->supportsSections() ) {
 161                      $modelName = $contentHandler->getModelID();
 162                      $this->dieUsage(
 163                          "Sections are not supported for this content model: $modelName.",
 164                          'sectionsnotsupported'
 165                      );
 166                  }
 167  
 168                  if ( $params['section'] == 'new' ) {
 169                      // DWIM if they're trying to prepend/append to a new section.
 170                      $content = null;
 171                  } else {
 172                      // Process the content for section edits
 173                      $section = $params['section'];
 174                      $content = $content->getSection( $section );
 175  
 176                      if ( !$content ) {
 177                          $this->dieUsage( "There is no section {$section}.", 'nosuchsection' );
 178                      }
 179                  }
 180              }
 181  
 182              if ( !$content ) {
 183                  $text = '';
 184              } else {
 185                  $text = $content->serialize( $contentFormat );
 186              }
 187  
 188              $params['text'] = $params['prependtext'] . $text . $params['appendtext'];
 189              $toMD5 = $params['prependtext'] . $params['appendtext'];
 190          }
 191  
 192          if ( $params['undo'] > 0 ) {
 193              if ( $params['undoafter'] > 0 ) {
 194                  if ( $params['undo'] < $params['undoafter'] ) {
 195                      list( $params['undo'], $params['undoafter'] ) =
 196                          array( $params['undoafter'], $params['undo'] );
 197                  }
 198                  $undoafterRev = Revision::newFromID( $params['undoafter'] );
 199              }
 200              $undoRev = Revision::newFromID( $params['undo'] );
 201              if ( is_null( $undoRev ) || $undoRev->isDeleted( Revision::DELETED_TEXT ) ) {
 202                  $this->dieUsageMsg( array( 'nosuchrevid', $params['undo'] ) );
 203              }
 204  
 205              if ( $params['undoafter'] == 0 ) {
 206                  $undoafterRev = $undoRev->getPrevious();
 207              }
 208              if ( is_null( $undoafterRev ) || $undoafterRev->isDeleted( Revision::DELETED_TEXT ) ) {
 209                  $this->dieUsageMsg( array( 'nosuchrevid', $params['undoafter'] ) );
 210              }
 211  
 212              if ( $undoRev->getPage() != $pageObj->getID() ) {
 213                  $this->dieUsageMsg( array( 'revwrongpage', $undoRev->getID(),
 214                      $titleObj->getPrefixedText() ) );
 215              }
 216              if ( $undoafterRev->getPage() != $pageObj->getID() ) {
 217                  $this->dieUsageMsg( array( 'revwrongpage', $undoafterRev->getID(),
 218                      $titleObj->getPrefixedText() ) );
 219              }
 220  
 221              $newContent = $contentHandler->getUndoContent(
 222                  $pageObj->getRevision(),
 223                  $undoRev,
 224                  $undoafterRev
 225              );
 226  
 227              if ( !$newContent ) {
 228                  $this->dieUsageMsg( 'undo-failure' );
 229              }
 230  
 231              $params['text'] = $newContent->serialize( $params['contentformat'] );
 232  
 233              // If no summary was given and we only undid one rev,
 234              // use an autosummary
 235              if ( is_null( $params['summary'] ) &&
 236                  $titleObj->getNextRevisionID( $undoafterRev->getID() ) == $params['undo']
 237              ) {
 238                  $params['summary'] = wfMessage( 'undo-summary' )
 239                      ->params ( $params['undo'], $undoRev->getUserText() )->inContentLanguage()->text();
 240              }
 241          }
 242  
 243          // See if the MD5 hash checks out
 244          if ( !is_null( $params['md5'] ) && md5( $toMD5 ) !== $params['md5'] ) {
 245              $this->dieUsageMsg( 'hashcheckfailed' );
 246          }
 247  
 248          // EditPage wants to parse its stuff from a WebRequest
 249          // That interface kind of sucks, but it's workable
 250          $requestArray = array(
 251              'wpTextbox1' => $params['text'],
 252              'format' => $contentFormat,
 253              'model' => $contentHandler->getModelID(),
 254              'wpEditToken' => $params['token'],
 255              'wpIgnoreBlankSummary' => '',
 256              'wpIgnoreBlankArticle' => true
 257          );
 258  
 259          if ( !is_null( $params['summary'] ) ) {
 260              $requestArray['wpSummary'] = $params['summary'];
 261          }
 262  
 263          if ( !is_null( $params['sectiontitle'] ) ) {
 264              $requestArray['wpSectionTitle'] = $params['sectiontitle'];
 265          }
 266  
 267          // TODO: Pass along information from 'undoafter' as well
 268          if ( $params['undo'] > 0 ) {
 269              $requestArray['wpUndidRevision'] = $params['undo'];
 270          }
 271  
 272          // Watch out for basetimestamp == ''
 273          // wfTimestamp() treats it as NOW, almost certainly causing an edit conflict
 274          if ( !is_null( $params['basetimestamp'] ) && $params['basetimestamp'] != '' ) {
 275              $requestArray['wpEdittime'] = wfTimestamp( TS_MW, $params['basetimestamp'] );
 276          } else {
 277              $requestArray['wpEdittime'] = $pageObj->getTimestamp();
 278          }
 279  
 280          if ( !is_null( $params['starttimestamp'] ) && $params['starttimestamp'] != '' ) {
 281              $requestArray['wpStarttime'] = wfTimestamp( TS_MW, $params['starttimestamp'] );
 282          } else {
 283              $requestArray['wpStarttime'] = wfTimestampNow(); // Fake wpStartime
 284          }
 285  
 286          if ( $params['minor'] || ( !$params['notminor'] && $user->getOption( 'minordefault' ) ) ) {
 287              $requestArray['wpMinoredit'] = '';
 288          }
 289  
 290          if ( $params['recreate'] ) {
 291              $requestArray['wpRecreate'] = '';
 292          }
 293  
 294          if ( !is_null( $params['section'] ) ) {
 295              $section = $params['section'];
 296              if ( !preg_match( '/^((T-)?\d+|new)$/', $section ) ) {
 297                  $this->dieUsage( "The section parameter must be a valid section id or 'new'", "invalidsection" );
 298              }
 299              $content = $pageObj->getContent();
 300              if ( $section !== '0' && $section != 'new' && ( !$content || !$content->getSection( $section ) ) ) {
 301                  $this->dieUsage( "There is no section {$section}.", 'nosuchsection' );
 302              }
 303              $requestArray['wpSection'] = $params['section'];
 304          } else {
 305              $requestArray['wpSection'] = '';
 306          }
 307  
 308          $watch = $this->getWatchlistValue( $params['watchlist'], $titleObj );
 309  
 310          // Deprecated parameters
 311          if ( $params['watch'] ) {
 312              $this->logFeatureUsage( 'action=edit&watch' );
 313              $watch = true;
 314          } elseif ( $params['unwatch'] ) {
 315              $this->logFeatureUsage( 'action=edit&unwatch' );
 316              $watch = false;
 317          }
 318  
 319          if ( $watch ) {
 320              $requestArray['wpWatchthis'] = '';
 321          }
 322  
 323          // Pass through anything else we might have been given, to support extensions
 324          // This is kind of a hack but it's the best we can do to make extensions work
 325          $requestArray += $this->getRequest()->getValues();
 326  
 327          global $wgTitle, $wgRequest;
 328  
 329          $req = new DerivativeRequest( $this->getRequest(), $requestArray, true );
 330  
 331          // Some functions depend on $wgTitle == $ep->mTitle
 332          // TODO: Make them not or check if they still do
 333          $wgTitle = $titleObj;
 334  
 335          $articleContext = new RequestContext;
 336          $articleContext->setRequest( $req );
 337          $articleContext->setWikiPage( $pageObj );
 338          $articleContext->setUser( $this->getUser() );
 339  
 340          /** @var $articleObject Article */
 341          $articleObject = Article::newFromWikiPage( $pageObj, $articleContext );
 342  
 343          $ep = new EditPage( $articleObject );
 344  
 345          // allow editing of non-textual content.
 346          $ep->allowNonTextContent = true;
 347  
 348          $ep->setContextTitle( $titleObj );
 349          $ep->importFormData( $req );
 350          $content = $ep->textbox1;
 351  
 352          // The following is needed to give the hook the full content of the
 353          // new revision rather than just the current section. (Bug 52077)
 354          if ( !is_null( $params['section'] ) &&
 355              $contentHandler->supportsSections() && $titleObj->exists()
 356          ) {
 357              // If sectiontitle is set, use it, otherwise use the summary as the section title (for
 358              // backwards compatibility with old forms/bots).
 359              if ( $ep->sectiontitle !== '' ) {
 360                  $sectionTitle = $ep->sectiontitle;
 361              } else {
 362                  $sectionTitle = $ep->summary;
 363              }
 364  
 365              $contentObj = $contentHandler->unserializeContent( $content, $contentFormat );
 366  
 367              $fullContentObj = $articleObject->replaceSectionContent(
 368                  $params['section'],
 369                  $contentObj,
 370                  $sectionTitle
 371              );
 372              if ( $fullContentObj ) {
 373                  $content = $fullContentObj->serialize( $contentFormat );
 374              } else {
 375                  // This most likely means we have an edit conflict which means that the edit
 376                  // wont succeed anyway.
 377                  $this->dieUsageMsg( 'editconflict' );
 378              }
 379          }
 380  
 381          // Run hooks
 382          // Handle APIEditBeforeSave parameters
 383          $r = array();
 384          if ( !wfRunHooks( 'APIEditBeforeSave', array( $ep, $content, &$r ) ) ) {
 385              if ( count( $r ) ) {
 386                  $r['result'] = 'Failure';
 387                  $apiResult->addValue( null, $this->getModuleName(), $r );
 388  
 389                  return;
 390              }
 391  
 392              $this->dieUsageMsg( 'hookaborted' );
 393          }
 394  
 395          // Do the actual save
 396          $oldRevId = $articleObject->getRevIdFetched();
 397          $result = null;
 398          // Fake $wgRequest for some hooks inside EditPage
 399          // @todo FIXME: This interface SUCKS
 400          $oldRequest = $wgRequest;
 401          $wgRequest = $req;
 402  
 403          $status = $ep->internalAttemptSave( $result, $user->isAllowed( 'bot' ) && $params['bot'] );
 404          $wgRequest = $oldRequest;
 405  
 406          switch ( $status->value ) {
 407              case EditPage::AS_HOOK_ERROR:
 408              case EditPage::AS_HOOK_ERROR_EXPECTED:
 409                  $this->dieUsageMsg( 'hookaborted' );
 410  
 411              case EditPage::AS_PARSE_ERROR:
 412                  $this->dieUsage( $status->getMessage(), 'parseerror' );
 413  
 414              case EditPage::AS_IMAGE_REDIRECT_ANON:
 415                  $this->dieUsageMsg( 'noimageredirect-anon' );
 416  
 417              case EditPage::AS_IMAGE_REDIRECT_LOGGED:
 418                  $this->dieUsageMsg( 'noimageredirect-logged' );
 419  
 420              case EditPage::AS_SPAM_ERROR:
 421                  $this->dieUsageMsg( array( 'spamdetected', $result['spam'] ) );
 422  
 423              case EditPage::AS_BLOCKED_PAGE_FOR_USER:
 424                  $this->dieUsageMsg( 'blockedtext' );
 425  
 426              case EditPage::AS_MAX_ARTICLE_SIZE_EXCEEDED:
 427              case EditPage::AS_CONTENT_TOO_BIG:
 428                  $this->dieUsageMsg( array( 'contenttoobig', $this->getConfig()->get( 'MaxArticleSize' ) ) );
 429  
 430              case EditPage::AS_READ_ONLY_PAGE_ANON:
 431                  $this->dieUsageMsg( 'noedit-anon' );
 432  
 433              case EditPage::AS_READ_ONLY_PAGE_LOGGED:
 434                  $this->dieUsageMsg( 'noedit' );
 435  
 436              case EditPage::AS_READ_ONLY_PAGE:
 437                  $this->dieReadOnly();
 438  
 439              case EditPage::AS_RATE_LIMITED:
 440                  $this->dieUsageMsg( 'actionthrottledtext' );
 441  
 442              case EditPage::AS_ARTICLE_WAS_DELETED:
 443                  $this->dieUsageMsg( 'wasdeleted' );
 444  
 445              case EditPage::AS_NO_CREATE_PERMISSION:
 446                  $this->dieUsageMsg( 'nocreate-loggedin' );
 447  
 448              case EditPage::AS_NO_CHANGE_CONTENT_MODEL:
 449                  $this->dieUsageMsg( 'cantchangecontentmodel' );
 450  
 451              case EditPage::AS_BLANK_ARTICLE:
 452                  $this->dieUsageMsg( 'blankpage' );
 453  
 454              case EditPage::AS_CONFLICT_DETECTED:
 455                  $this->dieUsageMsg( 'editconflict' );
 456  
 457              // case EditPage::AS_SUMMARY_NEEDED: Can't happen since we set wpIgnoreBlankSummary
 458              case EditPage::AS_TEXTBOX_EMPTY:
 459                  $this->dieUsageMsg( 'emptynewsection' );
 460  
 461              case EditPage::AS_SUCCESS_NEW_ARTICLE:
 462                  $r['new'] = '';
 463                  // fall-through
 464  
 465              case EditPage::AS_SUCCESS_UPDATE:
 466                  $r['result'] = 'Success';
 467                  $r['pageid'] = intval( $titleObj->getArticleID() );
 468                  $r['title'] = $titleObj->getPrefixedText();
 469                  $r['contentmodel'] = $titleObj->getContentModel();
 470                  $newRevId = $articleObject->getLatest();
 471                  if ( $newRevId == $oldRevId ) {
 472                      $r['nochange'] = '';
 473                  } else {
 474                      $r['oldrevid'] = intval( $oldRevId );
 475                      $r['newrevid'] = intval( $newRevId );
 476                      $r['newtimestamp'] = wfTimestamp( TS_ISO_8601,
 477                          $pageObj->getTimestamp() );
 478                  }
 479                  break;
 480  
 481              case EditPage::AS_SUMMARY_NEEDED:
 482                  $this->dieUsageMsg( 'summaryrequired' );
 483  
 484              case EditPage::AS_END:
 485              default:
 486                  // $status came from WikiPage::doEdit()
 487                  $errors = $status->getErrorsArray();
 488                  $this->dieUsageMsg( $errors[0] ); // TODO: Add new errors to message map
 489                  break;
 490          }
 491          $apiResult->addValue( null, $this->getModuleName(), $r );
 492      }
 493  
 494  	public function mustBePosted() {
 495          return true;
 496      }
 497  
 498  	public function isWriteMode() {
 499          return true;
 500      }
 501  
 502  	public function getDescription() {
 503          return 'Create and edit pages.';
 504      }
 505  
 506  	public function getAllowedParams() {
 507          return array(
 508              'title' => array(
 509                  ApiBase::PARAM_TYPE => 'string',
 510              ),
 511              'pageid' => array(
 512                  ApiBase::PARAM_TYPE => 'integer',
 513              ),
 514              'section' => null,
 515              'sectiontitle' => array(
 516                  ApiBase::PARAM_TYPE => 'string',
 517              ),
 518              'text' => null,
 519              'summary' => null,
 520              'minor' => false,
 521              'notminor' => false,
 522              'bot' => false,
 523              'basetimestamp' => null,
 524              'starttimestamp' => null,
 525              'recreate' => false,
 526              'createonly' => false,
 527              'nocreate' => false,
 528              'watch' => array(
 529                  ApiBase::PARAM_DFLT => false,
 530                  ApiBase::PARAM_DEPRECATED => true,
 531              ),
 532              'unwatch' => array(
 533                  ApiBase::PARAM_DFLT => false,
 534                  ApiBase::PARAM_DEPRECATED => true,
 535              ),
 536              'watchlist' => array(
 537                  ApiBase::PARAM_DFLT => 'preferences',
 538                  ApiBase::PARAM_TYPE => array(
 539                      'watch',
 540                      'unwatch',
 541                      'preferences',
 542                      'nochange'
 543                  ),
 544              ),
 545              'md5' => null,
 546              'prependtext' => null,
 547              'appendtext' => null,
 548              'undo' => array(
 549                  ApiBase::PARAM_TYPE => 'integer'
 550              ),
 551              'undoafter' => array(
 552                  ApiBase::PARAM_TYPE => 'integer'
 553              ),
 554              'redirect' => array(
 555                  ApiBase::PARAM_TYPE => 'boolean',
 556                  ApiBase::PARAM_DFLT => false,
 557              ),
 558              'contentformat' => array(
 559                  ApiBase::PARAM_TYPE => ContentHandler::getAllContentFormats(),
 560              ),
 561              'contentmodel' => array(
 562                  ApiBase::PARAM_TYPE => ContentHandler::getContentModels(),
 563              )
 564          );
 565      }
 566  
 567  	public function getParamDescription() {
 568          $p = $this->getModulePrefix();
 569  
 570          return array(
 571              'title' => "Title of the page you want to edit. Cannot be used together with {$p}pageid",
 572              'pageid' => "Page ID of the page you want to edit. Cannot be used together with {$p}title",
 573              'section' => 'Section number. 0 for the top section, \'new\' for a new section',
 574              'sectiontitle' => 'The title for a new section',
 575              'text' => 'Page content',
 576              'token' => array(
 577                  /* Standard description is automatically prepended */
 578                  'The token should always be sent as the last parameter, or at ' .
 579                      "least, after the {$p}text parameter"
 580              ),
 581              'summary'
 582                  => "Edit summary. Also section title when {$p}section=new and {$p}sectiontitle is not set",
 583              'minor' => 'Minor edit',
 584              'notminor' => 'Non-minor edit',
 585              'bot' => 'Mark this edit as bot',
 586              'basetimestamp' => array(
 587                  'Timestamp of the base revision (obtained through prop=revisions&rvprop=timestamp).',
 588                  'Used to detect edit conflicts; leave unset to ignore conflicts'
 589              ),
 590              'starttimestamp' => array(
 591                  'Timestamp when you began the editing process, e.g. when the current page content ' .
 592                      'was loaded for editing.',
 593                  'Used to detect edit conflicts; leave unset to ignore conflicts'
 594              ),
 595              'recreate' => 'Override any errors about the article having been deleted in the meantime',
 596              'createonly' => 'Don\'t edit the page if it exists already',
 597              'nocreate' => 'Throw an error if the page doesn\'t exist',
 598              'watch' => 'Add the page to your watchlist',
 599              'unwatch' => 'Remove the page from your watchlist',
 600              'watchlist' => 'Unconditionally add or remove the page from your ' .
 601                  'watchlist, use preferences or do not change watch',
 602              'md5' => array(
 603                  "The MD5 hash of the {$p}text parameter, or the {$p}prependtext " .
 604                      "and {$p}appendtext parameters concatenated.",
 605                  'If set, the edit won\'t be done unless the hash is correct'
 606              ),
 607              'prependtext' => "Add this text to the beginning of the page. Overrides {$p}text",
 608              'appendtext' => array( "Add this text to the end of the page. Overrides {$p}text.",
 609                  "Use {$p}section=new to append a new section" ),
 610              'undo' => "Undo this revision. Overrides {$p}text, {$p}prependtext and {$p}appendtext",
 611              'undoafter' => 'Undo all revisions from undo to this one. If not set, just undo one revision',
 612              'redirect' => 'Automatically resolve redirects',
 613              'contentformat' => 'Content serialization format used for the input text',
 614              'contentmodel' => 'Content model of the new content',
 615          );
 616      }
 617  
 618  	public function needsToken() {
 619          return 'csrf';
 620      }
 621  
 622  	public function getExamples() {
 623          return array(
 624              'api.php?action=edit&title=Test&summary=test%20summary&' .
 625              'text=article%20content&basetimestamp=20070824123454&token=%2B\\'
 626                  => 'Edit a page (anonymous user)',
 627              'api.php?action=edit&title=Test&summary=NOTOC&minor=&' .
 628                  'prependtext=__NOTOC__%0A&basetimestamp=20070824123454&token=%2B\\'
 629                  => 'Prepend __NOTOC__ to a page (anonymous user)',
 630              'api.php?action=edit&title=Test&undo=13585&undoafter=13579&' .
 631                  'basetimestamp=20070824123454&token=%2B\\'
 632                  => 'Undo r13579 through r13585 with autosummary (anonymous user)',
 633          );
 634      }
 635  
 636  	public function getHelpUrls() {
 637          return 'https://www.mediawiki.org/wiki/API:Edit';
 638      }
 639  }


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