.
*/
abstract class AbstractLayout {
private $noHtml;
private $loginRequired;
private $initDone;
private $output;
private $logger;
private $ldap;
const DEFAULTLAYOUT = "plain";
/**
* Default constructor
*
* @param boolean noHtml: disable HTML output (useful for sending binaries to the client)
* @param boolean loginRequired: should a user always be logged in when entering the page
*/
public function __construct($noHtml = false, $loginRequired = false) {
$this->noHtml = $noHtml;
$this->loginRequired = $loginRequired;
$this->logger = $GLOBALS['logger'];
$this->initDone = false;
$this->output = "";
}
/**
* Default destructor
*/
public function __destruct() {
}
/**
* Initialise layout: handle login/logout and provide basic access check
*
* Note: this function does only return if required access met
*/
public function init($detectEvent=true) {
$this->startSession();
$this->detectLayout();
$this->createDatabaseConnections();
#####################
### Login section ###
#####################
if( !isset($_SESSION['sess_uid']) ) {
$_SESSION['sess_uid'] = 0;
}
$authClass = "Auth" . AUTH_SYSTEM;
require_once(ROOTPATH . "include/classes/".$authClass.".php");
$this->ldap = new $authClass();
if( AUTH_SYSTEM!="None" && isset($_POST['sess_user']) && isset($_POST['sess_pass']) ) {
$this->tryAndHandleLogin($_POST['sess_user'], $_POST['sess_pass']);
}elseif( isset($_GET['logout']) ) {
$this->doLogout();
$this->afterLogout();
}elseif( $_SESSION['sess_uid']==0 && ($this->loginRequired || isset($_GET['login'])) ) {
$this->sslRedirect();
$this->displayLogin();
exit();
}
if( $detectEvent ) {
$this->detectEvent();
}
$this->initDone = true;
}
/**
* Inform user interface that required access level is not met. Show login form in case user is not logged in,
* or inform that he/she has insufficient access.
*
* Note: this function does not return
*/
public function noAccess() {
$this->output = "";
$this->displayTop();
$this->echoln("Sorry, you are not authorised to access this page.");
$this->echoln("
You might have to log in with another account that has more access rights.");
if( !PRODUCTION_MODE ) {
$this->displayLogs();
}
$this->flush();
$this->displayBottom();
exit();
}
/**
* Output current buffer to screen
*/
public function flush() {
echo $this->output;
$this->output = "";
}
public function pageHeader() {
if( !$this->initDone ) $this->init(); // If not initialised, do it now
}
public function pageFooter() {
$pageOutput = $this->output;
$this->output = "";
$this->displayTop();
$this->output .= $pageOutput;
if( !PRODUCTION_MODE ) {
$this->displayLogs();
}
$this->flush();
$this->displayBottom();
}
/**
* Redirect to a specific URL
*
* @param string URL where to redirect to
* @return false in case redirect is not possible, no return otherwise
*/
public function redirect($url) {
if( headers_sent() ) {
return false;
}else {
$this->output = "";
header("Status: 301");
header("Location: ".$url);
exit;
}
}
/**
* Output a line to screen
*
* @param string $t text to be send to screen
* @param boolean $addnewline (default: true) add a newline character at the end (only in debug mode)
*/
public function echoln($t, $addnewline=true) {
if( !PRODUCTION_MODE ) {
$this->output .= $t;
if( $addnewline ) $this->output .= "\n";
}else {
$this->output .= rtrim(ltrim($t), "\n\r\0\x0B");
}
}
/**
* Include een HTML file
*
* @param string $file to be included
*/
public function echoHtml($file) {
if( preg_match("/^[a-zA-Z0-9_\.-]*$/", $file) && file_exists(ROOTPATH . "html/" . $file) ) {
$data = file_get_contents(ROOTPATH . "html/" . $file);
$search = array(); $replace = array();
$search[] = "%PHP_SELF%"; $replace[] = $_SERVER['PHP_SELF'];
$search[] = "%USERNAME%"; $replace[] = (isset($_SESSION['sess_name'])?$_SESSION['sess_name']:"");
$search[] = "%ROOTPATH%"; $replace[] = ROOTPATH;
$this->echoln(str_replace($search, $replace, $data));
}else {
$this->warn("Cannot include HTML file: " . $file);
}
}
/**
* Output a error line to screen (in debug mode) or log it to file (in non-debug mode)
*
* @param string $msg error message to be reported
*/
public function error($msg) {
$this->logger->error($msg);
}
/**
* Output a warning line to screen (in debug mode) or log it to file (in non-debug mode)
*
* @param string $msg warning message to be reported
*/
public function warn($msg) {
$this->logger->warn($msg);
}
/**
* Output an information line to screen (in debug mode) or log it to file (in non-debug mode)
*
* @param string $msg information message to be reported
*/
public function info($msg) {
$this->logger->info($msg);
}
/**
* Output a debug line to screen (only in debug mode, in non-debug mode the line is ignored)
*
* @param string $msg debug message to be shown on screen
*/
public function debug($msg) {
if( !PRODUCTION_MODE ) {
$this->echoln("
".$msg."
");
}
}
/**
* Output the contents of an array to screen (only in debug mode, in non-debug mode the line is ignored)
*
* @param array $array array to be printed to screen
*/
public function debugArray($array) {
if( !PRODUCTION_MODE ) {
if( isset($_SERVER["REMOTE_ADDR"]) ) {
$this->debug(strtr( nl2br( strtr( preg_replace("/(\[.*pass.*\]) => .*/", "$1 => ******", print_r($array, true)), array(" " => " ")) ), array("
" => "
")));
#debug(strtr( nl2br( strtr( print_r($array, true), array(" " => " ")) ), array("
" => "
")));
}else {
$this->debug(print_r($array, true));
}
}
}
protected abstract function startSession();
protected abstract function tryAndHandleLogin($user, $password);
protected abstract function displayTop();
protected abstract function displayBottom();
protected abstract function displayLogin();
protected function getLdap() {
return $this->ldap;
}
protected function getNoHtml() {
return $this->noHtml;
}
protected function afterLogout() {
// Override me please if you want
}
protected function layoutItem($part) {
$parts = array();
$parts[] = "login";
$parts[] = "top";
$parts[] = "menu-top";
$parts[] = "menu-bottom";
$parts[] = "account-top";
$parts[] = "account-anonymous";
$parts[] = "account-loggedin";
$parts[] = "account-bottom";
$parts[] = "page-top";
$parts[] = "page-bottom";
$parts[] = "bottom";
$parts[] = "all";
if( in_array($part, $parts) ) {
if( $part=="top" ) header("Content-Type: text/html; charset=UTF-8");
if( $fd=fopen(ROOTPATH."layout/".$_SESSION['sess_layout']."/".$part.".html", "r") ) {
$search = array(); $replace = array();
$search[] = "%PHP_SELF%"; $replace[] = $_SERVER['PHP_SELF'];
$search[] = "%REQUEST_URI%"; $replace[] = preg_replace("/logout/", "", $_SERVER['REQUEST_URI']);
$search[] = "%USERNAME%"; $replace[] = (isset($_SESSION['sess_name'])?$_SESSION['sess_name']:"");
$search[] = "%RAWENCODEUSERNAME%"; $replace[] = (isset($_SESSION['sess_name'])?rawurlencode($_SESSION['sess_name']):"");
$search[] = "%LAYOUTDIR%"; $replace[] = ROOTPATH . "layout/".$_SESSION['sess_layout']."/";
$search[] = "%QUERY_STRING%"; $replace[] = preg_replace("/logout/", "", $_SERVER['QUERY_STRING']);
if( $this->getLdap()==null ) {
$search[] = "%AUTH_SYSTEM_NAME%"; $replace[] = "aegee.org";
$search[] = "%AUTH_REGISTRATION_URL%"; $replace[] = "http://www.aegee.org/";
}else {
$search[] = "%AUTH_SYSTEM_NAME%"; $replace[] = $this->getLdap()->getSystemName();
$search[] = "%AUTH_REGISTRATION_URL%"; $replace[] = $this->getLdap()->getRegistrationUrl();
}
while( !feof($fd) ) {
echo str_replace($search, $replace, fgets($fd, 4096));
}
fclose($fd);
}
}else {
// Not valid
}
}
private function displayLogs() {
foreach( $this->logger->getMessages() as $log ) {
switch( $log['Severity'] ) {
case "ERROR":
$this->echoln("".$log['Message']."
");
break;
case "WARN":
$this->echoln("".$log['Message']."
");
break;
case "INFO":
$this->echoln("".$log['Message']."
");
break;
default:
$this->echoln("".$log['Severity'].": ".$log['Message']."
");
break;
}
}
}
private function detectLayout() {
if( isset($_REQUEST['sess_layout']) ) {
if( preg_match("/^[a-z][0-9]$/", $_REQUEST['sess_layout'])==1 ) {
if( is_dir(ROOTPATH."layout/".$_REQUEST['sess_layout']) ) {
// Valid layout, class exists
$_SESSION['sess_layout'] = $_REQUEST['sess_layout'];
}else {
$this->debug("Invalid layout, does not exist");
}
}else {
$this->debug("Invalid layout syntax");
}
}
if( !isset($_SESSION['sess_layout']) ) $_SESSION['sess_layout'] = LAYOUT_DEFAULT;
if( file_exists(ROOTPATH."layout/".$_SESSION['sess_layout']."/icons.php") ) {
include_once(ROOTPATH."layout/".$_SESSION['sess_layout']."/icons.php");
if( is_array($LAYOUT_ICONS) ) {
$GLOBALS['LAYOUT_ICONS'] = $LAYOUT_ICONS;
}else {
$this->debug("Layout does not define icons.");
}
}else {
$this->debug("Layout does not have icons (missing icons.php in layout directory).");
}
}
private function createDatabaseConnections() {
$GLOBALS['sql'] = new MySQL(MYSQL_HOST, MYSQL_USER, MYSQL_PASS, MYSQL_DB);
$GLOBALS['sql2'] = new MySQL(MYSQL_HOST, MYSQL_USER, MYSQL_PASS, MYSQL_DB);
}
private function doLogout() {
$sess_layout = $_SESSION['sess_layout'];
$_SESSION = array();
$_SESSION['sess_layout'] = $sess_layout;
}
private function detectEvent() {
$dir = dirname($_SERVER['REQUEST_URI']."a")."/".ROOTPATH;
for( $i=0; $i<4; $i++ ) {
$dir = preg_replace('/\w+\/\.\.\//', '', $dir);
}
$relativeToRoot = substr(dirname($_SERVER['REQUEST_URI']."a")."/", strlen($dir));
$event = substr($relativeToRoot, 0, strpos($relativeToRoot, "/"));
if( $event!="" && $event!="admin" ) {
$query = "SELECT `id`, `title` FROM `events` WHERE `key`='".$GLOBALS['sql']->escape($event)."'";
if( $GLOBALS['sql']->query($query) && $GLOBALS['sql']->getNumRows()==1 ) {
$row = $GLOBALS['sql']->fetchAssoc();
define("EVENT_ID", $row['id']);
define("EVENT_TITLE", $row['title']);
}else {
$this->warn("Unknown event: " . $event . ". Referrer: " . (isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : "=unknown="));
$this->echoln("You are requesting an unknown event.
");
$this->echoln("Return to homepage
");
$this->pageFooter();
exit();
}
}else {
define("EVENT_ID", MAIN_ADMIN_EVENT_ID);
define("EVENT_TITLE", "");
}
}
/**
* Make sure the user connects via a secure link (https)
*/
protected function sslRedirect() {
if(headers_sent()) {
$this->error("ssl_redirect: Headers already sent.");
exit;
}
if( !isset($_SERVER['HTTPS']) ) {
if(!isset($_SERVER['REQUEST_URI']) OR !isset($_SERVER['HTTP_HOST'])) {
echo "\n \n";
echo " AEGEE Online Membership System\n";
echo " \n \n";
echo " Your browser doesn't support HTTP 1.1 requests.\n";
echo " Please use https:// instead of http://\n";
echo " \n";
exit;
}
header("Status: 301");
header("Location: https://".$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI']);
exit;
}
}
/**
* Strip a logout parameter from the url
*/
private function getUrl() {
$url = $_SERVER['REQUEST_URI'];
$pos = strpos($url, "logout");
if( $pos===false ) {
// Do nothing
}elseif( substr($url, $pos-1, 1)=="&" ) {
$url = substr($url, 0, $pos-1) . substr($url, $pos+6);
}elseif( substr($url, $pos-1, 1)=="?" && strlen($url)>($pos+6) && substr($url, $pos+6, 1)=="&" ) {
$url = substr($url, 0, $pos) . substr($url, $pos+7);
}elseif( substr($url, $pos-1, 1)=="?" && strlen($url)<=($pos+6) ) {
$url = substr($url, 0, $pos-1);
}
return $url;
}
protected function getLdapTranslation() {
$ldapTranslation = array();
$ldapTranslation['bodycode'] = "BodyCode";
$ldapTranslation['givenname'] = "FirstName";
$ldapTranslation['sn'] = "LastName";
$ldapTranslation['datebirth'] = "DateBirth";
$ldapTranslation['sex'] = "Sex";
$ldapTranslation['mail'] = "Email";
$ldapTranslation['street'] = "Street";
$ldapTranslation['postalcode'] = "Zip";
$ldapTranslation['l'] = "City";
$ldapTranslation['c'] = "CountryCode";
$ldapTranslation['phone'] = "Phone";
$ldapTranslation['mobile'] = "Mobile";
$ldapTranslation['fax'] = "Fax";
return $ldapTranslation;
}
}
/**
* Output a debug line to screen (only in debug mode, in non-debug mode the line is ignored)
*
* @param string $msg debug message to be shown on screen
*/
function debug($msg) {
if( !PRODUCTION_MODE ) {
echo "".$msg."
";
}
}
/**
* Output the contents of an array to screen (only in debug mode, in non-debug mode the line is ignored)
*
* @param array $array array to be printed to screen
*/
function debugArray($array) {
if( !PRODUCTION_MODE ) {
if( isset($_SERVER["REMOTE_ADDR"]) ) {
// Webbrowser
debug(strtr( nl2br( strtr( preg_replace("/(\[.*pass.*\]) => .*/", "$1 => ******", print_r($array, true)), array(" " => " ")) ), array("
" => "
")));
#debug(strtr( nl2br( strtr( print_r($array, true), array(" " => " ")) ), array("
" => "
")));
}else {
// Shell
debug(print_r($array, true));
}
}
}
?>