Foxtrott has uploaded a new change for review.

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

Change subject: Add 'uselayout' URL parameter
......................................................................

Add 'uselayout' URL parameter

To select a specific layout different from the one defined in
`$egChameleonLayoutFile` you can add the `uselayout` parameter to the URL.
However for some wikis it might not be desirable to have this feature. So to
make this work you have to define the available layouts in
LocalSettings.php. E.g. to include all layouts delivered with Chameleon add
```php
$egChameleonAvailableLayoutFiles = array(
    'standard'   => __DIR__ . '/skins/chameleon/layouts/standard.xml',
    'navhead'    => __DIR__ . '/skins/chameleon/layouts/navhead.xml',
    'fixedhead'  => __DIR__ . '/skins/chameleon/layouts/fixedhead.xml',
    'stickyhead' => __DIR__ . '/skins/chameleon/layouts/stickyhead.xml',
    'clean'      => __DIR__ . '/skins/chameleon/layouts/clean.xml',
);
```

Change-Id: Ie1d8eac82424053e5490d23d9ad864d84f725481
---
M Chameleon.php
M docs/customization.md
M docs/release-notes.md
M docs/testing.md
M src/Hooks/SetupAfterCache.php
M src/SkinChameleon.php
M tests/phpunit/Integration/StylesCompileTest.php
M tests/phpunit/Unit/Hooks/SetupAfterCacheTest.php
8 files changed, 215 insertions(+), 42 deletions(-)


  git pull ssh://gerrit.wikimedia.org:29418/mediawiki/skins/chameleon 
refs/changes/56/273656/1

diff --git a/Chameleon.php b/Chameleon.php
index 36605a7..c1a1573 100644
--- a/Chameleon.php
+++ b/Chameleon.php
@@ -47,7 +47,7 @@
        }
 
        // define the skin's version
