<?php
/**
* @version 1.0g
* @package MetaMod
* @copyright Copyright (C) 2007-2008 Stephen Brandon. All rights reserved.
* @license
*/
 
/** ensure this file is being included by a parent file */
defined( '_VALID_MOS' ) or
    die( 'Direct Access to this location is not allowed.' );

// Get various things incl. user permissions obj
global $mosConfig_absolute_path, $database, $my, $Itemid, $mosConfig_caching;

if(!function_exists('locateGeoIPInclude')){ 
	function locateGeoIPInclude($use_geoip) {
		global $mosConfig_absolute_path;
		include_once("mod_metamod/metamod.class.php"); // to get list of folders for geoip database

		// determine which file we are going to import, based on MetaMod parameter
		$geoIPDataFiles = array('','GeoIP.dat','GeoLiteCity.dat','GeoIPCity.dat');

		$geoip_folders = MetaModParameters::geoIPFolders();
		$file = '';
		// find the file in any of the standard locations
		foreach ($geoip_folders as $folder) {
			$target = $geoIPDataFiles[$use_geoip];
			$proposed_file = $mosConfig_absolute_path.$folder.'/'.$target;
			if (file_exists($proposed_file)) {
				$file = $proposed_file;
				break;
			}
		}
		return $file;		
	}
}

if(!function_exists('metaModLanguages')){ 
	function metaModLanguages(&$params)
	{
		$debug 			= trim( $params->get( 'debug', '0' ) );
		$opt_option		= trim( $params->get( 'language_option', '0' ) );
		$opt_compare_strict	= trim( $params->get( 'language_compare_strict', '1' ) );
		$opt_preferred		= trim( $params->get( 'language_preferred', '' ) );
		// for $language_preferred, order doesn't matter. MetaMod will just
		// look through the browser's list of languages one at a time, and
		// use the first one that also appears in $language_preferred.

		$language = '';
		$language_code = '';
		$language_region = '';
		$languages = explode(",",$_SERVER['HTTP_ACCEPT_LANGUAGE']);


		if ($opt_option == 0) {
			// main browser lang
			if (count($languages)) {
				$language = strtolower($languages[0]);
			}
		}

		if ($opt_option == 1) { // preferred language from list
			// want to go through each of the languages in the browser string, from the 1st one,
			// and see if any of these are in the list that the admin supplied.
			$preferred_languages = explode(",",$opt_preferred);
			for ($i = 0 ; $i < count($preferred_languages); $i++) {
				$preferred_languages[$i] = trim(strtolower( $preferred_languages[$i] ));
			}

			for ($i = 0 ; $i < count($languages); $i++) {
				// first get rid of ";q=XX" suffixes 
				$l = explode( ";", trim(strtolower( $languages[$i] )));
				$try_this = $l[0];
				preg_match("/([a-z]+)-/",$try_this,$try_this_matches);
				if (
					// strict or not strict, both need this
					in_array($try_this, $preferred_languages)
					||
					// if not strict, try the browser "major" type against "preferred" ones
					( !$opt_compare_strict && count($try_this_matches) > 0 && in_array($try_this_matches[1], $preferred_languages) ) 

				) {
					$language = $try_this;
					break;
				}
			}
		}

		if ($opt_option == 2) {
			// The language of the Joomla front-end as lower case iso string e.g. "en"
			// Looks for a JoomFish setting first, if it exists, otherwise takes default locale.
			$language = array_key_exists("iso_client_lang",$GLOBALS) ? $GLOBALS["iso_client_lang"] : "";
			if (!strlen($language)) $language = array_key_exists("mosConfig_locale",$GLOBALS) ? $GLOBALS["mosConfig_locale"] : "";
		}

		if ($language != '') {
			preg_match("/([a-z]+)(-([a-z]+))?/",$language,$language_matches);
			$language_code = $language_matches[1];
			if (count($language_matches) > 3) $language_region = $language_matches[3];
		}
		if ($debug) {
			echo '<i>$language:</i> '.htmlentities($language).'<br>';
			echo '<i>$language_code:</i> '.htmlentities($language_code).'<br>';
			echo '<i>$language_region:</i> '.htmlentities($language_region).'<br>';
		}
	
		return array($language,$language_code,$language_region);
	}
}

