1<?php 2/** 3 * webtrees: online genealogy 4 * Copyright (C) 2019 webtrees development team 5 * This program is free software: you can redistribute it and/or modify 6 * it under the terms of the GNU General Public License as published by 7 * the Free Software Foundation, either version 3 of the License, or 8 * (at your option) any later version. 9 * This program is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * GNU General Public License for more details. 13 * You should have received a copy of the GNU General Public License 14 * along with this program. If not, see <http://www.gnu.org/licenses/>. 15 */ 16namespace Fisharebest\Webtrees\Controller; 17 18use Fisharebest\Webtrees\Database; 19 20/** 21 * Base controller for all other controllers 22 */ 23class BaseController 24{ 25 // The controller accumulates Javascript (inline and external), and renders it in the footer 26 const JS_PRIORITY_HIGH = 0; 27 const JS_PRIORITY_NORMAL = 1; 28 const JS_PRIORITY_LOW = 2; 29 30 /** @var string[][] Inline JavaScript to add to the page. */ 31 private $inline_javascript = array( 32 self::JS_PRIORITY_HIGH => array(), 33 self::JS_PRIORITY_NORMAL => array(), 34 self::JS_PRIORITY_LOW => array(), 35 ); 36 37 /** @var string[] Exteral JavaScript files to load. */ 38 private $external_javascript = array(); 39 40 /** 41 * Startup activity 42 */ 43 public function __construct() 44 { 45 } 46 47 /** 48 * Make a list of external Javascript, so we can render them in the footer 49 * 50 * @param string $script_name 51 * 52 * @return $this 53 */ 54 public function addExternalJavascript($script_name) 55 { 56 $this->external_javascript[$script_name] = true; 57 58 return $this; 59 } 60 61 /** 62 * Make a list of inline Javascript, so we can render them in the footer 63 * NOTE: there is no need to use "jQuery(document).ready(function(){...})", etc. 64 * as this Javascript won’t be inserted until the very end of the page. 65 * 66 * @param string $script 67 * @param int $priority 68 * 69 * @return $this 70 */ 71 public function addInlineJavascript($script, $priority = self::JS_PRIORITY_NORMAL) 72 { 73 $tmp = &$this->inline_javascript[$priority]; 74 $tmp[] = $script; 75 76 return $this; 77 } 78 79 /** 80 * We've collected up Javascript fragments while rendering the page. 81 * Now display them in order. 82 * 83 * @return string 84 */ 85 public function getJavascript() 86 { 87 $javascript1 = ''; 88 $javascript2 = ''; 89 $javascript3 = ''; 90 91 // Inline (high priority) javascript 92 foreach ($this->inline_javascript[self::JS_PRIORITY_HIGH] as $script) { 93 $javascript1 .= $script; 94 } 95 96 // External javascript 97 foreach (array_keys($this->external_javascript) as $script_name) { 98 $javascript2 .= '<script src="' . $script_name . '"></script>'; 99 } 100 101 // Inline (lower priority) javascript 102 if ($this->inline_javascript) { 103 foreach ($this->inline_javascript as $priority => $scripts) { 104 if ($priority !== self::JS_PRIORITY_HIGH) { 105 foreach ($scripts as $script) { 106 $javascript3 .= $script; 107 } 108 } 109 } 110 } 111 112 // We could, in theory, inject JS at any point in the page (not just the bottom) - prepare for next time 113 $this->inline_javascript = array( 114 self::JS_PRIORITY_HIGH => array(), 115 self::JS_PRIORITY_NORMAL => array(), 116 self::JS_PRIORITY_LOW => array(), 117 ); 118 $this->external_javascript = array(); 119 120 return '<script>' . $javascript1 . '</script>' . $javascript2 . '<script>' . $javascript3 . '</script>'; 121 } 122 123 /** 124 * Print the page header, using the theme 125 * 126 * @return $this 127 */ 128 public function pageHeader() 129 { 130 // We've displayed the header - display the footer automatically 131 register_shutdown_function(array($this, 'pageFooter')); 132 133 return $this; 134 } 135 136 /** 137 * Print the page footer, using the theme 138 */ 139 public function pageFooter() 140 { 141 if (WT_DEBUG_SQL) { 142 echo Database::getQueryLog(); 143 } 144 echo $this->getJavascript(); 145 } 146} 147