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

Revision: 112752
Author:   awjrichards
Date:     2012-03-01 01:19:25 +0000 (Thu, 01 Mar 2012)
Log Message:
-----------
Refactored checks to see if we should be displaying the MobileFrontend view and 
removed dependency on looking for /only/ x-device headers so we handle 
previously unhandled cases where a user is using useformat=mobile; As part of 
refactor added methods to check if a user is coming from a mobile device 
(denoted by presense of x-device headers) or if a user is coming from a 'faux' 
mobile device (when using something like useformat=mobile); Added query string 
handling for mobile URL construction; Added corresponding tests; Added some 
additional cleanup to the tearDown routine in tests to unset x-device headers 
and refresh the value of ExtMobileFrontend:: to its default state.

Modified Paths:
--------------
    trunk/extensions/MobileFrontend/MobileFrontend.body.php
    trunk/extensions/MobileFrontend/tests/MobileFrontendTest.php

Modified: trunk/extensions/MobileFrontend/MobileFrontend.body.php
===================================================================
--- trunk/extensions/MobileFrontend/MobileFrontend.body.php     2012-03-01 
01:17:55 UTC (rev 112751)
+++ trunk/extensions/MobileFrontend/MobileFrontend.body.php     2012-03-01 
01:19:25 UTC (rev 112752)
@@ -43,6 +43,21 @@
        public static $logoutHtml;
        public static $loginHtml;
        public static $zeroRatedBanner;
