use Friendica\Database\DBA;
use Friendica\Network\HTTPException\InternalServerErrorException;
-require_once 'boot.php';
-require_once 'include/text.php';
-
/**
*
* class: App
public $query_string = '';
public $config = [];
public $page = [];
- public $pager = [];
- public $page_offset;
public $profile;
public $profile_uid;
public $user;
*/
private $isAjax;
+ /**
+ * @var MobileDetect
+ */
+ public $mobileDetect;
+
/**
* Register a stylesheet file path to be included in the <head> tag of every page.
* Inclusion is done in App->initHead().
$this->footerScripts[] = trim($url, '/');
}
- /**
- * @brief An array for all theme-controllable parameters
- *
- * Mostly unimplemented yet. Only options 'template_engine' and
- * beyond are used.
- */
- public $theme = [
- 'sourcename' => '',
- 'videowidth' => 425,
- 'videoheight' => 350,
- 'force_max_items' => 0,
- 'stylesheet' => '',
- 'template_engine' => 'smarty3',
- ];
-
- /**
- * @brief An array of registered template engines ('name'=>'class name')
- */
- public $template_engines = [];
-
- /**
- * @brief An array of instanced template engines ('name'=>'instance')
- */
- public $template_engine_instance = [];
public $process_id;
public $queue;
- private $ldelim = [
- 'internal' => '',
- 'smarty3' => '{{'
- ];
- private $rdelim = [
- 'internal' => '',
- 'smarty3' => '}}'
- ];
private $scheme;
private $hostname;
set_include_path(
get_include_path() . PATH_SEPARATOR
. $this->getBasePath() . DIRECTORY_SEPARATOR . 'include' . PATH_SEPARATOR
- . $this->getBasePath(). DIRECTORY_SEPARATOR . 'library' . PATH_SEPARATOR
+ . $this->getBasePath() . DIRECTORY_SEPARATOR . 'library' . PATH_SEPARATOR
. $this->getBasePath());
if (!empty($_SERVER['QUERY_STRING']) && strpos($_SERVER['QUERY_STRING'], 'pagename=') === 0) {
$this->module = 'home';
}
- // See if there is any page number information, and initialise pagination
- $this->pager['page'] = !empty($_GET['page']) && intval($_GET['page']) > 0 ? intval($_GET['page']) : 1;
- $this->pager['itemspage'] = 50;
- $this->pager['start'] = ($this->pager['page'] * $this->pager['itemspage']) - $this->pager['itemspage'];
-
- if ($this->pager['start'] < 0) {
- $this->pager['start'] = 0;
- }
- $this->pager['total'] = 0;
-
// Detect mobile devices
$mobile_detect = new MobileDetect();
+
+ $this->mobileDetect = $mobile_detect;
+
$this->is_mobile = $mobile_detect->isMobile();
$this->is_tablet = $mobile_detect->isTablet();
$this->isAjax = strtolower(defaults($_SERVER, 'HTTP_X_REQUESTED_WITH', '')) == 'xmlhttprequest';
// Register template engines
- $this->registerTemplateEngine('Friendica\Render\FriendicaSmartyEngine');
+ Core\Renderer::registerTemplateEngine('Friendica\Render\FriendicaSmartyEngine');
}
/**
* Load the configuration files
*
* First loads the default value for all the configuration keys, then the legacy configuration files, then the
- * expected local.ini.php
+ * expected local.config.php
*/
private function loadConfigFiles()
{
- $this->loadConfigFile($this->getBasePath() . DIRECTORY_SEPARATOR . 'config' . DIRECTORY_SEPARATOR . 'config.ini.php');
- $this->loadConfigFile($this->getBasePath() . DIRECTORY_SEPARATOR . 'config' . DIRECTORY_SEPARATOR . 'settings.ini.php');
+ $this->loadConfigFile($this->getBasePath() . '/config/defaults.config.php');
+ $this->loadConfigFile($this->getBasePath() . '/config/settings.config.php');
// Legacy .htconfig.php support
- if (file_exists($this->getBasePath() . DIRECTORY_SEPARATOR . '.htpreconfig.php')) {
+ if (file_exists($this->getBasePath() . '/.htpreconfig.php')) {
$a = $this;
- include $this->getBasePath() . DIRECTORY_SEPARATOR . '.htpreconfig.php';
+ include $this->getBasePath() . '/.htpreconfig.php';
}
// Legacy .htconfig.php support
- if (file_exists($this->getBasePath() . DIRECTORY_SEPARATOR . '.htconfig.php')) {
+ if (file_exists($this->getBasePath() . '/.htconfig.php')) {
$a = $this;
- include $this->getBasePath() . DIRECTORY_SEPARATOR . '.htconfig.php';
+ include $this->getBasePath() . '/.htconfig.php';
$this->setConfigValue('database', 'hostname', $db_host);
$this->setConfigValue('database', 'username', $db_user);
}
}
- if (file_exists($this->getBasePath() . DIRECTORY_SEPARATOR . 'config' . DIRECTORY_SEPARATOR . 'local.ini.php')) {
- $this->loadConfigFile($this->getBasePath() . DIRECTORY_SEPARATOR . 'config' . DIRECTORY_SEPARATOR . 'local.ini.php', true);
+ if (file_exists($this->getBasePath() . '/config/local.config.php')) {
+ $this->loadConfigFile($this->getBasePath() . '/config/local.config.php', true);
+ } elseif (file_exists($this->getBasePath() . '/config/local.ini.php')) {
+ $this->loadINIConfigFile($this->getBasePath() . '/config/local.ini.php', true);
}
}
/**
- * Tries to load the specified configuration file into the App->config array.
+ * Tries to load the specified legacy configuration file into the App->config array.
* Doesn't overwrite previously set values by default to prevent default config files to supersede DB Config.
*
- * The config format is INI and the template for configuration files is the following:
- *
- * <?php return <<<INI
- *
- * [section]
- * key = value
- *
- * INI;
- * // Keep this line
- *
+ * @deprecated since version 2018.12
* @param string $filepath
* @param bool $overwrite Force value overwrite if the config key already exists
* @throws Exception
*/
- public function loadConfigFile($filepath, $overwrite = false)
+ public function loadINIConfigFile($filepath, $overwrite = false)
{
if (!file_exists($filepath)) {
- throw new Exception('Error parsing non-existent config file ' . $filepath);
+ throw new Exception('Error parsing non-existent INI config file ' . $filepath);
}
$contents = include($filepath);
$config = parse_ini_string($contents, true, INI_SCANNER_TYPED);
if ($config === false) {
- throw new Exception('Error parsing config file ' . $filepath);
+ throw new Exception('Error parsing INI config file ' . $filepath);
}
- foreach ($config as $category => $values) {
- foreach ($values as $key => $value) {
- if ($overwrite) {
- $this->setConfigValue($category, $key, $value);
- } else {
- $this->setDefaultConfigValue($category, $key, $value);
- }
- }
+ $this->loadConfigArray($config, $overwrite);
+ }
+
+ /**
+ * Tries to load the specified configuration file into the App->config array.
+ * Doesn't overwrite previously set values by default to prevent default config files to supersede DB Config.
+ *
+ * The config format is PHP array and the template for configuration files is the following:
+ *
+ * <?php return [
+ * 'section' => [
+ * 'key' => 'value',
+ * ],
+ * ];
+ *
+ * @param string $filepath
+ * @param bool $overwrite Force value overwrite if the config key already exists
+ * @throws Exception
+ */
+ public function loadConfigFile($filepath, $overwrite = false)
+ {
+ if (!file_exists($filepath)) {
+ throw new Exception('Error loading non-existent config file ' . $filepath);
+ }
+
+ $config = include($filepath);
+
+ if (!is_array($config)) {
+ throw new Exception('Error loading config file ' . $filepath);
}
+
+ $this->loadConfigArray($config, $overwrite);
}
/**
* Loads addons configuration files
*
- * First loads all activated addons default configuration throught the load_config hook, then load the local.ini.php
+ * First loads all activated addons default configuration through the load_config hook, then load the local.config.php
* again to overwrite potential local addon configuration.
*/
private function loadAddonConfig()
{
// Loads addons default config
- Core\Addon::callHooks('load_config');
+ Core\Hook::callAll('load_config');
// Load the local addon config file to overwritten default addon config values
- if (file_exists($this->getBasePath() . DIRECTORY_SEPARATOR . 'config' . DIRECTORY_SEPARATOR . 'addon.ini.php')) {
- $this->loadConfigFile($this->getBasePath() . DIRECTORY_SEPARATOR . 'config' . DIRECTORY_SEPARATOR . 'addon.ini.php', true);
+ if (file_exists($this->getBasePath() . '/config/addon.config.php')) {
+ $this->loadConfigFile($this->getBasePath() . '/config/addon.config.php', true);
+ } elseif (file_exists($this->getBasePath() . '/config/addon.ini.php')) {
+ $this->loadINIConfigFile($this->getBasePath() . '/config/addon.ini.php', true);
+ }
+ }
+
+ /**
+ * Tries to load the specified configuration array into the App->config array.
+ * Doesn't overwrite previously set values by default to prevent default config files to supersede DB Config.
+ *
+ * @param array $config
+ * @param bool $overwrite Force value overwrite if the config key already exists
+ */
+ private function loadConfigArray(array $config, $overwrite = false)
+ {
+ foreach ($config as $category => $values) {
+ foreach ($values as $key => $value) {
+ if ($overwrite) {
+ $this->setConfigValue($category, $key, $value);
+ } else {
+ $this->setDefaultConfigValue($category, $key, $value);
+ }
+ }
}
}
$relative_script_path = defaults($_SERVER, 'REDIRECT_URI' , $relative_script_path);
$relative_script_path = defaults($_SERVER, 'REDIRECT_SCRIPT_URL', $relative_script_path);
$relative_script_path = defaults($_SERVER, 'SCRIPT_URL' , $relative_script_path);
+ $relative_script_path = defaults($_SERVER, 'REQUEST_URI' , $relative_script_path);
$this->urlPath = $this->getConfigValue('system', 'urlpath');
if (!empty($relative_script_path)) {
// Module
if (!empty($_SERVER['QUERY_STRING'])) {
- $path = trim(dirname($relative_script_path, substr_count(trim($_SERVER['QUERY_STRING'], '/'), '/') + 1), '/');
+ $path = trim(rdirname($relative_script_path, substr_count(trim($_SERVER['QUERY_STRING'], '/'), '/') + 1), '/');
} else {
// Root page
$path = trim($relative_script_path, '/');
// Use environment variables for mysql if they are set beforehand
if (!empty(getenv('MYSQL_HOST'))
- && (!empty(getenv('MYSQL_USERNAME')) || !empty(getenv('MYSQL_USER')))
+ && !empty(getenv('MYSQL_USERNAME') || !empty(getenv('MYSQL_USER')))
&& getenv('MYSQL_PASSWORD') !== false
&& !empty(getenv('MYSQL_DATABASE')))
{
$this->hostname = Core\Config::get('config', 'hostname');
}
- return $scheme . '://' . $this->hostname . (!empty($this->getURLPath()) ? '/' . $this->getURLPath() : '' );
+ return $scheme . '://' . $this->hostname . !empty($this->getURLPath() ? '/' . $this->getURLPath() : '' );
}
/**
$this->urlPath = trim($parsed['path'], '\\/');
}
- if (file_exists($this->getBasePath() . DIRECTORY_SEPARATOR . '.htpreconfig.php')) {
- include $this->getBasePath() . DIRECTORY_SEPARATOR . '.htpreconfig.php';
+ if (file_exists($this->getBasePath() . '/.htpreconfig.php')) {
+ include $this->getBasePath() . '/.htpreconfig.php';
}
if (Core\Config::get('config', 'hostname') != '') {
return $this->urlPath;
}
- public function setPagerTotal($n)
- {
- $this->pager['total'] = intval($n);
- }
-
- public function setPagerItemsPage($n)
- {
- $this->pager['itemspage'] = ((intval($n) > 0) ? intval($n) : 0);
- $this->pager['start'] = ($this->pager['page'] * $this->pager['itemspage']) - $this->pager['itemspage'];
- }
-
- public function setPagerPage($n)
- {
- $this->pager['page'] = $n;
- $this->pager['start'] = ($this->pager['page'] * $this->pager['itemspage']) - $this->pager['itemspage'];
- }
-
/**
* Initializes App->page['htmlhead'].
*
$this->page['title'] = $this->config['sitename'];
}
- if (!empty($this->theme['stylesheet'])) {
- $stylesheet = $this->theme['stylesheet'];
+ if (!empty(Core\Renderer::$theme['stylesheet'])) {
+ $stylesheet = Core\Renderer::$theme['stylesheet'];
} else {
$stylesheet = $this->getCurrentThemeStylesheetPath();
}
$touch_icon = 'images/friendica-128.png';
}
- // get data wich is needed for infinite scroll on the network page
- $infinite_scroll = infinite_scroll_data($this->module);
-
Core\Addon::callHooks('head', $this->page['htmlhead']);
- $tpl = get_markup_template('head.tpl');
+ $tpl = Core\Renderer::getMarkupTemplate('head.tpl');
/* put the head template at the beginning of page['htmlhead']
* since the code added by the modules frequently depends on it
* being first
*/
- $this->page['htmlhead'] = replace_macros($tpl, [
+ $this->page['htmlhead'] = Core\Renderer::replaceMacros($tpl, [
'$baseurl' => $this->getBaseURL(),
'$local_user' => local_user(),
'$generator' => 'Friendica' . ' ' . FRIENDICA_VERSION,
'$update_interval' => $interval,
'$shortcut_icon' => $shortcut_icon,
'$touch_icon' => $touch_icon,
- '$infinite_scroll' => $infinite_scroll,
'$block_public' => intval(Core\Config::get('system', 'block_public')),
'$stylesheets' => $this->stylesheets,
]) . $this->page['htmlhead'];
*/
if ($this->is_mobile || $this->is_tablet) {
if (isset($_SESSION['show-mobile']) && !$_SESSION['show-mobile']) {
- $link = 'toggle_mobile?address=' . curPageURL();
+ $link = 'toggle_mobile?address=' . urlencode(curPageURL());
} else {
- $link = 'toggle_mobile?off=1&address=' . curPageURL();
+ $link = 'toggle_mobile?off=1&address=' . urlencode(curPageURL());
}
- $this->page['footer'] .= replace_macros(get_markup_template("toggle_mobile_footer.tpl"), [
+ $this->page['footer'] .= Core\Renderer::replaceMacros(Core\Renderer::getMarkupTemplate("toggle_mobile_footer.tpl"), [
'$toggle_link' => $link,
'$toggle_text' => Core\L10n::t('toggle mobile')
]);
Core\Addon::callHooks('footer', $this->page['footer']);
- $tpl = get_markup_template('footer.tpl');
- $this->page['footer'] = replace_macros($tpl, [
+ $tpl = Core\Renderer::getMarkupTemplate('footer.tpl');
+ $this->page['footer'] = Core\Renderer::replaceMacros($tpl, [
'$baseurl' => $this->getBaseURL(),
'$footerScripts' => $this->footerScripts,
]) . $this->page['footer'];
public function removeBaseURL($origURL)
{
// Remove the hostname from the url if it is an internal link
- $nurl = normalise_link($origURL);
- $base = normalise_link($this->getBaseURL());
+ $nurl = Util\Strings::normaliseLink($origURL);
+ $base = Util\Strings::normaliseLink($this->getBaseURL());
$url = str_replace($base . '/', '', $nurl);
// if it is an external link return the orignal value
- if ($url == normalise_link($origURL)) {
+ if ($url == Util\Strings::normaliseLink($origURL)) {
return $origURL;
} else {
return $url;
}
}
- /**
- * @brief Register template engine class
- *
- * @param string $class
- */
- private function registerTemplateEngine($class)
- {
- $v = get_class_vars($class);
- if (!empty($v['name'])) {
- $name = $v['name'];
- $this->template_engines[$name] = $class;
- } else {
- echo "template engine <tt>$class</tt> cannot be registered without a name.\n";
- die();
- }
- }
-
- /**
- * @brief Return template engine instance.
- *
- * If $name is not defined, return engine defined by theme,
- * or default
- *
- * @return object Template Engine instance
- */
- public function getTemplateEngine()
- {
- $template_engine = defaults($this->theme, 'template_engine', 'smarty3');
-
- if (isset($this->template_engines[$template_engine])) {
- if (isset($this->template_engine_instance[$template_engine])) {
- return $this->template_engine_instance[$template_engine];
- } else {
- $class = $this->template_engines[$template_engine];
- $obj = new $class;
- $this->template_engine_instance[$template_engine] = $obj;
- return $obj;
- }
- }
-
- echo "template engine <tt>$template_engine</tt> is not registered!\n";
- exit();
- }
-
- /**
- * @brief Returns the active template engine.
- *
- * @return string the active template engine
- */
- public function getActiveTemplateEngine()
- {
- return $this->theme['template_engine'];
- }
-
- /**
- * sets the active template engine
- *
- * @param string $engine the template engine (default is Smarty3)
- */
- public function setActiveTemplateEngine($engine = 'smarty3')
- {
- $this->theme['template_engine'] = $engine;
- }
-
- /**
- * Gets the right delimiter for a template engine
- *
- * Currently:
- * Internal = ''
- * Smarty3 = '{{'
- *
- * @param string $engine The template engine (default is Smarty3)
- *
- * @return string the right delimiter
- */
- public function getTemplateLeftDelimiter($engine = 'smarty3')
- {
- return $this->ldelim[$engine];
- }
-
- /**
- * Gets the left delimiter for a template engine
- *
- * Currently:
- * Internal = ''
- * Smarty3 = '}}'
- *
- * @param string $engine The template engine (default is Smarty3)
- *
- * @return string the left delimiter
- */
- public function getTemplateRightDelimiter($engine = 'smarty3')
- {
- return $this->rdelim[$engine];
- }
-
/**
* Saves a timestamp for a value - f.e. a call
* Necessary for profiling Friendica
$processlist = DBA::processlist();
if ($processlist['list'] != '') {
- logger('Processcheck: Processes: ' . $processlist['amount'] . ' - Processlist: ' . $processlist['list'], LOGGER_DEBUG);
+ Core\Logger::log('Processcheck: Processes: ' . $processlist['amount'] . ' - Processlist: ' . $processlist['list'], Core\Logger::DEBUG);
if ($processlist['amount'] > $max_processes) {
- logger('Processcheck: Maximum number of processes for ' . $process . ' tasks (' . $max_processes . ') reached.', LOGGER_DEBUG);
+ Core\Logger::log('Processcheck: Maximum number of processes for ' . $process . ' tasks (' . $max_processes . ') reached.', Core\Logger::DEBUG);
return true;
}
}
$meminfo[$key] = (int) ($meminfo[$key] / 1024);
}
- if (!isset($meminfo['MemAvailable']) || !isset($meminfo['MemFree'])) {
+ if (!isset($meminfo['MemFree'])) {
return false;
}
- $free = $meminfo['MemAvailable'] + $meminfo['MemFree'];
+ $free = $meminfo['MemFree'];
$reached = ($free < $min_memory);
if ($reached) {
- logger('Minimal memory reached: ' . $free . '/' . $meminfo['MemTotal'] . ' - limit ' . $min_memory, LOGGER_DEBUG);
+ Core\Logger::log('Minimal memory reached: ' . $free . '/' . $meminfo['MemTotal'] . ' - limit ' . $min_memory, Core\Logger::DEBUG);
}
return $reached;
$load = Core\System::currentLoad();
if ($load) {
if (intval($load) > $maxsysload) {
- logger('system: load ' . $load . ' for ' . $process . ' tasks (' . $maxsysload . ') too high.');
+ Core\Logger::log('system: load ' . $load . ' for ' . $process . ' tasks (' . $maxsysload . ') too high.');
return true;
}
}
$resource = proc_open($cmdline . ' &', [], $foo, $this->getBasePath());
}
if (!is_resource($resource)) {
- logger('We got no resource for command ' . $cmdline, LOGGER_DEBUG);
+ Core\Logger::log('We got no resource for command ' . $cmdline, Core\Logger::DEBUG);
return;
}
proc_close($resource);
public static function isDirectoryUsable($directory, $check_writable = true)
{
if ($directory == '') {
- logger('Directory is empty. This shouldn\'t happen.', LOGGER_DEBUG);
+ Core\Logger::log('Directory is empty. This shouldn\'t happen.', Core\Logger::DEBUG);
return false;
}
if (!file_exists($directory)) {
- logger('Path "' . $directory . '" does not exist for user ' . self::getSystemUser(), LOGGER_DEBUG);
+ Core\Logger::log('Path "' . $directory . '" does not exist for user ' . self::getSystemUser(), Core\Logger::DEBUG);
return false;
}
if (is_file($directory)) {
- logger('Path "' . $directory . '" is a file for user ' . self::getSystemUser(), LOGGER_DEBUG);
+ Core\Logger::log('Path "' . $directory . '" is a file for user ' . self::getSystemUser(), Core\Logger::DEBUG);
return false;
}
if (!is_dir($directory)) {
- logger('Path "' . $directory . '" is not a directory for user ' . self::getSystemUser(), LOGGER_DEBUG);
+ Core\Logger::log('Path "' . $directory . '" is not a directory for user ' . self::getSystemUser(), Core\Logger::DEBUG);
return false;
}
if ($check_writable && !is_writable($directory)) {
- logger('Path "' . $directory . '" is not writable for user ' . self::getSystemUser(), LOGGER_DEBUG);
+ Core\Logger::log('Path "' . $directory . '" is not writable for user ' . self::getSystemUser(), Core\Logger::DEBUG);
return false;
}
return '';
}
- //// @TODO Compute the current theme only once (this behavior has
- /// already been implemented, but it didn't work well -
- /// https://github.com/friendica/friendica/issues/5092)
- $this->computeCurrentTheme();
+ if (!$this->currentTheme) {
+ $this->computeCurrentTheme();
+ }
return $this->currentTheme;
}
+ public function setCurrentTheme($theme)
+ {
+ $this->currentTheme = $theme;
+ }
+
/**
* Computes the current theme name based on the node settings, the user settings and the device type
*
// and www.example.com vs example.com.
// We will only change the url to an ip address if there is no existing setting
- if (empty($url) || (!link_compare($url, $this->getBaseURL())) && (!preg_match("/^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/", $this->getHostName()))) {
+ if (empty($url) || (!Util\Strings::compareLink($url, $this->getBaseURL())) && (!preg_match("/^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/", $this->getHostName()))) {
Core\Config::set('system', 'url', $this->getBaseURL());
}
}
} else {
// Someone came with an invalid parameter, maybe as a DDoS attempt
// We simply stop processing here
- logger("Invalid ZRL parameter " . $_GET['zrl'], LOGGER_DEBUG);
+ Core\Logger::log("Invalid ZRL parameter " . $_GET['zrl'], Core\Logger::DEBUG);
Core\System::httpExit(403, ['title' => '403 Forbidden']);
}
}
$this->module = 'maintenance';
} else {
$this->checkURL();
- check_db(false);
+ Core\Update::check(false);
Core\Addon::loadAddons();
Core\Hook::loadHooks();
}
$privateapps = Core\Config::get('config', 'private_addons', false);
if (Core\Addon::isEnabled($this->module) && file_exists("addon/{$this->module}/{$this->module}.php")) {
//Check if module is an app and if public access to apps is allowed or not
- if ((!local_user()) && Core\Addon::isApp($this->module) && $privateapps) {
+ if ((!local_user()) && Core\Hook::isAddonApp($this->module) && $privateapps) {
info(Core\L10n::t("You must be logged in to use addons. "));
} else {
include_once "addon/{$this->module}/{$this->module}.php";
}
if (!empty($_SERVER['QUERY_STRING']) && ($_SERVER['QUERY_STRING'] === 'q=internal_error.html') && isset($dreamhost_error_hack)) {
- logger('index.php: dreamhost_error_hack invoked. Original URI =' . $_SERVER['REQUEST_URI']);
+ Core\Logger::log('index.php: dreamhost_error_hack invoked. Original URI =' . $_SERVER['REQUEST_URI']);
$this->internalRedirect($_SERVER['REQUEST_URI']);
}
- logger('index.php: page not found: ' . $_SERVER['REQUEST_URI'] . ' ADDRESS: ' . $_SERVER['REMOTE_ADDR'] . ' QUERY: ' . $_SERVER['QUERY_STRING'], LOGGER_DEBUG);
+ Core\Logger::log('index.php: page not found: ' . $_SERVER['REQUEST_URI'] . ' ADDRESS: ' . $_SERVER['REMOTE_ADDR'] . ' QUERY: ' . $_SERVER['QUERY_STRING'], Core\Logger::DEBUG);
header($_SERVER["SERVER_PROTOCOL"] . ' 404 ' . Core\L10n::t('Not Found'));
- $tpl = get_markup_template("404.tpl");
- $this->page['content'] = replace_macros($tpl, [
+ $tpl = Core\Renderer::getMarkupTemplate("404.tpl");
+ $this->page['content'] = Core\Renderer::replaceMacros($tpl, [
'$message' => Core\L10n::t('Page not found.')
]);
}
}
- // Load current theme info
- $theme_info_file = 'view/theme/' . $this->getCurrentTheme() . '/theme.php';
- if (file_exists($theme_info_file)) {
- require_once $theme_info_file;
- }
-
- // initialise content region
- if ($this->getMode()->isNormal()) {
- Core\Addon::callHooks('page_content_top', $this->page['content']);
- }
+ $content = '';
// Call module functions
if ($this->module_loaded) {
}
if (! $this->error) {
- $arr = ['content' => $this->page['content']];
+ $arr = ['content' => $content];
Core\Addon::callHooks($this->module . '_mod_content', $arr);
- $this->page['content'] = $arr['content'];
+ $content = $arr['content'];
$arr = ['content' => call_user_func([$this->module_class, 'content'])];
Core\Addon::callHooks($this->module . '_mod_aftercontent', $arr);
- $this->page['content'] .= $arr['content'];
+ $content .= $arr['content'];
}
+ }
- if (function_exists(str_replace('-', '_', $this->getCurrentTheme()) . '_content_loaded')) {
- $func = str_replace('-', '_', $this->getCurrentTheme()) . '_content_loaded';
- $func($this);
- }
+ // Load current theme info after module has been executed as theme could have been set in module
+ $theme_info_file = 'view/theme/' . $this->getCurrentTheme() . '/theme.php';
+ if (file_exists($theme_info_file)) {
+ require_once $theme_info_file;
+ }
+
+ // initialise content region
+ if ($this->getMode()->isNormal()) {
+ Core\Addon::callHooks('page_content_top', $this->page['content']);
}
+ $this->page['content'] .= $content;
+
/* Create the page head after setting the language
* and getting any auth credentials.
*
// Add the navigation (menu) template
if ($this->module != 'install' && $this->module != 'maintenance') {
- $this->page['htmlhead'] .= replace_macros(get_markup_template('nav_head.tpl'), []);
+ $this->page['htmlhead'] .= Core\Renderer::replaceMacros(Core\Renderer::getMarkupTemplate('nav_head.tpl'), []);
$this->page['nav'] = Content\Nav::build($this);
}
// Theme templates expect $a as an App instance
$a = $this;
+ // Used as is in view/php/default.php
+ $lang = Core\L10n::getCurrentLang();
+
/// @TODO Looks unsafe (remote-inclusion), is maybe not but Core\Theme::getPathForFile() uses file_exists() but does not escape anything
require_once $template;
}
*/
public function internalRedirect($toUrl = '', $ssl = false)
{
- if (filter_var($toUrl, FILTER_VALIDATE_URL)) {
- throw new InternalServerErrorException('URL is not a relative path, please use System::externalRedirectTo');
+ if (!empty(parse_url($toUrl, PHP_URL_SCHEME))) {
+ throw new InternalServerErrorException("'$toUrl is not a relative path, please use System::externalRedirectTo");
}
$redirectTo = $this->getBaseURL($ssl) . '/' . ltrim($toUrl, '/');
Core\System::externalRedirect($redirectTo);
}
+
+ /**
+ * Automatically redirects to relative or absolute URL
+ * Should only be used if it isn't clear if the URL is either internal or external
+ *
+ * @param string $toUrl The target URL
+ *
+ */
+ public function redirect($toUrl)
+ {
+ if (!empty(parse_url($toUrl, PHP_URL_SCHEME))) {
+ Core\System::externalRedirect($toUrl);
+ } else {
+ $this->internalRedirect($toUrl);
+ }
+ }
}