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.

2427 lines
67 KiB

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