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