https://www.mediawiki.org/wiki/Special:Code/MediaWiki/113032

Revision: 113032
Author:   santhosh
Date:     2012-03-05 14:10:36 +0000 (Mon, 05 Mar 2012)
Log Message:
-----------
Group translatable pages into aggregate groups, - Special page and associated 
API, javascripts, css and images.
Card i18n#572

Modified Paths:
--------------
    trunk/extensions/Translate/PageTranslation.i18n.php
    trunk/extensions/Translate/Translate.alias.php
    trunk/extensions/Translate/Translate.php
    trunk/extensions/Translate/_autoload.php

Added Paths:
-----------
    trunk/extensions/Translate/api/ApiAggregateGroups.php
    
trunk/extensions/Translate/resources/ext.translate.special.aggregategroups.css
    
trunk/extensions/Translate/resources/ext.translate.special.aggregategroups.js
    trunk/extensions/Translate/resources/images/add.png
    trunk/extensions/Translate/resources/images/remove.png
    trunk/extensions/Translate/specials/SpecialAggregateGroups.php

Modified: trunk/extensions/Translate/PageTranslation.i18n.php
===================================================================
--- trunk/extensions/Translate/PageTranslation.i18n.php 2012-03-05 13:30:13 UTC 
(rev 113031)
+++ trunk/extensions/Translate/PageTranslation.i18n.php 2012-03-05 14:10:36 UTC 
(rev 113032)
@@ -112,6 +112,12 @@
 
        'tpt-download-page' => 'Export page with translations',
 
+       'tpt-aggregategroups' => 'Aggregate Groups',
+       'tpt-aggregategroup-add' => 'Add',
+       'tpt-aggregategroup-save' => 'Save',
+       'tpt-aggregategroup-add-new' => 'Add a new aggregate group',
+       'tpt-aggregategroup-new-name' => 'Name:',
+       'tpt-aggregategroup-new-description' => 'Description(optional):',
        'pt-parse-open' => 'Unbalanced <translate> tag.
 Translation template: <pre>$1</pre>',
        'pt-parse-close' => 'Unbalanced &lt;/translate> tag.

Modified: trunk/extensions/Translate/Translate.alias.php
===================================================================
--- trunk/extensions/Translate/Translate.alias.php      2012-03-05 13:30:13 UTC 
(rev 113031)
+++ trunk/extensions/Translate/Translate.alias.php      2012-03-05 14:10:36 UTC 
(rev 113032)
@@ -23,6 +23,7 @@
        'SupportedLanguages' => array( 'SupportedLanguages' ),
        'MyLanguage' => array( 'MyLanguage' ),
        'PageTranslationDeletePage' => array( 'PageTranslationDeletePage' ),
+       'AggregateGroups' => Array( 'AggregateGroups' ),
 );
 
 /** Afrikaans (Afrikaans) */
@@ -822,4 +823,4 @@
        'FirstSteps' => array( '入門' ),
        'SupportedLanguages' => array( '支持的語言' ),
        'MyLanguage' => array( '我的語言' ),
-);
\ No newline at end of file
+);

Modified: trunk/extensions/Translate/Translate.php
===================================================================
--- trunk/extensions/Translate/Translate.php    2012-03-05 13:30:13 UTC (rev 
113031)
+++ trunk/extensions/Translate/Translate.php    2012-03-05 14:10:36 UTC (rev 
113032)
@@ -45,6 +45,7 @@
 $wgExtensionMessagesFiles['Translate'] = "$dir/Translate.i18n.php";
 $wgExtensionMessagesFiles['FirstSteps'] = "$dir/FirstSteps.i18n.php";
 $wgExtensionMessagesFiles['PageTranslation'] = "$dir/PageTranslation.i18n.php";
+$wgExtensionMessagesFiles['AggregateGroups'] = "$dir/PageTranslation.i18n.php";
 $wgExtensionMessagesFiles['TranslateGroupDescriptions'] = 
"$dir/TranslateGroupDescriptions.i18n.php";
 $wgExtensionMessagesFiles['TranslateAlias'] = "$dir/Translate.alias.php";
 $wgExtensionMessagesFiles['TranslateMagic'] = "$dir/Translate.magic.php";