-       define( 'CHAMELEON_VERSION', '1.2.1-alpha' );
+       define( 'CHAMELEON_VERSION', '1.3-alpha' );
 
        // set credits
        $GLOBALS[ 'wgExtensionCredits' ][ 'skin' ][ ] = array(
@@ -79,13 +79,14 @@
         */
 
        /**
-        * @see https://www.mediawiki.org/wiki/Manual:Hooks/SetupAfterCache
+        * @see https://www.mediawiki.org/wiki/Manual:Hooks/BeforeInitialize
         */
        $GLOBALS[ 'wgHooks' ][ 'SetupAfterCache' ][ ] = function() {
 
                $setupAfterCache = new \Skins\Chameleon\Hooks\SetupAfterCache(
                        \Bootstrap\BootstrapManager::getInstance(),
-                       $GLOBALS
+                       $GLOBALS,
+                       $GLOBALS['wgRequest']
                );
 
                $setupAfterCache->process();
diff --git a/docs/customization.md b/docs/customization.md
index c9e875b..ff59459 100644
--- a/docs/customization.md
+++ b/docs/customization.md
@@ -74,6 +74,24 @@
 to follow.)
 
 
+### Selecting the layout from the browser address bar
+
+To select a specific layout different from the one defined in
+`$egChameleonLayoutFile` you can add the `uselayout` parameter to the URL.
+However for some wikis it might not be desirable to have this feature. So to
+make this work you have to define the available layouts in
+LocalSettings.php. E.g. to include all layouts delivered with Chameleon add
+```php
+$egChameleonAvailableLayoutFiles = array(
+       'standard'   => __DIR__ . '/skins/chameleon/layouts/standard.xml',
+       'navhead'    => __DIR__ . '/skins/chameleon/layouts/navhead.xml',
+       'fixedhead'  => __DIR__ . '/skins/chameleon/layouts/fixedhead.xml',
+       'stickyhead' => __DIR__ . '/skins/chameleon/layouts/stickyhead.xml',
+       'clean'      => __DIR__ . '/skins/chameleon/layouts/clean.xml',
+);
+```
+
+
 ### Triggering a cache update
 
 Compiling the style files is time-consuming. For this reason the styles are
diff --git a/docs/release-notes.md b/docs/release-notes.md
index b350c41..9eddbfa 100644
--- a/docs/release-notes.md
+++ b/docs/release-notes.md
@@ -1,9 +1,12 @@
 ## Release Notes
 
-### Chameleon 1.2.1
+### Chameleon 1.3
 
 Released on (tbd)
 
+Changes:
+* introduced URL parameter 'uselayout'
+
 Fixes:
 * Correctly follow symlinks
   ([Bug: T124714](https://phabricator.wikimedia.org/T124714))
diff --git a/docs/testing.md b/docs/testing.md
index 756e4df..42f2b40 100644
--- a/docs/testing.md
+++ b/docs/testing.md
@@ -5,7 +5,7 @@
 [`phpunit`][mw-testing] together with the PHPUnit configuration file found in
 the root directory of the skin.
 ```sh
-php mw-phpunit-runner.php [options]
+php tests/mw-phpunit-runner.php [options]
 ```
 
 Useful optional parameters:
diff --git a/src/Hooks/SetupAfterCache.php b/src/Hooks/SetupAfterCache.php
index c3484cc..a5562f9 100644
--- a/src/Hooks/SetupAfterCache.php
+++ b/src/Hooks/SetupAfterCache.php
@@ -1,6 +1,6 @@
 <?php
 /**
- * File containing the SetupAfterCache class
+ * File containing the BeforeInitialize class
  *
  * This file is part of the MediaWiki skin Chameleon.
  *
@@ -43,16 +43,19 @@
 
        protected $bootstrapManager = null;
        protected $configuration = array();
+       protected $request;
 
        /**
         * @since  1.0
         *
         * @param BootstrapManager $bootstrapManager
         * @param array $configuration
+        * @param \WebRequest $request
         */
-       public function __construct( BootstrapManager $bootstrapManager, array 
&$configuration ) {
+       public function __construct( BootstrapManager $bootstrapManager, array 
&$configuration, \WebRequest $request ) {
                $this->bootstrapManager = $bootstrapManager;
                $this->configuration = &$configuration;
+               $this->request = $request;
        }
 
        /**
@@ -94,33 +97,9 @@
 
        protected function addLateSettings() {
 
-               // if Visual Editor is installed and there is a setting to 
enable or disable it
-               if ( $this->hasConfiguration( 'wgVisualEditorSupportedSkins' ) 
&& $this->hasConfiguration( 'egChameleonEnableVisualEditor' ) ) {
-
-                       // if VE should be enabled
-                       if ( $this->configuration[ 
'egChameleonEnableVisualEditor' ] === true ) {
-
-                               // if Chameleon is not yet in the list of 
VE-enabled skins
-                               if ( !in_array( 'chameleon', 
$this->configuration[ 'wgVisualEditorSupportedSkins' ] ) ) {
-                                       $this->configuration[ 
'wgVisualEditorSupportedSkins' ][ ] = 'chameleon';
-                               }
-
-                       } else {
-                               // remove all entries of Chameleon from the 
list of VE-enabled skins
-                               $this->configuration[ 
'wgVisualEditorSupportedSkins' ] = array_diff(
-                                       $this->configuration[ 
'wgVisualEditorSupportedSkins' ],
-                                       array( 'chameleon' )
-                               );
-                       }
-               }
-
-               $this->configuration[ 'wgResourceModules' ][ 
'skin.chameleon.jquery-sticky' ] = array(
-                       'localBasePath' => $this->configuration[ 
'chameleonLocalPath' ] . '/resources/js',
-                       'remoteBasePath' => $this->configuration[ 
'chameleonRemotePath' ] . '/resources/js',
-                       'group' => 'skin.chameleon',
-                       'skinScripts' => array( 'chameleon' => array( 
'jquery-sticky/jquery.sticky.js', 'Components/Modifications/sticky.js' ) )
-               );
-
+               $this->addChameleonToVisualEditorSupportedSkins();
+               $this->addResourceModules();
+               $this->setLayoutFile();
        }
 
        protected function registerCommonBootstrapModules() {
@@ -216,4 +195,48 @@
                throw new RuntimeException( "Expected an accessible {$file} 
file" );
        }
 
+       protected function addChameleonToVisualEditorSupportedSkins() {
+
+               // if Visual Editor is installed and there is a setting to 
enable or disable it
+               if ( $this->hasConfiguration( 'wgVisualEditorSupportedSkins' ) 
&& $this->hasConfiguration( 'egChameleonEnableVisualEditor' ) ) {
+
+                       // if VE should be enabled
+                       if ( $this->configuration[ 
'egChameleonEnableVisualEditor' ] === true ) {
+
+                               // if Chameleon is not yet in the list of 
VE-enabled skins
+                               if ( !in_array( 'chameleon', 
$this->configuration[ 'wgVisualEditorSupportedSkins' ] ) ) {
+                                       $this->configuration[ 
'wgVisualEditorSupportedSkins' ][] = 'chameleon';
+                               }
+
+                       } else {
+                               // remove all entries of Chameleon from the 
list of VE-enabled skins
+                               $this->configuration[ 
'wgVisualEditorSupportedSkins' ] = array_diff(
+                                       $this->configuration[ 
'wgVisualEditorSupportedSkins' ],
+                                       array( 'chameleon' )
+                               );
+                       }
+               }
+       }
+
+       protected function addResourceModules() {
+               $this->configuration[ 'wgResourceModules' ][ 
'skin.chameleon.jquery-sticky' ] = array(
+                       'localBasePath'  => $this->configuration[ 
'chameleonLocalPath' ] . '/resources/js',
+                       'remoteBasePath' => $this->configuration[ 
'chameleonRemotePath' ] . '/resources/js',
+                       'group'          => 'skin.chameleon',
+                       'skinScripts'    => array( 'chameleon' => array( 
'jquery-sticky/jquery.sticky.js', 'Components/Modifications/sticky.js' ) )
+               );
+       }
+
+       protected function setLayoutFile() {
+
+               $layout = $this->request->getVal( 'uselayout' );
+
+               if ( $layout !== null &&
+                       $this->hasConfigurationOfTypeArray( 
'egChameleonAvailableLayoutFiles' ) &&
+                       array_key_exists( $layout, $this->configuration[ 
'egChameleonAvailableLayoutFiles' ] ) ) {
+
+                       $this->configuration[ 'egChameleonLayoutFile' ] = 
$this->configuration[ 'egChameleonAvailableLayoutFiles' ][ $layout ];
+               }
+       }
+
 }
diff --git a/src/SkinChameleon.php b/src/SkinChameleon.php
index af13e21..320a143 100644
--- a/src/SkinChameleon.php
+++ b/src/SkinChameleon.php
@@ -93,7 +93,7 @@
         * @return string
         */
        public function getPageClasses( $title ) {
-               $layoutName = Sanitizer::encodeAttribute( 'layout-' . basename( 
$GLOBALS['egChameleonLayoutFile'], '.xml' ) );
+               $layoutName = Sanitizer::escapeClass( 'layout-' . basename( 
$GLOBALS['egChameleonLayoutFile'], '.xml' ) );
                return implode( ' ', array( parent::getPageClasses( $title ), 
$layoutName ) );
        }
 }
diff --git a/tests/phpunit/Integration/StylesCompileTest.php 
b/tests/phpunit/Integration/StylesCompileTest.php
index 51282ea..0b328df 100644
--- a/tests/phpunit/Integration/StylesCompileTest.php
+++ b/tests/phpunit/Integration/StylesCompileTest.php
@@ -46,9 +46,14 @@
 
        public function testStylesCompile() {
 
+               $request = $this->getMockBuilder('\WebRequest')
+                       ->disableOriginalConstructor()
+                       ->getMock();
+
                $setupAfterCache = new SetupAfterCache(
                        BootstrapManager::getInstance(),
-                       $GLOBALS
+                       $GLOBALS,
+                       $request
                );
 
                $setupAfterCache->process();
diff --git a/tests/phpunit/Unit/Hooks/SetupAfterCacheTest.php 
b/tests/phpunit/Unit/Hooks/SetupAfterCacheTest.php
index 3f08d25..f5f3e31 100644
--- a/tests/phpunit/Unit/Hooks/SetupAfterCacheTest.php
+++ b/tests/phpunit/Unit/Hooks/SetupAfterCacheTest.php
@@ -77,9 +77,13 @@
 
                $configuration = array();
 
+               $request = $this->getMockBuilder('\WebRequest')
+                       ->disableOriginalConstructor()
+                       ->getMock();
+
                $this->assertInstanceOf(
                        '\Skins\Chameleon\Hooks\SetupAfterCache',
-                       new SetupAfterCache( $bootstrapManager, $configuration )
+                       new SetupAfterCache( $bootstrapManager, $configuration, 
$request )
                );
        }
 
@@ -125,9 +129,14 @@
                        'wgStylePath'                     => 
'notTestingwgStylePath',
                );
 
+               $request = $this->getMockBuilder('\WebRequest')
+                       ->disableOriginalConstructor()
+                       ->getMock();
+
                $instance = new SetupAfterCache(
                        $bootstrapManager,
-                       $configuration
+                       $configuration,
+                       $request
                );
 
                $instance->process();
@@ -159,9 +168,14 @@
                        'wgStylePath'                     => 
'notTestingwgStylePath'
                );
 
+               $request = $this->getMockBuilder('\WebRequest')
+                       ->disableOriginalConstructor()
+                       ->getMock();
+
                $instance = new SetupAfterCache(
                        $bootstrapManager,
-                       $configuration
+                       $configuration,
+                       $request
                );
 
                $this->setExpectedException( 'RuntimeException' );
@@ -201,12 +215,108 @@
                        'wgStylePath'                      => 
'notTestingwgStylePath'
                );
 
