use DOMDocument;
use DOMXPath;
use Exception;
+use Friendica\Core\Config\ConfigCache;
+use Friendica\Core\Config\ConfigCacheLoader;
use Friendica\Database\DBA;
+use Friendica\Factory\ConfigFactory;
use Friendica\Network\HTTPException\InternalServerErrorException;
-
-require_once 'boot.php';
-require_once 'include/text.php';
+use Psr\Log\LoggerInterface;
/**
*
public $module_loaded = false;
public $module_class = null;
public $query_string = '';
- public $config = [];
public $page = [];
public $profile;
public $profile_uid;
*/
private $isAjax;
+ /**
+ * @var MobileDetect
+ */
+ public $mobileDetect;
+
+ /**
+ * @var LoggerInterface The current logger of this App
+ */
+ private $logger;
+
+ /**
+ * @var ConfigCache The cached config
+ */
+ private $config;
+
+ /**
+ * Returns the current config cache of this node
+ *
+ * @return ConfigCache
+ */
+ public function getConfig()
+ {
+ return $this->config;
+ }
+
+ /**
+ * The basepath of this app
+ *
+ * @return string
+ */
+ public function getBasePath()
+ {
+ return $this->basePath;
+ }
+
/**
* Register a stylesheet file path to be included in the <head> tag of every page.
* Inclusion is done in App->initHead().
* @see initHead()
*
* @param string $path
+ * @throws InternalServerErrorException
*/
public function registerStylesheet($path)
{
- $url = str_replace($this->getBasePath() . DIRECTORY_SEPARATOR, '', $path);
+ $url = str_replace($this->basePath . DIRECTORY_SEPARATOR, '', $path);
$this->stylesheets[] = trim($url, '/');
}
* @see initFooter()
*
* @param string $path
+ * @throws InternalServerErrorException
*/
public function registerFooterScript($path)
{
- $url = str_replace($this->getBasePath() . DIRECTORY_SEPARATOR, '', $path);
+ $url = str_replace($this->basePath . DIRECTORY_SEPARATOR, '', $path);
$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;
/**
* @brief App constructor.
*
- * @param string $basePath Path to the app base folder
- * @param bool $isBackend Whether it is used for backend or frontend (Default true=backend)
+ * @param ConfigCache $config The Cached Config
+ * @param LoggerInterface $logger Logger of this application
+ * @param bool $isBackend Whether it is used for backend or frontend (Default true=backend)
*
* @throws Exception if the Basepath is not usable
*/
- public function __construct($basePath, $isBackend = true)
+ public function __construct(ConfigCache $config, LoggerInterface $logger, $isBackend = true)
{
- if (!static::isDirectoryUsable($basePath, false)) {
- throw new Exception('Basepath ' . $basePath . ' isn\'t usable.');
+ $this->config = $config;
+ $this->logger = $logger;
+ $this->basePath = $this->config->get('system', 'basepath');
+
+ if (!Core\System::isDirectoryUsable($this->basePath, false)) {
+ throw new Exception('Basepath ' . $this->basePath . ' isn\'t usable.');
}
+ $this->basePath = rtrim($this->basePath, DIRECTORY_SEPARATOR);
BaseObject::setApp($this);
- $this->basePath = rtrim($basePath, DIRECTORY_SEPARATOR);
$this->checkBackend($isBackend);
$this->checkFriendicaApp();
$this->callstack['rendering'] = [];
$this->callstack['parser'] = [];
- $this->mode = new App\Mode($basePath);
+ $this->mode = new App\Mode($this->basePath);
$this->reload();
set_include_path(
get_include_path() . PATH_SEPARATOR
- . $this->getBasePath() . DIRECTORY_SEPARATOR . 'include' . PATH_SEPARATOR
- . $this->getBasePath(). DIRECTORY_SEPARATOR . 'library' . PATH_SEPARATOR
- . $this->getBasePath());
+ . $this->basePath . DIRECTORY_SEPARATOR . 'include' . PATH_SEPARATOR
+ . $this->basePath . DIRECTORY_SEPARATOR . 'library' . PATH_SEPARATOR
+ . $this->basePath);
if (!empty($_SERVER['QUERY_STRING']) && strpos($_SERVER['QUERY_STRING'], 'pagename=') === 0) {
$this->query_string = substr($_SERVER['QUERY_STRING'], 9);
// 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');
}
/**
}
/**
- * Reloads the whole app instance
+ * Returns the Logger of the Application
+ *
+ * @return LoggerInterface The Logger
+ * @throws InternalServerErrorException when the logger isn't created
*/
- public function reload()
+ public function getLogger()
{
- // The order of the following calls is important to ensure proper initialization
- $this->loadConfigFiles();
-
- $this->loadDatabase();
-
- $this->getMode()->determine($this->getBasePath());
-
- $this->determineURLPath();
-
- Core\Config::load();
-
- if ($this->getMode()->has(App\Mode::DBAVAILABLE)) {
- Core\Hook::loadHooks();
-
- $this->loadAddonConfig();
+ if (empty($this->logger)) {
+ throw new InternalServerErrorException('Logger of the Application is not defined');
}
- $this->loadDefaultTimezone();
-
- Core\L10n::init();
-
- $this->process_id = Core\System::processID('log');
+ return $this->logger;
}
/**
- * 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
+ * Reloads the whole app instance
*/
- private function loadConfigFiles()
+ public function reload()
{
- $this->loadConfigFile($this->getBasePath() . DIRECTORY_SEPARATOR . 'config' . DIRECTORY_SEPARATOR . 'config.ini.php');
- $this->loadConfigFile($this->getBasePath() . DIRECTORY_SEPARATOR . 'config' . DIRECTORY_SEPARATOR . 'settings.ini.php');
+ Core\Config::init($this->config);
+ Core\PConfig::init($this->config);
- // Legacy .htconfig.php support
- if (file_exists($this->getBasePath() . DIRECTORY_SEPARATOR . '.htpreconfig.php')) {
- $a = $this;
- include $this->getBasePath() . DIRECTORY_SEPARATOR . '.htpreconfig.php';
- }
-
- // Legacy .htconfig.php support
- if (file_exists($this->getBasePath() . DIRECTORY_SEPARATOR . '.htconfig.php')) {
- $a = $this;
-
- include $this->getBasePath() . DIRECTORY_SEPARATOR . '.htconfig.php';
-
- $this->setConfigValue('database', 'hostname', $db_host);
- $this->setConfigValue('database', 'username', $db_user);
- $this->setConfigValue('database', 'password', $db_pass);
- $this->setConfigValue('database', 'database', $db_data);
- if (isset($a->config['system']['db_charset'])) {
- $this->setConfigValue('database', 'charset', $a->config['system']['db_charset']);
- }
-
- unset($db_host, $db_user, $db_pass, $db_data);
+ $this->loadDatabase();
- if (isset($default_timezone)) {
- $this->setConfigValue('system', 'default_timezone', $default_timezone);
- unset($default_timezone);
- }
+ $this->getMode()->determine($this->basePath);
- if (isset($pidfile)) {
- $this->setConfigValue('system', 'pidfile', $pidfile);
- unset($pidfile);
- }
+ $this->determineURLPath();
- if (isset($lang)) {
- $this->setConfigValue('system', 'language', $lang);
- unset($lang);
- }
+ if ($this->getMode()->has(App\Mode::DBCONFIGAVAILABLE)) {
+ $adapterType = $this->config->get('system', 'config_adapter');
+ $adapter = ConfigFactory::createConfig($adapterType, $this->config);
+ Core\Config::setAdapter($adapter);
+ $adapterP = ConfigFactory::createPConfig($adapterType, $this->config);
+ Core\PConfig::setAdapter($adapterP);
+ Core\Config::load();
}
- 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);
- }
- }
+ // again because DB-config could change the config
+ $this->getMode()->determine($this->basePath);
- /**
- * 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 INI and the template for configuration files is the following:
- *
- * <?php return <<<INI
- *
- * [section]
- * key = value
- *
- * INI;
- * // Keep this line
- *
- * @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 parsing non-existent config file ' . $filepath);
+ if ($this->getMode()->has(App\Mode::DBAVAILABLE)) {
+ Core\Hook::loadHooks();
+ $loader = new ConfigCacheLoader($this->basePath);
+ Core\Hook::callAll('load_config', $loader);
+ $this->config->loadConfigArray($loader->loadCoreConfig('addon'), true);
}
- $contents = include($filepath);
-
- $config = parse_ini_string($contents, true, INI_SCANNER_TYPED);
-
- if ($config === false) {
- throw new Exception('Error parsing config file ' . $filepath);
- }
+ $this->loadDefaultTimezone();
- foreach ($config as $category => $values) {
- foreach ($values as $key => $value) {
- if ($overwrite) {
- $this->setConfigValue($category, $key, $value);
- } else {
- $this->setDefaultConfigValue($category, $key, $value);
- }
- }
- }
- }
+ Core\L10n::init();
- /**
- * Loads addons configuration files
- *
- * First loads all activated addons default configuration throught the load_config hook, then load the local.ini.php
- * again to overwrite potential local addon configuration.
- */
- private function loadAddonConfig()
- {
- // Loads addons default config
- Core\Addon::callHooks('load_config');
+ $this->process_id = Core\System::processID('log');
- // 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);
- }
+ Core\Logger::setLogger($this->logger);
}
/**
*/
private function loadDefaultTimezone()
{
- if ($this->getConfigValue('system', 'default_timezone')) {
- $this->timezone = $this->getConfigValue('system', 'default_timezone');
+ if ($this->config->get('system', 'default_timezone')) {
+ $this->timezone = $this->config->get('system', 'default_timezone');
} else {
global $default_timezone;
$this->timezone = !empty($default_timezone) ? $default_timezone : 'UTC';
$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');
+ $this->urlPath = $this->config->get('system', 'urlpath');
/* $relative_script_path gives /relative/path/to/friendica/module/parameter
* QUERY_STRING gives pagename=module/parameter
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, '/');
return;
}
- $db_host = $this->getConfigValue('database', 'hostname');
- $db_user = $this->getConfigValue('database', 'username');
- $db_pass = $this->getConfigValue('database', 'password');
- $db_data = $this->getConfigValue('database', 'database');
- $charset = $this->getConfigValue('database', 'charset');
+ $db_host = $this->config->get('database', 'hostname');
+ $db_user = $this->config->get('database', 'username');
+ $db_pass = $this->config->get('database', 'password');
+ $db_data = $this->config->get('database', 'database');
+ $charset = $this->config->get('database', 'charset');
// 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')))
{
$stamp1 = microtime(true);
- if (DBA::connect($db_host, $db_user, $db_pass, $db_data, $charset)) {
+ if (DBA::connect($this->config, $db_host, $db_user, $db_pass, $db_data, $charset)) {
// Loads DB_UPDATE_VERSION constant
- Database\DBStructure::definition(false);
+ Database\DBStructure::definition($this->basePath, false);
}
unset($db_host, $db_user, $db_pass, $db_data, $charset);
$this->saveTimestamp($stamp1, 'network');
}
- /**
- * @brief Returns the base filesystem path of the App
- *
- * It first checks for the internal variable, then for DOCUMENT_ROOT and
- * finally for PWD
- *
- * @return string
- */
- public function getBasePath()
- {
- $basepath = $this->basePath;
-
- if (!$basepath) {
- $basepath = Core\Config::get('system', 'basepath');
- }
-
- if (!$basepath && !empty($_SERVER['DOCUMENT_ROOT'])) {
- $basepath = $_SERVER['DOCUMENT_ROOT'];
- }
-
- if (!$basepath && !empty($_SERVER['PWD'])) {
- $basepath = $_SERVER['PWD'];
- }
-
- return self::getRealPath($basepath);
- }
-
- /**
- * @brief Returns a normalized file path
- *
- * This is a wrapper for the "realpath" function.
- * That function cannot detect the real path when some folders aren't readable.
- * Since this could happen with some hosters we need to handle this.
- *
- * @param string $path The path that is about to be normalized
- * @return string normalized path - when possible
- */
- public static function getRealPath($path)
- {
- $normalized = realpath($path);
-
- if (!is_bool($normalized)) {
- return $normalized;
- } else {
- return $path;
- }
- }
-
public function getScheme()
{
return $this->scheme;
*
* @param bool $ssl Whether to append http or https under SSL_POLICY_SELFSIGN
* @return string Friendica server base URL
+ * @throws InternalServerErrorException
*/
public function getBaseURL($ssl = false)
{
* Clears the baseurl cache to prevent inconsistencies
*
* @param string $url
+ * @throws InternalServerErrorException
*/
public function setBaseURL($url)
{
$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->basePath . '/.htpreconfig.php')) {
+ include $this->basePath . '/.htpreconfig.php';
}
if (Core\Config::get('config', 'hostname') != '') {
// compose the page title from the sitename and the
// current module called
if (!$this->module == '') {
- $this->page['title'] = $this->config['sitename'] . ' (' . $this->module . ')';
+ $this->page['title'] = $this->config->get('config', 'sitename') . ' (' . $this->module . ')';
} else {
- $this->page['title'] = $this->config['sitename'];
+ $this->page['title'] = $this->config->get('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';
}
- Core\Addon::callHooks('head', $this->page['htmlhead']);
+ Core\Hook::callAll('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,
*/
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']);
+ Core\Hook::callAll('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'];
* @param string $origURL
*
* @return string The cleaned url
+ * @throws InternalServerErrorException
*/
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
*/
public function saveTimestamp($timestamp, $value)
{
- if (!isset($this->config['system']['profiler']) || !$this->config['system']['profiler']) {
+ $profiler = $this->config->get('system', 'profiler');
+
+ if (!isset($profiler) || !$profiler) {
return;
}
* Returns the current UserAgent as a String
*
* @return string the UserAgent as a String
+ * @throws InternalServerErrorException
*/
public function getUserAgent()
{
$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;
}
}
* @brief Checks if the minimal memory is reached
*
* @return bool Is the memory limit reached?
+ * @throws InternalServerErrorException
*/
public function isMinMemoryReached()
{
$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;
* @brief Checks if the maximum load is reached
*
* @return bool Is the load reached?
+ * @throws InternalServerErrorException
*/
public function isMaxLoadReached()
{
$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;
}
}
*
* @param string $command The command to execute
* @param array $args Arguments to pass to the command ( [ 'key' => value, 'key2' => value2, ... ]
+ * @throws InternalServerErrorException
*/
public function proc_run($command, $args)
{
return;
}
- $cmdline = $this->getConfigValue('config', 'php_path', 'php') . ' ' . escapeshellarg($command);
+ $cmdline = $this->config->get('config', 'php_path', 'php') . ' ' . escapeshellarg($command);
foreach ($args as $key => $value) {
if (!is_null($value) && is_bool($value) && !$value) {
}
if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') {
- $resource = proc_open('cmd /c start /b ' . $cmdline, [], $foo, $this->getBasePath());
+ $resource = proc_open('cmd /c start /b ' . $cmdline, [], $foo, $this->basePath);
} else {
- $resource = proc_open($cmdline . ' &', [], $foo, $this->getBasePath());
+ $resource = proc_open($cmdline . ' &', [], $foo, $this->basePath);
}
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);
}
- /**
- * @brief Returns the system user that is executing the script
- *
- * This mostly returns something like "www-data".
- *
- * @return string system username
- */
- private static function getSystemUser()
- {
- if (!function_exists('posix_getpwuid') || !function_exists('posix_geteuid')) {
- return '';
- }
-
- $processUser = posix_getpwuid(posix_geteuid());
- return $processUser['name'];
- }
-
- /**
- * @brief Checks if a given directory is usable for the system
- *
- * @return boolean the directory is usable
- */
- public static function isDirectoryUsable($directory, $check_writable = true)
- {
- if ($directory == '') {
- logger('Directory is empty. This shouldn\'t happen.', LOGGER_DEBUG);
- return false;
- }
-
- if (!file_exists($directory)) {
- logger('Path "' . $directory . '" does not exist for user ' . self::getSystemUser(), LOGGER_DEBUG);
- return false;
- }
-
- if (is_file($directory)) {
- logger('Path "' . $directory . '" is a file for user ' . self::getSystemUser(), LOGGER_DEBUG);
- return false;
- }
-
- if (!is_dir($directory)) {
- logger('Path "' . $directory . '" is not a directory for user ' . self::getSystemUser(), LOGGER_DEBUG);
- return false;
- }
-
- if ($check_writable && !is_writable($directory)) {
- logger('Path "' . $directory . '" is not writable for user ' . self::getSystemUser(), LOGGER_DEBUG);
- return false;
- }
-
- return true;
- }
-
- /**
- * @param string $cat Config category
- * @param string $k Config key
- * @param mixed $default Default value if it isn't set
- *
- * @return string Returns the value of the Config entry
- */
- public function getConfigValue($cat, $k, $default = null)
- {
- $return = $default;
-
- if ($cat === 'config') {
- if (isset($this->config[$k])) {
- $return = $this->config[$k];
- }
- } else {
- if (isset($this->config[$cat][$k])) {
- $return = $this->config[$cat][$k];
- }
- }
-
- return $return;
- }
-
- /**
- * Sets a default value in the config cache. Ignores already existing keys.
- *
- * @param string $cat Config category
- * @param string $k Config key
- * @param mixed $v Default value to set
- */
- private function setDefaultConfigValue($cat, $k, $v)
- {
- if (!isset($this->config[$cat][$k])) {
- $this->setConfigValue($cat, $k, $v);
- }
- }
-
- /**
- * Sets a value in the config cache. Accepts raw output from the config table
- *
- * @param string $cat Config category
- * @param string $k Config key
- * @param mixed $v Value to set
- */
- public function setConfigValue($cat, $k, $v)
- {
- // Only arrays are serialized in database, so we have to unserialize sparingly
- $value = is_string($v) && preg_match("|^a:[0-9]+:{.*}$|s", $v) ? unserialize($v) : $v;
-
- if ($cat === 'config') {
- $this->config[$k] = $value;
- } else {
- if (!isset($this->config[$cat])) {
- $this->config[$cat] = [];
- }
-
- $this->config[$cat][$k] = $value;
- }
- }
-
- /**
- * Deletes a value from the config cache
- *
- * @param string $cat Config category
- * @param string $k Config key
- */
- public function deleteConfigValue($cat, $k)
- {
- if ($cat === 'config') {
- if (isset($this->config[$k])) {
- unset($this->config[$k]);
- }
- } else {
- if (isset($this->config[$cat][$k])) {
- unset($this->config[$cat][$k]);
- }
- }
- }
-
-
- /**
- * Retrieves a value from the user config cache
- *
- * @param int $uid User Id
- * @param string $cat Config category
- * @param string $k Config key
- * @param mixed $default Default value if key isn't set
- *
- * @return string The value of the config entry
- */
- public function getPConfigValue($uid, $cat, $k, $default = null)
- {
- $return = $default;
-
- if (isset($this->config[$uid][$cat][$k])) {
- $return = $this->config[$uid][$cat][$k];
- }
-
- return $return;
- }
-
- /**
- * Sets a value in the user config cache
- *
- * Accepts raw output from the pconfig table
- *
- * @param int $uid User Id
- * @param string $cat Config category
- * @param string $k Config key
- * @param mixed $v Value to set
- */
- public function setPConfigValue($uid, $cat, $k, $v)
- {
- // Only arrays are serialized in database, so we have to unserialize sparingly
- $value = is_string($v) && preg_match("|^a:[0-9]+:{.*}$|s", $v) ? unserialize($v) : $v;
-
- if (!isset($this->config[$uid]) || !is_array($this->config[$uid])) {
- $this->config[$uid] = [];
- }
-
- if (!isset($this->config[$uid][$cat]) || !is_array($this->config[$uid][$cat])) {
- $this->config[$uid][$cat] = [];
- }
-
- $this->config[$uid][$cat][$k] = $value;
- }
-
- /**
- * Deletes a value from the user config cache
- *
- * @param int $uid User Id
- * @param string $cat Config category
- * @param string $k Config key
- */
- public function deletePConfigValue($uid, $cat, $k)
- {
- if (isset($this->config[$uid][$cat][$k])) {
- unset($this->config[$uid][$cat][$k]);
- }
- }
-
/**
* Generates the site's default sender email address
*
* @return string
+ * @throws InternalServerErrorException
*/
public function getSenderEmailAddress()
{
* Returns the current theme name.
*
* @return string the name of the current theme
+ * @throws InternalServerErrorException
*/
public function getCurrentTheme()
{
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
*
* Provide a sane default if nothing is chosen or the specified theme does not exist.
*
* @return string
+ * @throws InternalServerErrorException
*/
public function getCurrentThemeStylesheetPath()
{
// 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());
}
}
}
Core\Session::init();
- Core\Addon::callHooks('init_1');
+ Core\Hook::callAll('init_1');
}
// Exclude the backend processes from the session management
} 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($this->basePath, false);
Core\Addon::loadAddons();
Core\Hook::loadHooks();
}
}
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
+ // Initialize module that can set the current theme in the init() method, either directly or via App->profile_uid
if ($this->module_loaded) {
$this->page['page_title'] = $this->module;
$placeholder = '';
- Core\Addon::callHooks($this->module . '_mod_init', $placeholder);
+ Core\Hook::callAll($this->module . '_mod_init', $placeholder);
call_user_func([$this->module_class, 'init']);
if (!$this->error) {
call_user_func([$this->module_class, 'rawContent']);
}
+ }
- if (function_exists(str_replace('-', '_', $this->getCurrentTheme()) . '_init')) {
- $func = str_replace('-', '_', $this->getCurrentTheme()) . '_init';
- $func($this);
- }
+ // Load current theme info after module has been initialized 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;
+ }
+
+ if (function_exists(str_replace('-', '_', $this->getCurrentTheme()) . '_init')) {
+ $func = str_replace('-', '_', $this->getCurrentTheme()) . '_init';
+ $func($this);
+ }
+ if ($this->module_loaded) {
if (! $this->error && $_SERVER['REQUEST_METHOD'] === 'POST') {
- Core\Addon::callHooks($this->module . '_mod_post', $_POST);
+ Core\Hook::callAll($this->module . '_mod_post', $_POST);
call_user_func([$this->module_class, 'post']);
}
if (! $this->error) {
- Core\Addon::callHooks($this->module . '_mod_afterpost', $placeholder);
+ Core\Hook::callAll($this->module . '_mod_afterpost', $placeholder);
call_user_func([$this->module_class, 'afterpost']);
}
if (! $this->error) {
- $arr = ['content' => $this->page['content']];
- Core\Addon::callHooks($this->module . '_mod_content', $arr);
- $this->page['content'] = $arr['content'];
+ $arr = ['content' => $content];
+ Core\Hook::callAll($this->module . '_mod_content', $arr);
+ $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'];
+ Core\Hook::callAll($this->module . '_mod_aftercontent', $arr);
+ $content .= $arr['content'];
}
+ }
- if (function_exists(str_replace('-', '_', $this->getCurrentTheme()) . '_content_loaded')) {
- $func = str_replace('-', '_', $this->getCurrentTheme()) . '_content_loaded';
- $func($this);
- }
+ // initialise content region
+ if ($this->getMode()->isNormal()) {
+ Core\Hook::callAll('page_content_top', $this->page['content']);
}
+ $this->page['content'] .= $content;
+
/* Create the page head after setting the language
* and getting any auth credentials.
*
}
// Report anything which needs to be communicated in the notification area (before the main body)
- Core\Addon::callHooks('page_end', $this->page['content']);
+ Core\Hook::callAll('page_end', $this->page['content']);
// 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);
}
// And then append it to the target
$target->documentElement->appendChild($item);
}
- }
- if (isset($_GET["mode"]) && ($_GET["mode"] == "raw")) {
- header("Content-type: text/html; charset=utf-8");
+ if ($_GET["mode"] == "raw") {
+ header("Content-type: text/html; charset=utf-8");
- echo substr($target->saveHTML(), 6, -8);
+ echo substr($target->saveHTML(), 6, -8);
- exit();
+ exit();
+ }
}
$page = $this->page;
// 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)) {
+ if (!empty(parse_url($toUrl, PHP_URL_SCHEME))) {
throw new InternalServerErrorException("'$toUrl is not a relative path, please use System::externalRedirectTo");
}
* Should only be used if it isn't clear if the URL is either internal or external
*
* @param string $toUrl The target URL
- *
+ * @throws InternalServerErrorException
*/
public function redirect($toUrl)
{
- if (filter_var($toUrl, FILTER_VALIDATE_URL)) {
+ if (!empty(parse_url($toUrl, PHP_URL_SCHEME))) {
Core\System::externalRedirect($toUrl);
} else {
$this->internalRedirect($toUrl);