@@ -81,6 +82,7 @@
 $wgSpecialPages['SupportedLanguages'] = 'SpecialSupportedLanguages';
 // Unlisted special page; does not need $wgSpecialPageGroups.
 $wgSpecialPages['MyLanguage'] = 'SpecialMyLanguage';
+$wgSpecialPages['AggregateGroups'] = 'SpecialAggregateGroups';
 
 // API
 $wgAPIListModules['messagecollection'] = 'ApiQueryMessageCollection';
@@ -89,9 +91,11 @@
 $wgAPIMetaModules['messagetranslations'] = 'ApiQueryMessageTranslations';
 $wgAPIModules['translationreview'] = 'ApiTranslationReview';
 $wgAPIModules['groupreview'] = 'ApiGroupReview';
+$wgAPIModules['aggregategroups'] = 'ApiAggregateGroups';
 $wgAPIModules['ttmserver'] = 'ApiTTMServer';
 $wgHooks['APIQueryInfoTokens'][] = 'ApiTranslationReview::injectTokenFunction';
 $wgHooks['APIQueryInfoTokens'][] = 'ApiGroupReview::injectTokenFunction';
+$wgHooks['APIQueryInfoTokens'][] = 'ApiAggregateGroups::injectTokenFunction';
 
 // Register hooks.
 $wgHooks['EditPage::showEditForm:initial'][] = 'TranslateEditAddons::addTools';
@@ -254,6 +258,12 @@
        'position' => 'top',
 ) + $resourcePaths;
 
