2017-05-08 06:11:38 +00:00
< ? php
2024-08-24 15:27:00 +02:00
// Copyright (C) 2010-2024, the Friendica project
// SPDX-FileCopyrightText: 2010-2024 the Friendica project
//
// SPDX-License-Identifier: AGPL-3.0-or-later
2020-02-09 16:18:46 +01:00
2017-05-08 06:11:38 +00:00
namespace Friendica ;
2018-07-19 22:15:21 -04:00
use Exception ;
2019-08-12 18:13:58 +02:00
use Friendica\App\Arguments ;
2019-08-15 17:23:00 +02:00
use Friendica\App\BaseURL ;
2024-11-06 07:21:50 +00:00
use Friendica\App\Mode ;
2024-06-09 06:13:20 +00:00
use Friendica\App\Request ;
2021-11-21 23:37:17 +01:00
use Friendica\Capabilities\ICanCreateResponses ;
2023-01-08 01:17:06 -05:00
use Friendica\Content\Nav ;
2021-10-26 21:44:29 +02:00
use Friendica\Core\Config\Factory\Config ;
2022-10-20 21:27:32 +02:00
use Friendica\Core\Session\Capability\IHandleUserSessions ;
2022-12-16 21:59:32 +01:00
use Friendica\Database\Definition\DbaDefinition ;
use Friendica\Database\Definition\ViewDefinition ;
2021-03-10 09:40:42 -05:00
use Friendica\Module\Maintenance ;
2020-09-30 16:53:18 +02:00
use Friendica\Security\Authentication ;
2021-10-26 21:44:29 +02:00
use Friendica\Core\Config\ValueObject\Cache ;
use Friendica\Core\Config\Capability\IManageConfigValues ;
use Friendica\Core\PConfig\Capability\IManagePersonalConfigValues ;
2020-01-18 20:59:39 +01:00
use Friendica\Core\L10n ;
2019-07-23 20:01:45 -04:00
use Friendica\Core\System ;
2019-08-12 18:13:58 +02:00
use Friendica\Module\Special\HTTPException as ModuleHTTPException ;
2019-05-01 21:33:33 -04:00
use Friendica\Network\HTTPException ;
2024-03-16 12:54:17 +00:00
use Friendica\Protocol\ATProtocol\DID ;
2024-05-27 04:33:28 +00:00
use Friendica\Security\OpenWebAuth ;
2021-10-03 12:38:47 -04:00
use Friendica\Util\DateTimeFormat ;
2021-11-28 13:44:42 +01:00
use Friendica\Util\HTTPInputData ;
2019-03-19 06:44:51 +00:00
use Friendica\Util\HTTPSignature ;
2019-02-16 23:11:30 +01:00
use Friendica\Util\Profiler ;
2018-12-30 21:42:56 +01:00
use Psr\Log\LoggerInterface ;
2017-05-11 11:53:04 -04:00
2017-05-08 06:11:38 +00:00
/**
2020-01-19 06:05:23 +00:00
* Our main application structure for the life of this page .
2017-05-08 06:11:38 +00:00
*
* Primarily deals with the URL that got us here
* and tries to make some sense of it , and
* stores our page contents and config storage
* and anything else that might need to be passed around
* before we spit the page out .
*
*/
2018-01-15 19:13:21 -05:00
class App
{
2022-10-17 10:37:48 +00:00
const PLATFORM = 'Friendica' ;
2023-12-24 15:52:17 +01:00
const CODENAME = 'Yellow Archangel' ;
2024-08-17 17:33:40 +02:00
const VERSION = '2024.09-dev' ;
2022-10-17 10:37:48 +00:00
2018-10-06 16:27:20 +02:00
/**
2024-11-06 07:21:50 +00:00
* @ var Mode The Mode of the Application
2018-10-06 16:27:20 +02:00
*/
private $mode ;
2018-10-09 19:58:58 +02:00
/**
2019-04-08 21:12:10 +02:00
* @ var BaseURL
2018-10-09 19:58:58 +02:00
*/
2019-04-08 21:12:10 +02:00
private $baseURL ;
2018-10-09 19:58:58 +02:00
2024-06-09 06:13:20 +00:00
/** @var string */
private $requestId ;
2024-05-27 04:33:28 +00:00
/** @var Authentication */
private $auth ;
2018-12-30 21:42:56 +01:00
/**
2021-10-26 21:44:29 +02:00
* @ var IManageConfigValues The config
2019-02-03 22:22:04 +01:00
*/
private $config ;
2019-02-17 21:12:12 +01:00
/**
* @ var LoggerInterface The logger
2018-12-30 21:42:56 +01:00
*/
private $logger ;
2019-02-03 22:22:04 +01:00
/**
2019-02-16 23:11:30 +01:00
* @ var Profiler The profiler of this app
2019-02-03 22:22:04 +01:00
*/
2019-02-16 23:11:30 +01:00
private $profiler ;
2019-02-03 22:22:04 +01:00
2019-07-09 21:44:02 +02:00
/**
* @ var L10n The translator
*/
private $l10n ;
2019-08-12 18:13:58 +02:00
/**
* @ var App\Arguments
*/
private $args ;
2022-10-20 22:06:25 +02:00
/**
* @ var IHandleUserSessions
*/
2022-10-23 20:41:17 +02:00
private $session ;
2022-10-20 22:06:25 +02:00
2024-11-06 12:26:33 +00:00
/**
* @ var AppHelper $appHelper
*/
private $appHelper ;
2021-07-24 20:42:09 +00:00
/**
* Set the profile owner ID
*
2024-11-06 13:36:38 +01:00
* @ deprecated 2024.12 Use AppHelper :: setProfileOwner () instead
*
2021-07-24 22:08:33 +00:00
* @ param int $owner_id
* @ return void
2021-07-24 20:42:09 +00:00
*/
2021-07-24 20:34:07 +00:00
public function setProfileOwner ( int $owner_id )
{
2024-11-06 13:36:38 +01:00
$this -> appHelper -> setProfileOwner ( $owner_id );
2021-07-24 20:34:07 +00:00
}
2021-07-24 20:42:09 +00:00
/**
* Get the profile owner ID
*
2024-11-06 13:36:38 +01:00
* @ deprecated 2024.12 Use AppHelper :: getProfileOwner () instead
*
2021-07-24 22:08:33 +00:00
* @ return int
2021-07-24 20:42:09 +00:00
*/
2022-06-16 16:25:30 +02:00
public function getProfileOwner () : int
2021-07-24 20:34:07 +00:00
{
2024-11-06 13:36:38 +01:00
return $this -> appHelper -> getProfileOwner ();
2021-07-24 20:34:07 +00:00
}
2021-07-24 20:42:09 +00:00
/**
* Set the contact ID
2021-07-24 22:08:33 +00:00
*
2024-11-06 13:11:26 +01:00
* @ deprecated 2024.12 Use AppHelper :: setContactId () instead
*
2021-07-24 22:08:33 +00:00
* @ param int $contact_id
* @ return void
2021-07-24 20:42:09 +00:00
*/
2021-07-24 20:34:07 +00:00
public function setContactId ( int $contact_id )
{
2024-11-06 12:26:33 +00:00
$this -> appHelper -> setContactId ( $contact_id );
2021-07-24 20:34:07 +00:00
}
2021-07-24 20:42:09 +00:00
/**
* Get the contact ID
*
2024-11-06 13:11:26 +01:00
* @ deprecated 2024.12 Use AppHelper :: getContactId () instead
*
2021-07-24 22:08:33 +00:00
* @ return int
2021-07-24 20:42:09 +00:00
*/
2022-06-16 16:25:30 +02:00
public function getContactId () : int
2021-07-24 20:34:07 +00:00
{
2024-11-06 12:26:33 +00:00
return $this -> appHelper -> getContactId ();
2021-07-24 20:34:07 +00:00
}
2021-07-24 21:16:53 +00:00
/**
* Set the timezone
2021-07-24 22:08:33 +00:00
*
2024-11-06 07:52:46 +00:00
* @ deprecated 2024.12 Use AppHelper :: setTimeZone () instead
*
2021-10-03 12:38:47 -04:00
* @ param string $timezone A valid time zone identifier , see https :// www . php . net / manual / en / timezones . php
2021-07-24 22:08:33 +00:00
* @ return void
2021-07-24 21:16:53 +00:00
*/
public function setTimeZone ( string $timezone )
{
2024-11-06 12:26:33 +00:00
$this -> appHelper -> setTimeZone ( $timezone );
2021-07-24 21:16:53 +00:00
}
/**
* Get the timezone
*
2024-11-06 07:52:46 +00:00
* @ deprecated 2024.12 Use AppHelper :: getTimeZone () instead
2021-07-24 21:16:53 +00:00
*/
2022-06-16 16:25:30 +02:00
public function getTimeZone () : string
2021-07-24 21:16:53 +00:00
{
2024-11-06 12:26:33 +00:00
return $this -> appHelper -> getTimeZone ();
2021-07-24 21:16:53 +00:00
}
2021-07-25 19:39:10 +00:00
/**
* Set workerqueue information
*
2024-11-08 07:30:36 +00:00
* @ deprecated 2024.12 Use AppHelper :: setQueue () instead
*
2022-11-12 12:01:22 -05:00
* @ param array $queue
* @ return void
2021-07-25 19:39:10 +00:00
*/
2021-07-24 22:08:33 +00:00
public function setQueue ( array $queue )
{
2024-11-08 07:30:36 +00:00
$this -> appHelper -> setQueue ( $queue );
2021-07-24 22:08:33 +00:00
}
2021-07-25 19:39:10 +00:00
/**
* Fetch workerqueue information
*
2024-11-08 07:30:36 +00:00
* @ deprecated 2024.12 Use AppHelper :: getQueue () instead
*
2022-06-16 16:25:30 +02:00
* @ return array Worker queue
2021-07-25 19:39:10 +00:00
*/
2022-06-16 16:25:30 +02:00
public function getQueue () : array
2021-07-24 22:08:33 +00:00
{
2024-11-08 07:30:36 +00:00
return $this -> appHelper -> getQueue ();
2021-07-24 22:08:33 +00:00
}
2021-07-25 19:39:10 +00:00
/**
* Fetch a specific workerqueue field
*
2024-11-08 07:30:36 +00:00
* @ deprecated 2024.12 Use AppHelper :: getQueueValue () instead
*
2022-06-16 16:25:30 +02:00
* @ param string $index Work queue record to fetch
* @ return mixed Work queue item or NULL if not found
2021-07-25 19:39:10 +00:00
*/
2021-07-24 22:08:33 +00:00
public function getQueueValue ( string $index )
{
2024-11-08 07:30:36 +00:00
return $this -> appHelper -> getQueueValue ( $index );
2021-07-24 22:08:33 +00:00
}
2024-11-08 11:05:02 +00:00
/**
* @ deprecated 2024.12 Use AppHelper :: setThemeInfoValue () instead
*/
2021-07-25 19:39:10 +00:00
public function setThemeInfoValue ( string $index , $value )
{
2024-11-08 11:05:02 +00:00
$this -> appHelper -> setThemeInfoValue ( $index , $value );
2021-07-25 19:39:10 +00:00
}
2024-11-08 11:05:02 +00:00
/**
* @ deprecated 2024.12 Use AppHelper :: getThemeInfo () instead
*/
2021-07-25 19:39:10 +00:00
public function getThemeInfo ()
{
2024-11-08 11:05:02 +00:00
return $this -> appHelper -> getThemeInfo ();
2021-07-25 19:39:10 +00:00
}
2024-11-08 11:05:02 +00:00
/**
* @ deprecated 2024.12 Use AppHelper :: getThemeInfoValue () instead
*/
2021-07-25 19:39:10 +00:00
public function getThemeInfoValue ( string $index , $default = null )
{
2024-11-08 11:05:02 +00:00
return $this -> appHelper -> getThemeInfoValue ( $index , $default );
2021-07-25 19:39:10 +00:00
}
2019-02-03 22:22:04 +01:00
/**
* Returns the current config cache of this node
*
2024-11-08 12:06:30 +00:00
* @ deprecated 2024.12 Use AppHelper :: getConfigCache () instead
*
2020-01-19 22:23:44 +01:00
* @ return Cache
2019-02-03 22:22:04 +01:00
*/
2019-02-10 19:52:21 +01:00
public function getConfigCache ()
2019-02-03 22:22:04 +01:00
{
2024-11-08 12:06:30 +00:00
return $this -> appHelper -> getConfigCache ();
2019-02-03 22:22:04 +01:00
}
/**
* The basepath of this app
*
2024-11-08 12:06:30 +00:00
* @ deprecated 2024.12 Use AppHelper :: getBasePath () instead
*
2022-06-16 16:25:30 +02:00
* @ return string Base path from configuration
2019-02-03 22:22:04 +01:00
*/
2022-06-16 16:25:30 +02:00
public function getBasePath () : string
2019-02-03 22:22:04 +01:00
{
2024-11-08 12:06:30 +00:00
return $this -> appHelper -> getBasePath ();
2019-02-03 22:22:04 +01:00
}
2017-05-08 06:11:38 +00:00
/**
2021-10-26 22:09:11 +02:00
* @ param IManageConfigValues $config The Configuration
2024-11-06 07:21:50 +00:00
* @ param Mode $mode The mode of this Friendica app
2021-10-26 22:09:11 +02:00
* @ param BaseURL $baseURL The full base URL of this Friendica app
* @ param LoggerInterface $logger The current app logger
* @ param Profiler $profiler The profiler of this application
* @ param L10n $l10n The translator instance
* @ param App\Arguments $args The Friendica Arguments of the call
2022-10-25 08:07:42 +02:00
* @ param IHandleUserSessions $session The ( User ) Session handler
2022-12-16 21:59:32 +01:00
* @ param DbaDefinition $dbaDefinition
* @ param ViewDefinition $viewDefinition
2022-10-23 20:41:17 +02:00
*/
2024-11-06 07:21:50 +00:00
public function __construct (
Request $request ,
Authentication $auth ,
IManageConfigValues $config ,
Mode $mode ,
BaseURL $baseURL ,
LoggerInterface $logger ,
Profiler $profiler ,
L10n $l10n ,
Arguments $args ,
IHandleUserSessions $session ,
DbaDefinition $dbaDefinition ,
ViewDefinition $viewDefinition
) {
2024-06-09 06:13:20 +00:00
$this -> requestId = $request -> getRequestId ();
2024-05-27 04:33:28 +00:00
$this -> auth = $auth ;
2022-12-16 21:59:32 +01:00
$this -> config = $config ;
$this -> mode = $mode ;
$this -> baseURL = $baseURL ;
$this -> profiler = $profiler ;
$this -> logger = $logger ;
$this -> l10n = $l10n ;
$this -> args = $args ;
$this -> session = $session ;
2024-11-06 12:26:33 +00:00
$this -> appHelper = DI :: apphelper ();
2022-12-16 21:59:32 +01:00
$this -> load ( $dbaDefinition , $viewDefinition );
2019-08-15 16:18:08 +02:00
}
2017-05-08 06:11:38 +00:00
2019-08-15 16:18:08 +02:00
/**
* Load the whole app instance
*/
2022-12-16 21:59:32 +01:00
protected function load ( DbaDefinition $dbaDefinition , ViewDefinition $viewDefinition )
2019-08-15 16:18:08 +02:00
{
2023-05-04 17:48:13 +02:00
if ( $this -> config -> get ( 'system' , 'ini_max_execution_time' ) !== false ) {
set_time_limit (( int ) $this -> config -> get ( 'system' , 'ini_max_execution_time' ));
}
if ( $this -> config -> get ( 'system' , 'ini_pcre_backtrack_limit' ) !== false ) {
ini_set ( 'pcre.backtrack_limit' , ( int ) $this -> config -> get ( 'system' , 'ini_pcre_backtrack_limit' ));
}
2018-07-02 07:23:47 -04:00
2022-10-18 04:35:06 +00:00
// Normally this constant is defined - but not if "pcntl" isn't installed
if ( ! defined ( 'SIGTERM' )) {
define ( 'SIGTERM' , 15 );
}
2021-10-03 12:38:47 -04:00
// Ensure that all "strtotime" operations do run timezone independent
date_default_timezone_set ( 'UTC' );
2017-05-08 06:11:38 +00:00
set_include_path (
get_include_path () . PATH_SEPARATOR
2019-03-23 15:20:51 +01:00
. $this -> getBasePath () . DIRECTORY_SEPARATOR . 'include' . PATH_SEPARATOR
. $this -> getBasePath () . DIRECTORY_SEPARATOR . 'library' . PATH_SEPARATOR
. $this -> getBasePath ());
2017-05-08 06:11:38 +00:00
2019-08-15 16:18:08 +02:00
$this -> profiler -> reset ();
2018-06-25 20:38:41 -04:00
2024-11-06 07:21:50 +00:00
if ( $this -> mode -> has ( Mode :: DBAVAILABLE )) {
2019-02-23 01:24:08 +01:00
Core\Hook :: loadHooks ();
2023-01-05 22:13:10 +01:00
$loader = ( new Config ()) -> createConfigFileManager ( $this -> getBasePath (), $_SERVER );
2019-02-23 01:24:08 +01:00
Core\Hook :: callAll ( 'load_config' , $loader );
2022-12-16 21:59:32 +01:00
// Hooks are now working, reload the whole definitions with hook enabled
$dbaDefinition -> load ( true );
$viewDefinition -> load ( true );
2018-08-27 06:15:55 +02:00
}
$this -> loadDefaultTimezone ();
2019-08-15 16:18:08 +02:00
// Register template engines
Core\Renderer :: registerTemplateEngine ( 'Friendica\Render\FriendicaSmartyEngine' );
2018-08-27 06:15:55 +02:00
}
2018-06-27 23:05:38 -04:00
/**
* Loads the default timezone
*
* Include support for legacy $default_timezone
*
* @ global string $default_timezone
*/
2018-06-25 20:38:41 -04:00
private function loadDefaultTimezone ()
{
2019-02-03 22:22:04 +01:00
if ( $this -> config -> get ( 'system' , 'default_timezone' )) {
2021-10-03 12:38:47 -04:00
$timezone = $this -> config -> get ( 'system' , 'default_timezone' , 'UTC' );
2018-06-25 20:38:41 -04:00
} else {
global $default_timezone ;
2021-10-03 12:38:47 -04:00
$timezone = $default_timezone ? ? '' ? : 'UTC' ;
2018-06-25 20:38:41 -04:00
}
2024-11-06 12:26:33 +00:00
$this -> appHelper -> setTimeZone ( $timezone );
2018-06-25 20:38:41 -04:00
}
2018-04-28 18:30:13 -04:00
/**
2023-03-22 00:07:56 -04:00
* Returns the current theme name . May be overridden by the mobile theme name .
2018-04-28 18:30:13 -04:00
*
2024-11-08 09:39:16 +00:00
* @ deprecated 2024.12 Use AppHelper :: getCurrentTheme () instead
*
2022-06-16 16:25:30 +02:00
* @ return string Current theme name or empty string in installation phase
2019-10-06 12:07:06 -04:00
* @ throws Exception
2018-04-28 18:30:13 -04:00
*/
2022-06-16 16:25:30 +02:00
public function getCurrentTheme () : string
2018-04-28 18:30:13 -04:00
{
2024-11-08 09:39:16 +00:00
return $this -> appHelper -> getCurrentTheme ();
2018-04-28 18:30:13 -04:00
}
2019-10-06 12:07:06 -04:00
/**
* Returns the current mobile theme name .
*
2024-11-08 09:39:16 +00:00
* @ deprecated 2024.12 Use AppHelper :: getCurrentMobileTheme () instead
*
2022-06-16 16:25:30 +02:00
* @ return string Mobile theme name or empty string if installer
2019-10-06 12:07:06 -04:00
* @ throws Exception
*/
2022-06-16 16:25:30 +02:00
public function getCurrentMobileTheme () : string
2019-10-06 12:07:06 -04:00
{
2024-11-08 09:39:16 +00:00
return $this -> appHelper -> getCurrentMobileTheme ();
2019-10-06 12:07:06 -04:00
}
2022-06-16 16:25:30 +02:00
/**
* Setter for current theme name
*
2024-11-08 09:39:16 +00:00
* @ deprecated 2024.12 Use AppHelper :: setCurrentTheme () instead
*
2022-06-16 16:25:30 +02:00
* @ param string $theme Name of current theme
*/
public function setCurrentTheme ( string $theme )
2018-12-29 00:18:52 -05:00
{
2024-11-08 09:39:16 +00:00
$this -> appHelper -> setCurrentTheme ( $theme );
2018-12-29 00:18:52 -05:00
}
2022-06-16 16:25:30 +02:00
/**
* Setter for current mobile theme name
*
2024-11-08 09:39:16 +00:00
* @ deprecated 2024.12 Use AppHelper :: setCurrentMobileTheme () instead
*
2022-06-16 16:25:30 +02:00
* @ param string $theme Name of current mobile theme
*/
public function setCurrentMobileTheme ( string $theme )
2019-10-06 12:07:06 -04:00
{
2024-11-08 09:39:16 +00:00
$this -> appHelper -> setCurrentMobileTheme ( $theme );
2018-04-28 18:30:13 -04:00
}
/**
* Provide a sane default if nothing is chosen or the specified theme does not exist .
*
2024-11-08 12:06:30 +00:00
* @ deprecated 2024.12 Use AppHelper :: getCurrentThemeStylesheetPath () instead
*
2023-03-22 00:08:29 -04:00
* @ return string Current theme ' s stylesheet path
2019-10-06 12:07:06 -04:00
* @ throws Exception
2018-04-28 18:30:13 -04:00
*/
2022-06-16 16:25:30 +02:00
public function getCurrentThemeStylesheetPath () : string
2018-04-28 18:30:13 -04:00
{
2024-11-08 12:06:30 +00:00
return $this -> appHelper -> getCurrentThemeStylesheetPath ();
2018-04-28 18:30:13 -04:00
}
2018-10-13 18:57:31 +02:00
2018-10-21 22:24:47 -04:00
/**
* Frontend App script
*
* The App object behaves like a container and a dispatcher at the same time , including a representation of the
* request and a representation of the response .
*
* This probably should change to limit the size of this monster method .
2019-08-12 18:13:58 +02:00
*
2021-10-26 21:44:29 +02:00
* @ param App\Router $router
* @ param IManagePersonalConfigValues $pconfig
2021-11-28 14:01:13 +01:00
* @ param Authentication $auth The Authentication backend of the node
* @ param App\Page $page The Friendica page printing container
2022-12-26 21:17:32 +01:00
* @ param ModuleHTTPException $httpException The possible HTTP Exception container
2021-11-28 14:01:13 +01:00
* @ param HTTPInputData $httpInput A library for processing PHP input streams
* @ param float $start_time The start time of the overall script execution
2023-02-18 20:47:52 +01:00
* @ param array $server The $_SERVER array
2020-01-19 22:23:44 +01:00
*
2019-10-06 11:18:51 -04:00
* @ throws HTTPException\InternalServerErrorException
* @ throws \ImagickException
2018-10-21 22:24:47 -04:00
*/
2023-02-18 20:47:52 +01:00
public function runFrontend ( App\Router $router , IManagePersonalConfigValues $pconfig , Authentication $auth , App\Page $page , Nav $nav , ModuleHTTPException $httpException , HTTPInputData $httpInput , float $start_time , array $server )
2018-10-21 22:24:47 -04:00
{
2024-03-16 12:54:17 +00:00
$requeststring = ( $server [ 'REQUEST_METHOD' ] ? ? '' ) . ' ' . ( $server [ 'REQUEST_URI' ] ? ? '' ) . ' ' . ( $server [ 'SERVER_PROTOCOL' ] ? ? '' );
$this -> logger -> debug ( 'Request received' , [ 'address' => $server [ 'REMOTE_ADDR' ] ? ? '' , 'request' => $requeststring , 'referer' => $server [ 'HTTP_REFERER' ] ? ? '' , 'user-agent' => $server [ 'HTTP_USER_AGENT' ] ? ? '' ]);
2023-10-26 03:41:35 +00:00
$request_start = microtime ( true );
2023-09-11 08:47:35 +00:00
2020-12-10 00:02:23 +00:00
$this -> profiler -> set ( $start_time , 'start' );
2020-12-09 22:10:27 +00:00
$this -> profiler -> set ( microtime ( true ), 'classinit' );
2021-11-19 22:47:49 +01:00
$moduleName = $this -> args -> getModuleName ();
2022-09-20 16:30:56 +02:00
$page -> setLogging ( $this -> args -> getMethod (), $this -> args -> getModuleName (), $this -> args -> getCommand ());
2019-08-12 18:13:58 +02:00
2019-07-23 20:01:45 -04:00
try {
// Missing DB connection: ERROR
2024-11-06 07:21:50 +00:00
if ( $this -> mode -> has ( Mode :: LOCALCONFIGPRESENT ) && ! $this -> mode -> has ( Mode :: DBAVAILABLE )) {
2022-01-03 22:29:26 +01:00
throw new HTTPException\InternalServerErrorException ( $this -> l10n -> t ( 'Apologies but the website is unavailable at the moment.' ));
2019-07-23 20:01:45 -04:00
}
2018-10-21 22:24:47 -04:00
2019-08-15 16:18:08 +02:00
if ( ! $this -> mode -> isInstall ()) {
2019-07-23 20:01:45 -04:00
// Force SSL redirection
2023-02-18 20:47:52 +01:00
if ( $this -> config -> get ( 'system' , 'force_ssl' ) &&
( empty ( $server [ 'HTTPS' ]) || $server [ 'HTTPS' ] === 'off' ) &&
2023-05-24 08:04:34 -04:00
( empty ( $server [ 'HTTP_X_FORWARDED_PROTO' ]) || $server [ 'HTTP_X_FORWARDED_PROTO' ] === 'http' ) &&
2023-02-18 20:47:52 +01:00
! empty ( $server [ 'REQUEST_METHOD' ]) &&
$server [ 'REQUEST_METHOD' ] === 'GET' ) {
System :: externalRedirect ( $this -> baseURL . '/' . $this -> args -> getQueryString ());
2019-07-23 20:01:45 -04:00
}
Core\Hook :: callAll ( 'init_1' );
2019-03-19 06:44:51 +00:00
}
2024-03-16 12:54:17 +00:00
DID :: routeRequest ( $this -> args -> getCommand (), $server );
2020-10-02 09:31:39 +00:00
if ( $this -> mode -> isNormal () && ! $this -> mode -> isBackend ()) {
2024-03-16 12:54:17 +00:00
$requester = HTTPSignature :: getSigner ( '' , $server );
2019-07-23 20:01:45 -04:00
if ( ! empty ( $requester )) {
2024-05-27 04:33:28 +00:00
OpenWebAuth :: addVisitorCookieForHandle ( $requester );
2018-10-21 22:24:47 -04:00
}
}
2019-07-23 20:01:45 -04:00
// ZRL
2022-10-23 20:41:17 +02:00
if ( ! empty ( $_GET [ 'zrl' ]) && $this -> mode -> isNormal () && ! $this -> mode -> isBackend () && ! $this -> session -> getLocalUserId ()) {
2022-12-07 22:24:01 -05:00
// Only continue when the given profile link seems valid.
2021-12-08 20:23:07 +00:00
// Valid profile links contain a path with "/profile/" and no query parameters
2022-06-24 03:01:13 +02:00
if (( parse_url ( $_GET [ 'zrl' ], PHP_URL_QUERY ) == '' ) &&
2022-12-07 22:24:01 -05:00
strpos ( parse_url ( $_GET [ 'zrl' ], PHP_URL_PATH ) ? ? '' , '/profile/' ) !== false ) {
2024-05-27 04:33:28 +00:00
$this -> auth -> setUnauthenticatedVisitor ( $_GET [ 'zrl' ]);
OpenWebAuth :: zrlInit ();
2021-12-08 20:23:07 +00:00
} else {
// Someone came with an invalid parameter, maybe as a DDoS attempt
// We simply stop processing here
$this -> logger -> debug ( 'Invalid ZRL parameter.' , [ 'zrl' => $_GET [ 'zrl' ]]);
throw new HTTPException\ForbiddenException ();
2019-07-23 20:01:45 -04:00
}
}
2018-10-21 22:24:47 -04:00
2019-08-15 16:18:08 +02:00
if ( ! empty ( $_GET [ 'owt' ]) && $this -> mode -> isNormal ()) {
2019-07-23 20:01:45 -04:00
$token = $_GET [ 'owt' ];
2024-05-27 04:33:28 +00:00
OpenWebAuth :: init ( $token );
2019-07-23 20:01:45 -04:00
}
2018-10-21 22:24:47 -04:00
2021-10-24 23:17:22 -04:00
if ( ! $this -> mode -> isBackend ()) {
2024-11-06 13:21:57 +01:00
$auth -> withSession ();
2021-10-24 23:17:22 -04:00
}
2018-10-21 22:24:47 -04:00
2024-05-27 04:33:28 +00:00
if ( $this -> session -> isUnauthenticated ()) {
2019-07-23 20:01:45 -04:00
header ( 'X-Account-Management-Status: none' );
}
2018-10-21 22:24:47 -04:00
2019-07-23 20:01:45 -04:00
/*
* check_config () is responsible for running update scripts . These automatically
* update the DB schema whenever we push a new one out . It also checks to see if
* any addons have been added or removed and reacts accordingly .
*/
// in install mode, any url loads install module
// but we need "view" module for stylesheet
2019-08-15 16:18:08 +02:00
if ( $this -> mode -> isInstall () && $moduleName !== 'install' ) {
2019-12-16 00:28:31 +01:00
$this -> baseURL -> redirect ( 'install' );
2019-07-23 20:01:45 -04:00
} else {
2023-01-06 12:50:14 +01:00
Core\Update :: check ( $this -> getBasePath (), false );
2019-07-23 20:01:45 -04:00
Core\Addon :: loadAddons ();
Core\Hook :: loadHooks ();
}
2018-10-21 22:24:47 -04:00
2024-05-20 19:36:40 +00:00
// Compatibility with Hubzilla
if ( $moduleName == 'rpost' ) {
$this -> baseURL -> redirect ( 'compose' );
}
2019-07-23 20:01:45 -04:00
// Compatibility with the Android Diaspora client
2019-08-12 18:13:58 +02:00
if ( $moduleName == 'stream' ) {
2019-12-16 00:28:31 +01:00
$this -> baseURL -> redirect ( 'network?order=post' );
2019-07-23 20:01:45 -04:00
}
2018-10-21 22:24:47 -04:00
2019-08-12 18:13:58 +02:00
if ( $moduleName == 'conversations' ) {
2019-12-16 00:28:31 +01:00
$this -> baseURL -> redirect ( 'message' );
2019-07-23 20:01:45 -04:00
}
2018-10-21 22:24:47 -04:00
2019-08-12 18:13:58 +02:00
if ( $moduleName == 'commented' ) {
2019-12-16 00:28:31 +01:00
$this -> baseURL -> redirect ( 'network?order=comment' );
2019-07-23 20:01:45 -04:00
}
2018-10-21 22:24:47 -04:00
2019-08-12 18:13:58 +02:00
if ( $moduleName == 'liked' ) {
2019-12-16 00:28:31 +01:00
$this -> baseURL -> redirect ( 'network?order=comment' );
2019-07-23 20:01:45 -04:00
}
2018-10-21 22:24:47 -04:00
2019-08-12 18:13:58 +02:00
if ( $moduleName == 'activity' ) {
2019-12-16 00:28:31 +01:00
$this -> baseURL -> redirect ( 'network?conv=1' );
2019-07-23 20:01:45 -04:00
}
2018-10-21 22:24:47 -04:00
2019-08-12 18:13:58 +02:00
if (( $moduleName == 'status_messages' ) && ( $this -> args -> getCommand () == 'status_messages/new' )) {
2019-12-16 00:28:31 +01:00
$this -> baseURL -> redirect ( 'bookmarklet' );
2019-07-23 20:01:45 -04:00
}
2018-10-21 22:24:47 -04:00
2019-08-12 18:13:58 +02:00
if (( $moduleName == 'user' ) && ( $this -> args -> getCommand () == 'user/edit' )) {
2019-12-16 00:28:31 +01:00
$this -> baseURL -> redirect ( 'settings' );
2019-07-23 20:01:45 -04:00
}
2018-10-21 22:24:47 -04:00
2019-08-12 18:13:58 +02:00
if (( $moduleName == 'tag_followings' ) && ( $this -> args -> getCommand () == 'tag_followings/manage' )) {
2019-12-16 00:28:31 +01:00
$this -> baseURL -> redirect ( 'search' );
2019-07-23 20:01:45 -04:00
}
2018-10-21 22:24:47 -04:00
2021-07-25 05:08:29 +00:00
// Initialize module that can set the current theme in the init() method, either directly or via App->setProfileOwner
2019-12-30 20:02:09 +01:00
$page [ 'page_title' ] = $moduleName ;
2019-08-15 20:58:57 +02:00
2022-07-12 19:48:36 -04:00
// The "view" module is required to show the theme CSS
2024-11-06 07:21:50 +00:00
if ( ! $this -> mode -> isInstall () && ! $this -> mode -> has ( Mode :: MAINTENANCEDISABLED ) && $moduleName !== 'view' ) {
2021-11-20 15:38:03 +01:00
$module = $router -> getModule ( Maintenance :: class );
2021-03-10 09:40:42 -05:00
} else {
// determine the module class and save it to the module instance
// @todo there's an implicit dependency due SESSION::start(), so it has to be called here (yet)
2021-11-19 22:47:49 +01:00
$module = $router -> getModule ();
2021-03-10 09:40:42 -05:00
}
2018-10-21 22:24:47 -04:00
2023-07-08 21:01:48 -04:00
// Display can change depending on the requested language, so it shouldn't be cached whole
header ( 'Vary: Accept-Language' , false );
2021-11-28 13:44:42 +01:00
// Processes data from GET requests
2021-11-28 14:01:13 +01:00
$httpinput = $httpInput -> process ();
$input = array_merge ( $httpinput [ 'variables' ], $httpinput [ 'files' ], $request ? ? $_REQUEST );
2021-11-28 13:44:42 +01:00
2022-12-26 21:17:32 +01:00
// Let the module run its internal process (init, get, post, ...)
2021-12-09 13:04:51 +00:00
$timestamp = microtime ( true );
2022-12-26 21:17:32 +01:00
$response = $module -> run ( $httpException , $input );
2021-12-09 13:04:51 +00:00
$this -> profiler -> set ( microtime ( true ) - $timestamp , 'content' );
2023-07-09 22:44:40 -04:00
// Wrapping HTML responses in the theme template
2021-11-22 00:07:09 +01:00
if ( $response -> getHeaderLine ( ICanCreateResponses :: X_HEADER ) === ICanCreateResponses :: TYPE_HTML ) {
2024-05-14 08:37:10 +00:00
$response = $page -> run ( $this , $this -> session , $this -> baseURL , $this -> args , $this -> mode , $response , $this -> l10n , $this -> profiler , $this -> config , $pconfig , $nav , $this -> session -> getLocalUserId ());
2021-11-21 21:52:36 +01:00
}
2023-07-09 22:44:40 -04:00
2024-03-16 12:54:17 +00:00
$this -> logger -> debug ( 'Request processed sucessfully' , [ 'response' => $response -> getStatusCode (), 'address' => $server [ 'REMOTE_ADDR' ] ? ? '' , 'request' => $requeststring , 'referer' => $server [ 'HTTP_REFERER' ] ? ? '' , 'user-agent' => $server [ 'HTTP_USER_AGENT' ] ? ? '' , 'duration' => number_format ( microtime ( true ) - $request_start , 3 )]);
2024-06-09 06:13:20 +00:00
$this -> logSlowCalls ( microtime ( true ) - $request_start , $response -> getStatusCode (), $requeststring , $server [ 'HTTP_USER_AGENT' ] ? ? '' );
2023-09-21 09:17:38 -04:00
System :: echoResponse ( $response );
2019-08-15 16:18:08 +02:00
} catch ( HTTPException $e ) {
2024-03-16 12:54:17 +00:00
$this -> logger -> debug ( 'Request processed with exception' , [ 'response' => $e -> getCode (), 'address' => $server [ 'REMOTE_ADDR' ] ? ? '' , 'request' => $requeststring , 'referer' => $server [ 'HTTP_REFERER' ] ? ? '' , 'user-agent' => $server [ 'HTTP_USER_AGENT' ] ? ? '' , 'duration' => number_format ( microtime ( true ) - $request_start , 3 )]);
2024-06-09 06:13:20 +00:00
$this -> logSlowCalls ( microtime ( true ) - $request_start , $e -> getCode (), $requeststring , $server [ 'HTTP_USER_AGENT' ] ? ? '' );
2022-12-26 21:17:32 +01:00
$httpException -> rawContent ( $e );
2019-05-01 21:33:33 -04:00
}
2022-06-10 18:49:03 +00:00
$page -> logRuntime ( $this -> config , 'runFrontend' );
2018-10-20 18:19:55 +02:00
}
2018-10-13 20:02:04 +02:00
2018-10-24 20:16:14 +02:00
/**
2018-10-24 20:52:38 +02:00
* Automatically redirects to relative or absolute URL
2018-10-24 20:16:14 +02:00
* Should only be used if it isn ' t clear if the URL is either internal or external
*
* @ param string $toUrl The target URL
2019-08-15 16:18:08 +02:00
*
2019-05-01 21:33:33 -04:00
* @ throws HTTPException\InternalServerErrorException
2018-10-24 20:16:14 +02:00
*/
2022-06-16 16:25:30 +02:00
public function redirect ( string $toUrl )
2018-10-24 20:16:14 +02:00
{
2018-11-30 11:27:17 +00:00
if ( ! empty ( parse_url ( $toUrl , PHP_URL_SCHEME ))) {
2018-10-24 20:24:22 +02:00
Core\System :: externalRedirect ( $toUrl );
2018-10-24 20:16:14 +02:00
} else {
2019-12-03 21:11:42 +01:00
$this -> baseURL -> redirect ( $toUrl );
2018-10-24 20:16:14 +02:00
}
}
2024-06-09 06:13:20 +00:00
/**
* Log slow page executions
*
* @ param float $duration
* @ param integer $code
* @ param string $request
* @ param string $agent
* @ return void
*/
private function logSlowCalls ( float $duration , int $code , string $request , string $agent )
{
$logfile = $this -> config -> get ( 'system' , 'page_execution_logfile' );
$loglimit = $this -> config -> get ( 'system' , 'page_execution_log_limit' );
if ( empty ( $logfile ) || empty ( $loglimit ) || ( $duration < $loglimit )) {
return ;
}
@ file_put_contents (
$logfile ,
DateTimeFormat :: utcNow () . " \t " . round ( $duration , 3 ) . " \t " .
$this -> requestId . " \t " . $code . " \t " .
$request . " \t " . $agent . " \n " ,
FILE_APPEND
);
}
2017-05-08 06:11:38 +00:00
}