2010-07-01 23:48:07 +00:00
< ? php
2010-12-09 07:08:59 +00:00
/**
2017-11-16 18:05:41 +00:00
* @ file index . php
2011-11-12 12:21:14 +00:00
* Friendica
2010-12-09 07:08:59 +00:00
*/
2010-07-01 23:48:07 +00:00
2010-12-09 07:08:59 +00:00
/**
2017-11-16 18:05:41 +00:00
* Bootstrap the application
2010-12-09 07:08:59 +00:00
*/
2017-04-30 04:07:00 +00:00
use Friendica\App ;
2018-01-15 19:51:56 +00:00
use Friendica\Content\Nav ;
2018-01-17 18:42:40 +00:00
use Friendica\Core\Addon ;
2017-04-30 04:01:26 +00:00
use Friendica\Core\Config ;
2018-01-21 16:38:01 +00:00
use Friendica\Core\L10n ;
2018-02-03 05:46:05 +00:00
use Friendica\Core\Session ;
use Friendica\Core\System ;
use Friendica\Core\Theme ;
2017-11-05 10:33:46 +00:00
use Friendica\Core\Worker ;
2018-07-20 12:19:26 +00:00
use Friendica\Database\DBA ;
2018-01-15 02:41:56 +00:00
use Friendica\Model\Profile ;
2017-12-17 16:42:46 +00:00
use Friendica\Module\Login ;
2017-01-18 21:45:32 +00:00
2017-05-03 02:42:29 +00:00
require_once 'boot.php' ;
2010-07-01 23:48:07 +00:00
2016-07-02 06:54:57 +00:00
// We assume that the index.php is called by a frontend process
// The value is set to "true" by default in boot.php
2018-10-09 17:58:58 +00:00
$a = new App ( __DIR__ , false );
2016-07-02 06:54:57 +00:00
2010-12-09 07:08:59 +00:00
/**
* Try to open the database ;
*/
2017-03-25 11:43:07 +00:00
require_once " include/dba.php " ;
2010-12-09 07:08:59 +00:00
2018-06-30 18:40:09 +00:00
// Missing DB connection: ERROR
2018-10-06 14:27:20 +00:00
if ( $a -> getMode () -> has ( App\Mode :: LOCALCONFIGPRESENT ) && ! $a -> getMode () -> has ( App\Mode :: DBAVAILABLE )) {
2018-06-30 18:40:09 +00:00
System :: httpExit ( 500 , [ 'title' => 'Error 500 - Internal Server Error' , 'description' => 'Apologies but the website is unavailable at the moment.' ]);
}
2011-06-28 00:18:13 +00:00
2018-06-30 18:40:09 +00:00
// Max Load Average reached: ERROR
2018-06-30 18:07:01 +00:00
if ( $a -> isMaxProcessesReached () || $a -> isMaxLoadReached ()) {
2018-06-30 18:40:09 +00:00
header ( 'Retry-After: 120' );
header ( 'Refresh: 120; url=' . System :: baseUrl () . " / " . $a -> query_string );
System :: httpExit ( 503 , [ 'title' => 'Error 503 - Service Temporarily Unavailable' , 'description' => 'System is currently overloaded. Please try again later.' ]);
}
2016-06-01 05:04:31 +00:00
2018-10-06 14:27:20 +00:00
if ( ! $a -> getMode () -> isInstall ()) {
2018-10-09 17:58:58 +00:00
if ( Config :: get ( 'system' , 'force_ssl' ) && ( $a -> getScheme () == " http " )
2017-11-19 19:15:25 +00:00
&& ( intval ( Config :: get ( 'system' , 'ssl_policy' )) == SSL_POLICY_FULL )
&& ( substr ( System :: baseUrl (), 0 , 8 ) == " https:// " )
2018-03-13 06:21:44 +00:00
&& ( $_SERVER [ 'REQUEST_METHOD' ] == 'GET' )) {
2014-10-23 22:52:29 +00:00
header ( " HTTP/1.1 302 Moved Temporarily " );
2017-08-26 07:32:10 +00:00
header ( " Location: " . System :: baseUrl () . " / " . $a -> query_string );
2016-03-01 13:49:07 +00:00
exit ();
2014-10-23 22:52:29 +00:00
}
2018-03-03 17:10:55 +00:00
Config :: init ();
2018-02-03 05:46:05 +00:00
Session :: init ();
2018-01-17 18:42:40 +00:00
Addon :: loadHooks ();
Addon :: callHooks ( 'init_1' );
2013-01-19 06:38:49 +00:00
}
2013-01-14 23:35:41 +00:00
2018-01-21 16:38:01 +00:00
$lang = L10n :: getBrowserLanguage ();
2013-03-02 23:46:54 +00:00
2018-01-21 16:38:01 +00:00
L10n :: loadTranslationTable ( $lang );
2011-06-13 10:51:36 +00:00
2010-12-09 07:08:59 +00:00
/**
* Important stuff we always need to do .
2012-06-12 02:52:46 +00:00
*
2010-12-09 07:08:59 +00:00
* The order of these may be important so use caution if you think they ' re all
* intertwingled with no logical order and decide to sort it out . Some of the
2014-09-20 10:09:10 +00:00
* dependencies have changed , but at least at one time in the recent past - the
2010-12-09 07:08:59 +00:00
* order was critical to everything working properly
*/
2016-07-02 06:54:57 +00:00
// Exclude the backend processes from the session management
2018-10-09 17:58:58 +00:00
if ( ! $a -> isBackend ()) {
2016-07-02 06:54:57 +00:00
$stamp1 = microtime ( true );
session_start ();
2018-10-09 17:58:58 +00:00
$a -> saveTimestamp ( $stamp1 , " parser " );
2016-11-27 00:55:05 +00:00
} else {
2018-01-01 20:08:00 +00:00
$_SESSION = [];
2017-11-05 10:33:46 +00:00
Worker :: executeIfIdle ();
2016-07-02 06:54:57 +00:00
}
2010-07-01 23:48:07 +00:00
2011-03-31 11:57:31 +00:00
/**
* Language was set earlier , but we can over - ride it in the session .
* We have to do it here because the session was just now opened .
*/
2018-09-21 01:05:23 +00:00
if ( ! empty ( $_SESSION [ 'authenticated' ]) && empty ( $_SESSION [ 'language' ])) {
2015-11-08 13:23:49 +00:00
$_SESSION [ 'language' ] = $lang ;
2018-08-02 05:21:01 +00:00
// we haven't loaded user data yet, but we need user language
if ( ! empty ( $_SESSION [ 'uid' ])) {
$user = DBA :: selectFirst ( 'user' , [ 'language' ], [ 'uid' => $_SESSION [ 'uid' ]]);
if ( DBA :: isResult ( $user )) {
$_SESSION [ 'language' ] = $user [ 'language' ];
}
2017-05-07 20:52:00 +00:00
}
2011-09-21 23:00:17 +00:00
}
2015-11-08 13:23:49 +00:00
2018-09-21 01:05:23 +00:00
if ( ! empty ( $_SESSION [ 'language' ]) && $_SESSION [ 'language' ] !== $lang ) {
2011-03-31 11:57:31 +00:00
$lang = $_SESSION [ 'language' ];
2018-01-21 16:38:01 +00:00
L10n :: loadTranslationTable ( $lang );
2011-03-31 11:57:31 +00:00
}
2018-10-06 14:27:20 +00:00
if ( ! empty ( $_GET [ 'zrl' ]) && $a -> getMode () -> isNormal ()) {
2018-06-18 21:05:44 +00:00
$a -> query_string = Profile :: stripZrls ( $a -> query_string );
if ( ! local_user ()) {
// Only continue when the given profile link seems valid
// Valid profile links contain a path with "/profile/" and no query parameters
if (( parse_url ( $_GET [ 'zrl' ], PHP_URL_QUERY ) == " " ) &&
strstr ( parse_url ( $_GET [ 'zrl' ], PHP_URL_PATH ), " /profile/ " )) {
2018-07-10 12:27:56 +00:00
if ( defaults ( $_SESSION , " visitor_home " , " " ) != $_GET [ " zrl " ]) {
2018-06-18 21:05:44 +00:00
$_SESSION [ 'my_url' ] = $_GET [ 'zrl' ];
$_SESSION [ 'authenticated' ] = 0 ;
}
Profile :: zrlInit ( $a );
} 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 );
header ( 'HTTP/1.1 403 Forbidden' );
echo " <h1>403 Forbidden</h1> " ;
2018-09-21 01:05:23 +00:00
exit ();
2018-06-18 21:05:44 +00:00
}
2016-04-20 20:10:05 +00:00
}
2012-03-30 03:58:32 +00:00
}
2011-03-31 11:57:31 +00:00
2018-10-06 14:27:20 +00:00
if ( ! empty ( $_GET [ 'owt' ]) && $a -> getMode () -> isNormal ()) {
2018-06-18 21:05:44 +00:00
$token = $_GET [ 'owt' ];
$a -> query_string = Profile :: stripQueryParam ( $a -> query_string , 'owt' );
2018-06-20 16:38:23 +00:00
Profile :: openWebAuthInit ( $token );
2018-06-18 21:05:44 +00:00
}
2010-12-09 07:08:59 +00:00
/**
* For Mozilla auth manager - still needs sorting , and this might conflict with LRDD header .
* Apache / PHP lumps the Link : headers into one - and other services might not be able to parse it
2014-09-20 10:09:10 +00:00
* this way . There ' s a PHP flag to link the headers because by default this will over - write any other
2013-09-15 08:40:58 +00:00
* link header .
2010-12-09 07:08:59 +00:00
*
* What we really need to do is output the raw headers ourselves so we can keep them separate .
*/
2013-09-15 08:40:58 +00:00
2017-08-26 07:32:10 +00:00
// header('Link: <' . System::baseUrl() . '/amcd>; rel="acct-mgmt";');
2010-08-16 12:23:26 +00:00
2017-12-17 16:42:46 +00:00
Login :: sessionAuth ();
2010-07-01 23:48:07 +00:00
2018-09-21 01:05:23 +00:00
if ( empty ( $_SESSION [ 'authenticated' ])) {
2010-11-11 10:49:28 +00:00
header ( 'X-Account-Management-Status: none' );
2016-12-20 16:43:46 +00:00
}
2010-11-11 10:49:28 +00:00
2018-02-03 13:42:12 +00:00
$_SESSION [ 'sysmsg' ] = defaults ( $_SESSION , 'sysmsg' , []);
$_SESSION [ 'sysmsg_info' ] = defaults ( $_SESSION , 'sysmsg_info' , []);
$_SESSION [ 'last_updated' ] = defaults ( $_SESSION , 'last_updated' , []);
2011-12-12 04:32:43 +00:00
2010-12-09 07:08:59 +00:00
/*
2014-09-20 10:09:10 +00:00
* check_config () is responsible for running update scripts . These automatically
2011-03-10 10:45:37 +00:00
* update the DB schema whenever we push a new one out . It also checks to see if
2018-01-17 19:22:38 +00:00
* any addons have been added or removed and reacts accordingly .
2010-12-09 07:08:59 +00:00
*/
2014-09-20 10:09:10 +00:00
// in install mode, any url loads install module
// but we need "view" module for stylesheet
2018-10-06 14:27:20 +00:00
if ( $a -> getMode () -> isInstall () && $a -> module != 'view' ) {
2010-07-01 23:48:07 +00:00
$a -> module = 'install' ;
2018-10-06 14:27:20 +00:00
} elseif ( ! $a -> getMode () -> has ( App\Mode :: MAINTENANCEDISABLED ) && $a -> module != 'view' ) {
2013-01-14 23:35:41 +00:00
$a -> module = 'maintenance' ;
2016-12-20 16:43:46 +00:00
} else {
2013-01-19 06:38:49 +00:00
check_url ( $a );
2017-09-30 17:12:27 +00:00
check_db ( false );
2018-10-05 23:13:29 +00:00
Addon :: check ();
2013-01-15 03:31:32 +00:00
}
2010-07-01 23:48:07 +00:00
2018-01-15 19:51:56 +00:00
Nav :: setSelected ( 'nothing' );
2010-12-09 07:08:59 +00:00
2013-07-24 01:45:22 +00:00
//Don't populate apps_menu if apps are private
2017-11-19 19:15:25 +00:00
$privateapps = Config :: get ( 'config' , 'private_addons' );
2016-12-20 16:43:46 +00:00
if (( local_user ()) || ( ! $privateapps === " 1 " )) {
2018-01-15 13:05:12 +00:00
$arr = [ 'app_menu' => $a -> apps ];
2011-02-19 08:56:15 +00:00
2018-01-17 18:42:40 +00:00
Addon :: callHooks ( 'app_menu' , $arr );
2011-02-19 08:56:15 +00:00
2013-07-24 01:45:22 +00:00
$a -> apps = $arr [ 'app_menu' ];
}
2011-02-19 08:56:15 +00:00
2010-12-09 07:08:59 +00:00
/**
2011-03-10 10:45:37 +00:00
* We have already parsed the server path into $a -> argc and $a -> argv
2010-12-09 07:08:59 +00:00
*
* $a -> argv [ 0 ] is our module name . We will load the file mod / { $a -> argv [ 0 ]} . php
* and use it for handling our URL request .
* The module file contains a few functions that we call in various circumstances
* and in the following order :
2014-09-20 10:09:10 +00:00
*
2010-12-09 07:08:59 +00:00
* " module " _init
2011-03-10 10:45:37 +00:00
* " module " _post ( only called if there are $_POST variables )
2010-12-09 07:08:59 +00:00
* " module " _afterpost
* " module " _content - the string return of this function contains our page body
*
2014-09-20 10:09:10 +00:00
* Modules which emit other serialisations besides HTML ( XML , JSON , etc . ) should do
2010-12-13 01:40:23 +00:00
* so within the module init and / or post functions and then invoke killme () to terminate
* further processing .
2010-12-09 07:08:59 +00:00
*/
2017-01-26 13:28:43 +00:00
if ( strlen ( $a -> module )) {
2011-03-10 10:45:37 +00:00
/**
* We will always have a module name .
2018-01-17 19:22:38 +00:00
* First see if we have an addon which is masquerading as a module .
2011-03-10 10:45:37 +00:00
*/
2013-03-06 22:23:04 +00:00
// Compatibility with the Android Diaspora client
2018-04-17 16:46:57 +00:00
if ( $a -> module == 'stream' ) {
goaway ( 'network?f=&order=post' );
}
if ( $a -> module == 'conversations' ) {
goaway ( 'message' );
}
if ( $a -> module == 'commented' ) {
goaway ( 'network?f=&order=comment' );
}
if ( $a -> module == 'liked' ) {
goaway ( 'network?f=&order=comment' );
}
if ( $a -> module == 'activity' ) {
goaway ( 'network/?f=&conv=1' );
}
if (( $a -> module == 'status_messages' ) && ( $a -> cmd == 'status_messages/new' )) {
goaway ( 'bookmarklet' );
}
if (( $a -> module == 'user' ) && ( $a -> cmd == 'user/edit' )) {
goaway ( 'settings' );
}
if (( $a -> module == 'tag_followings' ) && ( $a -> cmd == 'tag_followings/manage' )) {
goaway ( 'search' );
2017-01-26 13:28:43 +00:00
}
2013-09-15 08:40:58 +00:00
2014-02-02 08:56:37 +00:00
// Compatibility with the Firefox App
2017-06-08 02:00:59 +00:00
if (( $a -> module == " users " ) && ( $a -> cmd == " users/sign_in " )) {
2014-02-02 08:56:37 +00:00
$a -> module = " login " ;
2017-01-26 13:28:43 +00:00
}
2014-02-02 08:56:37 +00:00
2017-11-19 19:15:25 +00:00
$privateapps = Config :: get ( 'config' , 'private_addons' );
2013-03-06 22:23:04 +00:00
2018-01-17 19:22:38 +00:00
if ( is_array ( $a -> addons ) && in_array ( $a -> module , $a -> addons ) && file_exists ( " addon/ { $a -> module } / { $a -> module } .php " )) {
2013-07-24 01:45:22 +00:00
//Check if module is an app and if public access to apps is allowed or not
2018-01-17 18:42:40 +00:00
if (( ! local_user ()) && Addon :: isApp ( $a -> module ) && $privateapps === " 1 " ) {
2018-01-21 18:33:59 +00:00
info ( L10n :: t ( " You must be logged in to use addons. " ));
2017-01-26 13:28:43 +00:00
} else {
2017-11-19 19:15:25 +00:00
include_once " addon/ { $a -> module } / { $a -> module } .php " ;
2017-01-26 13:28:43 +00:00
if ( function_exists ( $a -> module . '_module' )) {
2013-07-24 01:45:22 +00:00
$a -> module_loaded = true ;
2017-01-26 13:28:43 +00:00
}
2013-07-24 01:45:22 +00:00
}
2011-02-11 00:17:21 +00:00
}
2011-03-10 10:45:37 +00:00
2017-12-17 16:37:03 +00:00
// Controller class routing
if ( ! $a -> module_loaded && class_exists ( 'Friendica\\Module\\' . ucfirst ( $a -> module ))) {
$a -> module_class = 'Friendica\\Module\\' . ucfirst ( $a -> module );
$a -> module_loaded = true ;
}
2011-03-10 10:45:37 +00:00
/**
2016-02-09 08:39:29 +00:00
* If not , next look for a 'standard' program module in the 'mod' directory
2011-03-10 10:45:37 +00:00
*/
2017-12-17 16:37:03 +00:00
if ( ! $a -> module_loaded && file_exists ( " mod/ { $a -> module } .php " )) {
2017-11-19 19:15:25 +00:00
include_once " mod/ { $a -> module } .php " ;
2010-07-01 23:48:07 +00:00
$a -> module_loaded = true ;
}
2011-03-10 10:45:37 +00:00
/**
* The URL provided does not resolve to a valid module .
*
2014-09-20 10:09:10 +00:00
* On Dreamhost sites , quite often things go wrong for no apparent reason and they send us to '/internal_error.html' .
* We don ' t like doing this , but as it occasionally accounts for 10 - 20 % or more of all site traffic -
2011-03-10 10:45:37 +00:00
* we are going to trap this and redirect back to the requested page . As long as you don ' t have a critical error on your page
* this will often succeed and eventually do the right thing .
*
* Otherwise we are going to emit a 404 not found .
*/
2016-12-20 16:43:46 +00:00
if ( ! $a -> module_loaded ) {
2011-08-17 16:36:24 +00:00
// Stupid browser tried to pre-fetch our Javascript img template. Don't log the event or return anything - just quietly exit.
2018-09-21 01:05:23 +00:00
if ( ! empty ( $_SERVER [ 'QUERY_STRING' ]) && preg_match ( '/{[0-9]}/' , $_SERVER [ 'QUERY_STRING' ]) !== 0 ) {
2011-07-27 02:20:29 +00:00
killme ();
}
2018-09-21 01:05:23 +00:00
if ( ! empty ( $_SERVER [ 'QUERY_STRING' ]) && ( $_SERVER [ 'QUERY_STRING' ] === 'q=internal_error.html' ) && isset ( $dreamhost_error_hack )) {
2011-01-31 02:25:41 +00:00
logger ( 'index.php: dreamhost_error_hack invoked. Original URI =' . $_SERVER [ 'REQUEST_URI' ]);
2017-08-26 07:32:10 +00:00
goaway ( System :: baseUrl () . $_SERVER [ 'REQUEST_URI' ]);
2010-12-17 04:12:23 +00:00
}
2011-08-15 01:13:52 +00:00
logger ( 'index.php: page not found: ' . $_SERVER [ 'REQUEST_URI' ] . ' ADDRESS: ' . $_SERVER [ 'REMOTE_ADDR' ] . ' QUERY: ' . $_SERVER [ 'QUERY_STRING' ], LOGGER_DEBUG );
2018-01-21 18:33:59 +00:00
header ( $_SERVER [ " SERVER_PROTOCOL " ] . ' 404 ' . L10n :: t ( 'Not Found' ));
2011-09-19 09:52:32 +00:00
$tpl = get_markup_template ( " 404.tpl " );
2018-09-21 01:05:23 +00:00
$a -> page [ 'content' ] = replace_macros ( $tpl , [
'$message' => L10n :: t ( 'Page not found.' )
]);
2010-07-01 23:48:07 +00:00
}
}
2011-09-27 07:32:20 +00:00
/**
2017-11-19 19:15:25 +00:00
* Load current theme info
2011-09-27 07:32:20 +00:00
*/
2018-04-28 22:37:04 +00:00
$theme_info_file = 'view/theme/' . $a -> getCurrentTheme () . '/theme.php' ;
2017-11-19 19:15:25 +00:00
if ( file_exists ( $theme_info_file )) {
require_once $theme_info_file ;
2011-09-27 07:32:20 +00:00
}
2011-02-19 08:56:15 +00:00
2011-01-10 21:45:42 +00:00
/* initialise content region */
2018-10-06 14:27:20 +00:00
if ( $a -> getMode () -> isNormal ()) {
2018-01-17 18:42:40 +00:00
Addon :: callHooks ( 'page_content_top' , $a -> page [ 'content' ]);
2016-12-20 16:43:46 +00:00
}
2011-01-10 21:45:42 +00:00
/**
* Call module functions
*/
2017-01-26 13:28:43 +00:00
if ( $a -> module_loaded ) {
2010-07-01 23:48:07 +00:00
$a -> page [ 'page_title' ] = $a -> module ;
2012-06-19 03:57:43 +00:00
$placeholder = '' ;
2018-09-30 13:15:10 +00:00
Addon :: callHooks ( $a -> module . '_mod_init' , $placeholder );
2017-12-17 16:37:03 +00:00
if ( $a -> module_class ) {
call_user_func ([ $a -> module_class , 'init' ]);
} else if ( function_exists ( $a -> module . '_init' )) {
2010-07-01 23:48:07 +00:00
$func = $a -> module . '_init' ;
$func ( $a );
2010-12-09 07:08:59 +00:00
}
2010-07-01 23:48:07 +00:00
2018-09-30 13:15:10 +00:00
// "rawContent" is especially meant for technical endpoints.
// This endpoint doesn't need any theme initialization or other comparable stuff.
2018-09-30 20:47:28 +00:00
if ( ! $a -> error && $a -> module_class ) {
2018-09-30 13:15:10 +00:00
call_user_func ([ $a -> module_class , 'rawContent' ]);
}
2018-04-28 22:37:04 +00:00
if ( function_exists ( str_replace ( '-' , '_' , $a -> getCurrentTheme ()) . '_init' )) {
$func = str_replace ( '-' , '_' , $a -> getCurrentTheme ()) . '_init' ;
2012-04-08 12:52:00 +00:00
$func ( $a );
}
2017-12-17 16:37:03 +00:00
if ( ! $a -> error && $_SERVER [ 'REQUEST_METHOD' ] === 'POST' ) {
2018-01-17 18:42:40 +00:00
Addon :: callHooks ( $a -> module . '_mod_post' , $_POST );
2017-12-17 16:37:03 +00:00
if ( $a -> module_class ) {
call_user_func ([ $a -> module_class , 'post' ]);
} else if ( function_exists ( $a -> module . '_post' )) {
$func = $a -> module . '_post' ;
$func ( $a );
}
2010-07-01 23:48:07 +00:00
}
2017-12-17 16:37:03 +00:00
if ( ! $a -> error ) {
2018-01-17 18:42:40 +00:00
Addon :: callHooks ( $a -> module . '_mod_afterpost' , $placeholder );
2017-12-17 16:37:03 +00:00
if ( $a -> module_class ) {
call_user_func ([ $a -> module_class , 'afterpost' ]);
} else if ( function_exists ( $a -> module . '_afterpost' )) {
$func = $a -> module . '_afterpost' ;
$func ( $a );
}
2010-07-01 23:48:07 +00:00
}
2017-12-17 16:37:03 +00:00
if ( ! $a -> error ) {
2018-01-15 13:05:12 +00:00
$arr = [ 'content' => $a -> page [ 'content' ]];
2018-01-17 18:42:40 +00:00
Addon :: callHooks ( $a -> module . '_mod_content' , $arr );
2012-06-19 03:57:43 +00:00
$a -> page [ 'content' ] = $arr [ 'content' ];
2017-12-17 16:37:03 +00:00
if ( $a -> module_class ) {
2018-01-15 13:05:12 +00:00
$arr = [ 'content' => call_user_func ([ $a -> module_class , 'content' ])];
2017-12-17 16:37:03 +00:00
} else if ( function_exists ( $a -> module . '_content' )) {
$func = $a -> module . '_content' ;
2018-01-15 13:05:12 +00:00
$arr = [ 'content' => $func ( $a )];
2017-12-17 16:37:03 +00:00
}
2018-01-17 18:42:40 +00:00
Addon :: callHooks ( $a -> module . '_mod_aftercontent' , $arr );
2012-06-19 03:57:43 +00:00
$a -> page [ 'content' ] .= $arr [ 'content' ];
2010-07-01 23:48:07 +00:00
}
2018-04-28 22:37:04 +00:00
if ( function_exists ( str_replace ( '-' , '_' , $a -> getCurrentTheme ()) . '_content_loaded' )) {
$func = str_replace ( '-' , '_' , $a -> getCurrentTheme ()) . '_content_loaded' ;
2012-11-06 15:43:19 +00:00
$func ( $a );
}
2010-07-01 23:48:07 +00:00
}
2012-11-06 15:43:19 +00:00
/*
* Create the page head after setting the language
2017-03-25 12:56:56 +00:00
* and getting any auth credentials .
2012-11-06 15:43:19 +00:00
*
* Moved init_pagehead () and init_page_end () to after
* all the module functions have executed so that all
2017-03-25 12:56:56 +00:00
* theme choices made by the modules can take effect .
2012-11-06 15:43:19 +00:00
*/
2018-09-21 01:30:51 +00:00
$a -> initHead ();
2012-11-06 15:43:19 +00:00
2017-03-25 12:56:56 +00:00
/*
2012-11-06 15:43:19 +00:00
* Build the page ending -- this is stuff that goes right before
* the closing </ body > tag
*/
2018-09-21 01:01:05 +00:00
$a -> initFooter ();
2011-01-04 13:06:10 +00:00
2017-03-25 12:56:56 +00:00
/*
* now that we ' ve been through the module content , see if the page reported
* a permission problem and if so , a 403 response would seem to be in order .
*/
2018-01-21 18:33:59 +00:00
if ( stristr ( implode ( " " , $_SESSION [ 'sysmsg' ]), L10n :: t ( 'Permission denied' ))) {
header ( $_SERVER [ " SERVER_PROTOCOL " ] . ' 403 ' . L10n :: t ( 'Permission denied.' ));
2010-09-09 03:14:17 +00:00
}
2017-03-25 12:56:56 +00:00
/*
2010-12-09 07:08:59 +00:00
* Report anything which needs to be communicated in the notification area ( before the main body )
*/
2018-01-17 18:42:40 +00:00
Addon :: callHooks ( 'page_end' , $a -> page [ 'content' ]);
2011-01-10 21:45:42 +00:00
2017-03-25 12:56:56 +00:00
/*
2010-12-09 07:08:59 +00:00
* Add the navigation ( menu ) template
*/
2017-01-26 13:28:43 +00:00
if ( $a -> module != 'install' && $a -> module != 'maintenance' ) {
2018-01-15 19:51:56 +00:00
Nav :: build ( $a );
2011-02-22 04:19:33 +00:00
}
2010-07-01 23:48:07 +00:00
2013-01-03 18:16:10 +00:00
/**
* Build the page - now that we have all the components
*/
2017-06-08 02:00:59 +00:00
if ( isset ( $_GET [ " mode " ]) && (( $_GET [ " mode " ] == " raw " ) || ( $_GET [ " mode " ] == " minimal " ))) {
2013-10-14 22:43:11 +00:00
$doc = new DOMDocument ();
$target = new DOMDocument ();
$target -> loadXML ( " <root></root> " );
$content = mb_convert_encoding ( $a -> page [ " content " ], 'HTML-ENTITIES' , " UTF-8 " );
2017-03-24 20:17:00 +00:00
/// @TODO one day, kill those error-surpressing @ stuff, or PHP should ban it
2013-10-14 22:43:11 +00:00
@ $doc -> loadHTML ( $content );
2018-02-03 05:46:05 +00:00
$xpath = new DOMXPath ( $doc );
2013-10-14 22:43:11 +00:00
$list = $xpath -> query ( " //*[contains(@id,'tread-wrapper-')] " ); /* */
foreach ( $list as $item ) {
$item = $target -> importNode ( $item , true );
// And then append it to the target
$target -> documentElement -> appendChild ( $item );
}
2013-12-04 22:46:51 +00:00
}
2017-06-08 02:00:59 +00:00
if ( isset ( $_GET [ " mode " ]) && ( $_GET [ " mode " ] == " raw " )) {
2013-10-14 22:43:11 +00:00
header ( " Content-type: text/html; charset=utf-8 " );
echo substr ( $target -> saveHTML (), 6 , - 8 );
2018-09-21 01:05:23 +00:00
exit ();
2013-10-14 22:43:11 +00:00
}
2010-07-01 23:48:07 +00:00
$page = $a -> page ;
$profile = $a -> profile ;
2017-03-24 20:08:03 +00:00
header ( " X-Friendica-Version: " . FRIENDICA_VERSION );
2010-07-01 23:48:07 +00:00
header ( " Content-type: text/html; charset=utf-8 " );
2010-08-16 12:23:26 +00:00
2017-09-14 05:40:23 +00:00
if ( Config :: get ( 'system' , 'hsts' ) && ( Config :: get ( 'system' , 'ssl_policy' ) == SSL_POLICY_FULL )) {
header ( " Strict-Transport-Security: max-age=31536000 " );
}
// Some security stuff
header ( 'X-Content-Type-Options: nosniff' );
header ( 'X-XSS-Protection: 1; mode=block' );
header ( 'X-Permitted-Cross-Domain-Policies: none' );
header ( 'X-Frame-Options: sameorigin' );
// Things like embedded OSM maps don't work, when this is enabled
// header("Content-Security-Policy: default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval'; connect-src 'self'; style-src 'self' 'unsafe-inline'; font-src 'self'; img-src 'self' https: data:; media-src 'self' https:; child-src 'self' https:; object-src 'none'");
2017-03-24 20:17:00 +00:00
/*
2017-04-30 04:01:26 +00:00
* We use $_GET [ " mode " ] for special page templates . So we will check if we have
2017-03-24 20:17:00 +00:00
* to load another page template than the default one .
* The page templates are located in / view / php / or in the theme directory .
*/
2016-07-11 08:33:39 +00:00
if ( isset ( $_GET [ " mode " ])) {
2018-01-17 18:52:25 +00:00
$template = Theme :: getPathForFile ( $_GET [ " mode " ] . '.php' );
2016-07-11 08:33:39 +00:00
}
2010-07-01 23:48:07 +00:00
2016-07-11 08:33:39 +00:00
// If there is no page template use the default page template
2017-08-14 05:47:25 +00:00
if ( empty ( $template )) {
2018-01-17 18:52:25 +00:00
$template = Theme :: getPathForFile ( " default.php " );
2013-12-04 22:46:51 +00:00
}
2010-07-01 23:48:07 +00:00
2018-01-17 18:52:25 +00:00
/// @TODO Looks unsafe (remote-inclusion), is maybe not but Theme::getPathForFile() uses file_exists() but does not escape anything
2017-03-24 20:08:03 +00:00
require_once $template ;