http://www.mediawiki.org/wiki/Special:Code/MediaWiki/92340

Revision: 92340
Author:   salvatoreingala
Date:     2011-07-15 23:18:03 +0000 (Fri, 15 Jul 2011)
Log Message:
-----------
- Added timestamp to saved preferences, so that gadget preferences module may 
compute getModifiedTime() meaningfully
- Splitted gadget options from gadget module: Gadget's module is now 
'ext.Gadget.foo' => GadgetResourceLoaderModule while gadget preferences are in 
'ext.Gadget.foo.prefs' => GadgetOptionsResourceLoaderModule; the latter is in 
the 'private' group
- Now it loads default preferences for anonymous users.
- Moved GadgetsMainModule.php to the /backend folder

Modified Paths:
--------------
    branches/salvatoreingala/Gadgets/Gadgets.php
    branches/salvatoreingala/Gadgets/Gadgets_tests.php
    branches/salvatoreingala/Gadgets/backend/Gadget.php
    branches/salvatoreingala/Gadgets/backend/GadgetHooks.php
    branches/salvatoreingala/Gadgets/backend/GadgetPrefs.php
    branches/salvatoreingala/Gadgets/backend/GadgetResourceLoaderModule.php

Added Paths:
-----------
    
branches/salvatoreingala/Gadgets/backend/GadgetOptionsResourceLoaderModule.php
    branches/salvatoreingala/Gadgets/backend/GadgetsMainModule.php

Removed Paths:
-------------
    branches/salvatoreingala/Gadgets/ui/GadgetsMainModule.php

Modified: branches/salvatoreingala/Gadgets/Gadgets.php
===================================================================
--- branches/salvatoreingala/Gadgets/Gadgets.php        2011-07-15 23:08:02 UTC 
(rev 92339)
+++ branches/salvatoreingala/Gadgets/Gadgets.php        2011-07-15 23:18:03 UTC 
(rev 92340)
@@ -48,8 +48,9 @@
 $wgAutoloadClasses['Gadget'] = $dir . 'backend/Gadget.php';
 $wgAutoloadClasses['GadgetHooks'] = $dir . 'backend/GadgetHooks.php';
 $wgAutoloadClasses['GadgetResourceLoaderModule'] = $dir . 
'backend/GadgetResourceLoaderModule.php';
+$wgAutoloadClasses['GadgetOptionsResourceLoaderModule'] = $dir . 
'backend/GadgetOptionsResourceLoaderModule.php';
 $wgAutoloadClasses['GadgetPrefs'] = $dir . 'backend/GadgetPrefs.php';
-$wgAutoloadClasses['GadgetsMainModule'] = $dir . 'ui/GadgetsMainModule.php';
+$wgAutoloadClasses['GadgetsMainModule'] = $dir . 
'backend/GadgetsMainModule.php';
 $wgAutoloadClasses['SpecialGadgets'] = $dir . 'ui/SpecialGadgets.php';
 
 $wgSpecialPages['Gadgets'] = 'SpecialGadgets';
@@ -62,7 +63,7 @@
 $wgAjaxExportList[] = 'GadgetsAjax::setPreferences';
 
 $wgResourceModules['ext.gadgets'] = array(
-       'class'                 => 'GadgetsMainModule'
+       'class'                 => 'GadgetsMainModule',
 );
 
 $wgResourceModules['jquery.validate'] = array(

Modified: branches/salvatoreingala/Gadgets/Gadgets_tests.php
===================================================================
--- branches/salvatoreingala/Gadgets/Gadgets_tests.php  2011-07-15 23:08:02 UTC 
(rev 92339)
+++ branches/salvatoreingala/Gadgets/Gadgets_tests.php  2011-07-15 23:18:03 UTC 
(rev 92340)
@@ -589,8 +589,24 @@
                        )
                ) );
        }
