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.

2608 lines
68 KiB

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