+$wgResourceModules['ext.translate.special.aggregategroups'] = array(
+       'scripts' => 'resources/ext.translate.special.aggregategroups.js',
+       'styles' => 'resources/ext.translate.special.aggregategroups.css',
+       'position' => 'top',
+) + $resourcePaths;
+
 $wgResourceModules['ext.translate.special.supportedlanguages'] = array(
        'styles' => 'resources/ext.translate.special.supportedlanguages.css',
        'position' => 'top',

Modified: trunk/extensions/Translate/_autoload.php
===================================================================
--- trunk/extensions/Translate/_autoload.php    2012-03-05 13:30:13 UTC (rev 
113031)
+++ trunk/extensions/Translate/_autoload.php    2012-03-05 14:10:36 UTC (rev 
113032)
@@ -54,6 +54,7 @@
  * There are few more special pages in page translation section.
  * @{
  */
+$wgAutoloadClasses['SpecialAggregateGroups'] = 
"$dir/specials/SpecialAggregateGroups.php";
 $wgAutoloadClasses['SpecialFirstSteps'] = 
"$dir/specials/SpecialFirstSteps.php";
 $wgAutoloadClasses['SpecialImportTranslations'] = 
"$dir/specials/SpecialImportTranslations.php";
 $wgAutoloadClasses['SpecialLanguageStats'] = 
"$dir/specials/SpecialLanguageStats.php";
@@ -180,6 +181,7 @@
  * @{
  */
 $wgAutoloadClasses['ApiGroupReview'] = "$dir/api/ApiGroupReview.php";
+$wgAutoloadClasses['ApiAggregateGroups'] = "$dir/api/ApiAggregateGroups.php";
 $wgAutoloadClasses['ApiQueryMessageCollection'] = 
"$dir/api/ApiQueryMessageCollection.php";
 $wgAutoloadClasses['ApiQueryMessageGroupStats'] = 
"$dir/api/ApiQueryMessageGroupStats.php";
 $wgAutoloadClasses['ApiQueryMessageGroups'] = 
"$dir/api/ApiQueryMessageGroups.php";

Added: trunk/extensions/Translate/api/ApiAggregateGroups.php
===================================================================
--- trunk/extensions/Translate/api/ApiAggregateGroups.php                       
        (rev 0)
+++ trunk/extensions/Translate/api/ApiAggregateGroups.php       2012-03-05 
14:10:36 UTC (rev 113032)
@@ -0,0 +1,187 @@
+<?php
+/**
+ * API module for managing aggregate groups
+ * @file
+ * @author Santhosh Thottingal
+ * @copyright Copyright © 2011, Santhosh Thottingal
+ * @license http://www.gnu.org/copyleft/gpl.html GNU General Public License 
2.0 or later
+ */
+
+/**
+ * API module for managing aggregate groups
+ *
+ * @ingroup API TranslateAPI
+ */
+class ApiAggregateGroups extends ApiBase {
+       protected static $right = 'translate-manage';
+       protected static $salt = 'translate-manage';
+
+       public function execute() {
+               global $wgUser;
+
+               if ( !$wgUser->isallowed( self::$right ) ) {
+                       $this->dieUsage( 'Permission denied', 
'permissiondenied' );
+               }
+
+               $requestParams = $this->extractRequestParams();
+               $aggregateGroup = $requestParams['aggregategroup'];
+               if ( $requestParams['do'] === 'associate' ) {
+                       $group = $requestParams['group'];
+                       $aggregateGroups = TranslateMetadata::get( 
$aggregateGroup, 'subgroups' );
+                       if ( trim( $aggregateGroups ) ) {
+                               $aggregateGroups =  array_map( 'trim',  
explode( ',', $aggregateGroups ) );
+                       }
+                       else {
+                               $aggregateGroups = array();
+                       }
+                       $aggregateGroups[] = $group;
+                       $aggregateGroups = array_unique( $aggregateGroups );
+                       $newSubGroups =  implode( ',', $aggregateGroups );
+                       TranslateMetadata::set( $aggregateGroup, 'subgroups' , 
$newSubGroups ) ;
+               }
+               if ( $requestParams['do'] === 'dissociate' ) {
+                       $group = $requestParams['group'];
+                       $aggregateGroups = TranslateMetadata::get( 
$aggregateGroup, 'subgroups' );
+                       $aggregateGroups =  array_flip( explode( ',', 
$aggregateGroups ) ) ;
+                       if ( isset( $aggregateGroups[$group] ) ) {
+                               unset( $aggregateGroups[$group] );
+                       }
+                       $aggregateGroups = array_flip( $aggregateGroups );
+                       TranslateMetadata::set( $aggregateGroup, 'subgroups' , 
implode( ',', $aggregateGroups ) ) ;
+               }
+               if ( $requestParams['do'] === 'remove' ) {
+                       TranslateMetadata::set( $aggregateGroup, 'subgroups', 
false ) ;
+                       TranslateMetadata::set( $aggregateGroup, 'name', false 
) ;
+                       TranslateMetadata::set( $aggregateGroup, 'description', 
false ) ;
+               }
+               if ( $requestParams['do'] === 'add' ) {
+                       TranslateMetadata::set( $aggregateGroup, 'subgroups' , 
'' ) ;
+                       if ( trim( $requestParams['groupname'] ) ) {
+                               TranslateMetadata::set( $aggregateGroup, 'name' 
, trim( $requestParams['groupname'] ) ) ;
+                       }
+                       if ( trim( $requestParams['groupdescription'] ) ) {
+                               TranslateMetadata::set( $aggregateGroup, 
'description' , trim( $requestParams['groupdescription'] ) ) ;
+                       }
+               }
+               $output = array( 'result' => 'ok' );
+               $this->getResult()->addValue( null, $this->getModuleName(), 
$output );
+       }
+
+       public function isWriteMode() {
+               return true;
+       }
+
+       public function getTokenSalt() {
+               return self::$salt;
+       }
+       public function needsToken() {
+               return true;
+       }
+
+       public function getAllowedParams() {
+               global $wgTranslateWorkflowStates;
+               return array(
+                       'do' => array(
+                               ApiBase::PARAM_TYPE => array( 'associate', 
'dissociate', 'remove' , 'add' ),
+                               ApiBase::PARAM_REQUIRED => true,
+                       ),
+                       'aggregategroup' => array(
+                               ApiBase::PARAM_TYPE => 'string',
+                               ApiBase::PARAM_REQUIRED => true,
+                       ),
+                       'group' => array(
+                               ApiBase::PARAM_TYPE => array_keys( 
MessageGroups::getAllGroups() ),
+                       ),
+                       'groupname' => array(
+                               ApiBase::PARAM_TYPE => 'string',
+                       ),
+                       'groupdescription' => array(
+                               ApiBase::PARAM_TYPE => 'string',
+                       ),
+                       'token' => array(
+                               ApiBase::PARAM_TYPE => 'string',
+                               ApiBase::PARAM_REQUIRED => true,
+                       ),
+               );
+       }
+
+       public function getParamDescription() {
+               return array(
+                       'do' => 'Required operation, Either of associate, 
dissociate, add or remove',
+                       'group' => 'Message group id',
+                       'aggregategroup' => 'Aggregate group id',
+                       'groupname' => 'Aggregate group name',
+                       'groupdescription' => 'Aggregate group description',
+                       'token' => 'A token previously acquired with 
action=query&prop=info&intoken=aggregategroups',
+               );
+       }
+
+       public static function getAggregateGroups() {
+               $dbr = wfGetDB( DB_MASTER );
+               $tables = array( 'translate_metadata' );
+               $vars = array( 'tmd_group', 'tmd_value' );
+               $conds = array(
+                       'tmd_key' => 'subgroups',
+               );
+               $options = array(
+                       'ORDER BY' => 'tmd_group',
+               );
+               $res = $dbr->select( $tables, $vars, $conds, __METHOD__, 
$options );
+               $aggregateGroups = array();
+               foreach ( $res as $r ) {
+                       $aggregateGroups[$r->tmd_group] = array();
+                       $aggregateGroups[$r->tmd_group]['id'] = $r->tmd_group;
+                       $aggregateGroups[$r->tmd_group]['name'] = 
TranslateMetadata::get( $r->tmd_group, 'name' );
+                       $aggregateGroups[$r->tmd_group]['description'] = 
TranslateMetadata::get( $r->tmd_group, 'description' );
+                       $subGroupsArray = explode( ',', $r->tmd_value ) ;
+                       $subGroups = array();
+                       foreach ( $subGroupsArray as $subGroup ) {
+                               $subGroups[$subGroup] = 
MessageGroups::getGroup( trim( $subGroup ) );
+                       }
+                       $aggregateGroups[$r->tmd_group]['subgroups'] = 
$subGroups ;
+               }
+               return $aggregateGroups;
+       }
+
+       public function getDescription() {
+               return 'Manage aggregate groups';
+       }
+
+       public function getPossibleErrors() {
+               $right = self::$right;
+               return array_merge( parent::getPossibleErrors(), array(
+                       array( 'code' => 'permissiondenied', 'info' => "You 
must have $right right" ),
+               ) );
+       }
+
+       public function getExamples() {
+               return array(
+                       
"api.php?action=aggregategroups&do=associate&group=groupId&aggregategroup=aggregateGroupId",
+               );
+       }
+
+       public function getVersion() {
+               return __CLASS__ . ': $Id$';
+       }
+
+       public static function getToken( $pageid, $title ) {
+               global $wgUser;
+               if ( !$wgUser->isAllowed( self::$right ) ) {
+                       return false;
+               }
+
+               static $cachedToken = null;
+               if ( !is_null( $cachedToken ) ) {
+                       return $cachedToken;
+               }
+
+               $cachedToken = $wgUser->getEditToken( self::$salt );
+               return $cachedToken;
+       }
+
+       public static function injectTokenFunction( &$list ) {
+               $list['aggregategroups'] = array( __CLASS__, 'getToken' );
+               return true; // Hooks must return bool
+       }
+
+}


Property changes on: trunk/extensions/Translate/api/ApiAggregateGroups.php
___________________________________________________________________
Added: svn:keywords
   + Id
Added: svn:eol-style
   + native

Added: 
trunk/extensions/Translate/resources/ext.translate.special.aggregategroups.css
===================================================================
--- 
trunk/extensions/Translate/resources/ext.translate.special.aggregategroups.css  
                            (rev 0)
+++ 
trunk/extensions/Translate/resources/ext.translate.special.aggregategroups.css  
    2012-03-05 14:10:36 UTC (rev 113032)
@@ -0,0 +1,24 @@
+span.tp-aggregate-remove-ag-button,
+span.tp-aggregate-remove-button{
+       /* @embed */
+       background: url(images/remove.png) no-repeat scroll left center 
transparent;
+       padding: 10px;
+       cursor: pointer;
+}
+
+a.tpt-add-new-group{
+       /* @embed */
+       background: url(images/add.png) no-repeat scroll left center 
transparent;
+       padding-left: 20px;
+}
+div.tpt-add-new-group.hidden {
+       display:none;
+}
+
+input.tp-aggregategroup-add-name {
+       width: 250px;
+}
+
+input.tp-aggregategroup-add-description {
+       width: 500px;
+}


Property changes on: 
trunk/extensions/Translate/resources/ext.translate.special.aggregategroups.css
___________________________________________________________________
Added: svn:eol-style
   + native

Added: 
trunk/extensions/Translate/resources/ext.translate.special.aggregategroups.js
===================================================================
--- 
trunk/extensions/Translate/resources/ext.translate.special.aggregategroups.js   
                            (rev 0)
+++ 
trunk/extensions/Translate/resources/ext.translate.special.aggregategroups.js   
    2012-03-05 14:10:36 UTC (rev 113032)
@@ -0,0 +1,151 @@
+jQuery( function( $ ) {
+
+       $( document ).ready( function () {
+
+               function associate( event ){
+                       var aggregategroup = event.target.id;
+                       var selected = $( '#tp-aggregate-groups-select-'+ 
aggregategroup + ' option:selected' ).text();
+                       var group = $( '#tp-aggregate-groups-select-'+ 
aggregategroup + ' option:selected' ).val();
+                       var $select= $( 'select.tp-aggregate-group-chooser' ) ;
+
+                       var successFunction = function( data, textStatus ) {
+                               if ( data.error ) {
+                                       alert( data.error.info );
+                               }else{
+                                       $( '#tp-aggregate-groups-ol-'+ 
aggregategroup ).append( '<li><a id='+group+' 
href='+selected+'>'+selected+'</a><span class=\'tp-aggregate-remove-button\' 
id='+group+'></span></li>' );
+                                       $( 'option#'+ group ).remove();
+                                       $( 'span#'+group ).on ( "click", 
function(event){ dissociate(event); } );
+                               }
+                       };
+
+                       var params = {
+                               action: "aggregategroups",
+                               'do' : 'associate',
+                               token: $( "#token" ).val(),
+                               group: group,
+                               aggregategroup: aggregategroup,
+                               format: "json"
+                       };
+                       $.post( mw.util.wikiScript( "api" ), params, 
successFunction );
+               }
+
+               function dissociate(event){
+                       var group = event.target.id;
+                       var selected = $( 'a#'+group ).text();
+                       var $select= $( 'select.tp-aggregate-group-chooser' ) ;
+                       var aggregategroup = $( 'a#'+group ).closest( 'div' 
).find( 'h2' ).attr( 'id' );
+
+                       var successFunction = function( data, textStatus ) {
+                               if ( data.error ) {
+                                       alert( data.error.info );
+                               }else{
+                                       $select.each( function(){
+                                               $( this ).append( '<option 
value="'+group+'">'+selected+'</option>' );
+                                       } );
+                                       $( 'span#'+ group ).closest( 'li' 
).remove();
+                               }
+                       };
+
+                       var params = {
+                               action: "aggregategroups",
+                               'do' : 'dissociate',
+                               token: $( "#token" ).val(),
+                               group: group,
+                               aggregategroup: aggregategroup,
+                               format: "json"
+                       };
+                       $.post( mw.util.wikiScript( "api" ), params, 
successFunction );
+               }
+
+               function removeGroup(event){
+                       var aggregategroup = event.target.id;
+                       var $select= $( 'select.tp-aggregate-group-chooser') ;
+
+                       var successFunction = function( data, textStatus ) {
+                               if ( data.error ) {
+                                       alert( data.error.info );
+                               }else{
+                                       $( 'span#'+ aggregategroup 
).parent().parent().find('li a').each(function(){
+                                               $groupId = $( this ).attr('id');
+                                               $groupName = $( this ).text();
+                                               $select.each( function(){
+                                                       $ (this 
).append('<option value="'+$groupId+'">'+$groupName+'</option>');
+                                               } );
+                                       });
+                                       $( 'span#'+ aggregategroup 
).closest('div#tpt-aggregate-group').remove();
+                               }
+                       };
+
+                       var params = {
+                               action: "aggregategroups",
+                               'do' : 'remove',
+                               token: $( "#token" ).val(),
+                               aggregategroup: aggregategroup,
+                               format: "json"
+                       };
+                       $.post( mw.util.wikiScript( "api" ), params, 
successFunction );
+               }
+
+               $( 'input.tp-aggregate-add-button' ).on ( "click", function( 
event ){
+                       associate(event);
+               } );
+
+               $( 'span.tp-aggregate-remove-button' ).on ( "click", function( 
event ){
+                       dissociate(event);
+                } );
+
+               $( 'span.tp-aggregate-remove-ag-button' ).on ( "click", 
function( event ){
+                       removeGroup(event);
+                } );
+
+               $( 'a.tpt-add-new-group' ).on ( "click", function( event ){
+                       $( 'div.tpt-add-new-group' ).removeClass( 'hidden' );
+               } );
+
+               $( '#tpt-aggregategroups-save' ). on ( "click", function( event 
){
+                       var aggregateGroup = $( 
'input.tp-aggregategroup-add-name' ).val().toLowerCase().replace( ' ', '_');
+                       var aggregateGroupName = $( 
'input.tp-aggregategroup-add-name' ).val();
+                       var aggregateGroupDesc = $( 
'input.tp-aggregategroup-add-description' ).val();
+                       var $select= $( 'select.tp-aggregate-group-chooser' ) ;
+
+                       var successFunction = function( data, textStatus ) {
+                               if ( data.error ) {
+                                       alert( data.error.info );
+                               }else{
+                                       $removeSpan  =  $( '<span>' ).attr( 
'id', aggregateGroup ).addClass( 'tp-aggregate-remove-ag-button' );
+                                       $div = $( "<div 
id='tpt-aggregate-group'>" )
+                                               .append ( $( '<h2>' ).attr( 
'id', aggregateGroup ).text( aggregateGroupName ) 
+                                                       .append ( $removeSpan ) 
) 
+                                               .append ( $('<p>').text( 
aggregateGroupDesc ) )
+                                               .append ( $('<ol 
id=\'tp-aggregate-groups-ol-'+aggregateGroup+'\'>') );
+
+                                       if (  $select.length > 0 ){
+                                               var $groupSelector = $( $( 
'select.tp-aggregate-group-chooser')[0] ).clone();
+                                               $groupSelector.attr('id', 
'tp-aggregate-groups-select-' + aggregateGroup);
+                                               var $addButton =  $( $( 
'input.tp-aggregate-add-button')[0]).clone();
+                                               $addButton.attr( 'id', 
aggregateGroup);
+                                               $div.append( $groupSelector 
).append( $addButton );
+                                               $addButton.on ( "click", 
function( event ){ associate(event); } );
+                                               $removeSpan.on ( "click", 
function( event ){ removeGroup(event); } );
+                                               $( 'div.tpt-add-new-group' 
).addClass('hidden');
+                                       }else{
+                                               // First group in the wiki. 
Cannot clone the group selector, just reload this time.
+                                               location.reload();
+                                       }
+                                       $( 'a.tpt-add-new-group' ).before ( 
$div ) ;
+                               }
+                       };
+
+                       var params = {
+                               action: "aggregategroups",
+                               'do' : 'add',
+                               token: $( "#token" ).val(),
+                               aggregategroup: aggregateGroup,
+                               groupname : aggregateGroupName,
+                               groupdescription: aggregateGroupDesc,
+                               format: "json"
+                       };
+                       $.post( mw.util.wikiScript( "api" ), params, 
successFunction );
+               } )
+       } );
+} );


Property changes on: 
trunk/extensions/Translate/resources/ext.translate.special.aggregategroups.js
___________________________________________________________________
Added: svn:eol-style
   + native

Added: trunk/extensions/Translate/resources/images/add.png
===================================================================
(Binary files differ)


Property changes on: trunk/extensions/Translate/resources/images/add.png
___________________________________________________________________
Added: svn:mime-type
   + image/png

Added: trunk/extensions/Translate/resources/images/remove.png
===================================================================
(Binary files differ)


Property changes on: trunk/extensions/Translate/resources/images/remove.png
___________________________________________________________________
Added: svn:mime-type
   + image/png

Added: trunk/extensions/Translate/specials/SpecialAggregateGroups.php
===================================================================
--- trunk/extensions/Translate/specials/SpecialAggregateGroups.php              
                (rev 0)
+++ trunk/extensions/Translate/specials/SpecialAggregateGroups.php      
2012-03-05 14:10:36 UTC (rev 113032)
@@ -0,0 +1,191 @@
+<?php
+/**
+ * Contains logic for special page Special:AggregateGroups.
+ *
+ * @file
+ * @author Santhosh Thottingal
+ * @copyright Copyright © 2012 Santhosh Thottingal
+ * @license http://www.gnu.org/copyleft/gpl.html GNU General Public License 
2.0 or later
+ */
+
+class SpecialAggregateGroups extends SpecialPage {
+
+       /**
+        * @var User
+        */
+       protected $user;
+
+       function __construct() {
+               parent::__construct( 'AggregateGroups' );
+       }
+
+       public function execute( $parameters ) {
+               $this->setHeaders();
+
+               global $wgRequest, $wgOut, $wgUser;
+               $this->user = $wgUser;
+               $request = $wgRequest;
+
+               // Check permissions
+               if ( !$this->user->isAllowed( 'translate-manage' ) ) {
+                       $wgOut->permissionRequired( 'translate-manage' );
+                       return;
+               }
+
+               // Check permissions
+               if ( $wgRequest->wasPosted() && !$this->user->matchEditToken( 
$wgRequest->getText( 'token' ) ) ) {
+                       self::superDebug( __METHOD__, "token failure", 
$this->user );
+                       $wgOut->permissionRequired( 'translate-manage' );
+                       return;
+               }
+               $wgOut->setPageTitle( wfMsg( 'tpt-aggregategroups' ) );
+               $this->showAggregateGroups();
+
+       }
+
+       public function loadPagesFromDB() {
+               $dbr = wfGetDB( DB_MASTER );
+               $tables = array( 'page', 'revtag' );
+               $vars = array( 'page_id', 'page_title', 'page_namespace', 
'page_latest', 'MAX(rt_revision) as rt_revision', 'rt_type' );
+               $conds = array(
+                       'page_id=rt_page',
+                       'rt_type' => array( RevTag::getType( 'tp:mark' ), 
RevTag::getType( 'tp:tag' ) ),
+               );
+               $options = array(
+                       'ORDER BY' => 'page_namespace, page_title',
+                       'GROUP BY' => 'page_id, rt_type',
+               );
+               $res = $dbr->select( $tables, $vars, $conds, __METHOD__, 
$options );
+
+               return $res;
+       }
+
+       protected function buildPageArray( /*db result*/ $res ) {
+               $pages = array();
+               foreach ( $res as $r ) {
+                       // We have multiple rows for same page, because of 
different tags
+                       if ( !isset( $pages[$r->page_id] ) ) {
+                               $pages[$r->page_id] = array();
+                               $title = Title::newFromRow( $r );
+                               $pages[$r->page_id]['title'] = $title;
+                               $pages[$r->page_id]['latest'] = intval( 
$title->getLatestRevID() );
+                       }
+
+                       $tag = RevTag::typeToTag( $r->rt_type );
+                       $pages[$r->page_id][$tag] = intval( $r->rt_revision );
+               }
+               return $pages;
+       }
+
+
+       protected function showAggregateGroups() {
+               global $wgOut;
+               $wgOut->addModules( 'ext.translate.special.aggregategroups' );
+
+               $aggregategroups = ApiAggregateGroups::getAggregateGroups( );
+               $res = $this->loadPagesFromDB();
+               $pages = $this->buildPageArray( $res );
+               $pages = $this->filterUnGroupedPages( $pages,  $aggregategroups 
);
+               foreach ( $aggregategroups as $id => $group ) {
+                       $wgOut->addHtml( "<div id='tpt-aggregate-group'>" );
+
+                       $removeSpan = Html::element( 'span', array(
+                               'class' => 'tp-aggregate-remove-ag-button',
+                               'id' => $id ) ) ;
+                       $wgOut->addHtml( "<h2 id='$id'>" . $group['name'] .  
$removeSpan . "</h2>" );
+
+                       $wgOut->addHtml( "<p>" . $group['description'] . "</p>" 
);
+
+                       $wgOut->addHtml( "<ol id='tp-aggregate-groups-ol-$id'>" 
);
+                       $subgroups = $group['subgroups'];
+                       foreach ( $subgroups as $subgroupId => $subgroup ) {
+                               $removeSpan =   Html::element( 'span', array(
+                                               'class' => 
'tp-aggregate-remove-button',
+                                               'id' => $subgroupId ) );
+                               if ( $subgroup ) {
+                                       $wgOut->addHtml( "<li>" .
+                                               Linker::linkKnown( 
$subgroup->getTitle(),
+                                                       null,
+                                                       array( 'id' => 
$subgroupId )
+                                                       )
+                                               . "$removeSpan </li>" );
+                               }
+                       }
+                       $wgOut->addHtml( "</ol>" );
+
+                       $this->groupSelector ( $pages, $id );
+                       $addButton = Html::element( 'input',
+                               array( 'type' => 'button',
+                                       'value' =>  wfMsg( 
'tpt-aggregategroup-add' ),
+                                       'id' => $id, 'class' => 
'tp-aggregate-add-button' )
+                               );
+                       $wgOut->addHtml( $addButton );
+                       $wgOut->addHtml( "</div>" );
+               }
+
+
+               $wgOut->addHtml( Html::element( 'input',
+                       array( 'type' => 'hidden',
+                               'id' => 'token',
+                               'value' => ApiAggregateGroups::getToken( 0, '' )
+                               ) ) );
+               $wgOut->addHtml( "<br/><a class='tpt-add-new-group' href='#'>" .
+                       wfMsg( 'tpt-aggregategroup-add-new' ) .
+                        "</a>" );
+               $newGroupNameLabel = wfMsg( 'tpt-aggregategroup-new-name' );
+               $newGroupName = Html::element( 'input', array( 'class' => 
'tp-aggregategroup-add-name' ) );
+               $newGroupDescriptionLabel = wfMsg( 
'tpt-aggregategroup-new-description' );
+               $newGroupDescription = Html::element( 'input',
+                               array( 'class' => 
'tp-aggregategroup-add-description' )
+                        );
+               $saveButton = Html::element( 'input',
+                       array( 'type' => 'button',
+                               'value' =>  wfMsg( 'tpt-aggregategroup-save' ),
+                               'id' => 'tpt-aggregategroups-save', 'class' => 
'tp-aggregate-save-button' )
+                       );
+               $newGroupDiv = Html::rawElement( 'div',
+                       array( 'class' => 'tpt-add-new-group hidden' ) ,
+                       "$newGroupNameLabel $newGroupName <br/> 
$newGroupDescriptionLabel $newGroupDescription <br/> $saveButton" );
+               $wgOut->addHtml( $newGroupDiv );
+       }
+
+       protected function groupSelector(  $pages, $id ) {
+               global $wgOut;
+               $out = $wgOut;
+               if ( !count( $pages ) ) {
+                       $wgOut->addWikiMsg( 'tpt-list-nopages' );
+                       return;
+               }
+               $options = "\n";
+               if ( count( $pages ) ) {
+                       foreach ( $pages as $pageId => $page ) {
+                               $title =  $page['title']->getText();
+                               $pageid = 
TranslatablePage::getMessageGroupIdFromTitle( $page['title'] ) ;
+                               $options .= Xml::option(  $title , $pageid, 
false , array( 'id' => $pageid ) ) . "\n";
+                       }
+               }
+               $selector = Xml::tags( 'select',
+                               array(
+                                       'id' => 'tp-aggregate-groups-select-' . 
$id,
+                                       'name' => 'group',
+                                       'class' => 'tp-aggregate-group-chooser',
+                                       ),
+                               $options
+                       );
+               $out->addHtml( $selector );
+       }
+
+       protected function filterUnGroupedPages( $pages,  $aggregategroups ) {
+               foreach ( $aggregategroups as  $aggregategroup ) {
+                       $subgroups = $aggregategroup['subgroups'];
+                       foreach ( $pages as  $id => $page ) {
+                                       $pageid = 
TranslatablePage::getMessageGroupIdFromTitle( $page['title'] ) ;
+                                       if ( isset( $subgroups[$pageid] ) ) {
+                                               unset( $pages[$id] );
+                                       }
+                       }
+               }
+               return $pages;
+       }
+
+}


Property changes on: 
trunk/extensions/Translate/specials/SpecialAggregateGroups.php
___________________________________________________________________
Added: svn:eol-style
   + native


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

Reply via email to