]> git.mxchange.org Git - friendica.git/blob - index.php
Guesss what? Yeah, some documentation
[friendica.git] / index.php
1 <?php
2
3
4 /**
5  *
6  * Friendica
7  *
8  */
9
10 /**
11  *
12  * bootstrap the application
13  *
14  */
15
16 require_once('boot.php');
17 require_once('object/BaseObject.php');
18
19 $a = new App;
20 BaseObject::set_app($a);
21
22 /**
23  *
24  * Load the configuration file which contains our DB credentials.
25  * Ignore errors. If the file doesn't exist or is empty, we are running in installation mode.
26  *
27  */
28
29 $install = ((file_exists('.htconfig.php') && filesize('.htconfig.php')) ? false : true);
30
31 @include(".htconfig.php");
32
33
34
35
36
37 /**
38  *
39  * Try to open the database;
40  *
41  */
42
43 require_once("include/dba.php");
44
45 if(!$install) {
46         $db = new dba($db_host, $db_user, $db_pass, $db_data, $install);
47             unset($db_host, $db_user, $db_pass, $db_data);
48
49         /**
50          * Load configs from db. Overwrite configs from .htconfig.php
51          */
52
53         load_config('config');
54         load_config('system');
55
56         $maxsysload_frontend = intval(get_config('system','maxloadavg_frontend'));
57         if($maxsysload_frontend < 1)
58                 $maxsysload_frontend = 50;
59
60         $load = current_load();
61         if($load) {
62                 if($load > $maxsysload_frontend) {
63                         logger('system: load ' . $load . ' too high. Service Temporarily Unavailable.');
64                         header($_SERVER["SERVER_PROTOCOL"].' 503 Service Temporarily Unavailable');
65                         header('Retry-After: 300');
66                         die("System is currently unavailable. Please try again later");
67                 }
68         }
69
70
71         if (get_config('system','force_ssl') AND ($a->get_scheme() == "http") AND
72                 (intval(get_config('system','ssl_policy')) == SSL_POLICY_FULL) AND
73                 (substr($a->get_baseurl(), 0, 8) == "https://")) {
74                 header("HTTP/1.1 302 Moved Temporarily");
75                 header("Location: ".$a->get_baseurl()."/".$a->query_string);
76                 exit();
77         }
78
79         require_once("include/session.php");
80         load_hooks();
81         call_hooks('init_1');
82
83         $maintenance = get_config('system', 'maintenance');
84 }
85
86 $lang = get_browser_language();
87
88 load_translation_table($lang);
89
90 /**
91  *
92  * Important stuff we always need to do.
93  *
94  * The order of these may be important so use caution if you think they're all
95  * intertwingled with no logical order and decide to sort it out. Some of the
96  * dependencies have changed, but at least at one time in the recent past - the
97  * order was critical to everything working properly
98  *
99  */
100
101 session_start();
102
103 /**
104  * Language was set earlier, but we can over-ride it in the session.
105  * We have to do it here because the session was just now opened.
106  */
107 if (x($_SESSION,'authenticated') && !x($_SESSION,'language')) {
108         // we didn't loaded user data yet, but we need user language
109         $r = q("SELECT language FROM user WHERE uid=%d", intval($_SESSION['uid']));
110         $_SESSION['language'] = $lang;
111         if (count($r)>0) $_SESSION['language'] = $r[0]['language'];
112 }
113
114 if((x($_SESSION,'language')) && ($_SESSION['language'] !== $lang)) {
115         $lang = $_SESSION['language'];
116         load_translation_table($lang);
117 }
118
119 if((x($_GET,'zrl')) && (!$install && !$maintenance)) {
120         $_SESSION['my_url'] = $_GET['zrl'];
121         $a->query_string = preg_replace('/[\?&]zrl=(.*?)([\?&]|$)/is','',$a->query_string);
122         zrl_init($a);
123 }
124
125 /**
126  *
127  * For Mozilla auth manager - still needs sorting, and this might conflict with LRDD header.
128  * Apache/PHP lumps the Link: headers into one - and other services might not be able to parse it
129  * this way. There's a PHP flag to link the headers because by default this will over-write any other
130  * link header.
131  *
132  * What we really need to do is output the raw headers ourselves so we can keep them separate.
133  *
134  */
135
136 // header('Link: <' . $a->get_baseurl() . '/amcd>; rel="acct-mgmt";');
137
138 if((x($_SESSION,'authenticated')) || (x($_POST,'auth-params')) || ($a->module === 'login'))
139         require("include/auth.php");
140
141 if(! x($_SESSION,'authenticated'))
142         header('X-Account-Management-Status: none');
143
144 /* set up page['htmlhead'] and page['end'] for the modules to use */
145 $a->page['htmlhead'] = '';
146 $a->page['end'] = '';
147
148
149 if(! x($_SESSION,'sysmsg'))
150         $_SESSION['sysmsg'] = array();
151
152 if(! x($_SESSION,'sysmsg_info'))
153         $_SESSION['sysmsg_info'] = array();
154
155 /*
156  * check_config() is responsible for running update scripts. These automatically
157  * update the DB schema whenever we push a new one out. It also checks to see if
158  * any plugins have been added or removed and reacts accordingly.
159  */
160
161 // in install mode, any url loads install module
162 // but we need "view" module for stylesheet
163 if($install && $a->module!="view")
164         $a->module = 'install';
165 elseif($maintenance && $a->module!="view")
166         $a->module = 'maintenance';
167 else {
168         check_url($a);
169         check_db();
170         check_plugins($a);
171 }
172
173 nav_set_selected('nothing');
174
175 //Don't populate apps_menu if apps are private
176 $privateapps = get_config('config','private_addons');
177 if((local_user()) || (! $privateapps === "1"))
178 {
179         $arr = array('app_menu' => $a->apps);
180
181         call_hooks('app_menu', $arr);
182
183         $a->apps = $arr['app_menu'];
184 }
185
186 /**
187  *
188  * We have already parsed the server path into $a->argc and $a->argv
189  *
190  * $a->argv[0] is our module name. We will load the file mod/{$a->argv[0]}.php
191  * and use it for handling our URL request.
192  * The module file contains a few functions that we call in various circumstances
193  * and in the following order:
194  *
195  * "module"_init
196  * "module"_post (only called if there are $_POST variables)
197  * "module"_afterpost
198  * "module"_content - the string return of this function contains our page body
199  *
200  * Modules which emit other serialisations besides HTML (XML,JSON, etc.) should do
201  * so within the module init and/or post functions and then invoke killme() to terminate
202  * further processing.
203  */
204
205 if(strlen($a->module)) {
206
207         /**
208          *
209          * We will always have a module name.
210          * First see if we have a plugin which is masquerading as a module.
211          *
212          */
213
214         // Compatibility with the Android Diaspora client
215         if ($a->module == "stream")
216                 $a->module = "network";
217
218         // Compatibility with the Firefox App
219         if (($a->module == "users") AND ($a->cmd == "users/sign_in"))
220                 $a->module = "login";
221
222         $privateapps = get_config('config','private_addons');
223
224         if(is_array($a->plugins) && in_array($a->module,$a->plugins) && file_exists("addon/{$a->module}/{$a->module}.php")) {
225                 //Check if module is an app and if public access to apps is allowed or not
226                 if((!local_user()) && plugin_is_app($a->module) && $privateapps === "1") {
227                         info( t("You must be logged in to use addons. "));
228                 }
229                 else {
230                         include_once("addon/{$a->module}/{$a->module}.php");
231                         if(function_exists($a->module . '_module'))
232                                 $a->module_loaded = true;
233                 }
234         }
235
236         /**
237          * If not, next look for a 'standard' program module in the 'mod' directory
238          */
239
240         if((! $a->module_loaded) && (file_exists("mod/{$a->module}.php"))) {
241                 include_once("mod/{$a->module}.php");
242                 $a->module_loaded = true;
243         }
244
245         /**
246          *
247          * The URL provided does not resolve to a valid module.
248          *
249          * On Dreamhost sites, quite often things go wrong for no apparent reason and they send us to '/internal_error.html'.
250          * We don't like doing this, but as it occasionally accounts for 10-20% or more of all site traffic -
251          * 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
252          * this will often succeed and eventually do the right thing.
253          *
254          * Otherwise we are going to emit a 404 not found.
255          *
256          */
257
258         if(! $a->module_loaded) {
259
260                 // Stupid browser tried to pre-fetch our Javascript img template. Don't log the event or return anything - just quietly exit.
261                 if((x($_SERVER,'QUERY_STRING')) && preg_match('/{[0-9]}/',$_SERVER['QUERY_STRING']) !== 0) {
262                         killme();
263                 }
264
265                 if((x($_SERVER,'QUERY_STRING')) && ($_SERVER['QUERY_STRING'] === 'q=internal_error.html') && isset($dreamhost_error_hack)) {
266                         logger('index.php: dreamhost_error_hack invoked. Original URI =' . $_SERVER['REQUEST_URI']);
267                         goaway($a->get_baseurl() . $_SERVER['REQUEST_URI']);
268                 }
269
270                 logger('index.php: page not found: ' . $_SERVER['REQUEST_URI'] . ' ADDRESS: ' . $_SERVER['REMOTE_ADDR'] . ' QUERY: ' . $_SERVER['QUERY_STRING'], LOGGER_DEBUG);
271                 header($_SERVER["SERVER_PROTOCOL"] . ' 404 ' . t('Not Found'));
272                 $tpl = get_markup_template("404.tpl");
273                 $a->page['content'] = replace_macros($tpl, array(
274                         '$message' =>  t('Page not found.' )
275                 ));
276         }
277 }
278
279 /**
280  * load current theme info
281  */
282 $theme_info_file = "view/theme/".current_theme()."/theme.php";
283 if (file_exists($theme_info_file)){
284         require_once($theme_info_file);
285 }
286
287
288 /* initialise content region */
289
290 if(! x($a->page,'content'))
291         $a->page['content'] = '';
292
293 if(!$install && !$maintenance)
294         call_hooks('page_content_top',$a->page['content']);
295
296 /**
297  * Call module functions
298  */
299
300 if($a->module_loaded) {
301         $a->page['page_title'] = $a->module;
302         $placeholder = '';
303
304         if(function_exists($a->module . '_init')) {
305                 call_hooks($a->module . '_mod_init', $placeholder);
306                 $func = $a->module . '_init';
307                 $func($a);
308         }
309
310         if(function_exists(str_replace('-','_',current_theme()) . '_init')) {
311                 $func = str_replace('-','_',current_theme()) . '_init';
312                 $func($a);
313         }
314 //      elseif (x($a->theme_info,"extends") && file_exists("view/theme/".$a->theme_info["extends"]."/theme.php")) {
315 //              require_once("view/theme/".$a->theme_info["extends"]."/theme.php");
316 //              if(function_exists(str_replace('-','_',$a->theme_info["extends"]) . '_init')) {
317 //                      $func = str_replace('-','_',$a->theme_info["extends"]) . '_init';
318 //                      $func($a);
319 //              }
320 //      }
321
322         if(($_SERVER['REQUEST_METHOD'] === 'POST') && (! $a->error)
323                 && (function_exists($a->module . '_post'))
324                 && (! x($_POST,'auth-params'))) {
325                 call_hooks($a->module . '_mod_post', $_POST);
326                 $func = $a->module . '_post';
327                 $func($a);
328         }
329
330         if((! $a->error) && (function_exists($a->module . '_afterpost'))) {
331                 call_hooks($a->module . '_mod_afterpost',$placeholder);
332                 $func = $a->module . '_afterpost';
333                 $func($a);
334         }
335
336         if((! $a->error) && (function_exists($a->module . '_content'))) {
337                 $arr = array('content' => $a->page['content']);
338                 call_hooks($a->module . '_mod_content', $arr);
339                 $a->page['content'] = $arr['content'];
340                 $func = $a->module . '_content';
341                 $arr = array('content' => $func($a));
342                 call_hooks($a->module . '_mod_aftercontent', $arr);
343                 $a->page['content'] .= $arr['content'];
344         }
345
346         if(function_exists(str_replace('-','_',current_theme()) . '_content_loaded')) {
347                 $func = str_replace('-','_',current_theme()) . '_content_loaded';
348                 $func($a);
349         }
350 }
351
352 /*
353  * Create the page head after setting the language
354  * and getting any auth credentials
355  *
356  * Moved init_pagehead() and init_page_end() to after
357  * all the module functions have executed so that all
358  * theme choices made by the modules can take effect
359  */
360
361 $a->init_pagehead();
362
363 /**
364  * Build the page ending -- this is stuff that goes right before
365  * the closing </body> tag
366  */
367
368 $a->init_page_end();
369
370 // If you're just visiting, let javascript take you home
371
372 if(x($_SESSION,'visitor_home'))
373         $homebase = $_SESSION['visitor_home'];
374 elseif(local_user())
375         $homebase = 'profile/' . $a->user['nickname'];
376
377 if(isset($homebase))
378         $a->page['content'] .= '<script>var homebase="' . $homebase . '" ; </script>';
379
380 // now that we've been through the module content, see if the page reported
381 // a permission problem and if so, a 403 response would seem to be in order.
382
383 if(stristr( implode("",$_SESSION['sysmsg']), t('Permission denied'))) {
384         header($_SERVER["SERVER_PROTOCOL"] . ' 403 ' . t('Permission denied.'));
385 }
386
387 /**
388  *
389  * Report anything which needs to be communicated in the notification area (before the main body)
390  *
391  */
392
393 /*if(x($_SESSION,'sysmsg')) {
394         $a->page['content'] = "<div id=\"sysmsg\" class=\"error-message\">{$_SESSION['sysmsg']}</div>\r\n"
395                 . ((x($a->page,'content')) ? $a->page['content'] : '');
396         $_SESSION['sysmsg']="";
397         unset($_SESSION['sysmsg']);
398 }
399 if(x($_SESSION,'sysmsg_info')) {
400         $a->page['content'] = "<div id=\"sysmsg_info\" class=\"info-message\">{$_SESSION['sysmsg_info']}</div>\r\n"
401                 . ((x($a->page,'content')) ? $a->page['content'] : '');
402         $_SESSION['sysmsg_info']="";
403         unset($_SESSION['sysmsg_info']);
404 }*/
405
406
407
408 call_hooks('page_end', $a->page['content']);
409
410
411 /**
412  *
413  * Add the navigation (menu) template
414  *
415  */
416
417 if($a->module != 'install' && $a->module != 'maintenance') {
418         nav($a);
419 }
420
421 /**
422  * Add a "toggle mobile" link if we're using a mobile device
423  */
424
425 if($a->is_mobile || $a->is_tablet) {
426         if(isset($_SESSION['show-mobile']) && !$_SESSION['show-mobile']) {
427                 $link = 'toggle_mobile?address=' . curPageURL();
428         }
429         else {
430                 $link = 'toggle_mobile?off=1&address=' . curPageURL();
431         }
432         $a->page['footer'] = replace_macros(get_markup_template("toggle_mobile_footer.tpl"), array(
433                                 '$toggle_link' => $link,
434                                 '$toggle_text' => t('toggle mobile')
435                          ));
436 }
437
438 /**
439  * Build the page - now that we have all the components
440  */
441
442 if(!$a->theme['stylesheet'])
443         $stylesheet = current_theme_url();
444 else
445         $stylesheet = $a->theme['stylesheet'];
446
447 $a->page['htmlhead'] = str_replace('{{$stylesheet}}',$stylesheet,$a->page['htmlhead']);
448 //$a->page['htmlhead'] = replace_macros($a->page['htmlhead'], array('$stylesheet' => $stylesheet));
449
450 if (isset($_GET["mode"]) AND (($_GET["mode"] == "raw") OR ($_GET["mode"] == "minimal"))) {
451         $doc = new DOMDocument();
452
453         $target = new DOMDocument();
454         $target->loadXML("<root></root>");
455
456         $content = mb_convert_encoding($a->page["content"], 'HTML-ENTITIES', "UTF-8");
457
458         @$doc->loadHTML($content);
459
460         $xpath = new DomXPath($doc);
461
462         $list = $xpath->query("//*[contains(@id,'tread-wrapper-')]");  /* */
463
464         foreach ($list as $item) {
465
466                 $item = $target->importNode($item, true);
467
468                 // And then append it to the target
469                 $target->documentElement->appendChild($item);
470         }
471 }
472
473 if (isset($_GET["mode"]) AND ($_GET["mode"] == "raw")) {
474
475         header("Content-type: text/html; charset=utf-8");
476
477         echo substr($target->saveHTML(), 6, -8);
478
479         session_write_close();
480         exit;
481
482 } elseif (get_pconfig(local_user(),'system','infinite_scroll')
483           AND ($a->module == "network") AND ($_GET["mode"] != "minimal")) {
484         if (is_string($_GET["page"]))
485                 $pageno = $_GET["page"];
486         else
487                 $pageno = 1;
488
489         $reload_uri = "";
490
491         foreach ($_GET AS $param => $value)
492                 if (($param != "page") AND ($param != "q"))
493                         $reload_uri .= "&".$param."=".urlencode($value);
494
495         if (($a->page_offset != "") AND !strstr($reload_uri, "&offset="))
496                 $reload_uri .= "&offset=".urlencode($a->page_offset);
497
498
499 $a->page['htmlhead'] .= <<< EOT
500 <script type="text/javascript">
501
502 $(document).ready(function() {
503     num = $pageno;
504 });
505
506 function loadcontent() {
507         if (lockLoadContent) return;
508         lockLoadContent = true;
509
510         $("#scroll-loader").fadeIn('normal');
511
512         num+=1;
513
514         console.log('Loading page ' + num);
515
516         $.get('/network?mode=raw$reload_uri&page=' + num, function(data) {
517                 $("#scroll-loader").hide();
518                 if ($(data).length > 0) {
519                         $(data).insertBefore('#conversation-end');
520                         lockLoadContent = false;
521                 } else {
522                         $("#scroll-end").fadeIn('normal');
523                 }
524         });
525 }
526
527 var num = $pageno;
528 var lockLoadContent = false;
529
530 $(window).scroll(function(e){
531
532         if ($(document).height() != $(window).height()) {
533                 // First method that is expected to work - but has problems with Chrome
534                 if ($(window).scrollTop() > ($(document).height() - $(window).height() * 1.5))
535                         loadcontent();
536         } else {
537                 // This method works with Chrome - but seems to be much slower in Firefox
538                 if ($(window).scrollTop() > (($("section").height() + $("header").height() + $("footer").height()) - $(window).height() * 1.5))
539                         loadcontent();
540         }
541 });
542 </script>
543
544 EOT;
545
546 }
547
548 $page    = $a->page;
549 $profile = $a->profile;
550
551 header("X-Friendica-Version: ".FRIENDICA_VERSION);
552 header("Content-type: text/html; charset=utf-8");
553
554
555 if (isset($_GET["mode"]) AND ($_GET["mode"] == "minimal")) {
556         //$page['content'] = substr($target->saveHTML(), 6, -8)."\n\n".
557         //                      '<div id="conversation-end"></div>'."\n\n";
558
559         require "view/minimal.php";
560 } else {
561         $template = 'view/theme/' . current_theme() . '/'
562                 . ((x($a->page,'template')) ? $a->page['template'] : 'default' ) . '.php';
563
564         if(file_exists($template))
565                 require_once($template);
566         else
567                 require_once(str_replace('theme/' . current_theme() . '/', '', $template));
568 }
569
570 session_write_close();
571 exit;