-       
+
        /**
+        * Tests Gadget::getDefaults
+        *
+        * @dataProvider prefsDescProvider
+        */
+       function testGetDefaults( $prefsDescription ) {
+               $this->assertEquals( GadgetPrefs::getDefaults( 
$prefsDescription ), array(
+                       'testBoolean' => true,
+                       'testBoolean2' => true,
+                       'testNumber' => 7,
+                       'testNumber2' => 7,
+                       'testSelect' => 3,
+                       'testSelect2' => 3
+               ) );
+       }
+
+       /**
         * Tests Gadget::setPrefsDescription, 
GadgetPrefs::checkPrefsAgainstDescription,
         * GadgetPrefs::matchPrefsWithDescription and Gadget::setPrefs.
         *

Modified: branches/salvatoreingala/Gadgets/backend/Gadget.php
===================================================================
--- branches/salvatoreingala/Gadgets/backend/Gadget.php 2011-07-15 23:08:02 UTC 
(rev 92339)
+++ branches/salvatoreingala/Gadgets/backend/Gadget.php 2011-07-15 23:18:03 UTC 
(rev 92340)
@@ -22,6 +22,7 @@
         */
        const GADGET_CLASS_VERSION = 5;
 
+       //Fields stored in cache
        private $version = self::GADGET_CLASS_VERSION,
                $scripts = array(),
                $styles = array(),
@@ -32,9 +33,10 @@
                        $requiredRights = array(),
                        $onByDefault = false,
                        $category,
-                       $mTime = null, //upper bound on last modification time; 
UNIX timestamp
                        $prefsDescription = null,
-                       $preferences = null;
+                       //The following fields are initialized after saving the 
gadget to cache for registered users
+                       $preferences = null,
+                       $prefsTimestamp = 1; //last time user preferences for 
this gadget have been changed; UNIX timestamp
 
        /**
         * Creates an instance of this class from definition in 
MediaWiki:Gadgets-definition
@@ -55,9 +57,6 @@
                $gadget = new Gadget();
                $gadget->name = trim( str_replace(' ', '_', $m[1] ) );
                $gadget->definition = $definition;
-
-               //TODO: make this more precise with gadget-specific info. 
Untile then, 'now' is an upper bound.
-               $gadget->mTime = wfTimestamp( TS_UNIX );
                
                //Parse gadget options
                $options = trim( $m[2], ' []' );
@@ -114,6 +113,9 @@
                        if ( isset( $prefsDescriptionJson ) ) {
                                $prefsDescription = FormatJson::decode( 
$prefsDescriptionJson, true );
                                $gadget->setPrefsDescription( $prefsDescription 
);
+                               
+                               //Load default gadget preferences. Only useful 
for anonymous users
+                               $gadget->setPrefs( GadgetPrefs::getDefaults( 
$prefsDescription ) );
                        }
                }
                
@@ -156,6 +158,13 @@
        }
 
        /**
+        * @return String: Name of ResourceLoader module for this gadget's 
preferences
+        */
+       public function getPrefsModuleName() {
+               return "{$this->getModuleName()}.prefs";
+       }
+
+       /**
         * Checks whether this is an instance of an older version of this class 
deserialized from cache
         * @return Boolean
         */
@@ -255,14 +264,15 @@
                return new GadgetResourceLoaderModule( $pages, 
$this->dependencies, $this );
        }
 
+       
        /**
-        * Returns an upper bound on the modification time of the gadget.
-        * Used by GadgetResourceLoaderModule to compute its own mTime.
+        * Returns ResourceLoader module for this gadget's preferences, see
+        * getPrefsModuleName().
         * 
-        * @return String the UNIX timestamp of this gadget's modificaton time.
+        * @return Mixed: GadgetOptionsResourceLoaderModule or false
         */
-       public function getModifiedTime() {
-               return $this->mTime;
+       public function getPrefsModule() {
+               return new GadgetOptionsResourceLoaderModule( $this );
        }
 
        /**
@@ -492,9 +502,30 @@
                $this->preferences = $prefs;
 
                if ( $savePrefs ) {
+                       $this->setPrefsTimestamp( wfTimestamp( TS_UNIX ) ); 
//update timestamp before saving
                        $user = RequestContext::getMain()->getUser();
                        $user->saveSettings();
                }
                return true;
        }
+
+       /**
+        * Returns the modification time of gadget preferences.
+        * Used by GadgetResourceLoaderModule to compute its own mTime.
+        * Returns 1 if setPrefsTimestamp() has never been called, or the 
previously stored value otherwise.
+        * 
+        * @return String the UNIX timestamp of this gadget's modificaton time.
+        */
+       public function getPrefsTimestamp() {
+               return $this->prefsTimestamp;
+       }
+
+       /**
+        * Sets the modification time of gadget preferences.
+        * 
+        * @param $timestamp String: the UNIX timestamp of the last time 
preferences has been saved.
+        */
+       public function setPrefsTimestamp( $timestamp ) {
+               $this->prefsTimestamp = $timestamp;
+       }
 }

