'; // HTML5
private $canonical_url='';
private $meta_robots ='noindex,nofollow'; // Most pages are not intended for robots
protected $page_header =false; // Have we printed a page header?
private $page_title =WT_WEBTREES; //
$page_title
// The controller accumulates Javascript (inline and external), and renders it in the footer
const JS_PRIORITY_HIGH = 0;
const JS_PRIORITY_NORMAL = 1;
const JS_PRIORITY_LOW = 2;
private $inline_javascript=array(
self::JS_PRIORITY_HIGH =>array(),
self::JS_PRIORITY_NORMAL=>array(),
self::JS_PRIORITY_LOW =>array(),
);
private $external_javascript=array();
// Startup activity
public function __construct() {
// (almost?) every page uses these scripts....
$this
->addExternalJavascript(WT_STATIC_URL.'js/webtrees.js')
->addExternalJavascript(WT_JQUERY_URL)
->addExternalJavascript(WT_JQUERYUI_URL);
}
// Shutdown activity
public function __destruct() {
// If we printed a header, automatically print a footer
if ($this->page_header) {
$this->pageFooter();
}
}
// What should this page show in the browser's title bar?
public function setPageTitle($page_title) {
$this->page_title=$page_title;
return $this;
}
// Some pages will want to display this as $page_title
public function getPageTitle() {
return $this->page_title;
}
// What is the preferred URL for this page?
public function setCanonicalUrl($canonical_url) {
$this->canonical_url=$canonical_url;
return $this;
}
// Should robots index this page?
public function setMetaRobots($meta_robots) {
$this->meta_robots=$meta_robots;
return $this;
}
// Restrict access
public function requireAdminLogin() {
require_once WT_ROOT.'includes/functions/functions.php'; // for get_query_url
if (!WT_USER_IS_ADMIN) {
header('Location: '.WT_LOGIN_URL.'?url='.rawurlencode(get_query_url()));
exit;
}
return $this;
}
// Restrict access
public function requireManagerLogin($ged_id=WT_GED_ID) {
require_once WT_ROOT.'includes/functions/functions.php'; // for get_query_url
if (
$ged_id==WT_GED_ID && !WT_USER_GEDCOM_ADMIN ||
$ged_id!=WT_GED_ID && userGedcomAdmin(WT_USER_ID, $gedcom_id)
) {
header('Location: '.WT_LOGIN_URL.'?url='.rawurlencode(get_query_url()));
exit;
}
return $this;
}
// Restrict access
public function requireAcceptLogin() {
require_once WT_ROOT.'includes/functions/functions.php'; // for get_query_url
if (!WT_USER_CAN_ACCEPT) {
header('Location: '.WT_LOGIN_URL.'?url='.rawurlencode(get_query_url()));
exit;
}
return $this;
}
// Restrict access
public function requireEditorLogin() {
require_once WT_ROOT.'includes/functions/functions.php'; // for get_query_url
if (!WT_USER_CAN_EDIT) {
header('Location: '.WT_LOGIN_URL.'?url='.rawurlencode(get_query_url()));
exit;
}
return $this;
}
// Restrict access
public function requireMemberLogin() {
require_once WT_ROOT.'includes/functions/functions.php'; // for get_query_url
if (!WT_USER_ID) {
header('Location: '.WT_LOGIN_URL.'?url='.rawurlencode(get_query_url()));
exit;
}
return $this;
}
// Make a list of external Javascript, so we can render them in the footer
public function addExternalJavascript($script_name) {
$this->external_javascript[$script_name]=true;
return $this;
}
// Make a list of inline Javascript, so we can render them in the footer
// NOTE: there is no need to use "jQuery(document).ready(function(){...})", etc.
// as this Javascript won't be inserted until the very end of the page.
public function addInlineJavascript($script, $priority=self::JS_PRIORITY_NORMAL) {
if (WT_DEBUG) {
/* Show where the JS was added */
$backtrace=debug_backtrace();
$script='/* '.$backtrace[0]['file'].':'.$backtrace[0]['line'].' */'.PHP_EOL.$script;
}
$tmp=&$this->inline_javascript[$priority];
$tmp[]=$script;
return $this;
}
// We've collected up Javascript fragments while rendering the page.
// Now display them.
public function getJavascript() {
// Modernizr.load() doesn't seem to work well with AJAX responses.
// Temporarily disable this while we investigate
$TMP_HTML='';
$html='';
// Insert the high priority scripts before external resources
if ($this->inline_javascript[self::JS_PRIORITY_HIGH]) {
$html.=PHP_EOL.'';
$this->inline_javascript[self::JS_PRIORITY_HIGH] = array();
}
// Load external libraries asynchronously
$load_js=array();
foreach (array_keys($this->external_javascript) as $script_name) {
$load_js[]='"'.$script_name.'"';
$TMP_HTML.='';
}
$load_js='[' . implode(',', $load_js) . ']';
// Process the scripts, in priority order, after the libraries have loaded
$complete_js='';
if ($this->inline_javascript) {
foreach ($this->inline_javascript as $scripts) {
foreach ($scripts as $script) {
$complete_js.=$script;
}
}
}
// We could, in theory, inject JS at any point in the page (not just the bottom) - prepare for next time
$this->inline_javascript=array(
self::JS_PRIORITY_HIGH =>array(),
self::JS_PRIORITY_NORMAL=>array(),
self::JS_PRIORITY_LOW =>array(),
);
$this->external_javascript=array();
return $TMP_HTML.'';
return $html.'';
}
// Print the page header, using the theme
public function pageHeader() {
// Import global variables into the local scope, for the theme's header.php
global $BROWSERTYPE, $SEARCH_SPIDER, $TEXT_DIRECTION, $REQUIRE_AUTHENTICATION;
global $stylesheet, $headerfile, $view;
// The title often includes the names of records, which may have markup
// that cannot be used in the page title.
$title=html_entity_decode(strip_tags($this->page_title), ENT_QUOTES, 'UTF-8');
// Initialise variables for the theme's header.php
$LINK_CANONICAL =$this->canonical_url;
$META_ROBOTS =$this->meta_robots;
$GEDCOM_TITLE =get_gedcom_setting(WT_GED_ID, 'title');
$META_DESCRIPTION=get_gedcom_setting(WT_GED_ID, 'META_DESCRIPTION', $GEDCOM_TITLE);
$META_GENERATOR =WT_WEBTREES.'-'.WT_VERSION_TEXT.' - '.WT_WEBTREES_URL;
$META_TITLE =get_gedcom_setting(WT_GED_ID, 'META_TITLE');
if ($META_TITLE) {
$title.=' - '.$META_TITLE;
}
// This javascript needs to be loaded in the header, *before* the CSS.
// All other javascript should be defered until the end of the page
$javascript= '';
// Give Javascript access to some PHP constants
$this->addInlineJavascript('
var WT_STATIC_URL = "'.WT_STATIC_URL.'";
var WT_THEME_DIR = "'.WT_THEME_DIR.'";
var WT_MODULES_DIR = "'.WT_MODULES_DIR.'";
var WT_GEDCOM = "'.WT_GEDCOM.'";
var WT_GED_ID = "'.WT_GED_ID.'";
var WT_USER_ID = "'.WT_USER_ID.'";
var textDirection = "'.$TEXT_DIRECTION.'";
var browserType = "'.$BROWSERTYPE.'";
var WT_SCRIPT_NAME = "'.WT_SCRIPT_NAME.'";
var WT_LOCALE = "'.WT_LOCALE.'";
var accesstime = '.WT_DB::prepare("SELECT UNIX_TIMESTAMP(NOW())")->fetchOne().';
', self::JS_PRIORITY_HIGH);
// Temporary fix for access to main menu hover elements on android touch devices
$this->addInlineJavascript('
var ua = navigator.userAgent.toLowerCase();
var isAndroid = ua.indexOf("android") > -1;
if(isAndroid) {
jQuery("#main-menu > li > a").attr("href", "#");
jQuery("a.icon_arrow").attr("href", "#");
}
');
// Tell IE to use standards mode instead of compatability mode.
if ($BROWSERTYPE=='msie') {
header("X-UA-Compatible: IE=Edge");
}
header('Content-Type: text/html; charset=UTF-8');
require WT_ROOT.$headerfile;
// Flush the output, so the browser can render the header and load javascript
// while we are preparing data for the page
if (ini_get('output_buffering')) {
ob_flush();
}
flush();
// Once we've displayed the header, we should no longer write session data.
Zend_Session::writeClose();
// We've displayed the header - display the footer automatically
$this->page_header=true;
return $this;
}
// Print the page footer, using the theme
protected function pageFooter() {
global $footerfile, $TEXT_DIRECTION, $view;
require WT_ROOT.$footerfile;
if (WT_DEBUG_SQL) {
echo WT_DB::getQueryLog();
}
echo $this->getJavascript();
echo '