if(!function_exists('metaModGMTTimestampForDateInTimezone')){ 
	function metaModGMTTimestampForDateInTimezone($datetime_text,$zone="default") {
		// the default is a conversion according to system time, plus GMT offset
		// (which takes it back to GMT), plus Joomla config offset (which takes
		// it to the standard Joomla timezone).
		if ($zone == "default") { 
			// Interpret given datetime in current locale with strtotime (converts back to GMT). 
			// Add local timezone (dateZ). 
			// Subtract Joomla's offset.
			// ... Joomla's offset is a number of hours AHEAD of GMT that the admin chose in the "locale" panel in Joomla
			//     and so we subtract that from the calculated date to get back to GMT again. It's not perfect but OK.
			//     Best to specify the timezone exactly with the MetaMod dropdown, cos that respects daylight savings etc.
			$ff = strtotime($datetime_text) + date("Z") - ($GLOBALS['mosConfig_offset_user'] * 3600);
			return $ff;
		}
		// otherwise, set the timezone and recalculate
		$old_tz = getenv('TZ');
		putenv("TZ=$zone"); // interpret anything in strtotime() as being "local" to that zone. Also date("Z") gives the hours offset of that zone.
		$stamp = strtotime($datetime_text);
		putenv("TZ=$old_tz");
		return $stamp;
	}
}

global $Itemid,$option;
$id = array_key_exists('id',$_REQUEST) ? $_REQUEST['id'] : '';
$task = array_key_exists('task',$_REQUEST) ? $_REQUEST['task'] : ''; // for Joomla 1.5, this would be 'view'

// Retrieve parameters
$php 				= trim( $params->get( 'php', '' ) );
$start_datetime 		= trim( $params->get( 'start_datetime', '' ) );
$end_datetime 			= trim( $params->get( 'end_datetime', '' ) );
$timezone 			= trim( $params->get( 'timezone', 'default' ) );
$style				= intval( $params->get( 'style', '0' ) );
$use_geoip 			= intval( $params->get( 'use_geoip', '0' ) );
$module_ids 			= trim( $params->get( 'module_ids', '0' ) );
$debug 				= trim( $params->get( 'debug', '0' ) );

$now 				= time(); // GMT timestamp for "now"

/* I need to be able to:
- compare (a) the current GMT timestamp on the computer, to (b) the GMT equivalent of the given text date in a given zone.
*/

if ($debug) {
	echo '<b>MetaMod debug info:</b><br />';
	echo '<i>$option:</i> '.htmlentities($option).'<br />';
	echo '<i>$task:</i> '.htmlentities($task).'<br />';
	echo '<i>$id:</i> '.htmlentities($id).'<br />';
	echo '<i>$Itemid:</i> '.htmlentities($Itemid).'<br />';
	echo '<i>$timezone:</i> '.htmlentities($timezone).'<br />';
	echo '<i>now:</i> '.htmlentities($now).'<br />';
}

// LANGUAGE HANDLING
list($language,$language_code,$language_region) = metaModLanguages($params);


$include_countries	= strtoupper(trim( $params->get( 'include_countries', '' ) ));
$exclude_countries	= strtoupper(trim( $params->get( 'exclude_countries', '' ) ));

// quit if we're not to start yet
if ($start_datetime != '') {
	$then = metaModGMTTimestampForDateInTimezone($start_datetime,$timezone);
 	if ($then > $now) {
		if ($debug) {
			echo 'Start date/time has not been reached.<br />';
		}
		return;
	}
	if ($debug) {
		echo 'Start date/time has been reached.<br />';
	}
}

// quit if we are too late to display this item
if ($end_datetime != '') {
	$then = metaModGMTTimestampForDateInTimezone($end_datetime,$timezone);
 	if ($then < $now) {
		if ($debug) {
			echo 'End date/time has already passed.<br />';
		}
		return;
	}
	if ($debug) {
		echo 'End date/time has not passed.<br />';
	}
}

static $geoip = null;

$fromCountryId = defined("_GEOIP_FROM_COUNTRY_ID") ? _GEOIP_FROM_COUNTRY_ID : '';
$fromCountryName = defined("_GEOIP_FROM_COUNTRY_NAME") ? _GEOIP_FROM_COUNTRY_NAME : '';
$ip = $_SERVER['REMOTE_ADDR'];

if ($use_geoip) {
	if ($fromCountryId == '' && $fromCountryName == '' && $geoip == null) {

		// find the location of the geoip data file, depending on which we are to use
		$include_file = locateGeoIPInclude($use_geoip);
		if ($include_file == null) {
			if ($debug) {
				echo "<b>ERROR: cannot locate necessary GeoIP data file in any standard location. Disabing GeoIP.</b><br />";
			}
		} else {
			$geoIPFiles = array('','geoip.inc','geoipcity.inc','geoipcity.inc');
		
			// grab the appropriate code for whichever geoip stuff we have 
			if (!function_exists("geoip_open")) {
				include_once("mod_metamod/geoip-php4/".$geoIPFiles[$use_geoip]);
			}
		
			// open the data file
			$gi = geoip_open($include_file,GEOIP_STANDARD);

			if ($use_geoip == 1) { // GeoIP Country (free or commercial)
				$fromCountryId = geoip_country_code_by_addr($gi, $ip);
				$fromCountryName = geoip_country_name_by_addr($gi, $ip);
			} else { // GeoCity or GeoLiteCity
				$geoip = geoip_record_by_addr($gi, $ip);
				$fromCountryId = $geoip->country_code;
				$fromCountryName = $geoip->country_name;
				if ($geoip == null && $debug) {
					echo "No GeoCity info found for $ip. Using default country.<br />";
				}
			}
			geoip_close($gi);

			// set some defaults if necessary (probably can't happen)
			if ($fromCountryId == '') $fromCountryId = "GB";
			if ($fromCountryName == '') $fromCountryName = "United Kingdom";
			// save these away for next time
			define ("_GEOIP_FROM_COUNTRY_ID",$fromCountryId);
			define ("_GEOIP_FROM_COUNTRY_NAME",$fromCountryName);
		} // we found the geoip data file
	} // we needed to cache the geoip for the current request
} // we were told to use a particular variant of GeoIP

