Yurik has uploaded a new change for review.

  https://gerrit.wikimedia.org/r/194874

Change subject: Implemented api action=editcollection
......................................................................

Implemented api action=editcollection

The eastiest way to use it - create a file settings.d/00.php (in vagrant):
if ( class_exists( 'ExtensionRegistry' ) && file_exists( 
"$IP/extensions/Gather/extension.json" ) ) {
    ExtensionRegistry::getInstance()->queue( 
"$IP/extensions/Gather/extension.json" );
} else {
    include_once "$IP/extensions/Gather/Gather.php";
}
$wgDebugAPI = true;  // This allows GET requests to be treated as POST for easy 
debugging

Copy token number from 
http://localhost:8080/w/api.php?action=query&meta=tokens&type=watch

Replace token number in this URL (leave the %2B\ intact) and run:
http://localhost:8080/w/api.php?action=editcollection&token=833e0b1f14270c04b7c2daa3caf742b154f9a8fe%2B\&generator=allpages&label=mylist
Which will take first 10 pages of your wiki and add them to the new collection.

See result in http://localhost:8080/wiki/User:Admin/GatherCollections.json

API doc http://localhost:8080/w/api.php?action=help&modules=editcollection

Change-Id: Iaf6cc4553f2563fb2c9ffce2eac40eb13122253a
---
M Gather.php
M extension.json
A includes/api/ApiEditCollection.php
3 files changed, 326 insertions(+), 0 deletions(-)


  git pull ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/Gather 
refs/changes/74/194874/1

diff --git a/Gather.php b/Gather.php
index 64f74e8..11f702b 100644
--- a/Gather.php
+++ b/Gather.php
@@ -63,6 +63,7 @@
 
        'Gather\SpecialGather' => 'specials/SpecialGather',
 
+       'Gather\api\ApiEditCollection' => 'api/ApiEditCollection',
        'Gather\api\CollectionsListApi' => 'api/CollectionsListApi',
 
 );
@@ -84,6 +85,7 @@
 
 // Api
 $wgAPIModules['gather'] = 'Gather\api\CollectionsListApi';
+$wgAPIModules['editcollection'] = 'Gather\api\ApiEditCollection';
 
 // ResourceLoader modules
 require_once __DIR__ . "/resources/Resources.php";
diff --git a/extension.json b/extension.json
index 1a2ed0e..24ccfc8 100644
--- a/extension.json
+++ b/extension.json
@@ -47,8 +47,13 @@
                "Gather\\views\\CollectionsListItemCard": 
"includes/views/CollectionsListItemCard.php",
                "Gather\\views\\helpers\\CSS": "includes/views/helpers/CSS.php",
                "Gather\\SpecialGather": "includes/specials/SpecialGather.php",
+               "Gather\\api\\ApiEditCollection": 
"includes/api/ApiEditCollection.php",
                "Gather\\api\\CollectionsListApi": 
"includes/api/CollectionsListApi.php"
        },