+               $request = $this->getMockBuilder('\WebRequest')
+                       ->disableOriginalConstructor()
+                       ->getMock();
+
                $instance = new SetupAfterCache(
                        $bootstrapManager,
-                       $configuration
+                       $configuration,
+                       $request
                );
 
                $instance->process();
+       }
+
+       /**
+        * @covers ::process
+        * @covers ::registerExternalLessVariables
+        *
+        * @dataProvider processWithRequestedLayoutFileProvider
+        */
+       public function testProcessWithRequestedLayoutFile( 
$availableLayoutFiles, $defaultLayoutFile, $requestedLayout, 
$expectedLayoutfile ) {
+
+               $bootstrapManager = $this->getMockBuilder( 
'\Bootstrap\BootstrapManager' )
+                       ->disableOriginalConstructor()
+                       ->getMock();
+
+               $configuration = array(
+                       'egChameleonAvailableLayoutFiles'  => 
$availableLayoutFiles,
+                       'egChameleonLayoutFile'            => 
$defaultLayoutFile,
+                       'IP'                               => 'notTestingIP',
+                       'wgScriptPath'                     => 
'notTestingwgScriptPath',
+                       'wgStyleDirectory'                 => 
'notTestingwgStyleDirectory',
+                       'wgStylePath'                      => 
'notTestingwgStylePath'
+               );
+
+               $request = $this->getMockBuilder('\WebRequest')
+                       ->disableOriginalConstructor()
+                       ->getMock();
+
+               $request->expects( $this->once() )
+                       ->method( 'getVal' )
+                       ->will( $this->returnValue( $requestedLayout ) );
+
+               $instance = new SetupAfterCache(
+                       $bootstrapManager,
+                       $configuration,
+                       $request
+               );
+
+               $instance->process();
+
+               $this->assertEquals(
+                       $expectedLayoutfile,
+                       $configuration['egChameleonLayoutFile']
+               );
+       }
+
+       public function processWithRequestedLayoutFileProvider() {
+
+               $provider = array();
+
+               // no layout files available => keep default layout file
+               $provider[] = array(
+                       null,
+                       'standard.xml',
+                       'someOtherLayout',
+                       'standard.xml'
+               );
+
+               // no specific layout requested => keep default layout file
+               $provider[] = array(
+                       array(
+                               'layout1' => 'layout1.xml',
+                               'layout2' => 'layout2.xml',
+                       ),
+                       'standard.xml',
+                       null,
+                       'standard.xml'
+               );
+
+               // requested layout not available => keep default layout file
+               $provider[] = array(
+                       array(
+                               'layout1' => 'layout1.xml',
+                               'layout2' => 'layout2.xml',
+                       ),
+                       'standard.xml',
+                       'someOtherLayout',
+                       'standard.xml'
+               );
+
+               // requested layout available => return requested layout file
+               $provider[] = array(
+                       array(
+                               'layout1' => 'layout1.xml',
+                               'layout2' => 'layout2.xml',
+                       ),
+                       'standard.xml',
+                       'layout1',
+                       'layout1.xml'
+               );
+
+               return $provider;
        }
 
        /**
@@ -220,9 +330,14 @@
                        ->disableOriginalConstructor()
                        ->getMock();
 
+               $request = $this->getMockBuilder('\WebRequest')
+                       ->disableOriginalConstructor()
+                       ->getMock();
+
                $instance = new SetupAfterCache(
                        $bootstrapManager,
-                       $changes
+                       $changes,
+                       $request
                );
 
                $instance->adjustConfiguration( $origConfig );
@@ -270,9 +385,14 @@
 
                $configurationToBeAdjusted = $configuration + 
$defaultConfiguration;
 
+               $request = $this->getMockBuilder('\WebRequest')
+                       ->disableOriginalConstructor()
+                       ->getMock();
+
                $instance = new SetupAfterCache(
                        $bootstrapManager,
-                       $configurationToBeAdjusted
+                       $configurationToBeAdjusted,
+                       $request
                );
 
                $instance->process();
@@ -349,6 +469,9 @@
                return $provider;
        }
 
+       /**
+        * Provides test data for the adjustConfiguration test
+        */
        public function adjustConfigurationProvider() {
 
                $provider = array();

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

Gerrit-MessageType: newchange
Gerrit-Change-Id: Ie1d8eac82424053e5490d23d9ad864d84f725481
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/skins/chameleon
Gerrit-Branch: master
Gerrit-Owner: Foxtrott <[email protected]>

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

Reply via email to