if (($fromCountryId || $fromCountryName) && $debug) {
	echo "<i>Country:</i> " .$fromCountryId . "<br />";
	echo "<i>Country Name:</i> " . $fromCountryName . "<br />";
}

if($geoip && $debug)
{
	echo "<i>Country Code 2:</i> " . $geoip->country_code3 . "<br />";
	echo "<i>Region:</i> " .$geoip->region . "<br />";
	echo "<i>City:</i> " .$geoip->city . "<br />";
	echo "<i>Postal Code:</i> " .$geoip->postal_code . "<br />";
	echo "<i>Latitude:</i> " .$geoip->latitude . "<br />";
	echo "<i>Longitude:</i> " .$geoip->longitude . "<br />";
	echo "<i>DMA Code:</i> " .$geoip->dma_code . "<br />";
	echo "<i>Area Code:</i> " .$geoip->area_code . "<br />";
}						

if ($use_geoip) {
	if (strlen($include_countries)) {
		// reject if fromCountryId is not in the list
		if (strpos($include_countries,$fromCountryId) === false) {
			if ($debug) {
				echo 'Rejecting: '.$fromCountryId.' is not in include list<br />';
			}
			return;
		}
		if ($debug) {
			echo 'Accepting: '.$fromCountryId.' is in include list<br />';
		}
	}
	if (strlen($exclude_countries)) {
		// reject if fromCountryId is in the list
		if (! (strpos($exclude_countries,$fromCountryId) === false)) {
			if ($debug) {
				echo 'Rejecting: '.$fromCountryId.' is in exclude list<br />';
			}
			return;
		}
		if ($debug) {
			echo 'Accepting: '.$fromCountryId.' is not in exclude list<br />';
		}
	}
}

// get results from php script
$mods = strlen($php) ? eval(str_replace("\r<br />","\n",str_replace("\n<br />","\n",$php))) : '';

// convert comma-separated list of module ids (specified statically) to an array of integers
$static_ids = strlen($module_ids) ? array_map("intval",explode(",",$module_ids)) : array();

// convert comma-separated list of module ids (returned from PHP code) to an array of integers
if (!is_array($mods)) {
	if (is_numeric($mods)) $mods = array($mods);
	if (is_string($mods))  $mods = array_map("intval",explode(",",$mods));
	if (!is_array($mods))  $mods = array();
}

// combine the 2 sets of numbers
$all_mod_array = array_filter(array_merge($static_ids,$mods)); // remove everything equating to "0" / false

if ($debug) {
	echo 'Including modules: '.implode(', ',$all_mod_array).'<br />';
}

if (count($all_mod_array)) {
	$all_mod_numbers = "('".implode("','",array_map("intval", $all_mod_array ))."')";
	$query = "SELECT id, title, module, position, content, showtitle, params"
	. "\n FROM #__modules AS m"
	. "\n WHERE m.published = 1"
	. "\n AND m.access <= ". (int) $my->gid
	. "\n AND m.client_id != 1"
	. "\n AND m.id in $all_mod_numbers"
	. "\n ORDER BY ordering";

	$database->setQuery( $query );
	$modules = $database->loadObjectList();
	
	// following code stolen from frontend.php		
	$cache =& mosCache::getCache( 'com_content' );
	require_once( $mosConfig_absolute_path . '/includes/frontend.html.php' );
	$count = 1;
	foreach ($modules as $module) {
		$params = new mosParameters( $module->params );

		if ((substr("$module->module",0,4))=='mod_') {
		// normal modules
			if ($params->get('cache') == 1 && $mosConfig_caching == 1) {
			// module caching
				$cache->call('modules_html::module2', $module, $params, $Itemid, $style, $my->gid  );
			} else {
				modules_html::module2( $module, $params, $Itemid, $style, $count );
			}
		} else {
		// custom or new modules
			if ($params->get('cache') == 1 && $mosConfig_caching == 1) {
			// module caching
				$cache->call('modules_html::module', $module, $params, $Itemid, $style, 0, $my->gid );
			} else {
				modules_html::module( $module, $params, $Itemid, $style );
			}
		}

		$count++;
	}	
}
?>