+    "APIModules": {
+      "editcollection": "Gather\\api\\ApiEditCollection",
+      "gather": "Gather\\api\\CollectionsListApi"
+    },
        "ResourceModules": {
                "ext.gather.icons": {
                        "targets": [
diff --git a/includes/api/ApiEditCollection.php 
b/includes/api/ApiEditCollection.php
new file mode 100644
index 0000000..a587770
--- /dev/null
+++ b/includes/api/ApiEditCollection.php
@@ -0,0 +1,319 @@
+<?php
+/**
+ *
+ *
+ * Created on Mar 6, 2015
+ *
+ * Copyright © 2015 Yuri Astrakhan "<Firstname><Lastname>@gmail.com",
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ */
+
+namespace Gather\api;
+use ApiBase;
+use FormatJson;
+use Gather\stores\UserPageCollectionsList;
+use JsonContent;
+use Status;
+use stdClass;
+use Title;
+use User;
+use ApiPageSet;
+use WikiPage;
+
+/**
+ * API module to allow users to manage collections
+ *
+ * @ingroup API
+ */
+class ApiEditCollection extends ApiBase {
+       private $mPageSet = null;
+
+       /**
+        * @throws \UsageException
+        */
+       public function execute() {
+               $user = $this->getUser();
+               if ( !$user->isLoggedIn() ) {
+                       $this->dieUsage( 'You must be logged-in to have a 
watchlist', 'notloggedin' );
+               }
+
+               if ( !$user->isAllowed( 'editmywatchlist' ) ) {
+                       $this->dieUsage( 'You don\'t have permission to edit 
your watchlist',
+                               'permissiondenied' );
+               }
+
+               $params = $this->extractRequestParams();
+               $pageSet = $this->getPageSet();
+               $p = $this->getModulePrefix();
+
+               $id = $params['id'];
+               $isNew = !$id;
+
+               if ( $params['deletecollection'] ) {
+
+                       // Disallow all parameters except deletecollection, id, 
and token
+                       $tmp = $params + $pageSet->extractRequestParams();
+                       unset( $tmp['deletecollection'] );
+                       unset( $tmp['id'] );
+                       unset( $tmp['token'] );
+                       $extraParams =
+                               array_keys( array_filter( $tmp, function ( $x ) 
{
+                                       return $x !== null && $x !== false;
+                               } ) );
+
+                       if ( $extraParams ) {
+                               $this->dieUsage( "The parameter 
{$p}deletecollection must not be used with " .
+                                                                implode( ", ", 
$extraParams ), 'invalidparammix' );
+                       }
+                       if ( $isNew ) {
+                               $this->dieUsage( "Collection must be identified 
with {$p}id when {$p}deletecollection is used", 'invalidparammix' );
+                       }
+               }
+
+               $status = self::loadData( $user );
+               if ( !$status->isOK() ) {
+                       $this->getResult()
+                               ->addValue( 'error', null, 
$this->getResult()->convertStatusToArray( $status ) );
+                       return;
+               }
+
+               $data = $status->getValue();
+               /** @var stdClass $collection */
+               $collection = null;
+
+               if ( $isNew ) {
+                       if ( $params['remove'] ) {
+                               $this->dieUsage( "Collection must be identified 
with {$p}id when {$p}remove is used", 'invalidparammix' );
+                       }
+                       if ( !$params['label'] ) {
+                               $this->dieUsage( "Collection {$p}label must be 
given for new collections", 'invalidparammix' );
+                       }
+
+                       $id = 1;
+                       if ( $data ) {
+                               foreach ( $data as $c ) {
+                                       if ( $c->id > $id ) {
+                                               $id = $c->id + 1;
+                                       }
+                               }
+                       } else {
+                               $data = array();
+                       }
+
+                       $collection = new stdClass();
+                       $collection->id = $id;
+                       $collection->owner = $user->getName();
+                       $collection->title = $params['label'];
+                       $collection->description = $params['description'];
+                       $collection->public = true;
+                       $collection->image = null;
+                       $collection->items = array();
+                       $collection->count = 0;
+
+                       $data[] = $collection;
+               } else {
+                       foreach ( $data as $c ) {
+                               if ( $c->id === $id ) {
+                                       $collection = $c;
+                                       break;
+                               }
+                       }
+                       if ( $collection === null ) {
+                               $this->dieUsage( "Collection {$p}id was not 
found", 'badid' );
+                       }
+                       if ( $params['label'] || $params['description'] ) {
+                               $collection->title = $params['label'] ?: 
$collection->title;
+                               $collection->description = 
$params['description'] ?: $collection->description;
+                       }
+               }
+
+               if ( $params['deletecollection'] ) {
+                       $data = array_filter( $data, function ( $x ) use ( $id 
) {
+                               return $x->id !== $id;
+                       } );
+               } else {
+
+                       $this->getResult()->beginContinuation( 
$params['continue'], array(), array() );
+
+                       $pageSet->execute();
+                       $res = $pageSet->getInvalidTitlesAndRevisions( array(
+                               'invalidTitles',
+                               'special',
+                               'missingIds',
+                               'missingRevIds',
+                               'interwikiTitles'
+                       ) );
+
+                       foreach ( $pageSet->getMissingTitles() as $title ) {
+                               $r = $this->watchTitle( $collection, $title, 
$user, $params );
+                               $r['missing'] = 1;
+                               $res[] = $r;
+                       }
+
+                       foreach ( $pageSet->getGoodTitles() as $title ) {
+                               $r = $this->watchTitle( $collection, $title, 
$user, $params );
+                               $res[] = $r;
+                       }
+                       $this->getResult()->setIndexedTagName( $res, 'w' );
+                       $this->getResult()->addValue( $this->getModuleName(), 
'pages', $res );
+                       $this->getResult()->endContinuation();
+
+                       $collection->count = count( $collection->items );
+               }
+
+               self::save( $user, $data );
+       }
+
+       private function watchTitle( stdClass $collection, Title $title, User 
$user, array $params ) {
+               $titleStr = $title->getPrefixedText();
+
+               if ( !$title->isWatchable() ) {
+                       return array( 'title' => $titleStr, 'watchable' => 0 );
+               }
+
+               $res = array( 'title' => $titleStr );
+               $key = array_search( $titleStr, $collection->items );
+
+               if ( $params['remove'] ) {
+//                     $status = UnwatchAction::doUnwatch( $title, $user );
+                       if ( $key !== false ) {
+                               unset( $collection->items[$key] );
+                               $status = Status::newGood();
+                       } else {
+                               $status = Status::newFatal( 'not-found' ); // 
TODO: proper message
+                       }
+                       if ( $status->isOK() ) {
+                               $res['removed'] = '';
+                               $res['message'] = $this->msg( 
'removedwatchtext', $title->getPrefixedText() )
+                                       ->title( $title )->parseAsBlock();
+                       }
+               } else {
+//                     $status = WatchAction::doWatch( $title, $user );
+                       if ( $key !== false ) {
+                               $status = Status::newFatal( 'already-added' ); 
// TODO: proper message
+                       } else {
+                               $collection->items[] = $titleStr;
+                               $status = Status::newGood();
+                       }
+                       if ( $status->isOK() ) {
+                               $res['added'] = '';
+                               $res['message'] = $this->msg( 'addedwatchtext', 
$titleStr )
+                                       ->title( $title )->parseAsBlock();
+                       }
+               }
+
+               if ( !$status->isOK() ) {
+                       $res['error'] = $this->getErrorFromStatus( $status );
+               }
+
+               return $res;
+       }
+
+       /**
+        * Get a cached instance of an ApiPageSet object
+        * @return ApiPageSet
+        */
+       private function getPageSet() {
+               if ( $this->mPageSet === null ) {
+                       $this->mPageSet = new ApiPageSet( $this );
+               }
+
+               return $this->mPageSet;
+       }
+
+       public function mustBePosted() {
+               return true;
+       }
+
+       public function isWriteMode() {
+               return true;
+       }
+
+       public function needsToken() {
+               return 'watch';
+       }
+
+       public function getAllowedParams( $flags = 0 ) {
+               $result = array(
+                       'id' => array(
+                               ApiBase::PARAM_TYPE => 'integer',
+                       ),
+                       'label' => array(
+                               ApiBase::PARAM_TYPE => 'string',
+                       ),
+                       'description' => array(
+                               ApiBase::PARAM_TYPE => 'string',
+                       ),
+                       'remove' => false,
+                       'deletecollection' => false,
+                       'continue' => array(
+                               ApiBase::PARAM_HELP_MSG => 
'api-help-param-continue',
+                       ),
+               );
+               if ( $flags ) {
+                       $result += $this->getPageSet()->getFinalParams( $flags 
);
+               }
+
+               return $result;
+       }
+
+//     protected function getExamplesMessages() {
+//             return array(
+//             );
+//     }
+
+       public function getHelpUrls() {
+               return '//www.mediawiki.org/wiki/Extension:Gather';
+       }
+
+
+       /**
+        * Temporary function to get data from a JSON blob stored on the user's 
page
+        * @param User $user
+        * @return Status
+        */
+       public function loadData( $user ) {
+               $title = UserPageCollectionsList::getStorageTitle( $user );
+               $page = WikiPage::factory( $title );
+               $status = null;
+               if ( $page->exists() ) {
+                       $content = $page->getContent();
+                       if ( $page->getContentModel() === CONTENT_MODEL_JSON ) {
+                               $status = $content->getData();
+                       }
+               }
+               if ( !$status ) {
+                       $status = Status::newFatal( 'unknown' ); // TODO: fix
+               }
+               return $status;
+       }
+
+       /**
+        * Temporary function to save data to the JSON blob stored on the 
user's page
+        * @param User $user
+        * @param $data
+        * @return Status
+        */
+       public function save( User $user, $data ) {
+               $title = UserPageCollectionsList::getStorageTitle( $user );
+               $page = WikiPage::factory( $title );
+               $content = new JsonContent( FormatJson::encode( $data, 
FormatJson::ALL_OK ) );
+               return $page->doEditContent( $content, 'ApiEditCollection.php' 
);
+       }
+}

-- 
To view, visit https://gerrit.wikimedia.org/r/194874
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: Iaf6cc4553f2563fb2c9ffce2eac40eb13122253a
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/extensions/Gather
Gerrit-Branch: master
Gerrit-Owner: Yurik <[email protected]>

_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to