Friendica Communications Platform (please note that this is a clone of the repository at github, issues are handled there) https://friendi.ca
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

2498 lines
65 KiB

11 years ago
11 years ago
10 years ago
6 years ago
5 years ago
11 years ago
10 years ago
11 years ago
11 years ago
10 years ago
11 years ago
10 years ago
10 years ago
11 years ago
10 years ago
10 years ago
10 years ago
9 years ago
11 years ago
11 years ago
11 years ago
11 years ago
10 years ago
9 years ago
9 years ago
9 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
11 years ago
11 years ago
11 years ago
11 years ago
10 years ago
11 years ago
11 years ago
6 years ago
6 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
9 years ago
11 years ago
11 years ago
6 years ago
10 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
6 years ago
6 years ago
11 years ago
  1. <?php
  2. /** @file boot.php
  3. *
  4. * This file defines some global constants and includes the central App class.
  5. */
  6. /**
  7. * Friendica
  8. *
  9. * Friendica is a communications platform for integrated social communications
  10. * utilising decentralised communications and linkage to several indie social
  11. * projects - as well as popular mainstream providers.
  12. *
  13. * Our mission is to free our friends and families from the clutches of
  14. * data-harvesting corporations, and pave the way to a future where social
  15. * communications are free and open and flow between alternate providers as
  16. * easily as email does today.
  17. */
  18. require_once('include/autoloader.php');
  19. require_once('include/config.php');
  20. require_once('include/network.php');
  21. require_once('include/plugin.php');
  22. require_once('include/text.php');
  23. require_once('include/datetime.php');
  24. require_once('include/pgettext.php');
  25. require_once('include/nav.php');
  26. require_once('include/cache.php');
  27. require_once('library/Mobile_Detect/Mobile_Detect.php');
  28. require_once('include/features.php');
  29. require_once('include/identity.php');
  30. require_once('include/pidfile.php');
  31. require_once('update.php');
  32. require_once('include/dbstructure.php');
  33. define ( 'FRIENDICA_PLATFORM', 'Friendica');
  34. define ( 'FRIENDICA_CODENAME', 'Asparagus');
  35. define ( 'FRIENDICA_VERSION', '3.5.1-dev' );
  36. define ( 'DFRN_PROTOCOL_VERSION', '2.23' );
  37. define ( 'DB_UPDATE_VERSION', 1208 );
  38. /**
  39. * @brief Constant with a HTML line break.
  40. *
  41. * Contains a HTML line break (br) element and a real carriage return with line
  42. * feed for the source.
  43. * This can be used in HTML and JavaScript where needed a line break.
  44. */
  45. define ( 'EOL', "<br />\r\n" );
  46. define ( 'ATOM_TIME', 'Y-m-d\TH:i:s\Z' );
  47. /**
  48. * @brief Image storage quality.
  49. *
  50. * Lower numbers save space at cost of image detail.
  51. * For ease of upgrade, please do not change here. Change jpeg quality with
  52. * $a->config['system']['jpeg_quality'] = n;
  53. * in .htconfig.php, where n is netween 1 and 100, and with very poor results
  54. * below about 50
  55. *
  56. */
  57. define ( 'JPEG_QUALITY', 100 );
  58. /**
  59. * $a->config['system']['png_quality'] from 0 (uncompressed) to 9
  60. */
  61. define ( 'PNG_QUALITY', 8 );
  62. /**
  63. *
  64. * An alternate way of limiting picture upload sizes. Specify the maximum pixel
  65. * length that pictures are allowed to be (for non-square pictures, it will apply
  66. * to the longest side). Pictures longer than this length will be resized to be
  67. * this length (on the longest side, the other side will be scaled appropriately).
  68. * Modify this value using
  69. *
  70. * $a->config['system']['max_image_length'] = n;
  71. *
  72. * in .htconfig.php
  73. *
  74. * If you don't want to set a maximum length, set to -1. The default value is
  75. * defined by 'MAX_IMAGE_LENGTH' below.
  76. *
  77. */
  78. define ( 'MAX_IMAGE_LENGTH', -1 );
  79. /**
  80. * Not yet used
  81. */
  82. define ( 'DEFAULT_DB_ENGINE', 'MyISAM' );
  83. /**
  84. * @name SSL Policy
  85. *
  86. * SSL redirection policies
  87. * @{
  88. */
  89. define ( 'SSL_POLICY_NONE', 0 );
  90. define ( 'SSL_POLICY_FULL', 1 );
  91. define ( 'SSL_POLICY_SELFSIGN', 2 );
  92. /* @}*/
  93. /**
  94. * @name Logger
  95. *
  96. * log levels
  97. * @{
  98. */
  99. define ( 'LOGGER_NORMAL', 0 );
  100. define ( 'LOGGER_TRACE', 1 );
  101. define ( 'LOGGER_DEBUG', 2 );
  102. define ( 'LOGGER_DATA', 3 );
  103. define ( 'LOGGER_ALL', 4 );
  104. /* @}*/
  105. /**
  106. * @name Cache
  107. *
  108. * Cache levels
  109. * @{
  110. */
  111. define ( 'CACHE_MONTH', 0 );
  112. define ( 'CACHE_WEEK', 1 );
  113. define ( 'CACHE_DAY', 2 );
  114. define ( 'CACHE_HOUR', 3 );
  115. define ( 'CACHE_HALF_HOUR', 4 );
  116. define ( 'CACHE_QUARTER_HOUR', 5 );
  117. define ( 'CACHE_FIVE_MINUTES', 6 );
  118. define ( 'CACHE_MINUTE', 7 );
  119. /* @}*/
  120. /**
  121. * @name Register
  122. *
  123. * Registration policies
  124. * @{
  125. */
  126. define ( 'REGISTER_CLOSED', 0 );
  127. define ( 'REGISTER_APPROVE', 1 );
  128. define ( 'REGISTER_OPEN', 2 );
  129. /** @}*/
  130. /**
  131. * @name Contact_is
  132. *
  133. * Relationship types
  134. * @{
  135. */
  136. define ( 'CONTACT_IS_FOLLOWER', 1);
  137. define ( 'CONTACT_IS_SHARING', 2);
  138. define ( 'CONTACT_IS_FRIEND', 3);
  139. /** @}*/
  140. /**
  141. * @name Update
  142. *
  143. * DB update return values
  144. * @{
  145. */
  146. define ( 'UPDATE_SUCCESS', 0);
  147. define ( 'UPDATE_FAILED', 1);
  148. /** @}*/
  149. /**
  150. * @name page/profile types
  151. *
  152. * PAGE_NORMAL is a typical personal profile account
  153. * PAGE_SOAPBOX automatically approves all friend requests as CONTACT_IS_SHARING, (readonly)
  154. * PAGE_COMMUNITY automatically approves all friend requests as CONTACT_IS_SHARING, but with
  155. * write access to wall and comments (no email and not included in page owner's ACL lists)
  156. * PAGE_FREELOVE automatically approves all friend requests as full friends (CONTACT_IS_FRIEND).
  157. *
  158. * @{
  159. */
  160. define ( 'PAGE_NORMAL', 0 );
  161. define ( 'PAGE_SOAPBOX', 1 );
  162. define ( 'PAGE_COMMUNITY', 2 );
  163. define ( 'PAGE_FREELOVE', 3 );
  164. define ( 'PAGE_BLOG', 4 );
  165. define ( 'PAGE_PRVGROUP', 5 );
  166. /** @}*/
  167. /**
  168. * @name account types
  169. *
  170. * ACCOUNT_TYPE_PERSON - the account belongs to a person
  171. * Associated page types: PAGE_NORMAL, PAGE_SOAPBOX, PAGE_FREELOVE
  172. *
  173. * ACCOUNT_TYPE_ORGANISATION - the account belongs to an organisation
  174. * Associated page type: PAGE_SOAPBOX
  175. *
  176. * ACCOUNT_TYPE_NEWS - the account is a news reflector
  177. * Associated page type: PAGE_SOAPBOX
  178. *
  179. * ACCOUNT_TYPE_COMMUNITY - the account is community forum
  180. * Associated page types: PAGE_COMMUNITY, PAGE_PRVGROUP
  181. * @{
  182. */
  183. define ( 'ACCOUNT_TYPE_PERSON', 0 );
  184. define ( 'ACCOUNT_TYPE_ORGANISATION',1 );
  185. define ( 'ACCOUNT_TYPE_NEWS', 2 );
  186. define ( 'ACCOUNT_TYPE_COMMUNITY', 3 );
  187. /** @}*/
  188. /**
  189. * @name CP
  190. *
  191. * Type of the community page
  192. * @{
  193. */
  194. define ( 'CP_NO_COMMUNITY_PAGE', -1 );
  195. define ( 'CP_USERS_ON_SERVER', 0 );
  196. define ( 'CP_GLOBAL_COMMUNITY', 1 );
  197. /** @}*/
  198. /**
  199. * @name Network
  200. *
  201. * Network and protocol family types
  202. * @{
  203. */
  204. define ( 'NETWORK_DFRN', 'dfrn'); // Friendica, Mistpark, other DFRN implementations
  205. define ( 'NETWORK_ZOT', 'zot!'); // Zot!
  206. define ( 'NETWORK_OSTATUS', 'stat'); // status.net, identi.ca, GNU-social, other OStatus implementations
  207. define ( 'NETWORK_FEED', 'feed'); // RSS/Atom feeds with no known "post/notify" protocol
  208. define ( 'NETWORK_DIASPORA', 'dspr'); // Diaspora
  209. define ( 'NETWORK_MAIL', 'mail'); // IMAP/POP
  210. define ( 'NETWORK_MAIL2', 'mai2'); // extended IMAP/POP
  211. define ( 'NETWORK_FACEBOOK', 'face'); // Facebook API
  212. define ( 'NETWORK_LINKEDIN', 'lnkd'); // LinkedIn
  213. define ( 'NETWORK_XMPP', 'xmpp'); // XMPP
  214. define ( 'NETWORK_MYSPACE', 'mysp'); // MySpace
  215. define ( 'NETWORK_GPLUS', 'goog'); // Google+
  216. define ( 'NETWORK_PUMPIO', 'pump'); // pump.io
  217. define ( 'NETWORK_TWITTER', 'twit'); // Twitter
  218. define ( 'NETWORK_DIASPORA2', 'dspc'); // Diaspora connector
  219. define ( 'NETWORK_STATUSNET', 'stac'); // Statusnet connector
  220. define ( 'NETWORK_APPNET', 'apdn'); // app.net
  221. define ( 'NETWORK_NEWS', 'nntp'); // Network News Transfer Protocol
  222. define ( 'NETWORK_ICALENDAR', 'ical'); // iCalendar
  223. define ( 'NETWORK_PHANTOM', 'unkn'); // Place holder
  224. /** @}*/
  225. /**
  226. * These numbers are used in stored permissions
  227. * and existing allocations MUST NEVER BE CHANGED
  228. * OR RE-ASSIGNED! You may only add to them.
  229. */
  230. $netgroup_ids = array(
  231. NETWORK_DFRN => (-1),
  232. NETWORK_ZOT => (-2),
  233. NETWORK_OSTATUS => (-3),
  234. NETWORK_FEED => (-4),
  235. NETWORK_DIASPORA => (-5),
  236. NETWORK_MAIL => (-6),
  237. NETWORK_MAIL2 => (-7),
  238. NETWORK_FACEBOOK => (-8),
  239. NETWORK_LINKEDIN => (-9),
  240. NETWORK_XMPP => (-10),
  241. NETWORK_MYSPACE => (-11),
  242. NETWORK_GPLUS => (-12),
  243. NETWORK_PUMPIO => (-13),
  244. NETWORK_TWITTER => (-14),
  245. NETWORK_DIASPORA2 => (-15),
  246. NETWORK_STATUSNET => (-16),
  247. NETWORK_APPNET => (-17),
  248. NETWORK_NEWS => (-18),
  249. NETWORK_ICALENDAR => (-19),
  250. NETWORK_PHANTOM => (-127),
  251. );
  252. /**
  253. * Maximum number of "people who like (or don't like) this" that we will list by name
  254. */
  255. define ( 'MAX_LIKERS', 75);
  256. /**
  257. * Communication timeout
  258. */
  259. define ( 'ZCURL_TIMEOUT' , (-1));
  260. /**
  261. * @name Notify
  262. *
  263. * Email notification options
  264. * @{
  265. */
  266. define ( 'NOTIFY_INTRO', 0x0001 );
  267. define ( 'NOTIFY_CONFIRM', 0x0002 );
  268. define ( 'NOTIFY_WALL', 0x0004 );
  269. define ( 'NOTIFY_COMMENT', 0x0008 );
  270. define ( 'NOTIFY_MAIL', 0x0010 );
  271. define ( 'NOTIFY_SUGGEST', 0x0020 );
  272. define ( 'NOTIFY_PROFILE', 0x0040 );
  273. define ( 'NOTIFY_TAGSELF', 0x0080 );
  274. define ( 'NOTIFY_TAGSHARE', 0x0100 );
  275. define ( 'NOTIFY_POKE', 0x0200 );
  276. define ( 'NOTIFY_SHARE', 0x0400 );
  277. define ( 'NOTIFY_SYSTEM', 0x8000 );
  278. /* @}*/
  279. /**
  280. * @name Term
  281. *
  282. * Tag/term types
  283. * @{
  284. */
  285. define ( 'TERM_UNKNOWN', 0 );
  286. define ( 'TERM_HASHTAG', 1 );
  287. define ( 'TERM_MENTION', 2 );
  288. define ( 'TERM_CATEGORY', 3 );
  289. define ( 'TERM_PCATEGORY', 4 );
  290. define ( 'TERM_FILE', 5 );
  291. define ( 'TERM_SAVEDSEARCH', 6 );
  292. define ( 'TERM_CONVERSATION', 7 );
  293. define ( 'TERM_OBJ_POST', 1 );
  294. define ( 'TERM_OBJ_PHOTO', 2 );
  295. /**
  296. * @name Namespaces
  297. *
  298. * Various namespaces we may need to parse
  299. * @{
  300. */
  301. define ( 'NAMESPACE_ZOT', 'http://purl.org/zot' );
  302. define ( 'NAMESPACE_DFRN' , 'http://purl.org/macgirvin/dfrn/1.0' );
  303. define ( 'NAMESPACE_THREAD' , 'http://purl.org/syndication/thread/1.0' );
  304. define ( 'NAMESPACE_TOMB' , 'http://purl.org/atompub/tombstones/1.0' );
  305. define ( 'NAMESPACE_ACTIVITY', 'http://activitystrea.ms/spec/1.0/' );
  306. define ( 'NAMESPACE_ACTIVITY_SCHEMA', 'http://activitystrea.ms/schema/1.0/' );
  307. define ( 'NAMESPACE_MEDIA', 'http://purl.org/syndication/atommedia' );
  308. define ( 'NAMESPACE_SALMON_ME', 'http://salmon-protocol.org/ns/magic-env' );
  309. define ( 'NAMESPACE_OSTATUSSUB', 'http://ostatus.org/schema/1.0/subscribe' );
  310. define ( 'NAMESPACE_GEORSS', 'http://www.georss.org/georss' );
  311. define ( 'NAMESPACE_POCO', 'http://portablecontacts.net/spec/1.0' );
  312. define ( 'NAMESPACE_FEED', 'http://schemas.google.com/g/2010#updates-from' );
  313. define ( 'NAMESPACE_OSTATUS', 'http://ostatus.org/schema/1.0' );
  314. define ( 'NAMESPACE_STATUSNET', 'http://status.net/schema/api/1/' );
  315. define ( 'NAMESPACE_ATOM1', 'http://www.w3.org/2005/Atom' );
  316. /* @}*/
  317. /**
  318. * @name Activity
  319. *
  320. * Activity stream defines
  321. * @{
  322. */
  323. define ( 'ACTIVITY_LIKE', NAMESPACE_ACTIVITY_SCHEMA . 'like' );
  324. define ( 'ACTIVITY_DISLIKE', NAMESPACE_DFRN . '/dislike' );
  325. define ( 'ACTIVITY_ATTEND', NAMESPACE_ZOT . '/activity/attendyes' );
  326. define ( 'ACTIVITY_ATTENDNO', NAMESPACE_ZOT . '/activity/attendno' );
  327. define ( 'ACTIVITY_ATTENDMAYBE', NAMESPACE_ZOT . '/activity/attendmaybe' );
  328. define ( 'ACTIVITY_OBJ_HEART', NAMESPACE_DFRN . '/heart' );
  329. define ( 'ACTIVITY_FRIEND', NAMESPACE_ACTIVITY_SCHEMA . 'make-friend' );
  330. define ( 'ACTIVITY_REQ_FRIEND', NAMESPACE_ACTIVITY_SCHEMA . 'request-friend' );
  331. define ( 'ACTIVITY_UNFRIEND', NAMESPACE_ACTIVITY_SCHEMA . 'remove-friend' );
  332. define ( 'ACTIVITY_FOLLOW', NAMESPACE_ACTIVITY_SCHEMA . 'follow' );
  333. define ( 'ACTIVITY_UNFOLLOW', NAMESPACE_ACTIVITY_SCHEMA . 'stop-following' );
  334. define ( 'ACTIVITY_JOIN', NAMESPACE_ACTIVITY_SCHEMA . 'join' );
  335. define ( 'ACTIVITY_POST', NAMESPACE_ACTIVITY_SCHEMA . 'post' );
  336. define ( 'ACTIVITY_UPDATE', NAMESPACE_ACTIVITY_SCHEMA . 'update' );
  337. define ( 'ACTIVITY_TAG', NAMESPACE_ACTIVITY_SCHEMA . 'tag' );
  338. define ( 'ACTIVITY_FAVORITE', NAMESPACE_ACTIVITY_SCHEMA . 'favorite' );
  339. define ( 'ACTIVITY_SHARE', NAMESPACE_ACTIVITY_SCHEMA . 'share' );
  340. define ( 'ACTIVITY_POKE', NAMESPACE_ZOT . '/activity/poke' );
  341. define ( 'ACTIVITY_MOOD', NAMESPACE_ZOT . '/activity/mood' );
  342. define ( 'ACTIVITY_OBJ_BOOKMARK', NAMESPACE_ACTIVITY_SCHEMA . 'bookmark' );
  343. define ( 'ACTIVITY_OBJ_COMMENT', NAMESPACE_ACTIVITY_SCHEMA . 'comment' );
  344. define ( 'ACTIVITY_OBJ_NOTE', NAMESPACE_ACTIVITY_SCHEMA . 'note' );
  345. define ( 'ACTIVITY_OBJ_PERSON', NAMESPACE_ACTIVITY_SCHEMA . 'person' );
  346. define ( 'ACTIVITY_OBJ_IMAGE', NAMESPACE_ACTIVITY_SCHEMA . 'image' );
  347. define ( 'ACTIVITY_OBJ_PHOTO', NAMESPACE_ACTIVITY_SCHEMA . 'photo' );
  348. define ( 'ACTIVITY_OBJ_VIDEO', NAMESPACE_ACTIVITY_SCHEMA . 'video' );
  349. define ( 'ACTIVITY_OBJ_P_PHOTO', NAMESPACE_ACTIVITY_SCHEMA . 'profile-photo' );
  350. define ( 'ACTIVITY_OBJ_ALBUM', NAMESPACE_ACTIVITY_SCHEMA . 'photo-album' );
  351. define ( 'ACTIVITY_OBJ_EVENT', NAMESPACE_ACTIVITY_SCHEMA . 'event' );
  352. define ( 'ACTIVITY_OBJ_GROUP', NAMESPACE_ACTIVITY_SCHEMA . 'group' );
  353. define ( 'ACTIVITY_OBJ_TAGTERM', NAMESPACE_DFRN . '/tagterm' );
  354. define ( 'ACTIVITY_OBJ_PROFILE', NAMESPACE_DFRN . '/profile' );
  355. define ( 'ACTIVITY_OBJ_QUESTION', 'http://activityschema.org/object/question' );
  356. /* @}*/
  357. /**
  358. * @name Gravity
  359. *
  360. * Item weight for query ordering
  361. * @{
  362. */
  363. define ( 'GRAVITY_PARENT', 0);
  364. define ( 'GRAVITY_LIKE', 3);
  365. define ( 'GRAVITY_COMMENT', 6);
  366. /* @}*/
  367. /**
  368. * @name Priority
  369. *
  370. * Process priority for the worker
  371. * @{
  372. */
  373. define('PRIORITY_UNDEFINED', 0);
  374. define('PRIORITY_CRITICAL', 10);
  375. define('PRIORITY_HIGH', 20);
  376. define('PRIORITY_MEDIUM', 30);
  377. define('PRIORITY_LOW', 40);
  378. define('PRIORITY_NEGLIGIBLE',50);
  379. /* @}*/
  380. // Normally this constant is defined - but not if "pcntl" isn't installed
  381. if (!defined("SIGTERM"))
  382. define("SIGTERM", 15);
  383. /**
  384. *
  385. * Reverse the effect of magic_quotes_gpc if it is enabled.
  386. * Please disable magic_quotes_gpc so we don't have to do this.
  387. * See http://php.net/manual/en/security.magicquotes.disabling.php
  388. *
  389. */
  390. function startup() {
  391. error_reporting(E_ERROR | E_WARNING | E_PARSE);
  392. set_time_limit(0);
  393. // This has to be quite large to deal with embedded private photos
  394. ini_set('pcre.backtrack_limit', 500000);
  395. if (get_magic_quotes_gpc()) {
  396. $process = array(&$_GET, &$_POST, &$_COOKIE, &$_REQUEST);
  397. while (list($key, $val) = each($process)) {
  398. foreach ($val as $k => $v) {
  399. unset($process[$key][$k]);
  400. if (is_array($v)) {
  401. $process[$key][stripslashes($k)] = $v;
  402. $process[] = &$process[$key][stripslashes($k)];
  403. } else {
  404. $process[$key][stripslashes($k)] = stripslashes($v);
  405. }
  406. }
  407. }
  408. unset($process);
  409. }
  410. }
  411. /**
  412. *
  413. * class: App
  414. *
  415. * @brief Our main application structure for the life of this page.
  416. *
  417. * Primarily deals with the URL that got us here
  418. * and tries to make some sense of it, and
  419. * stores our page contents and config storage
  420. * and anything else that might need to be passed around
  421. * before we spit the page out.
  422. *
  423. */
  424. class App {
  425. public $module_loaded = false;
  426. public $query_string;
  427. public $config;
  428. public $page;
  429. public $profile;
  430. public $profile_uid;
  431. public $user;
  432. public $cid;
  433. public $contact;
  434. public $contacts;
  435. public $page_contact;
  436. public $content;
  437. public $data = array();
  438. public $error = false;
  439. public $cmd;
  440. public $argv;
  441. public $argc;
  442. public $module;
  443. public $pager;
  444. public $strings;
  445. public $path;
  446. public $hooks;
  447. public $timezone;
  448. public $interactive = true;
  449. public $plugins;
  450. public $apps = array();
  451. public $identities;
  452. public $is_mobile = false;
  453. public $is_tablet = false;
  454. public $is_friendica_app;
  455. public $performance = array();
  456. public $callstack = array();
  457. public $theme_info = array();
  458. public $backend = true;
  459. public $nav_sel;
  460. public $category;
  461. // Allow themes to control internal parameters
  462. // by changing App values in theme.php
  463. public $sourcename = '';
  464. public $videowidth = 425;
  465. public $videoheight = 350;
  466. public $force_max_items = 0;
  467. public $theme_thread_allow = true;
  468. public $theme_events_in_profile = true;
  469. /**
  470. * @brief An array for all theme-controllable parameters
  471. *
  472. * Mostly unimplemented yet. Only options 'template_engine' and
  473. * beyond are used.
  474. */
  475. public $theme = array(
  476. 'sourcename' => '',
  477. 'videowidth' => 425,
  478. 'videoheight' => 350,
  479. 'force_max_items' => 0,
  480. 'thread_allow' => true,
  481. 'stylesheet' => '',
  482. 'template_engine' => 'smarty3',
  483. );
  484. /**
  485. * @brief An array of registered template engines ('name'=>'class name')
  486. */
  487. public $template_engines = array();
  488. /**
  489. * @brief An array of instanced template engines ('name'=>'instance')
  490. */
  491. public $template_engine_instance = array();
  492. public $process_id;
  493. private $ldelim = array(
  494. 'internal' => '',
  495. 'smarty3' => '{{'
  496. );
  497. private $rdelim = array(
  498. 'internal' => '',
  499. 'smarty3' => '}}'
  500. );
  501. private $scheme;
  502. private $hostname;
  503. private $baseurl;
  504. private $db;
  505. private $curl_code;
  506. private $curl_content_type;
  507. private $curl_headers;
  508. private $cached_profile_image;
  509. private $cached_profile_picdate;
  510. private static $a;
  511. /**
  512. * @brief App constructor.
  513. */
  514. function __construct() {
  515. global $default_timezone;
  516. $hostname = "";
  517. if (file_exists(".htpreconfig.php"))
  518. @include(".htpreconfig.php");
  519. $this->timezone = ((x($default_timezone)) ? $default_timezone : 'UTC');
  520. date_default_timezone_set($this->timezone);
  521. $this->performance["start"] = microtime(true);
  522. $this->performance["database"] = 0;
  523. $this->performance["database_write"] = 0;
  524. $this->performance["network"] = 0;
  525. $this->performance["file"] = 0;
  526. $this->performance["rendering"] = 0;
  527. $this->performance["parser"] = 0;
  528. $this->performance["marktime"] = 0;
  529. $this->performance["markstart"] = microtime(true);
  530. $this->callstack["database"] = array();
  531. $this->callstack["network"] = array();
  532. $this->callstack["file"] = array();
  533. $this->callstack["rendering"] = array();
  534. $this->callstack["parser"] = array();
  535. $this->config = array();
  536. $this->page = array();
  537. $this->pager= array();
  538. $this->query_string = '';
  539. $this->process_id = uniqid("log", true);
  540. startup();
  541. set_include_path(
  542. 'include' . PATH_SEPARATOR
  543. . 'library' . PATH_SEPARATOR
  544. . 'library/phpsec' . PATH_SEPARATOR
  545. . 'library/langdet' . PATH_SEPARATOR
  546. . '.' );
  547. $this->scheme = 'http';
  548. if((x($_SERVER,'HTTPS') && $_SERVER['HTTPS']) ||
  549. (x($_SERVER['HTTP_FORWARDED']) && preg_match("/proto=https/", $_SERVER['HTTP_FORWARDED'])) ||
  550. (x($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https') ||
  551. (x($_SERVER['HTTP_X_FORWARDED_SSL']) && $_SERVER['HTTP_X_FORWARDED_SSL'] == 'on') ||
  552. (x($_SERVER['FRONT_END_HTTPS']) && $_SERVER['FRONT_END_HTTPS'] == 'on') ||
  553. (x($_SERVER,'SERVER_PORT') && (intval($_SERVER['SERVER_PORT']) == 443)) // XXX: reasonable assumption, but isn't this hardcoding too much?
  554. ) {
  555. $this->scheme = 'https';
  556. }
  557. if(x($_SERVER,'SERVER_NAME')) {
  558. $this->hostname = $_SERVER['SERVER_NAME'];
  559. if(x($_SERVER,'SERVER_PORT') && $_SERVER['SERVER_PORT'] != 80 && $_SERVER['SERVER_PORT'] != 443)
  560. $this->hostname .= ':' . $_SERVER['SERVER_PORT'];
  561. /*
  562. * Figure out if we are running at the top of a domain
  563. * or in a sub-directory and adjust accordingly
  564. */
  565. $path = trim(dirname($_SERVER['SCRIPT_NAME']),'/\\');
  566. if(isset($path) && strlen($path) && ($path != $this->path))
  567. $this->path = $path;
  568. }
  569. if ($hostname != "")
  570. $this->hostname = $hostname;
  571. if (is_array($_SERVER["argv"]) && $_SERVER["argc"]>1 && substr(end($_SERVER["argv"]), 0, 4)=="http" ) {
  572. $this->set_baseurl(array_pop($_SERVER["argv"]) );
  573. $_SERVER["argc"] --;
  574. }
  575. #set_include_path("include/$this->hostname" . PATH_SEPARATOR . get_include_path());
  576. if((x($_SERVER,'QUERY_STRING')) && substr($_SERVER['QUERY_STRING'],0,9) === "pagename=") {
  577. $this->query_string = substr($_SERVER['QUERY_STRING'],9);
  578. // removing trailing / - maybe a nginx problem
  579. if (substr($this->query_string, 0, 1) == "/")
  580. $this->query_string = substr($this->query_string, 1);
  581. } elseif((x($_SERVER,'QUERY_STRING')) && substr($_SERVER['QUERY_STRING'],0,2) === "q=") {
  582. $this->query_string = substr($_SERVER['QUERY_STRING'],2);
  583. // removing trailing / - maybe a nginx problem
  584. if (substr($this->query_string, 0, 1) == "/")
  585. $this->query_string = substr($this->query_string, 1);
  586. }
  587. if (x($_GET,'pagename'))
  588. $this->cmd = trim($_GET['pagename'],'/\\');
  589. elseif (x($_GET,'q'))
  590. $this->cmd = trim($_GET['q'],'/\\');
  591. // fix query_string
  592. $this->query_string = str_replace($this->cmd."&",$this->cmd."?", $this->query_string);
  593. // unix style "homedir"
  594. if(substr($this->cmd,0,1) === '~')
  595. $this->cmd = 'profile/' . substr($this->cmd,1);
  596. // Diaspora style profile url
  597. if(substr($this->cmd,0,2) === 'u/')
  598. $this->cmd = 'profile/' . substr($this->cmd,2);
  599. /*
  600. *
  601. * Break the URL path into C style argc/argv style arguments for our
  602. * modules. Given "http://example.com/module/arg1/arg2", $this->argc
  603. * will be 3 (integer) and $this->argv will contain:
  604. * [0] => 'module'
  605. * [1] => 'arg1'
  606. * [2] => 'arg2'
  607. *
  608. *
  609. * There will always be one argument. If provided a naked domain
  610. * URL, $this->argv[0] is set to "home".
  611. *
  612. */
  613. $this->argv = explode('/',$this->cmd);
  614. $this->argc = count($this->argv);
  615. if((array_key_exists('0',$this->argv)) && strlen($this->argv[0])) {
  616. $this->module = str_replace(".", "_", $this->argv[0]);
  617. $this->module = str_replace("-", "_", $this->module);
  618. }
  619. else {
  620. $this->argc = 1;
  621. $this->argv = array('home');
  622. $this->module = 'home';
  623. }
  624. /*
  625. * See if there is any page number information, and initialise
  626. * pagination
  627. */
  628. $this->pager['page'] = ((x($_GET,'page') && intval($_GET['page']) > 0) ? intval($_GET['page']) : 1);
  629. $this->pager['itemspage'] = 50;
  630. $this->pager['start'] = ($this->pager['page'] * $this->pager['itemspage']) - $this->pager['itemspage'];
  631. if($this->pager['start'] < 0)
  632. $this->pager['start'] = 0;
  633. $this->pager['total'] = 0;
  634. /*
  635. * Detect mobile devices
  636. */
  637. $mobile_detect = new Mobile_Detect();
  638. $this->is_mobile = $mobile_detect->isMobile();
  639. $this->is_tablet = $mobile_detect->isTablet();
  640. // Friendica-Client
  641. $this->is_friendica_app = ($_SERVER['HTTP_USER_AGENT'] == "Apache-HttpClient/UNAVAILABLE (java 1.4)");
  642. /*
  643. * register template engines
  644. */
  645. $dc = get_declared_classes();
  646. foreach ($dc as $k) {
  647. if (in_array("ITemplateEngine", class_implements($k))){
  648. $this->register_template_engine($k);
  649. }
  650. }
  651. self::$a = $this;
  652. }
  653. function get_basepath() {
  654. $basepath = get_config("system", "basepath");
  655. if ($basepath == "")
  656. $basepath = dirname(__FILE__);
  657. if ($basepath == "")
  658. $basepath = $_SERVER["DOCUMENT_ROOT"];
  659. if ($basepath == "")
  660. $basepath = $_SERVER["PWD"];
  661. return($basepath);
  662. }
  663. function get_scheme() {
  664. return($this->scheme);
  665. }
  666. /**
  667. * @brief Retrieves the Friendica instance base URL
  668. *
  669. * This function assembles the base URL from multiple parts:
  670. * - Protocol is determined either by the request or a combination of
  671. * system.ssl_policy and the $ssl parameter.
  672. * - Host name is determined either by system.hostname or inferred from request
  673. * - Path is inferred from SCRIPT_NAME
  674. *
  675. * Caches the result (depending on $ssl value) for performance.
  676. *
  677. * Note: $ssl parameter value doesn't directly correlate with the resulting protocol
  678. *
  679. * @param bool $ssl Whether to append http or https under SSL_POLICY_SELFSIGN
  680. * @return string Friendica server base URL
  681. */
  682. function get_baseurl($ssl = false) {
  683. // Is the function called statically?
  684. if (!is_object($this)) {
  685. return self::$a->get_baseurl($ssl);
  686. }
  687. // Arbitrary values, the resulting url protocol can be different
  688. $cache_index = $ssl ? 'https' : 'http';
  689. // Cached value found, nothing to process
  690. if (isset($this->baseurl[$cache_index])) {
  691. return $this->baseurl[$cache_index];
  692. }
  693. $scheme = $this->scheme;
  694. if ((x($this->config, 'system')) && (x($this->config['system'], 'ssl_policy'))) {
  695. if (intval($this->config['system']['ssl_policy']) === SSL_POLICY_FULL) {
  696. $scheme = 'https';
  697. }
  698. // Basically, we have $ssl = true on any links which can only be seen by a logged in user
  699. // (and also the login link). Anything seen by an outsider will have it turned off.
  700. if ($this->config['system']['ssl_policy'] == SSL_POLICY_SELFSIGN) {
  701. if ($ssl) {
  702. $scheme = 'https';
  703. } else {
  704. $scheme = 'http';
  705. }
  706. }
  707. }
  708. if (get_config('config', 'hostname') != '') {
  709. $this->hostname = get_config('config', 'hostname');
  710. }
  711. $this->baseurl[$cache_index] = $scheme . "://" . $this->hostname . ((isset($this->path) && strlen($this->path)) ? '/' . $this->path : '' );
  712. return $this->baseurl[$cache_index];
  713. }
  714. /**
  715. * @brief Initializes the baseurl components
  716. *
  717. * Clears the baseurl cache to prevent inconstistencies
  718. *
  719. * @param string $url
  720. */
  721. function set_baseurl($url) {
  722. $parsed = @parse_url($url);
  723. $this->baseurl = [];
  724. if($parsed) {
  725. $this->scheme = $parsed['scheme'];
  726. $hostname = $parsed['host'];
  727. if (x($parsed, 'port')) {
  728. $hostname .= ':' . $parsed['port'];
  729. }
  730. if (x($parsed, 'path')) {
  731. $this->path = trim($parsed['path'], '\\/');
  732. }
  733. if (file_exists(".htpreconfig.php")) {
  734. @include(".htpreconfig.php");
  735. }
  736. if (get_config('config', 'hostname') != '') {
  737. $this->hostname = get_config('config', 'hostname');
  738. }
  739. if (!isset($this->hostname) OR ($this->hostname == '')) {
  740. $this->hostname = $hostname;
  741. }
  742. }
  743. }
  744. function get_hostname() {
  745. if (get_config('config','hostname') != "")
  746. $this->hostname = get_config('config','hostname');
  747. return $this->hostname;
  748. }
  749. function set_hostname($h) {
  750. $this->hostname = $h;
  751. }
  752. function set_path($p) {
  753. $this->path = trim(trim($p),'/');
  754. }
  755. function get_path() {
  756. return $this->path;
  757. }
  758. function set_pager_total($n) {
  759. $this->pager['total'] = intval($n);
  760. }
  761. function set_pager_itemspage($n) {
  762. $this->pager['itemspage'] = ((intval($n) > 0) ? intval($n) : 0);
  763. $this->pager['start'] = ($this->pager['page'] * $this->pager['itemspage']) - $this->pager['itemspage'];
  764. }
  765. function set_pager_page($n) {
  766. $this->pager['page'] = $n;
  767. $this->pager['start'] = ($this->pager['page'] * $this->pager['itemspage']) - $this->pager['itemspage'];
  768. }
  769. function init_pagehead() {
  770. $interval = ((local_user()) ? get_pconfig(local_user(),'system','update_interval') : 40000);
  771. // If the update is "deactivated" set it to the highest integer number (~24 days)
  772. if ($interval < 0)
  773. $interval = 2147483647;
  774. if($interval < 10000)
  775. $interval = 40000;
  776. // compose the page title from the sitename and the
  777. // current module called
  778. if (!$this->module=='')
  779. {
  780. $this->page['title'] = $this->config['sitename'].' ('.$this->module.')';
  781. } else {
  782. $this->page['title'] = $this->config['sitename'];
  783. }
  784. /* put the head template at the beginning of page['htmlhead']
  785. * since the code added by the modules frequently depends on it
  786. * being first
  787. */
  788. if(!isset($this->page['htmlhead']))
  789. $this->page['htmlhead'] = '';
  790. // If we're using Smarty, then doing replace_macros() will replace
  791. // any unrecognized variables with a blank string. Since we delay
  792. // replacing $stylesheet until later, we need to replace it now
  793. // with another variable name
  794. if($this->theme[