+       
+       /**
+        * @var string xDevice header information
+        */
+       protected $xDevice;
+       
+       /**
+        * @var string MediaWiki 'action'
+        */
+       protected $action;
+       
+       /**
+        * @var string
+        */
+       protected $mobileAction;
 
        /**
         * @var WmlContext
@@ -127,8 +142,7 @@
         */
        public function testCanonicalRedirect( $request, $title, $output ) {
                global $wgUsePathInfo;
-               $xDevice = isset( $_SERVER['HTTP_X_DEVICE'] ) ? 
$_SERVER['HTTP_X_DEVICE'] : '';
-               if ( empty( $xDevice ) ) {
+               if ( !$this->shouldDisplayMobileView() ) {
                        return true; // Let the redirect happen
                } else {
                        if ( $title->getNamespace() == NS_SPECIAL ) {
@@ -294,15 +308,14 @@
         */
        public function beforePageRedirect( $out, &$redirect, &$code ) {
                wfProfileIn( __METHOD__ );
+               $shouldDisplayMobileView = $this->shouldDisplayMobileView();
                if ( $out->getTitle()->isSpecial( 'Userlogin' ) ) {
-                       $xDevice = isset( $_SERVER['HTTP_X_DEVICE'] ) ? 
$_SERVER['HTTP_X_DEVICE'] : '';
-                       if ( $xDevice ) {
+                       if ( $shouldDisplayMobileView ) {
                                $forceHttps = true;
                                $redirect = $this->getMobileUrl( $redirect, 
$forceHttps );
                        }
                } else if ( $out->getTitle()->isSpecial( 'Randompage' ) ) {
-                       $xDevice = isset( $_SERVER['HTTP_X_DEVICE'] ) ? 
$_SERVER['HTTP_X_DEVICE'] : '';
-                       if ( $xDevice ) {
+                       if ( $shouldDisplayMobileView ) {
                                $redirect = $this->getMobileUrl( $redirect );
                        }
                }
@@ -325,22 +338,15 @@
                // Thus, globalized objects will not be available as expected 
in the function.
                // This is stated to be intended behavior, as per the 
following: [http://bugs.php.net/bug.php?id=40104]
 
-               $xDevice = isset( $_SERVER['HTTP_X_DEVICE'] ) ? 
$_SERVER['HTTP_X_DEVICE'] : '';
+               $xDevice = $this->getXDevice();
                self::$useFormat = $wgRequest->getText( 'useformat' );
                $this->wmlContext->setUseFormat( self::$useFormat );
-               $mobileAction = $wgRequest->getText( 'mobileaction' );
-               $action = $wgRequest->getText( 'action' );
+               $mobileAction = $this->getMobileAction();               
 
-               if ( self::$useFormat !== 'mobile' && self::$useFormat !== 
'mobile-wap' &&
-                       !$xDevice ) {
+               if ( !$this->shouldDisplayMobileView() ) {
                        wfProfileOut( __METHOD__ );
                        return true;
                }
-               if ( $action === 'edit' || $action === 'history' ||
-                        $mobileAction === 'view_normal_site' ) {
-                       wfProfileOut( __METHOD__ );
-                       return true;
-               }
 
                $userAgent = $_SERVER['HTTP_USER_AGENT'];
                $acceptHeader = isset( $_SERVER["HTTP_ACCEPT"] ) ? 
$_SERVER["HTTP_ACCEPT"] : '';
@@ -1271,6 +1277,7 @@
        public function getMobileUrl( $url, $forceHttps = false ) {
                $parsedUrl = wfParseUrl( $url );
                $this->updateMobileUrlHost( $parsedUrl );
+               $this->updateMobileUrlQueryString( $parsedUrl );
                if ( $forceHttps ) {
                        $parsedUrl[ 'scheme' ] = 'https';
                }
@@ -1342,6 +1349,20 @@
                $parsedUrl[ 'path' ] = $wgScriptPath . $templatePathSansToken . 
$pathSansScriptPath;    
        }
 
+       protected function updateMobileUrlQueryString( &$parsedUrl ) {
+               if ( !$this->isFauxMobileDevice() ) {
+                       return;
+               }
+               
+               if ( !isset( $parsedUrl[ 'query' ] )) {
+                       $parsedUrl[ 'query' ] = 'useformat=' . urlencode( 
self::$useFormat );
+               } else {
+                       $query = wfCgiToArray( $parsedUrl[ 'query' ] );
+                       $query[ 'useformat' ] = urlencode( self::$useFormat );
+                       $parsedUrl[ 'query' ] = wfArrayToCgi( $query );
+               }
+       }
+
        /**
         * Parse mobile URL template into its host and path components.
         *
@@ -1377,6 +1398,67 @@
                }
        }
 
+       protected function isMobileDevice() {
+               $xDevice = $this->getXDevice();
+
+               if ( empty( $xDevice )) {
+                       return false;
+               }
+               
+               return true;
+       }
+       
+       protected function isFauxMobileDevice() {
+               if ( self::$useFormat !== 'mobile' && self::$useFormat !== 
'mobile-wap') {
+                       return false;
+               } 
+
+               return true;
+       }
+       
+       protected function shouldDisplayMobileView() {
+               if ( !$this->isMobileDevice() && !$this->isFauxMobileDevice() ) 
{
+                       return false;
+               }
+               
+               $action = $this->getAction();
+               $mobileAction = $this->getMobileAction();
+               
+               if ( $action === 'edit' || $action === 'history' ||
+                        $mobileAction === 'view_normal_site' ) {
+                       return false;
+               }
+                               
+               return true;
+       }
+
+       public function getXDevice() {
+               if ( is_null( $this->xDevice ) ) {
+                       $this->xDevice = isset( $_SERVER['HTTP_X_DEVICE'] ) ? 
+                                       $_SERVER['HTTP_X_DEVICE'] : '';
+               }
+               
+               return $this->xDevice;
+       }
+
+       public function getMobileAction() {
+               global $wgRequest;
+               if ( is_null( $this->mobileAction )) {
+                       $this->mobileAction = $wgRequest->getText( 
'mobileaction' );
+               }
+               
+               return $this->mobileAction;
+       }
+       
+       public function getAction() {
+               global $wgRequest;
+               if ( is_null( $this->action )) {
+                       $this->action = $wgRequest->getText( 'action' );
+               }
+               
+               return $this->action;
+       }
+       
        public function getVersion() {
                return __CLASS__ . ': $Id$';
        }

Modified: trunk/extensions/MobileFrontend/tests/MobileFrontendTest.php
===================================================================
--- trunk/extensions/MobileFrontend/tests/MobileFrontendTest.php        
2012-03-01 01:17:55 UTC (rev 112751)
+++ trunk/extensions/MobileFrontend/tests/MobileFrontendTest.php        
2012-03-01 01:19:25 UTC (rev 112752)
@@ -26,6 +26,8 @@
        protected function tearDown() {
                global $wgExtMobileFrontend;
                unset( $wgExtMobileFrontend );
+               unset( $_SERVER[ 'HTTP_X_DEVICE' ] );
+               ExtMobileFrontend::$useFormat = null;
                parent::tearDown();
        }
 
@@ -102,4 +104,203 @@
                $updateMobileUrlHost->invokeArgs( $wgExtMobileFrontend, array( 
&$parsedUrl ) );
                $this->assertEquals( 
"http://en.wikipedia.org/wiki/mobile/Gustavus_Airport";, wfAssembleUrl( 
$parsedUrl ) );
        }
+       
+       /**
+        * @dataProvider updateMobileUrlQueryStringProvider
+        */
+       public function testUpdateMobileUrlQueryString( $assert, $useFormat ) {
+               global $wgRequest, $wgExtMobileFrontend;
+               
+               $testMethod = ( $assert ) ? 'assertTrue' : 'assertFalse';
+               $url = 
'http://en.wikipedia.org/wiki/Article/?something=bananas';
+               if ( !empty( $useFormat ) ) $url .= "&useformat=" . $useFormat;
+               ExtMobileFrontend::$useFormat = $useFormat;
+               
+               $parsedUrl = wfParseUrl( $url );
+               
+               $updateMobileUrlQueryString = self::getMethod( 
'updateMobileUrlQueryString' );
+               $updateMobileUrlQueryString->invokeArgs( $wgExtMobileFrontend, 
array( &$parsedUrl) );
+               
+               $targetUrl = wfAssembleUrl( $parsedUrl );
+               $this->$testMethod( $url == $targetUrl, $targetUrl );
+       }
+       
+       public function updateMobileUrlQueryStringProvider() {
+               return array(
+                       array( true, 'mobile' ),
+                       array( true, 'mobile-wap' ),
+                       array( true, '' ),
+               );
+       }
+       
+       /**
+        * @dataProvider isMobileDeviceProvider
+        */
+       public function testIsMobileDevice( $isDevice, $msg, $xDevice = null ) {
+               global $wgReqeust, $wgExtMobileFrontend;
+               $isMobileDevice = self::getMethod( 'isMobileDevice' );
+               
+               $testMethod = ( $isDevice ) ? 'assertTrue' : 'assertFalse';
+               
+               if ( !is_null( $xDevice )) {
+                       $_SERVER[ 'HTTP_X_DEVICE' ] = $xDevice;
+               }
+               
+               $this->$testMethod( $isMobileDevice->invokeArgs( 
$wgExtMobileFrontend, array() ), $msg );
+       }
+       
+       public function isMobileDeviceProvider() {
+               return array(
+                       array( false, 'Nothing set' ),
+                       array( true, 'HTTP_X_DEVICE = webkit', 'webkit' ),
+               );
+       }
+       
+       /**
+        * @dataProvider isFauxMobileDeviceProvider
+        */
+       public function testIsFauxMobileDevice( $isFauxDevice, $msg, 
$useformat=null ) {
+               global $wgRequest, $wgExtMobileFrontend;
+               $isFauxMobileDevice = self::getMethod( 'isFauxMobileDevice' );
+               
+               $testMethod = ( $isFauxDevice ) ? 'assertTrue' : 'assertFalse';
+               
+               ExtMobileFrontend::$useFormat = $useformat;
+               $this->$testMethod( $isFauxMobileDevice->invokeArgs( 
$wgExtMobileFrontend, array() ), $msg );
+       }
+       
+       public function isFauxMobileDeviceProvider() {
+               return array(
+                       array( false, 'Nothing set' ),
+                       array( true, 'useformat=mobile', 'mobile' ),
+                       array( true, 'useformat=mobile-wap', 'mobile-wap' ),
+                       array( false, 'useformat=yourmom', 'yourmom' ),
+               );
+       }
+       
+       /**
+        * @dataProvider shouldDisplayMobileViewProvider
+        */
+       public function testShouldDisplayMobileView( $shouldDisplay, 
$xDevice=null, $requestVal=array(), $msg=null ) {
+               global $wgRequest, $wgExtMobileFrontend;
+               $shouldDisplayMobileView = self::getMethod( 
'shouldDisplayMobileView' );
+       
+               $testMethod = ( $shouldDisplay ) ? 'assertTrue' : 'assertFalse';
+               
+               if ( count( $requestVal )) {
+                       foreach ( $requestVal as $key => $val ) {
+                               if ( $key == 'useformat' ) {
+                                       ExtMobileFrontend::$useFormat = $val;
+                               } else {
+                                       $wgRequest->setVal( $key, $val );
+                               }
+                       }
+               }
+               
+               if ( !is_null( $xDevice )) {
+                       $_SERVER[ 'HTTP_X_DEVICE' ] = $xDevice;
+               }
+               
+               $this->$testMethod( $shouldDisplayMobileView->invokeArgs( 
$wgExtMobileFrontend, array() ), $msg );
+               
+               // clean up
+               if ( count( $requestVal )) {
+                       foreach ( $requestVal as $key => $val ) {
+                               if ( $key == 'useformat' ) {
+                                       continue;
+                               } else {
+                                       $wgRequest->unsetVal( $key );
+                               }
+                       }
+               }
+       }
+       
+       public function shouldDisplayMobileViewProvider() {
+               return array(
+                       array( false, null, array() ),
+                       array( true, 'webkit', array() ),
+                       array( false, 'webkit', array( 'action' => 'edit' ) ),
+                       array( false, 'webkit', array( 'mobileaction' => 
'view_normal_site' ) ),
+                       array( true, null, array( 'useformat' => 'mobile-wap' ) 
),
+                       array( false, null, array( 'useformat' => 'mobile-wap', 
'action' => 'edit' ) ),
+                       array( false, null, array( 'useformat' => 'mobile-wap', 
'action' => 'history' ) ),
+                       array( false, null, array( 'useformat' => 'mobile-wap', 
'mobileaction' => 'view_normal_site' ) ),
+                       array( true, null, array( 'useformat' => 'mobile' ) ),
+                       array( false, null, array( 'useformat' => 'mobile', 
'action' => 'edit' ) ),
+                       array( false, null, array( 'useformat' => 'mobile', 
'action' => 'history' ) ),
+                       array( false, null, array( 'useformat' => 'mobile', 
'mobileaction' => 'view_normal_site' ) ),
+               );
+       }
+       
+       /**
+        * @dataProvider getXDeviceProvider
+        */
+       public function testGetXDevice( $xDevice=null ) {
+               global $wgExtMobileFrontend;
+               if ( is_null( $xDevice ) ) {
+                       $assert = '';
+                       if ( isset( $_SERVER[ 'HTTP_X_DEVICE' ] ) ) {
+                               unset( $_SERVER[ 'HTTP_X_DEVICE' ] );
+                       }
+               } else {
+                       $_SERVER[ 'HTTP_X_DEVICE' ] = $xDevice;
+                       $assert = $xDevice;
+               }
+               $this->assertEquals( $assert, 
$wgExtMobileFrontend->getXDevice() );
+       }
+       
+       public function getXDeviceProvider() {
+               return array(
+                       array( 'webkit' ),
+                       array( null ),
+               );
+       }
+       
+       /**
+        * @dataProvider getMobileActionProvider
+        */
+       public function testGetMobileAction( $mobileaction=null ) {
+               global $wgRequest, $wgExtMobileFrontend;
+
+               if ( is_null( $mobileaction )) {
+                       $assert = '';
+                       $wgRequest->unsetVal( 'mobileaction' );
+               } else {
+                       $wgRequest->setVal( 'mobileaction', $mobileaction );
+                       $assert = $mobileaction;
+               }
+
+               $this->assertEquals( $assert, 
$wgExtMobileFrontend->getMobileAction() );
+       }
+       
+       public function getMobileActionProvider() {
+               return array(
+                       array( null ),
+                       array( 'view_normal_site' ),
+               );
+       }
+       
+       /**
+        * @dataProvider getActionProvider
+        */
+       public function testGetAction( $action=null ) {
+               global $wgRequest, $wgExtMobileFrontend;
+               
+               if ( is_null( $action )) {
+                       $assert = '';
+                       $wgRequest->unsetVal( 'action' );
+               } else {
+                       $wgRequest->setVal( 'action', $action );
+                       $assert = $action;
+               }
+               
+               $this->assertEquals( $assert, $wgExtMobileFrontend->getAction() 
);
+       }
+       
+       public function getActionProvider() {
+               return array(
+                       array( null ),
+                       array( 'edit' ),
+               );
+       }
 }


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

Reply via email to