Modified: branches/salvatoreingala/Gadgets/backend/GadgetHooks.php
===================================================================
--- branches/salvatoreingala/Gadgets/backend/GadgetHooks.php    2011-07-15 
23:08:02 UTC (rev 92339)
+++ branches/salvatoreingala/Gadgets/backend/GadgetHooks.php    2011-07-15 
23:18:03 UTC (rev 92340)
@@ -148,6 +148,9 @@
                foreach ( $gadgets as $g ) {
                        $module = $g->getModule();
                        if ( $module ) {
+                               if ( $g->getPrefsDescription() !== null ) {
+                                       $resourceLoader->register( 
$g->getPrefsModuleName(), $g->getPrefsModule() );
+                               }
                                $resourceLoader->register( $g->getModuleName(), 
$module );
                        }
                }
@@ -230,13 +233,15 @@
 
                //Find out all existing gadget preferences and save them in a 
map
                $preferencesCache = array();
+               $timestampCache = array();
                foreach ( $options as $option => $value ) {
                        $m = array();
                        if ( preg_match( '/gadget-([a-zA-Z](?:[-_:.\w\d 
]*[a-zA-Z0-9])?)-config/', $option, $m ) ) {
                                $gadgetName = trim( str_replace(' ', '_', $m[1] 
) );
-                               $gadgetPrefs = unserialize( $value );
-                               if ( $gadgetPrefs !== false ) {
-                                       $preferencesCache[$gadgetName] = 
$gadgetPrefs;
+                               $bundle = unserialize( $value );
+                               if ( is_array( $bundle ) && isset( 
$bundle['timestamp'] ) && isset( $bundle['prefs'] ) ) {
+                                       $preferencesCache[$gadgetName] = 
$bundle['prefs'];
+                                       $timestampCache[$gadgetName] = 
$bundle['timestamp'];
                                } else {
                                        //should not happen; just in case
                                        wfDebug( __METHOD__ . ": couldn't 
unserialize settings for gadget " .
@@ -252,15 +257,18 @@
                        if ( $prefsDescription !== null ) {
                                if ( isset( 
$preferencesCache[$gadget->getName()] ) ) {
                                        $userPrefs = 
$preferencesCache[$gadget->getName()];
+                                       $timestamp = 
$timestampCache[$gadget->getName()];
                                }
                                
                                if ( !isset( $userPrefs ) ) {
                                        $userPrefs = array(); //no saved prefs 
(or invalid entry in DB), use defaults
+                                       $timestamp = 1;
                                }
-                               
+
                                GadgetPrefs::matchPrefsWithDescription( 
$prefsDescription, $userPrefs );
                                
                                $gadget->setPrefs( $userPrefs );
+                               $gadget->setPrefsTimestamp( $timestamp );
                        }
                }
 
@@ -296,16 +304,19 @@
                                $prefsDescription = 
$gadget->getPrefsDescription();
                                
                                //Remove preferences that equal their default
-                               foreach ( $prefs as $prefName => $value ) {
-                                       if ( 
$prefsDescription['fields'][$prefName]['default'] === $value ) {
+                               foreach ( $prefsDescription['fields'] as 
$prefDescription ) {
+                                       $prefName = $prefDescription['name'];
+                                       $prefDefault = 
$prefDescription['default'];
+                                       if ( $prefs[$prefName] === $prefDefault 
) {
                                                unset( $prefs[$prefName] );
                                        }
                                }
                                
-                               //Only save it if at least one preference 
differs from default
-                               if ( !empty( $prefs ) ) {
-                                       
$options["gadget-{$gadget->getName()}-config"] = serialize( $prefs );
-                               }
+                               //Save back preferences
+                               $options["gadget-{$gadget->getName()}-config"] 
= serialize( array( 
+                                       'timestamp' => 
$gadget->getPrefsTimestamp(),
+                                       'prefs' => $prefs
+                               ) );
                        }
                }
                

Added: 
branches/salvatoreingala/Gadgets/backend/GadgetOptionsResourceLoaderModule.php
===================================================================
--- 
branches/salvatoreingala/Gadgets/backend/GadgetOptionsResourceLoaderModule.php  
                            (rev 0)
+++ 
branches/salvatoreingala/Gadgets/backend/GadgetOptionsResourceLoaderModule.php  
    2011-07-15 23:18:03 UTC (rev 92340)
@@ -0,0 +1,75 @@
+<?php
+
+/**
+ * Gadgets extension - lets users select custom javascript gadgets
+ *
+ *
+ * For more info see http://mediawiki.org/wiki/Extension:Gadgets
+ *
+ * @file
+ * @ingroup Extensions
+ * @author Daniel Kinzler, brightbyte.de
+ * @copyright © 2007 Daniel Kinzler
+ * @license GNU General Public Licence 2.0 or later
+ */
+
+/**
+ * Class representing the user-specific options for a gadget
+ */
+class GadgetOptionsResourceLoaderModule extends ResourceLoaderModule {
+       private $gadget;
+
+       /**
+        * Creates an instance of this class
+        * @param $gadget Gadget: the gadget this module is built upon.
+        */
+       public function __construct( $gadget ) {
+               $this->gadget = $gadget;
+       }
+
+       /**
+        * Overrides ResourceLoaderModule::getDependencies()
+        * @return Array: Names of resources this module depends on
+        */
+       public function getDependencies() {
+               return array( 'ext.gadgets' );
+       }
+       
+       /**
+        * Overrides ResourceLoaderModule::getGroup()
+        * @return String
+        */
+       public function getGroup() {
+               return 'private';
+       }
+
+       /**
+        * Overrides ResourceLoaderModule::getScript()
+        * @param $context ResourceLoaderContext
+        * @return String
+        */
+       public function getScript( ResourceLoaderContext $context ) {
+               $gadgetInfo = array(
+                       'name'   => $this->gadget->getName(),
+                       'config' => $this->gadget->getPrefs()
+               );
+               return Xml::encodeJsCall( 'mw.gadgets.info.set', 
+                       array( $this->gadget->getName(), $gadgetInfo ) );
+       }
+       
+       /**
+        * Overrides ResourceLoaderModule::getModifiedTime()
+        * @param $context ResourceLoaderContext
+        * @return Integer
+        */
+       public function getModifiedTime( ResourceLoaderContext $context ) {
+               $prefsMTime = $this->gadget->getPrefsTimestamp();
+
+               $resourceLoader = $context->getResourceLoader();
+               $parentModule = $resourceLoader->getModule( 
$this->gadget->getModuleName() );
+               $gadgetMTime = $parentModule->getModifiedTime( $context );
+
+               return max( $gadgetMTime, $prefsMTime );
+       }
+}
+


Property changes on: 
branches/salvatoreingala/Gadgets/backend/GadgetOptionsResourceLoaderModule.php
___________________________________________________________________
Added: svn:eol-style
   + native

Modified: branches/salvatoreingala/Gadgets/backend/GadgetPrefs.php
===================================================================
--- branches/salvatoreingala/Gadgets/backend/GadgetPrefs.php    2011-07-15 
23:08:02 UTC (rev 92339)
+++ branches/salvatoreingala/Gadgets/backend/GadgetPrefs.php    2011-07-15 
23:18:03 UTC (rev 92340)
@@ -534,6 +534,20 @@
        }
        
        /**
+        * Return default preferences according to the given description.
+        * 
+        * @param $prefsDescription Array: reference of the array of 
preferences to match.
+        * It is assumed that $prefsDescription is a valid description of 
preferences.
+        * 
+        * @return Array: the set of default preferences, keyed by preference 
name.
+        */
+       public static function getDefaults( $prefsDescription ) {
+               $prefs = array();
+               self::matchPrefsWithDescription( $prefsDescription, $prefs );
+               return $prefs;
+       }
+       
+       /**
         * Returns true if $str should be interpreted as a message, false 
otherwise.
         * 
         * @param $str String

Modified: 
branches/salvatoreingala/Gadgets/backend/GadgetResourceLoaderModule.php
===================================================================
--- branches/salvatoreingala/Gadgets/backend/GadgetResourceLoaderModule.php     
2011-07-15 23:08:02 UTC (rev 92339)
+++ branches/salvatoreingala/Gadgets/backend/GadgetResourceLoaderModule.php     
2011-07-15 23:18:03 UTC (rev 92340)
@@ -28,6 +28,7 @@
         *              'MediaWiki:Gadget-foo.css' => array( 'type' => 'style' 
),
         * )
         * @param $dependencies Array: Names of resources this module depends on
+        * @param $gadget Gadget: the gadget this module is built upon.
         */
        public function __construct( $pages, $dependencies, $gadget ) {
                $this->pages = $pages;
@@ -48,47 +49,48 @@
         * @return Array: Names of resources this module depends on
         */
        public function getDependencies() {
-               return $this->dependencies;
-       }
-       
-       public function getGroup() {
-               //Modules for gadgets with preferences must be kept private, if 
the user can set preferences
-               if ( $this->gadget->getPrefsDescription() !== null
-                       && RequestContext::getMain()->getUser()->isLoggedIn() )
-               {
-                       return 'private';
-               } else {
-                       return parent::getGroup();
+               $deps = array( 'ext.gadgets' );
+               if ( $this->gadget->getPrefsDescription() !== null ){
+                       $deps[] = $this->gadget->getPrefsModuleName();
                }
+               
+               return array_merge(
+                               $this->dependencies,
+                               $deps
+                       );
        }
        
+       /**
+        * Overrides ResourceLoaderModule::getScript()
+        * @param $context ResourceLoaderContext
+        * @return String
+        */
        public function getScript( ResourceLoaderContext $context ) {
                $prefs = $this->gadget->getPrefs();
                
                //Enclose gadget's code in a closure, with "this" bound to the
                //configuration object (or to "window" for non-configurable 
gadgets)
-               $header = '(function(){';
+               $header = "(function(){";
                
-               //TODO: it may be nice add other metadata for the gadget
-               $boundObject = array( 'config' => $prefs );
-               
-               if ( $prefs !== NULL ) {
-                       //Bind configuration object to "this".
-                       $footer = '}).' . Xml::encodeJsCall( 'apply', 
-                               array( $boundObject, array() )
-                       ) . ';';
+               if ( $prefs !== null ) {
+                       //Bind gadget info to "this".
+                       $footer = "}).apply( 
mw.gadgets.info.get('{$this->gadget->getName()}') );";
                } else {
                        //Bind window to "this"
-                       $footer = '}).apply( window, [] );';
+                       $footer = "}).apply( window );";
                }
                
                return $header . parent::getScript( $context ) . $footer;
        }
        
+       /**
+        * Overrides ResourceLoaderModule::getModifiedTime()
+        * @param $context ResourceLoaderContext
+        * @return Integer
+        */
        public function getModifiedTime( ResourceLoaderContext $context ) {
-               $touched = wfTimestamp( TS_UNIX, 
RequestContext::getMain()->getUser()->getTouched() );
-               $gadgetMTime = $this->gadget->getModifiedTime();
-               return max( parent::getModifiedTime( $context ), $touched, 
$gadgetMTime );
+               //TODO: should also depend on the mTime of preferences 
description page
+               return parent::getModifiedTime( $context );
        }
 }
 

Copied: branches/salvatoreingala/Gadgets/backend/GadgetsMainModule.php (from 
rev 91026, branches/salvatoreingala/Gadgets/ui/GadgetsMainModule.php)
===================================================================
--- branches/salvatoreingala/Gadgets/backend/GadgetsMainModule.php              
                (rev 0)
+++ branches/salvatoreingala/Gadgets/backend/GadgetsMainModule.php      
2011-07-15 23:18:03 UTC (rev 92340)
@@ -0,0 +1,50 @@
+<?php
+
+/**
+ * Gadgets extension - lets users select custom javascript gadgets
+ *
+ *
+ * For more info see http://mediawiki.org/wiki/Extension:Gadgets
+ *
+ * @file
+ * @ingroup Extensions
+ * @author Daniel Kinzler, brightbyte.de
+ * @copyright © 2007 Daniel Kinzler
+ * @license GNU General Public Licence 2.0 or later
+ */
+
+/**
+ * Class implementing the ext.gadgets module. Required by 
ext.gadgets.preferences.
+ */
+class GadgetsMainModule extends ResourceLoaderModule {
+       
+       public function getModifiedTime( ResourceLoaderContext $context ) {
+               $gadgets = Gadget::loadList();
+               
+               $m = 1;
+               $resourceLoader = $context->getResourceLoader();
+               foreach ( $gadgets as $gadget ) {
+                       if ( $gadget->hasModule() ) {
+                               $module = $resourceLoader->getModule( 
$gadget->getModuleName() );
+                               $m = max( $m, $module->getModifiedTime( 
$context ) );
+                       }
+               }
+               return $m;
+       }
+       
+       public function getScript( ResourceLoaderContext $context ) {
+               $configurableGadgets = array();
+               $gadgets = Gadget::loadList();
+               
+               foreach ( $gadgets as $gadget ) {
+                       if ( $gadget->getPrefsDescription() !== null ) {
+                               $configurableGadgets[] = $gadget->getName();
+                       }
+               }
+
+               $script = "mw.gadgets = {};\n";
+               $script .= "mw.gadgets.info = new mw.Map();\n";
+               $script .= "mw.gadgets.configurableGadgets = " . 
Xml::encodeJsVar( $configurableGadgets ) . ";\n";
+               return $script;
+       }
+}

Deleted: branches/salvatoreingala/Gadgets/ui/GadgetsMainModule.php
===================================================================
--- branches/salvatoreingala/Gadgets/ui/GadgetsMainModule.php   2011-07-15 
23:08:02 UTC (rev 92339)
+++ branches/salvatoreingala/Gadgets/ui/GadgetsMainModule.php   2011-07-15 
23:18:03 UTC (rev 92340)
@@ -1,45 +0,0 @@
-<?php
-
-/**
- * Gadgets extension - lets users select custom javascript gadgets
- *
- *
- * For more info see http://mediawiki.org/wiki/Extension:Gadgets
- *
- * @file
- * @ingroup Extensions
- * @author Daniel Kinzler, brightbyte.de
- * @copyright © 2007 Daniel Kinzler
- * @license GNU General Public Licence 2.0 or later
- */
-
-/**
- * Class implementing the ext.gadgets module. Required by 
ext.gadgets.preferences.
- */
-class GadgetsMainModule extends ResourceLoaderModule {
-       
-       public function getModifiedTime( ResourceLoaderContext $context ) {
-               $gadgets = Gadget::loadList();
-               
-               $m = 0;
-               foreach ( $gadgets as $gadget ) {
-                       $m = max( $m, $gadget->getModifiedTime() );
-               }
-               return $m;
-       }
-       
-       public function getScript( ResourceLoaderContext $context ) {
-               $configurableGadgets = array();
-               $gadgets = Gadget::loadList();
-               
-               foreach ( $gadgets as $gadget ) {
-                       if ( $gadget->getPrefsDescription() !== null ) {
-                               $configurableGadgets[] = $gadget->getName();
-                       }
-               }
-
-               $script = "mw.gadgets = {}\n";
-               $script .= "mw.gadgets.configurableGadgets = " . 
Xml::encodeJsVar( $configurableGadgets ) . ";\n";
-               return $script;
-       }
-}


_______________________________________________
MediaWiki-CVS mailing list
MediaWiki-CVS@lists.wikimedia.org
https://lists.wikimedia.org/mailman/listinfo/mediawiki-cvs

Reply via email to