<?php
// MobileSkin.body.php
 
# Needs to be called within MobileSkin extension; not standalone
if ( !defined('MOBILESKIN') ) {
	echo("This is an extension to the MediaWiki MobileSkin extension and cannot be run standalone.\n" );
	die(-1);
}
 
class MobileSkin {
 
	var $defaultDevice;	// string containing name of default mobile device; usually "mobile"
	var $defaultSkin;	// skin to use when we have to punt
	var $mobileDevices;	// list of mobile devices, skins, and HTTP_USER_AGENT (browser) strings/patterns to look for
	var $mobileDebug;	// 0 = none; 1 = in/out of methods; 2 = full detail
 
//	##### CONSTRUCTOR #####
 
//	Get things set up.
	public function MobileSkin() {
 
	//	Set defaults
		$this->defaultDevice= 'mobile';
		$this->defaultSkin  = 'chick';
		$this->mobileDebug  = 2;
 
	//	Set up devices, skins, and patterns (list) to find
		$this->mobileDevices = array (
			array (	
				'device'	=> 'android', 
				'skin'		=> 'chick', 
				'patterns'	=> array ('android') 
			),
			array (	
				'device'	=> 'blackberry', 
				'skin'		=> 'chick', 
				'patterns'	=> array ('blackberry') 
			),
			array (	
				'device'	=> 'iphone', 
				'skin'		=> 'iphone', 
				'patterns'	=> array ('iphone', 'ipod') 
			),
			array (	
				'device'	=> 'mobile', 
				'skin'		=> 'mobile', 
				'patterns'	=> array (
					'176x220', '240x320', 
					'alcatel', 'amoi', 'audio', 'avant', 'benq', 'bird', 
					'cdm', 'chtml', 'compal', 
					'dbt', 'dddi', 'docomo', 'eric', 'gradi', 'hand', 'HTC', 
					'iemobile', 'j2me', 'java', 'jb', 'kdd', 'kg', 'lg', 
					'mib', 'midp', 'mitsu', 'mmm', 'mmp', 'mobi', 'mot-', 'moto', 'motorola', 
					'NEC', 'nokia', 'novarra', 'opwv', 
					'panasonic', 'pda', 'pg', 'philips', 'phone', 'pocket', 'pt', 'rover', 
					'sagem', 'samsung', 'sany', 'sch', 'SEC-', 'sendo', 'sgh', 'sharp', 
					'SIE-', 'smartphone', 'sony', 'sonyericsson', 'symbian', 
					'up.b', 'voda', 'vox', 'vx', 'wap', 'windows ce','wireless', 
					'xx' # last entry, no final comma
				) 
			),
			array (
				'device'	=> 'palm', 
				'skin'		=> 'chick', 
				'patterns'	=> array ('palm') 
			) #last entry, no final comma
		);
 
	}//function init
 
 
//	##### PUBLIC METHODS (functions) #####
 
//	Get the mobile device name, if any.
//	INPUT:	-nothing-
//	OUTPUT:	device name or empty string (which indicates it is not a [known] mobile device)
	public function getMobileDevice() {
		if (function_exists('wfDebug') && ($this->mobileDebug > 0)) 
			wfDebug( "MobileSkin: getMobileDevice()\n" );
 
		$returnValue = '';	// default: not a mobile device
		if (isset($_SERVER['HTTP_X_WAP_PROFILE'])) {
			$returnValue = $this->defaultDevice;
		} elseif ((!$returnValue) && preg_match('/wap.|.wap/i',$_SERVER['HTTP_ACCEPT'])) {
			$returnValue = $this->defaultDevice;
		} else {	// check HTTP_USER_AGENT
			if ( isset($_SERVER['HTTP_USER_AGENT']) ) {
				$browser = $_SERVER['HTTP_USER_AGENT'];
				if (function_exists('wfDebug') && ($this->mobileDebug > 1)) 
					wfDebug( "MobileSkin: browser is '$browser'\n" );
 
				foreach ($this->mobileDevices as $thisDevice) {
					if (strlen($returnValue) > 0) break;
					$deviceName = $thisDevice['device'];
					#$deviceSkin = $thisDevice['skin'];
					$deviceList = $thisDevice['patterns'];
					if (function_exists('wfDebug') && ($this->mobileDebug > 1)) 
						wfDebug( "MobileSkin: check device '$deviceName'\n" );
 
					foreach ($deviceList as $pattern) {
						if (strlen($returnValue) > 0) break;
						if (function_exists('wfDebug') && ($this->mobileDebug > 1)) 
							wfDebug( "MobileSkin: test pattern '$pattern'\n" );
 
						$stmp = '/' . strtolower(str_replace('/','',$pattern)) . '/i';
						if (preg_match($stmp, $browser)) {
							$returnValue = $deviceName;
						}
					} // for each pattern
				} // for each device
			}// browser string available
		}// not WAP
		if ((strlen($returnValue) > 0) && (function_exists('wfDebug')) && ($this->mobileDebug > 0)) 
			wfDebug( "MobileSkin: getMobileDevice() = '$returnValue'\n" );
		return strtolower($returnValue);
	}//function getMobileDevice
 
 
//	Get the mobile skin name, if any.
//	INPUT:	-nothing-
//	OUTPUT:	skin name or empty string (which indicates it is not a [known] mobile device)
	public function getMobileSkin( $deviceName ) {
		if (function_exists('wfDebug') && ($this->mobileDebug > 0)) 
			wfDebug( "MobileSkin: getMobileSkin()\n" );
 
		$returnValue = '';	// default: not a mobile device
		if (strlen($deviceName) > 0) {	// test a specific device
			foreach ($this->mobileDevices as $thisDevice) {
				if (strlen($returnValue) > 0) break;
				if ($deviceName == $thisDevice['device']) {
					$returnValue = $thisDevice['skin'];
				}
			} // for each device
 
		// OTHERWISE: check for skin using information from the actual device
		} elseif (isset($_SERVER['HTTP_X_WAP_PROFILE'])) {
			$returnValue = $this->defaultSkin;
		} elseif ((!$returnValue) && preg_match('/wap.|.wap/i',$_SERVER['HTTP_ACCEPT'])) {
			$returnValue = $this->defaultSkin;
		} else {	// check HTTP_USER_AGENT
			if ( isset($_SERVER['HTTP_USER_AGENT']) ) {
				$browser = $_SERVER['HTTP_USER_AGENT'];
				foreach ($this->mobileDevices as $thisDevice) {
					if (strlen($returnValue) > 0) break;
					#$deviceName = $thisDevice['device'];
					$deviceSkin = $thisDevice['skin'];
					$deviceList = $thisDevice['patterns'];
					foreach ($deviceList as $pattern) {
						if (strlen($returnValue) > 0) break;
						$stmp = '/' . strtolower(str_replace('/','',$pattern)) . '/i';
						if (preg_match($stmp, $browser)) {
							$returnValue = $deviceSkin;
						}
					} // for each pattern
				} // for each device
			}// browser string available
		}// not WAP
		if ((strlen($returnValue) > 0) && (function_exists('wfDebug')) && ($this->mobileDebug > 0)) 
			wfDebug( "MobileSkin: getMobileSkin() = '$returnValue'\n" );
		return strtolower($returnValue);
	}//function getMobileSkin
 
 
//	This function simply indicates if the device is a known mobile device or not (TRUE/FALSE).
	public function isMobile() {
		return (strlen($this->getMobileDevice()) > 0);
	}//function isMobile
 
//	This function indicates if the device is an iPhone or not (TRUE/FALSE).
	public function isIphone() {
		return ($thisMobileDevice() == 'iphone');
	}//function isIphone
 
 
//	Determine if the named skin code files can be found.
//	Actually looks on disk to see if the skin file is installed on the site.
	public function isSkinInstalled( &$skinName ) {
		$returnValue = false;	// skin was not found
		if (strlen(trim($skinName)) > 0) {
			$filename = 'skins/' . str_replace(' ','',ucwords(strtolower(trim($skinName)))) . '.php'; // typical name is first letter capitalized
			if (file_exists($filename)) $returnValue = true;
			if ((!$returnValue) && ($skinName == 'iphone')) { // special capitalization
				$filename = 'skins/iPhone.php';
				if (file_exists($filename)) $returnValue = true;
			}
		}
		return $returnValue;
	}//function isSkinInstalled
 
 
//	Actually change the skin if it is a mobile device.
	public function changeSkin( &$out, &$sk ) {
		global $wgUser;
 
		$returnValue = false;	// skin not changed
		if (function_exists('wfDebug') && ($this->mobileDebug > 0)) 
			wfDebug( "MobileSkin: changeskin()\n" );
 
		$sk = $wgUser->getSkin();	// initialize access to user's skin
		if (function_exists('wfDebug') && ($this->mobileDebug > 1)) 
			wfDebug( "MobileSkin: user selected skin is '$sk->getSkinName()'\n" );
 
		$deviceName = $this->getMobileDevice();
		if (function_exists('wfDebug') && ($this->mobileDebug > 1)) 
			wfDebug( "MobileSkin: device is '$deviceName'\n" );
 
		if (strlen($deviceName) > 0) {
			$skin = $this->getMobileSkin('');
			if (function_exists('wfDebug') && ($this->mobileDebug > 1)) 
				wfDebug( "MobileSkin: skin is '$skin'\n" );
 
			if (!$this->isSkinInstalled($skin)) {
				if (function_exists('wfDebug') && ($this->mobileDebug > 1)) 
					wfDebug( "MobileSkin: skin '$skin' is NOT INSTALLED; default $this->defaultSkin will be used\n" );
 
				$skin = $this->defaultSkin;
			}
 
			$sk = Skin::newFromKey($skin);	// temporarily change skin for this page
			if (function_exists('wfDebug') && ($this->mobileDebug > 1)) 
				wfDebug( "MobileSkin: user selected skin is '$sk->getSkinName()' ($skin)\n" );
 
			$returnValue = true;	// changed
		}
 
		return $returnValue;
	}//function changeSkin
 
}//class MobileSkin
