diff options
Diffstat (limited to 'bin/wiki/vendor/addwiki/mediawiki-api/src/Service')
25 files changed, 2059 insertions, 0 deletions
diff --git a/bin/wiki/vendor/addwiki/mediawiki-api/src/Service/CategoryTraverser.php b/bin/wiki/vendor/addwiki/mediawiki-api/src/Service/CategoryTraverser.php new file mode 100644 index 00000000..c82b5d69 --- /dev/null +++ b/bin/wiki/vendor/addwiki/mediawiki-api/src/Service/CategoryTraverser.php @@ -0,0 +1,161 @@ +<?php + +namespace Mediawiki\Api\Service; + +use Mediawiki\Api\CategoryLoopException; +use Mediawiki\Api\MediawikiApi; +use Mediawiki\Api\SimpleRequest; +use Mediawiki\DataModel\Page; +use Mediawiki\DataModel\Pages; + +/** + * Category traverser. + * + * Note on spelling 'descendant' (from Wiktionary): + * The adjective, "descending from a biological ancestor", may be spelt either + * with an 'a' or with an 'e' in the final syllable. However the noun descendant, + * "one who is the progeny of someone", may be spelt only with an 'a'. + */ +class CategoryTraverser extends Service { + + const CALLBACK_CATEGORY = 10; + const CALLBACK_PAGE = 20; + + /** + * @var string[] + */ + protected $namespaces; + + /** + * @var callable[] + */ + protected $callbacks; + + /** + * Used to remember the previously-visited categories when traversing. + * @var string[] + */ + protected $alreadyVisited; + + /** + * @param MediawikiApi $api The API to connect to. + */ + public function __construct( MediawikiApi $api ) { + parent::__construct( $api ); + $this->callbacks = []; + } + + /** + * Query the remote site for the list of namespaces in use, so that later we can tell what's a + * category and what's not. This populates $this->namespaces, and will not re-request on + * repeated invocations. + * @return void + */ + protected function retrieveNamespaces() { + if ( is_array( $this->namespaces ) ) { + return; + } + $params = [ 'meta' => 'siteinfo', 'siprop' => 'namespaces' ]; + $namespaces = $this->api->getRequest( new SimpleRequest( 'query', $params ) ); + if ( isset( $namespaces['query']['namespaces'] ) ) { + $this->namespaces = $namespaces['query']['namespaces']; + } + } + + /** + * Register a callback that will be called for each page or category visited during the + * traversal. + * @param int $type One of the 'CALLBACK_' constants of this class. + * @param callable $callback A callable that takes two \Mediawiki\DataModel\Page parameters. + */ + public function addCallback( $type, $callback ) { + if ( !isset( $this->callbacks[$type] ) ) { + $this->callbacks[$type] = []; + } + $this->callbacks[$type][] = $callback; + } + + /** + * Visit every descendant page of $rootCategoryName (which will be a Category + * page, because there are no desecendants of any other pages). + * @param Page $rootCat The full name of the page to start at. + * @param Page[] $currentPath Used only when recursing into this method, to track each path + * through the category hierarchy in case of loops. + * @return Pages All descendants of the given category. + * @throws CategoryLoopException If a category loop is detected. + */ + public function descend( Page $rootCat, $currentPath = null ) { + // Make sure we know the namespace IDs. + $this->retrieveNamespaces(); + + $rootCatName = $rootCat->getPageIdentifier()->getTitle()->getText(); + if ( is_null( $currentPath ) ) { + $this->alreadyVisited = []; + $currentPath = new Pages(); + } + $this->alreadyVisited[] = $rootCatName; + $currentPath->addPage( $rootCat ); + + // Start a list of child pages. + $descendants = new Pages(); + do { + $pageListGetter = new PageListGetter( $this->api ); + $members = $pageListGetter->getPageListFromCategoryName( $rootCatName ); + foreach ( $members->toArray() as $member ) { + /** @var Title */ + $memberTitle = $member->getPageIdentifier()->getTitle(); + + // See if this page is a Category page. + $isCat = false; + if ( isset( $this->namespaces[ $memberTitle->getNs() ] ) ) { + $ns = $this->namespaces[ $memberTitle->getNs() ]; + $isCat = ( isset( $ns['canonical'] ) && $ns['canonical'] === 'Category' ); + } + // If it's a category, descend into it. + if ( $isCat ) { + // If this member has already been visited on this branch of the traversal, + // throw an Exception with information about which categories form the loop. + if ( $currentPath->hasPage( $member ) ) { + $currentPath->addPage( $member ); + $loop = new CategoryLoopException(); + $loop->setCategoryPath( $currentPath ); + throw $loop; + } + // Don't go any further if we've already visited this member + // (does not indicate a loop, however; we've already caught that above). + if ( in_array( $memberTitle->getText(), $this->alreadyVisited ) ) { + continue; + } + // Call any registered callbacked, and carry on to the next branch. + $this->call( self::CALLBACK_CATEGORY, [ $member, $rootCat ] ); + $newDescendants = $this->descend( $member, $currentPath ); + $descendants->addPages( $newDescendants ); + // Re-set the path. + $currentPath = new Pages(); + } else { + // If it's a page, add it to the list and carry on. + $descendants->addPage( $member ); + $this->call( self::CALLBACK_PAGE, [ $member, $rootCat ] ); + } + } + } while ( isset( $result['continue'] ) ); + return $descendants; + } + + /** + * Call all the registered callbacks of a particular type. + * @param int $type The callback type; should match one of the 'CALLBACK_' constants. + * @param mixed[] $params The parameters to pass to the callback function. + */ + protected function call( $type, $params ) { + if ( !isset( $this->callbacks[$type] ) ) { + return; + } + foreach ( $this->callbacks[$type] as $callback ) { + if ( is_callable( $callback ) ) { + call_user_func_array( $callback, $params ); + } + } + } + +} diff --git a/bin/wiki/vendor/addwiki/mediawiki-api/src/Service/FileUploader.php b/bin/wiki/vendor/addwiki/mediawiki-api/src/Service/FileUploader.php new file mode 100644 index 00000000..5ada5739 --- /dev/null +++ b/bin/wiki/vendor/addwiki/mediawiki-api/src/Service/FileUploader.php @@ -0,0 +1,139 @@ +<?php + +namespace Mediawiki\Api\Service; + +use Exception; +use Mediawiki\Api\MultipartRequest; +use Mediawiki\Api\SimpleRequest; + +/** + * @access private + * + * @author Addshore + */ +class FileUploader extends Service { + + /** @var int */ + protected $chunkSize; + + /** + * Set the chunk size used for chunked uploading. + * + * Chunked uploading is available in MediaWiki 1.20 and above, although prior to version 1.25, + * SVGs could not be uploaded via chunked uploading. + * + * @link https://www.mediawiki.org/wiki/API:Upload#Chunked_uploading + * + * @param int $chunkSize In bytes. + */ + public function setChunkSize( $chunkSize ) { + $this->chunkSize = $chunkSize; + } + + /** + * Upload a file. + * + * @param string $targetName The name to give the file on the wiki (no 'File:' prefix required). + * @param string $location Can be local path or remote URL. + * @param string $text Initial page text for new files. + * @param string $comment Upload comment. Also used as the initial page text for new files if + * text parameter not provided. + * @param string $watchlist Unconditionally add or remove the page from your watchlist, use + * preferences or do not change watch. Possible values: 'watch', 'preferences', 'nochange'. + * @param bool $ignoreWarnings Ignore any warnings. This must be set to upload a new version of + * an existing image. + * + * @return bool + */ + public function upload( + $targetName, + $location, + $text = '', + $comment = '', + $watchlist = 'preferences', + $ignoreWarnings = false + ) { + $params = [ + 'filename' => $targetName, + 'token' => $this->api->getToken(), + ]; + // Watchlist behaviour. + if ( in_array( $watchlist, [ 'watch', 'nochange' ] ) ) { + $params['watchlist'] = $watchlist; + } + // Ignore warnings? + if ( $ignoreWarnings ) { + $params['ignorewarnings'] = '1'; + } + // Page text. + if ( !empty( $text ) ) { + $params['text'] = $text; + } + // Revision comment. + if ( !empty( $comment ) ) { + $params['comment'] = $comment; + } + + if ( is_file( $location ) ) { + // Normal single-request upload. + $params['filesize'] = filesize( $location ); + $params['file'] = fopen( $location, 'r' ); + if ( is_int( $this->chunkSize ) && $this->chunkSize > 0 ) { + // Chunked upload. + $params = $this->uploadByChunks( $params ); + } + } else { + // Upload from URL. + $params['url'] = $location; + } + + $response = $this->api->postRequest( new SimpleRequest( 'upload', $params ) ); + return ( $response['upload']['result'] === 'Success' ); + } + + /** + * Upload a file by chunks and get the parameters for the final upload call. + * @param mixed[] $params The request parameters. + * @return mixed[] + * @throws Exception + */ + protected function uploadByChunks( $params ) { + // Get the file handle for looping, but don't keep it in the request parameters. + $fileHandle = $params['file']; + unset( $params['file'] ); + // Track the chunks and offset. + $chunksDone = 0; + $params['offset'] = 0; + while ( true ) { + + // 1. Make the request. + $params['chunk'] = fread( $fileHandle, $this->chunkSize ); + $contentDisposition = 'form-data; name="chunk"; filename="' . $params['filename'] . '"'; + $request = MultipartRequest::factory() + ->setParams( $params ) + ->setAction( 'upload' ) + ->setMultipartParams( [ + 'chunk' => [ 'headers' => [ 'Content-Disposition' => $contentDisposition ] ], + ] ); + $response = $this->api->postRequest( $request ); + + // 2. Deal with the response. + $chunksDone++; + $params['offset'] = ( $chunksDone * $this->chunkSize ); + if ( !isset( $response['upload']['filekey'] ) ) { + // This should never happen. Even the last response still has the filekey. + throw new Exception( 'Unable to get filekey for chunked upload' ); + } + $params['filekey'] = $response['upload']['filekey']; + if ( $response['upload']['result'] === 'Continue' ) { + // Amend parameters for next upload POST request. + $params['offset'] = $response['upload']['offset']; + } else { + // The final upload POST will be done in self::upload() + // to commit the upload out of the stash area. + unset( $params['chunk'], $params['offset'] ); + return $params; + } + } + } +} diff --git a/bin/wiki/vendor/addwiki/mediawiki-api/src/Service/ImageRotator.php b/bin/wiki/vendor/addwiki/mediawiki-api/src/Service/ImageRotator.php new file mode 100644 index 00000000..ba5624dc --- /dev/null +++ b/bin/wiki/vendor/addwiki/mediawiki-api/src/Service/ImageRotator.php @@ -0,0 +1,56 @@ +<?php + +namespace Mediawiki\Api\Service; + +use Mediawiki\Api\SimpleRequest; +use Mediawiki\Api\UsageException; +use Mediawiki\DataModel\File; + +/** + * @access private + * + * @author Addshore + */ +class ImageRotator extends Service { + + /** + * NOTE: This service has not been fully tested + * + * @param File $file + * @param int $rotation Degrees to rotate image clockwise, One value: 90, 180, 270 + * + * @throws UsageException + * @return bool + */ + public function rotate( File $file, $rotation ) { + $params = [ + 'rotation' => $rotation, + 'token' => $this->api->getToken(), + ]; + + if ( !is_null( $file->getPageIdentifier()->getTitle() ) ) { + $params['titles'] = $file->getPageIdentifier()->getTitle()->getText(); + } else { + $params['pageids'] = $file->getPageIdentifier()->getId(); + } + + $result = $this->api->postRequest( new SimpleRequest( 'imagerotate', $params ) ); + + // This module sometimes gives odd errors so deal with them.. + if ( array_key_exists( 'imagerotate', $result ) ) { + $imageRotate = array_pop( $result['imagerotate'] ); + if ( array_key_exists( 'result', $imageRotate ) && + $imageRotate['result'] == 'Failure' + ) { + throw new UsageException( + 'imagerotate-Failure', + $imageRotate['errormessage'], + $result + ); + } + } + + return true; + } + +} diff --git a/bin/wiki/vendor/addwiki/mediawiki-api/src/Service/LogListGetter.php b/bin/wiki/vendor/addwiki/mediawiki-api/src/Service/LogListGetter.php new file mode 100644 index 00000000..d9394919 --- /dev/null +++ b/bin/wiki/vendor/addwiki/mediawiki-api/src/Service/LogListGetter.php @@ -0,0 +1,83 @@ +<?php + +namespace Mediawiki\Api\Service; + +use Mediawiki\Api\SimpleRequest; +use Mediawiki\DataModel\Log; +use Mediawiki\DataModel\LogList; +use Mediawiki\DataModel\Page; +use Mediawiki\DataModel\PageIdentifier; +use Mediawiki\DataModel\Revisions; +use Mediawiki\DataModel\Title; + +/** + * @access private + * + * @author Thomas Arrow + */ +class LogListGetter extends Service { + + /** + * @param array $extraParams + * + * @return LogList + */ + public function getLogList( array $extraParams = [] ) { + $logList = new LogList(); + + while ( true ) { + $params = [ + 'list' => 'logevents', + 'leprop' => 'title|ids|type|user|timestamp|comment|details' + ]; + + $newParams = array_merge( $extraParams, $params ); + $result = $this->api->getRequest( new SimpleRequest( 'query', $newParams ) ); + + foreach ( $result[ 'query' ]['logevents'] as $logevent ) { + $logList->addLog( + new Log( + $logevent['logid'], + $logevent['type'], + $logevent['action'], + $logevent['timestamp'], + $logevent['user'], + new Page( + new PageIdentifier( + new Title( $logevent['title'], $logevent['ns'] ), + $logevent['pageid'] + ), + new Revisions() + ), + $logevent['comment'], + $this->getLogDetailsFromEvent( $logevent ) + ) + ); + } + + return $logList; + } + } + + /** + * @param array $event + * + * @return array + */ + private function getLogDetailsFromEvent( $event ) { + $ignoreKeys = array_flip( [ + 'logid', + 'ns', + 'title', + 'pageid', + 'logpage', + 'type', + 'action', + 'user', + 'type', + 'timestamp', + 'comment' ] ); + return array_diff_key( $event, $ignoreKeys ); + } + +} diff --git a/bin/wiki/vendor/addwiki/mediawiki-api/src/Service/NamespaceGetter.php b/bin/wiki/vendor/addwiki/mediawiki-api/src/Service/NamespaceGetter.php new file mode 100644 index 00000000..c3f00030 --- /dev/null +++ b/bin/wiki/vendor/addwiki/mediawiki-api/src/Service/NamespaceGetter.php @@ -0,0 +1,108 @@ +<?php + +namespace Mediawiki\Api\Service; + +use Mediawiki\Api\SimpleRequest; +use Mediawiki\DataModel\NamespaceInfo; + +/** + * @access private + * + * @author gbirke + */ +class NamespaceGetter extends Service { + + /** + * Find a namespace by its canonical name + * + * @param string $canonicalName + * @return NamespaceInfo|null + */ + public function getNamespaceByCanonicalName( $canonicalName ) { + $result = $this->getNamespaceResult()['query']; + foreach ( $result['namespaces'] as $nsInfo ) { + if ( !empty( $nsInfo['canonical'] ) && $nsInfo['canonical'] === $canonicalName ) { + return $this->createNamespaceFromQuery( $nsInfo, $result['namespacealiases'] ); + } + } + return null; + } + + /** + * Find a namespace by its canonical name, local name or namespace alias + * + * @param string $name + * @return NamespaceInfo|null + */ + public function getNamespaceByName( $name ) { + $result = $this->getNamespaceResult()['query']; + foreach ( $result['namespaces'] as $nsInfo ) { + if ( ( !empty( $nsInfo['canonical'] ) && $nsInfo['canonical'] === $name ) || + $nsInfo['*'] === $name ) { + return $this->createNamespaceFromQuery( $nsInfo, $result['namespacealiases'] ); + } + } + foreach ( $result['namespacealiases'] as $alias ) { + if ( $alias['*'] === $name && !empty( $result['namespaces'][$alias['id']] ) ) { + return $this->createNamespaceFromQuery( + $result['namespaces'][$alias['id']], + $result['namespacealiases'] + ); + } + } + return null; + } + + /** + * @return NamespaceInfo[] + */ + public function getNamespaces() { + $namespaces = []; + $result = $this->getNamespaceResult()['query']; + foreach ( $result['namespaces'] as $nsInfo ) { + $namespaces[$nsInfo['id']] = $this->createNamespaceFromQuery( + $nsInfo, $result['namespacealiases'] + ); + } + return $namespaces; + } + + private function createNamespaceFromQuery( $nsInfo, $namespaceAliases ) { + return new NamespaceInfo( + $nsInfo['id'], + empty( $nsInfo['canonical'] ) ? '' : $nsInfo['canonical'], + $nsInfo['*'], + $nsInfo['case'], + empty( $nsInfo['defaultcontentmodel'] ) ? null : $nsInfo['defaultcontentmodel'], + $this->getAliases( $nsInfo['id'], $namespaceAliases ) + ); + } + + /** + * @param int $id + * @param array $namespaceAliases Alias list, as returned by the API + * @return string[] + */ + private function getAliases( $id, $namespaceAliases ) { + $aliases = []; + foreach ( $namespaceAliases as $alias ) { + if ( $alias['id'] === $id ) { + $aliases[] = $alias['*']; + } + } + return $aliases; + } + + /** + * @return array + */ + private function getNamespaceResult() { + return $this->api->getRequest( new SimpleRequest( + 'query', [ + 'meta' => 'siteinfo', + 'siprop' => 'namespaces|namespacealiases' + ] + ) ); + } + +} diff --git a/bin/wiki/vendor/addwiki/mediawiki-api/src/Service/PageDeleter.php b/bin/wiki/vendor/addwiki/mediawiki-api/src/Service/PageDeleter.php new file mode 100644 index 00000000..60c43e30 --- /dev/null +++ b/bin/wiki/vendor/addwiki/mediawiki-api/src/Service/PageDeleter.php @@ -0,0 +1,105 @@ +<?php + +namespace Mediawiki\Api\Service; + +use Mediawiki\Api\SimpleRequest; +use Mediawiki\DataModel\Page; +use Mediawiki\DataModel\PageIdentifier; +use Mediawiki\DataModel\Revision; +use Mediawiki\DataModel\Title; + +/** + * @access private + * + * @author Addshore + */ +class PageDeleter extends Service { + + /** + * @since 0.2 + * + * @param Page $page + * @param array $extraParams + * + * @return bool + */ + public function delete( Page $page, array $extraParams = [] ) { + $this->api->postRequest( new SimpleRequest( + 'delete', + $this->getDeleteParams( $page->getPageIdentifier(), $extraParams ) + ) ); + return true; + } + + /** + * @since 0.2 + * + * @param Revision $revision + * @param array $extraParams + * + * @return bool + */ + public function deleteFromRevision( Revision $revision, array $extraParams = [] ) { + $this->api->postRequest( new SimpleRequest( + 'delete', + $this->getDeleteParams( $revision->getPageIdentifier(), $extraParams ) + ) ); + return true; + } + + /** + * @since 0.2 + * + * @param int $pageid + * @param array $extraParams + * + * @return bool + */ + public function deleteFromPageId( $pageid, array $extraParams = [] ) { + $this->api->postRequest( new SimpleRequest( + 'delete', + $this->getDeleteParams( new PageIdentifier( null, $pageid ), $extraParams ) + ) ); + return true; + } + + /** + * @since 0.5 + * + * @param Title|string $title + * @param array $extraParams + * + * @return bool + */ + public function deleteFromPageTitle( $title, array $extraParams = [] ) { + if ( is_string( $title ) ) { + $title = new Title( $title ); + } + $this->api->postRequest( new SimpleRequest( + 'delete', + $this->getDeleteParams( new PageIdentifier( $title ), $extraParams ) + ) ); + return true; + } + + /** + * @param PageIdentifier $identifier + * @param array $extraParams + * + * @return array + */ + private function getDeleteParams( PageIdentifier $identifier, $extraParams ) { + $params = []; + + if ( !is_null( $identifier->getId() ) ) { + $params['pageid'] = $identifier->getId(); + } else { + $params['title'] = $identifier->getTitle()->getTitle(); + } + + $params['token'] = $this->api->getToken( 'delete' ); + + return array_merge( $extraParams, $params ); + } + +} diff --git a/bin/wiki/vendor/addwiki/mediawiki-api/src/Service/PageGetter.php b/bin/wiki/vendor/addwiki/mediawiki-api/src/Service/PageGetter.php new file mode 100644 index 00000000..6c5c54cf --- /dev/null +++ b/bin/wiki/vendor/addwiki/mediawiki-api/src/Service/PageGetter.php @@ -0,0 +1,246 @@ +<?php + +namespace Mediawiki\Api\Service; + +use Mediawiki\Api\SimpleRequest; +use Mediawiki\DataModel\Content; +use Mediawiki\DataModel\EditInfo; +use Mediawiki\DataModel\Page; +use Mediawiki\DataModel\PageIdentifier; +use Mediawiki\DataModel\Revision; +use Mediawiki\DataModel\Revisions; +use Mediawiki\DataModel\Title; +use RuntimeException; + +/** + * @access private + * + * @author Addshore + */ +class PageGetter extends Service { + + /** + * @since 0.2 + * + * @param int $id + * @param array $extraParams + * + * @return Page + */ + public function getFromRevisionId( $id, array $extraParams = [] ) { + $result = + $this->api->getRequest( + new SimpleRequest( + 'query', + $this->getQuery( [ 'revids' => $id ], $extraParams ) + ) + ); + + return $this->newPageFromResult( array_shift( $result['query']['pages'] ) ); + } + + /** + * @since 0.2 + * + * @param string|Title $title + * @param array $extraParams + * + * @return Page + */ + public function getFromTitle( $title, array $extraParams = [] ) { + if ( $title instanceof Title ) { + $title = $title->getTitle(); + } + $result = + $this->api->getRequest( + new SimpleRequest( + 'query', + $this->getQuery( [ 'titles' => $title ], $extraParams ) + ) + ); + + return $this->newPageFromResult( array_shift( $result['query']['pages'] ) ); + } + + /** + * @since 0.2 + * + * @param int $id + * @param array $extraParams + * + * @return Page + */ + public function getFromPageId( $id, array $extraParams = [] ) { + $result = + $this->api->getRequest( + new SimpleRequest( + 'query', + $this->getQuery( [ 'pageids' => $id ], $extraParams ) + ) + ); + + return $this->newPageFromResult( array_shift( $result['query']['pages'] ) ); + } + + /** + * @since 0.4 + * + * @param PageIdentifier $pageIdentifier + * @param array $extraParams + * + * @throws RuntimeException + * @return Page + */ + public function getFromPageIdentifier( + PageIdentifier $pageIdentifier, + array $extraParams = [] + ) { + if ( !$pageIdentifier->identifiesPage() ) { + throw new RuntimeException( '$pageIdentifier does not identify a page' ); + } + if ( !is_null( $pageIdentifier->getId() ) ) { + return $this->getFromPageId( $pageIdentifier->getId(), $extraParams ); + } else { + return $this->getFromTitle( $pageIdentifier->getTitle(), $extraParams ); + } + } + + /** + * @since 0.2 + * + * @param Page $page + * @param array $extraParams + * + * @return Page + */ + public function getFromPage( Page $page, array $extraParams = [] ) { + $result = + $this->api->getRequest( + new SimpleRequest( + 'query', + $this->getQuery( [ 'pageids' => $page->getId() ], $extraParams ) + ) + ); + $revisions = $this->getRevisionsFromResult( array_shift( $result['query']['pages'] ) ); + $revisions->addRevisions( $page->getRevisions() ); + + return new Page( + $page->getPageIdentifier(), + $revisions + ); + } + + /** + * @since 0.2 + * + * @param Revision $revision + * @param array $extraParams + * + * @return Page + */ + public function getFromRevision( Revision $revision, array $extraParams = [] ) { + $result = + $this->api->getRequest( + new SimpleRequest( + 'query', + $this->getQuery( [ 'revids' => $revision->getId() ], $extraParams ) + ) + ); + $revisions = $this->getRevisionsFromResult( array_shift( $result['query']['pages'] ) ); + $revisions->addRevision( $revision ); + + return new Page( + new PageIdentifier( + new Title( + $result['title'], + $result['ns'] + ), + $result['pageid'] + ), + $revisions + ); + } + + /** + * @param array $additionalParams + * + * @param array $extraParams + * + * @return array + */ + private function getQuery( $additionalParams, array $extraParams = [] ) { + $base = [ + 'prop' => 'revisions|info|pageprops', + 'rvprop' => 'ids|flags|timestamp|user|size|sha1|comment|content|tags', + 'inprop' => 'protection', + ]; + + return array_merge( $extraParams, $base, $additionalParams ); + } + + /** + * @param array $array + * + * @return Revisions + */ + private function getRevisionsFromResult( $array ) { + $revisions = new Revisions(); + $pageid = $array['pageid']; + foreach ( $array['revisions'] as $revision ) { + $revisions->addRevision( + new Revision( + $this->getContent( $array['contentmodel'], $revision['*'] ), + new PageIdentifier( new Title( $array['title'], $array['ns'] ), $pageid ), + $revision['revid'], + new EditInfo( + $revision['comment'], + array_key_exists( 'minor', $revision ), + array_key_exists( 'bot', $revision ) + ), + $revision['user'], + $revision['timestamp'] + ) + ); + } + + return $revisions; + } + + /** + * @param string $model + * @param string $content returned from the API + * + * @throws RuntimeException + * @return Content + */ + private function getContent( $model, $content ) { + return new Content( $content, $model ); + } + + /** + * @param array $array + * + * @return Page + */ + private function newPageFromResult( $array ) { + if ( array_key_exists( 'pageid', $array ) ) { + $pageid = $array['pageid']; + $revisions = $this->getRevisionsFromResult( $array ); + } else { + $pageid = 0; + $revisions = new Revisions(); + } + + return new Page( + new PageIdentifier( + new Title( + $array['title'], + $array['ns'] + ), + $pageid + ), + $revisions + ); + } + +} diff --git a/bin/wiki/vendor/addwiki/mediawiki-api/src/Service/PageListGetter.php b/bin/wiki/vendor/addwiki/mediawiki-api/src/Service/PageListGetter.php new file mode 100644 index 00000000..6b6d0007 --- /dev/null +++ b/bin/wiki/vendor/addwiki/mediawiki-api/src/Service/PageListGetter.php @@ -0,0 +1,147 @@ +<?php + +namespace Mediawiki\Api\Service; + +use Mediawiki\Api\SimpleRequest; +use Mediawiki\DataModel\Page; +use Mediawiki\DataModel\PageIdentifier; +use Mediawiki\DataModel\Pages; +use Mediawiki\DataModel\Title; + +/** + * @access private + * + * @author Addshore + */ +class PageListGetter extends Service { + + /** + * Get the set of pages in a given category. Extra parameters can include: + * cmtype: default 'page|subcat|file' + * cmlimit: default 10, maximum 500 (5000 for bots) + * + * @link https://www.mediawiki.org/wiki/API:Categorymembers + * @since 0.3 + * + * @param string $name + * @param array $extraParams + * + * @return Pages + */ + public function getPageListFromCategoryName( $name, array $extraParams = [] ) { + $params = array_merge( $extraParams, [ + 'list' => 'categorymembers', + 'cmtitle' => $name, + ] ); + return $this->runQuery( $params, 'cmcontinue', 'categorymembers' ); + } + + /** + * List pages that transclude a certain page. + * + * @link https://www.mediawiki.org/wiki/API:Embeddedin + * @since 0.5 + * + * @param string $pageName + * @param array $extraParams + * + * @return Pages + */ + public function getPageListFromPageTransclusions( $pageName, array $extraParams = [] ) { + $params = array_merge( $extraParams, [ + 'list' => 'embeddedin', + 'eititle' => $pageName, + ] ); + return $this->runQuery( $params, 'eicontinue', 'embeddedin' ); + } + + /** + * Get all pages that link to the given page. + * + * @link https://www.mediawiki.org/wiki/API:Linkshere + * @since 0.5 + * @uses PageListGetter::runQuery() + * + * @param string $pageName The page name + * @param string[] Any extra parameters to use: lhprop, lhnamespace, lhshow, lhlimit + * + * @return Pages + */ + public function getFromWhatLinksHere( $pageName, $extraParams = [] ) { + $params = array_merge( $extraParams, [ + 'prop' => 'info', + 'generator' => 'linkshere', + 'titles' => $pageName, + ] ); + return $this->runQuery( $params, 'glhcontinue', 'pages' ); + } + + /** + * Get all pages that have the given prefix. + * + * @link https://www.mediawiki.org/wiki/API:Allpages + * + * @param string $prefix The page title prefix. + * + * @return Pages + */ + public function getFromPrefix( $prefix ) { + $params = [ + 'list' => 'allpages', + 'apprefix' => $prefix, + ]; + return $this->runQuery( $params, 'apcontinue', 'allpages' ); + } + + /** + * Get up to 10 random pages. + * + * @link https://www.mediawiki.org/wiki/API:Random + * @uses PageListGetter::runQuery() + * + * @param array $extraParams + * + * @return Pages + */ + public function getRandom( array $extraParams = [] ) { + $params = array_merge( $extraParams, [ 'list' => 'random' ] ); + return $this->runQuery( $params, null, 'random', 'id', false ); + } + + /** + * Run a query to completion. + * + * @param string[] $params Query parameters + * @param string $contName Result subelement name for continue details + * @param string $resName Result element name for main results array + * @param string $pageIdName Result element name for page ID + * @param bool $cont Whether to continue the query, using multiple requests + * @return Pages + */ + protected function runQuery( $params, $contName, $resName, $pageIdName = 'pageid', $cont = true ) { + $pages = new Pages(); + + do { + // Set up continue parameter if it's been set already. + if ( isset( $result['continue'][$contName] ) ) { + $params[$contName] = $result['continue'][$contName]; + } + + // Run the actual query. + $result = $this->api->getRequest( new SimpleRequest( 'query', $params ) ); + if ( !array_key_exists( 'query', $result ) ) { + return $pages; + } + + // Add the results to the output page list. + foreach ( $result['query'][$resName] as $member ) { + $pageTitle = new Title( $member['title'], $member['ns'] ); + $page = new Page( new PageIdentifier( $pageTitle, $member[$pageIdName] ) ); + $pages->addPage( $page ); + } + + } while ( $cont && isset( $result['continue'] ) ); + + return $pages; + } +} diff --git a/bin/wiki/vendor/addwiki/mediawiki-api/src/Service/PageMover.php b/bin/wiki/vendor/addwiki/mediawiki-api/src/Service/PageMover.php new file mode 100644 index 00000000..f7eba2af --- /dev/null +++ b/bin/wiki/vendor/addwiki/mediawiki-api/src/Service/PageMover.php @@ -0,0 +1,68 @@ +<?php + +namespace Mediawiki\Api\Service; + +use Mediawiki\Api\SimpleRequest; +use Mediawiki\DataModel\Page; +use Mediawiki\DataModel\Title; + +/** + * @access private + * + * @author Addshore + */ +class PageMover extends Service { + + /** + * @since 0.2 + * + * @param Page $page + * @param Title $target + * @param array $extraParams + * + * @return bool + */ + public function move( Page $page, Title $target, array $extraParams = [] ) { + $this->api->postRequest( + new SimpleRequest( + 'move', $this->getMoveParams( $page->getId(), $target, $extraParams ) + ) + ); + + return true; + } + + /** + * @since 0.2 + * + * @param int $pageid + * @param Title $target + * @param array $extraParams + * + * @return bool + */ + public function moveFromPageId( $pageid, Title $target, array $extraParams = [] ) { + $this->api->postRequest( + new SimpleRequest( 'move', $this->getMoveParams( $pageid, $target, $extraParams ) ) + ); + + return true; + } + + /** + * @param int $pageid + * @param Title $target + * @param array $extraParams + * + * @return array + */ + private function getMoveParams( $pageid, $target, $extraParams ) { + $params = []; + $params['fromid'] = $pageid; + $params['to'] = $target->getTitle(); + $params['token'] = $this->api->getToken( 'move' ); + + return array_merge( $extraParams, $params ); + } + +} diff --git a/bin/wiki/vendor/addwiki/mediawiki-api/src/Service/PageProtector.php b/bin/wiki/vendor/addwiki/mediawiki-api/src/Service/PageProtector.php new file mode 100644 index 00000000..e3988e84 --- /dev/null +++ b/bin/wiki/vendor/addwiki/mediawiki-api/src/Service/PageProtector.php @@ -0,0 +1,55 @@ +<?php + +namespace Mediawiki\Api\Service; + +use InvalidArgumentException; +use Mediawiki\Api\SimpleRequest; +use Mediawiki\DataModel\Page; + +/** + * @access private + * + * @author Addshore + */ +class PageProtector extends Service { + + /** + * @since 0.3 + * + * @param Page $page + * @param string[] $protections where the 'key' is the action and the 'value' is the group + * @param array $extraParams + * + * @return bool + * @throws InvalidArgumentException + */ + public function protect( Page $page, $protections, array $extraParams = [] ) { + if ( !is_array( $protections ) || empty( $protections ) ) { + throw new InvalidArgumentException( + '$protections must be an array with keys and values' + ); + } + + $params = [ + 'pageid' => $page->getId(), + 'token' => $this->api->getToken( 'protect' ), + ]; + $protectionsString = ''; + foreach ( $protections as $action => $value ) { + if ( !is_string( $action ) || !is_string( $value ) ) { + throw new InvalidArgumentException( + 'All keys and elements of $protections must be strings' + ); + } + $protectionsString = $action . '=' . $value . '|'; + } + $params['protections'] = rtrim( $protectionsString, '|' ); + + $this->api->postRequest( + new SimpleRequest( 'protect', array_merge( $extraParams, $params ) ) + ); + + return true; + } + +} diff --git a/bin/wiki/vendor/addwiki/mediawiki-api/src/Service/PagePurger.php b/bin/wiki/vendor/addwiki/mediawiki-api/src/Service/PagePurger.php new file mode 100644 index 00000000..6f9057f1 --- /dev/null +++ b/bin/wiki/vendor/addwiki/mediawiki-api/src/Service/PagePurger.php @@ -0,0 +1,116 @@ +<?php + +namespace Mediawiki\Api\Service; + +use Mediawiki\Api\Generator\ApiGenerator; +use Mediawiki\Api\SimpleRequest; +use Mediawiki\DataModel\Pages; +use Mediawiki\DataModel\Page; + +/** + * @access private + * + * @author Addshore + * @author Thomas Arrow + */ +class PagePurger extends Service { + + /** + * @since 0.3 + * + * @brief Purge a single page + * + * Purges a single page by submitting a + * 'purge' action to the mediawiki api + * with the parameter 'pageids' set to + * the singe page id + * + * @param Page $page the page that is going to be purged + * + * @return bool return true if the purge was successful + */ + public function purge( Page $page ) { + $responseArray = $this->api->postRequest( + new SimpleRequest( 'purge', [ 'pageids' => $page->getId() ] ) + ); + + // the purge response for the page + $purgeResponse = $responseArray['purge'][0]; + + return array_key_exists( 'purged', $purgeResponse ); + } + + /** + * @since 0.7 + * + * @brief Purge multiple pages + * + * Purges all the pages of the Pages object + * by submitting a 'purge' action to the mediawiki + * api with the parameter 'pageids' set to be the + * pages ids in multiple-value seperation. + * + * @param Pages $pages the pages that are going to be purged + * + * @return Pages the pages that have been purged successfully + */ + public function purgePages( Pages $pages ) { + $pagesArray = $pages->toArray(); + $pagesIds = []; + + foreach ( $pagesArray as $page ) { + array_push( $pagesIds, $page->getId() ); + } + + // convert an array to multiple-value format + // because the mediawiki api require multiple + // values to be seperated like the example + // ex: [111, 222, 333] => "111|222|333" + $pageIdsMultiple = implode( '|', $pagesIds ); + + $responseArray = $this->api->postRequest( + new SimpleRequest( 'purge', [ 'pageids' => $pageIdsMultiple ] ) + ); + + // array that will hold the successfully purged pages + $purgedPages = new Pages(); + + // for every purge result + foreach ( $responseArray['purge'] as $purgeResponse ) { + // if the purge for the page was successful + if ( array_key_exists( 'purged', $purgeResponse ) ) { + // we iterate all the input pages + foreach ( $pagesArray as $page ) { + // and if the page from the input was successfully purged + if ( $purgeResponse['title'] === $page->getTitle()->getText() ) { + // add it in the purgedPages object + $purgedPages->addPage( $page ); + + break; + } + + } + + } + + } + + return $purgedPages; + } + + /** + * @since 0.6 + * + * @param ApiGenerator $generator + * + * @return bool + */ + public function purgeGenerator( ApiGenerator $generator ) { + $this->api->postRequest( + new SimpleRequest( 'purge', $generator->getParams() ) + ); + + return true; + } + +} diff --git a/bin/wiki/vendor/addwiki/mediawiki-api/src/Service/PageRestorer.php b/bin/wiki/vendor/addwiki/mediawiki-api/src/Service/PageRestorer.php new file mode 100644 index 00000000..a422bd97 --- /dev/null +++ b/bin/wiki/vendor/addwiki/mediawiki-api/src/Service/PageRestorer.php @@ -0,0 +1,76 @@ +<?php + +namespace Mediawiki\Api\Service; + +use Mediawiki\Api\SimpleRequest; +use Mediawiki\DataModel\Page; +use Mediawiki\DataModel\Title; +use OutOfBoundsException; + +/** + * @access private + * + * @author Addshore + */ +class PageRestorer extends Service { + + /** + * @since 0.3 + * + * @param Page $page + * @param array $extraParams + * + * @return bool + */ + public function restore( Page $page, array $extraParams = [] ) { + $this->api->postRequest( + new SimpleRequest( + 'undelete', + $this->getUndeleteParams( $page->getTitle(), $extraParams ) + ) + ); + + return true; + } + + /** + * @param Title $title + * @param array $extraParams + * + * @return array + */ + private function getUndeleteParams( Title $title, $extraParams ) { + $params = []; + + $params['title'] = $title->getTitle(); + $params['token'] = $this->getUndeleteToken( $title ); + + return array_merge( $extraParams, $params ); + } + + /** + * @param Title $title + * + * @throws OutOfBoundsException + * @returns string + */ + private function getUndeleteToken( Title $title ) { + $response = $this->api->postRequest( + new SimpleRequest( + 'query', [ + 'list' => 'deletedrevs', + 'titles' => $title->getTitle(), + 'drprop' => 'token', + ] + ) + ); + if ( array_key_exists( 'token', $response['query']['deletedrevs'][0] ) ) { + return $response['query']['deletedrevs'][0]['token']; + } else { + throw new OutOfBoundsException( + 'Could not get page undelete token from list=deletedrevs query' + ); + } + } + +} diff --git a/bin/wiki/vendor/addwiki/mediawiki-api/src/Service/PageWatcher.php b/bin/wiki/vendor/addwiki/mediawiki-api/src/Service/PageWatcher.php new file mode 100644 index 00000000..e7afab17 --- /dev/null +++ b/bin/wiki/vendor/addwiki/mediawiki-api/src/Service/PageWatcher.php @@ -0,0 +1,37 @@ +<?php + +namespace Mediawiki\Api\Service; + +use Mediawiki\Api\SimpleRequest; +use Mediawiki\DataModel\Page; + +/** + * @access private + * + * @author Addshore + */ +class PageWatcher extends Service { + + /** + * @param Page $page + * + * @return bool + */ + public function watch( Page $page ) { + $params = [ + 'token' => $this->api->getToken( 'watch' ), + ]; + if ( !is_null( $page->getPageIdentifier()->getId() ) ) { + $params['pageids'] = $page->getPageIdentifier()->getId(); + } elseif ( !is_null( $page->getPageIdentifier()->getTitle() ) ) { + $params['titles'] = $page->getPageIdentifier()->getTitle()->getTitle(); + } elseif ( !is_null( $page->getRevisions()->getLatest() ) ) { + $params['revids'] = $page->getRevisions()->getLatest()->getId(); + } + + $this->api->postRequest( new SimpleRequest( 'watch', $params ) ); + + return true; + } + +} diff --git a/bin/wiki/vendor/addwiki/mediawiki-api/src/Service/Parser.php b/bin/wiki/vendor/addwiki/mediawiki-api/src/Service/Parser.php new file mode 100644 index 00000000..da83e39e --- /dev/null +++ b/bin/wiki/vendor/addwiki/mediawiki-api/src/Service/Parser.php @@ -0,0 +1,47 @@ +<?php + +namespace Mediawiki\Api\Service; + +use GuzzleHttp\Promise\PromiseInterface; +use Mediawiki\Api\SimpleRequest; +use Mediawiki\DataModel\PageIdentifier; + +/** + * @access private + * + * @author Addshore + */ +class Parser extends Service { + + /** + * @param PageIdentifier $pageIdentifier + * + * @return array the parse result (raw from the api) + */ + public function parsePage( PageIdentifier $pageIdentifier ) { + return $this->parsePageAsync( $pageIdentifier )->wait(); + } + + /** + * @param PageIdentifier $pageIdentifier + * + * @return PromiseInterface of array the parse result (raw from the api) + */ + public function parsePageAsync( PageIdentifier $pageIdentifier ) { + $params = []; + if ( $pageIdentifier->getId() !== null ) { + $params['pageid'] = $pageIdentifier->getId(); + } elseif ( $pageIdentifier->getTitle() !== null ) { + $params['page'] = $pageIdentifier->getTitle()->getText(); + } else { + throw new \RuntimeException( 'No way to identify page' ); + } + + $promise = $this->api->getRequestAsync( new SimpleRequest( 'parse', $params ) ); + + return $promise->then( function ( $result ) { + return $result['parse']; + } ); + } + +} diff --git a/bin/wiki/vendor/addwiki/mediawiki-api/src/Service/RevisionDeleter.php b/bin/wiki/vendor/addwiki/mediawiki-api/src/Service/RevisionDeleter.php new file mode 100644 index 00000000..b12a7278 --- /dev/null +++ b/bin/wiki/vendor/addwiki/mediawiki-api/src/Service/RevisionDeleter.php @@ -0,0 +1,39 @@ +<?php + +namespace Mediawiki\Api\Service; + +use Mediawiki\Api\SimpleRequest; +use Mediawiki\DataModel\Revision; + +/** + * @access private + * + * @author Addshore + */ +class RevisionDeleter extends Service { + + /** + * @since 0.5 + * + * @param Revision $revision + * + * @return bool + */ + public function delete( Revision $revision ) { + $params = [ + 'type' => 'revision', + 'hide' => 'content', + // Note: pre 1.24 this is a delete token, post it is csrf + 'token' => $this->api->getToken( 'delete' ), + 'ids' => $revision->getId(), + ]; + + $this->api->postRequest( new SimpleRequest( + 'revisiondelete', + $params + ) ); + + return true; + } + +} diff --git a/bin/wiki/vendor/addwiki/mediawiki-api/src/Service/RevisionPatroller.php b/bin/wiki/vendor/addwiki/mediawiki-api/src/Service/RevisionPatroller.php new file mode 100644 index 00000000..e642fd96 --- /dev/null +++ b/bin/wiki/vendor/addwiki/mediawiki-api/src/Service/RevisionPatroller.php @@ -0,0 +1,47 @@ +<?php + +namespace Mediawiki\Api\Service; + +use Mediawiki\Api\SimpleRequest; +use Mediawiki\DataModel\Revision; + +/** + * @access private + * + * @author Addshore + */ +class RevisionPatroller extends Service { + + /** + * @since 0.3 + * + * @param Revision $revision + * + * @return bool success + */ + public function patrol( Revision $revision ) { + $this->api->postRequest( new SimpleRequest( + 'patrol', [ + 'revid' => $revision->getId(), + 'token' => $this->getTokenForRevision( $revision ), + ] ) ); + return true; + } + + /** + * @param Revision $revision + * + * @returns string + */ + private function getTokenForRevision( Revision $revision ) { + $result = $this->api->postRequest( new SimpleRequest( 'query', [ + 'list' => 'recentchanges', + 'rcstart' => $revision->getTimestamp(), + 'rcend' => $revision->getTimestamp(), + 'rctoken' => 'patrol', + ] ) ); + $result = array_shift( $result['query']['recentchanges'] ); + return $result['patroltoken']; + } + +} diff --git a/bin/wiki/vendor/addwiki/mediawiki-api/src/Service/RevisionRestorer.php b/bin/wiki/vendor/addwiki/mediawiki-api/src/Service/RevisionRestorer.php new file mode 100644 index 00000000..fb82c252 --- /dev/null +++ b/bin/wiki/vendor/addwiki/mediawiki-api/src/Service/RevisionRestorer.php @@ -0,0 +1,39 @@ +<?php + +namespace Mediawiki\Api\Service; + +use Mediawiki\Api\SimpleRequest; +use Mediawiki\DataModel\Revision; + +/** + * @access private + * + * @author Addshore + */ +class RevisionRestorer extends Service { + + /** + * @since 0.5 + * + * @param Revision $revision + * + * @return bool + */ + public function restore( Revision $revision ) { + $params = [ + 'type' => 'revision', + 'show' => 'content', + // Note: pre 1.24 this is a delete token, post it is csrf + 'token' => $this->api->getToken( 'delete' ), + 'ids' => $revision->getId(), + ]; + + $this->api->postRequest( new SimpleRequest( + 'revisiondelete', + $params + ) ); + + return true; + } + +} diff --git a/bin/wiki/vendor/addwiki/mediawiki-api/src/Service/RevisionRollbacker.php b/bin/wiki/vendor/addwiki/mediawiki-api/src/Service/RevisionRollbacker.php new file mode 100644 index 00000000..76a2f5c7 --- /dev/null +++ b/bin/wiki/vendor/addwiki/mediawiki-api/src/Service/RevisionRollbacker.php @@ -0,0 +1,73 @@ +<?php + +namespace Mediawiki\Api\Service; + +use Mediawiki\Api\SimpleRequest; +use Mediawiki\DataModel\Revision; +use Mediawiki\DataModel\Title; + +/** + * @access private + * + * @author Addshore + */ +class RevisionRollbacker extends Service { + + /** + * @since 0.3 + * + * @param Revision $revision + * @param Title $title if using MW 1.24 of lower (https://gerrit.wikimedia.org/r/#/c/133063/) + * + * @return bool + */ + public function rollback( Revision $revision, Title $title = null ) { + $this->api->postRequest( + new SimpleRequest( 'rollback', $this->getRollbackParams( $revision, $title ) ) + ); + + return true; + } + + /** + * @param Revision $revision + * @param Title|null $title + * + * @return array + */ + private function getRollbackParams( Revision $revision, $title ) { + $params = []; + if ( !is_null( $title ) ) { + // This is needed prior to https://gerrit.wikimedia.org/r/#/c/133063/ + $params['title'] = $title->getTitle(); + } else { + // This will work after https://gerrit.wikimedia.org/r/#/c/133063/ + $params['pageid'] = $revision->getPageId(); + } + $params['user'] = $revision->getUser(); + $params['token'] = $this->getTokenForRevision( $revision ); + + return $params; + } + + /** + * @param Revision $revision + * + * @returns string + */ + private function getTokenForRevision( Revision $revision ) { + $result = $this->api->postRequest( + new SimpleRequest( + 'query', [ + 'prop' => 'revisions', + 'revids' => $revision->getId(), + 'rvtoken' => 'rollback', + ] + ) + ); + $result = array_shift( $result['query']['pages'] ); + + return $result['revisions'][0]['rollbacktoken']; + } + +} diff --git a/bin/wiki/vendor/addwiki/mediawiki-api/src/Service/RevisionSaver.php b/bin/wiki/vendor/addwiki/mediawiki-api/src/Service/RevisionSaver.php new file mode 100644 index 00000000..00b91ee6 --- /dev/null +++ b/bin/wiki/vendor/addwiki/mediawiki-api/src/Service/RevisionSaver.php @@ -0,0 +1,96 @@ +<?php + +namespace Mediawiki\Api\Service; + +use Mediawiki\Api\SimpleRequest; +use Mediawiki\DataModel\EditInfo; +use Mediawiki\DataModel\Revision; +use RuntimeException; + +/** + * @access private + * + * @author Addshore + * @author DFelten (EditInfo fix) + */ +class RevisionSaver extends Service { + + /** + * @since 0.2 + * + * @param Revision $revision + * @param EditInfo $editInfo + * + * @return bool success + */ + public function save( Revision $revision, EditInfo $editInfo = null ) { + $editInfo = $editInfo ? $editInfo : $revision->getEditInfo(); + + $result = $this->api->postRequest( + new SimpleRequest( 'edit', $this->getEditParams( $revision, $editInfo ) ) + ); + return ( $result['edit']['result'] == 'Success' ); + } + + /** + * @param Revision $revision + * @param EditInfo $editInfo + * + * @throws RuntimeException + * @returns array + */ + private function getEditParams( Revision $revision, EditInfo $editInfo = null ) { + if ( !$revision->getPageIdentifier()->identifiesPage() ) { + throw new RuntimeException( '$revision PageIdentifier does not identify a page' ); + } + + $params = []; + + $content = $revision->getContent(); + $data = $content->getData(); + if ( !is_string( $data ) ) { + throw new RuntimeException( 'Dont know how to save content of this model.' ); + } + $params['text'] = $content->getData(); + $params['md5'] = md5( $content->getData() ); + + $timestamp = $revision->getTimestamp(); + if ( !is_null( $timestamp ) ) { + $params['basetimestamp'] = $timestamp; + } + + if ( !is_null( $revision->getPageIdentifier()->getId() ) ) { + $params['pageid'] = $revision->getPageIdentifier()->getId(); + } else { + $params['title'] = $revision->getPageIdentifier()->getTitle()->getTitle(); + } + + $params['token'] = $this->api->getToken(); + + if ( $this->api->isLoggedin() ) { + $params['assert'] = 'user'; + } + + $this->addEditInfoParams( $editInfo, $params ); + + return $params; + } + + /** + * @param null|EditInfo $editInfo + * @param array &$params + */ + private function addEditInfoParams( $editInfo, &$params ) { + if ( !is_null( $editInfo ) ) { + $params['summary'] = $editInfo->getSummary(); + if ( $editInfo->getMinor() ) { + $params['minor'] = true; + } + if ( $editInfo->getBot() ) { + $params['bot'] = true; + $params['assert'] = 'bot'; + } + } + } + +} diff --git a/bin/wiki/vendor/addwiki/mediawiki-api/src/Service/RevisionUndoer.php b/bin/wiki/vendor/addwiki/mediawiki-api/src/Service/RevisionUndoer.php new file mode 100644 index 00000000..e411030e --- /dev/null +++ b/bin/wiki/vendor/addwiki/mediawiki-api/src/Service/RevisionUndoer.php @@ -0,0 +1,48 @@ +<?php + +namespace Mediawiki\Api\Service; + +use Mediawiki\Api\SimpleRequest; +use Mediawiki\DataModel\Revision; + +/** + * @access private + * + * @author Addshore + */ +class RevisionUndoer extends Service { + + /** + * @param Revision $revision + * + * @return bool + */ + public function undo( Revision $revision ) { + $this->api->postRequest( new SimpleRequest( + 'edit', + $this->getParamsFromRevision( $revision ) + ) ); + return true; + } + + /** + * @param Revision $revision + * + * @return array + */ + private function getParamsFromRevision( Revision $revision ) { + $params = [ + 'undo' => $revision->getId(), + 'token' => $this->api->getToken(), + ]; + + if ( !is_null( $revision->getPageIdentifier()->getId() ) ) { + $params['pageid'] = $revision->getPageIdentifier()->getId(); + } else { + $params['title'] = $revision->getPageIdentifier()->getTitle()->getTitle(); + } + + return $params; + } + +} diff --git a/bin/wiki/vendor/addwiki/mediawiki-api/src/Service/Service.php b/bin/wiki/vendor/addwiki/mediawiki-api/src/Service/Service.php new file mode 100644 index 00000000..4a4b466b --- /dev/null +++ b/bin/wiki/vendor/addwiki/mediawiki-api/src/Service/Service.php @@ -0,0 +1,23 @@ +<?php + +namespace MediaWiki\Api\Service; + +use Mediawiki\Api\MediawikiApi; + +/** + * The base service functions that all services inherit. + * @since 0.7.2 + */ +abstract class Service { + + /** @var MediawikiApi */ + protected $api; + + /** + * @param MediawikiApi $api The API to in for this service. + */ + public function __construct( MediawikiApi $api ) { + $this->api = $api; + } + +} diff --git a/bin/wiki/vendor/addwiki/mediawiki-api/src/Service/UserBlocker.php b/bin/wiki/vendor/addwiki/mediawiki-api/src/Service/UserBlocker.php new file mode 100644 index 00000000..9cf9f421 --- /dev/null +++ b/bin/wiki/vendor/addwiki/mediawiki-api/src/Service/UserBlocker.php @@ -0,0 +1,45 @@ +<?php + +namespace Mediawiki\Api\Service; + +use InvalidArgumentException; +use Mediawiki\Api\SimpleRequest; +use Mediawiki\DataModel\User; + +/** + * @access private + * + * @author Addshore + */ +class UserBlocker extends Service { + + /** + * @since 0.3 + * + * @param User|string $user + * @param array $extraParams + * + * @throws InvalidArgumentException + * @return bool + */ + public function block( $user, array $extraParams = [] ) { + if ( !$user instanceof User && !is_string( $user ) ) { + throw new InvalidArgumentException( '$user must be either a string or User object' ); + } + + if ( $user instanceof User ) { + $user = $user->getName(); + } + + $params = [ + 'user' => $user, + 'token' => $this->api->getToken( 'block' ), + ]; + + $params = array_merge( $extraParams, $params ); + + $this->api->postRequest( new SimpleRequest( 'block', $params ) ); + return true; + } + +} diff --git a/bin/wiki/vendor/addwiki/mediawiki-api/src/Service/UserCreator.php b/bin/wiki/vendor/addwiki/mediawiki-api/src/Service/UserCreator.php new file mode 100644 index 00000000..8d74b107 --- /dev/null +++ b/bin/wiki/vendor/addwiki/mediawiki-api/src/Service/UserCreator.php @@ -0,0 +1,83 @@ +<?php + +namespace Mediawiki\Api\Service; + +use InvalidArgumentException; +use Mediawiki\Api\SimpleRequest; +use Mediawiki\Api\UsageException; + +/** + * @access private + * + * @author Addshore + */ +class UserCreator extends Service { + + /** + * @param string $username + * @param string $password + * @param string|null $email + * + * @return bool + */ + public function create( $username, $password, $email = null ) { + if ( !is_string( $username ) ) { + throw new InvalidArgumentException( '$username should be a string' ); + } + if ( !is_string( $password ) ) { + throw new InvalidArgumentException( '$password should be a string' ); + } + if ( !is_string( $email ) && !is_null( $email ) ) { + throw new InvalidArgumentException( '$email should be a string or null' ); + } + + $params = [ + 'createreturnurl' => $this->api->getApiUrl(), + 'createtoken' => $this->api->getToken( 'createaccount' ), + 'username' => $username, + 'password' => $password, + 'retype' => $password, + ]; + + if ( !is_null( $email ) ) { + $params['email'] = $email; + } + + try { + $result = $this->api->postRequest( new SimpleRequest( 'createaccount', $params ) ); + return $result['createaccount']['status'] === 'PASS'; + } catch ( UsageException $exception ) { + // If the above request failed, try again in the old way. + if ( $exception->getApiCode() === 'noname' ) { + return $this->createPreOneTwentySeven( $params ); + } + throw $exception; + } + } + + /** + * Create a user in the pre 1.27 manner. + * @link https://www.mediawiki.org/wiki/API:Account_creation/pre-1.27 + * @return bool + */ + protected function createPreOneTwentySeven( $params ) { + $newParams = [ + 'name' => $params['username'], + 'password' => $params['password'], + ]; + if ( array_key_exists( 'email', $params ) ) { + $newParams['email'] = $params['email']; + } + // First get the token. + $tokenRequest = new SimpleRequest( 'createaccount', $newParams ); + $result = $this->api->postRequest( $tokenRequest ); + if ( $result['createaccount']['result'] == 'NeedToken' ) { + // Then send the token to create the account. + $newParams['token'] = $result['createaccount']['token']; + $request = new SimpleRequest( 'createaccount', $newParams ); + $result = $this->api->postRequest( $request ); + } + return ( $result['createaccount']['result'] === 'Success' ); + } + +} diff --git a/bin/wiki/vendor/addwiki/mediawiki-api/src/Service/UserGetter.php b/bin/wiki/vendor/addwiki/mediawiki-api/src/Service/UserGetter.php new file mode 100644 index 00000000..d3bfbd5b --- /dev/null +++ b/bin/wiki/vendor/addwiki/mediawiki-api/src/Service/UserGetter.php @@ -0,0 +1,63 @@ +<?php + +namespace Mediawiki\Api\Service; + +use Mediawiki\Api\SimpleRequest; +use Mediawiki\DataModel\User; + +/** + * @access private + * + * @author Addshore + */ +class UserGetter extends Service { + + /** + * @param string $username + * + * @return User + */ + public function getFromUsername( $username ) { + $result = $this->api->getRequest( + new SimpleRequest( + 'query', [ + 'list' => 'users', + 'ususers' => $username, + 'usprop' => 'gender|emailable|registration|editcount|rights|implicitgroups|groups|blockinfo', + ] + ) + ); + + return $this->newUserFromListUsersResult( array_shift( $result['query']['users'] ) ); + } + + /** + * @param array $array + * + * @return User + */ + private function newUserFromListUsersResult( $array ) { + if ( array_key_exists( 'userid', $array ) ) { + return new User( + $array['name'], + $array['userid'], + $array['editcount'], + $array['registration'], + [ 'groups' => $array['groups'], 'implicitgroups' => $array['implicitgroups'] ], + $array['rights'], + $array['gender'] + ); + } else { + return new User( + $array['name'], + 0, + 0, + '', + [ 'groups' => [], 'implicitgroups' => [] ], + [], + '' + ); + } + } + +} diff --git a/bin/wiki/vendor/addwiki/mediawiki-api/src/Service/UserRightsChanger.php b/bin/wiki/vendor/addwiki/mediawiki-api/src/Service/UserRightsChanger.php new file mode 100644 index 00000000..4fbea9c1 --- /dev/null +++ b/bin/wiki/vendor/addwiki/mediawiki-api/src/Service/UserRightsChanger.php @@ -0,0 +1,59 @@ +<?php + +namespace Mediawiki\Api\Service; + +use Mediawiki\Api\SimpleRequest; +use Mediawiki\DataModel\User; + +/** + * @access private + * + * @author Addshore + */ +class UserRightsChanger extends Service { + + /** + * @since 0.3 + * + * @param User $user + * @param string[] $add + * @param string[] $remove + * @param array $extraParams + * + * @return bool + */ + public function change( + User $user, + $add = [], + $remove = [], + array $extraParams = [] + ) { + $result = $this->api->postRequest( + new SimpleRequest( + 'query', [ + 'list' => 'users', + 'ustoken' => 'userrights', + 'ususers' => $user->getName(), + ] + ) + ); + + $params = [ + 'user' => $user->getName(), + 'token' => $result['query']['users'][0]['userrightstoken'], + ]; + if ( !empty( $add ) ) { + $params['add'] = implode( '|', $add ); + } + if ( !empty( $remove ) ) { + $params['remove'] = implode( '|', $remove ); + } + + $this->api->postRequest( + new SimpleRequest( 'userrights', array_merge( $extraParams, $params ) ) + ); + + return true; + } + +} |