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.

932 lines
27 KiB

4 years ago
4 years ago
  1. <?php
  2. /**
  3. * @file include/identity.php
  4. */
  5. use Friendica\App;
  6. require_once 'include/ForumManager.php';
  7. require_once 'include/bbcode.php';
  8. require_once 'mod/proxy.php';
  9. require_once 'include/cache.php';
  10. /**
  11. *
  12. * @brief Loads a profile into the page sidebar.
  13. *
  14. * The function requires a writeable copy of the main App structure, and the nickname
  15. * of a registered local account.
  16. *
  17. * If the viewer is an authenticated remote viewer, the profile displayed is the
  18. * one that has been configured for his/her viewing in the Contact manager.
  19. * Passing a non-zero profile ID can also allow a preview of a selected profile
  20. * by the owner.
  21. *
  22. * Profile information is placed in the App structure for later retrieval.
  23. * Honours the owner's chosen theme for display.
  24. *
  25. * @attention Should only be run in the _init() functions of a module. That ensures that
  26. * the theme is chosen before the _init() function of a theme is run, which will usually
  27. * load a lot of theme-specific content
  28. *
  29. * @param App $a
  30. * @param string $nickname
  31. * @param int $profile
  32. * @param array $profiledata
  33. */
  34. function profile_load(App $a, $nickname, $profile = 0, $profiledata = array()) {
  35. $user = q("SELECT `uid` FROM `user` WHERE `nickname` = '%s' LIMIT 1",
  36. dbesc($nickname)
  37. );
  38. if (!$user && count($user) && !count($profiledata)) {
  39. logger('profile error: ' . $a->query_string, LOGGER_DEBUG);
  40. notice( t('Requested account is not available.') . EOL );
  41. $a->error = 404;
  42. return;
  43. }
  44. $pdata = get_profiledata_by_nick($nickname, $user[0]['uid'], $profile);
  45. if (($pdata === false) || (!count($pdata)) && !count($profiledata)) {
  46. logger('profile error: ' . $a->query_string, LOGGER_DEBUG);
  47. notice( t('Requested profile is not available.') . EOL );
  48. $a->error = 404;
  49. return;
  50. }
  51. // fetch user tags if this isn't the default profile
  52. if (!$pdata['is-default']) {
  53. $x = q("SELECT `pub_keywords` FROM `profile` WHERE `uid` = %d AND `is-default` = 1 LIMIT 1",
  54. intval($pdata['profile_uid'])
  55. );
  56. if ($x && count($x))
  57. $pdata['pub_keywords'] = $x[0]['pub_keywords'];
  58. }
  59. $a->profile = $pdata;
  60. $a->profile_uid = $pdata['profile_uid'];
  61. $a->profile['mobile-theme'] = get_pconfig($a->profile['profile_uid'], 'system', 'mobile_theme');
  62. $a->profile['network'] = NETWORK_DFRN;
  63. $a->page['title'] = $a->profile['name'] . " @ " . $a->config['sitename'];
  64. if (!$profiledata && !get_pconfig(local_user(),'system','always_my_theme'))
  65. $_SESSION['theme'] = $a->profile['theme'];
  66. $_SESSION['mobile-theme'] = $a->profile['mobile-theme'];
  67. /*
  68. * load/reload current theme info
  69. */
  70. $a->set_template_engine(); // reset the template engine to the default in case the user's theme doesn't specify one
  71. $theme_info_file = "view/theme/" . current_theme() . "/theme.php";
  72. if (file_exists($theme_info_file)) {
  73. require_once $theme_info_file;
  74. }
  75. if (! (x($a->page,'aside')))
  76. $a->page['aside'] = '';
  77. if (local_user() && local_user() == $a->profile['uid'] && $profiledata) {
  78. $a->page['aside'] .= replace_macros(get_markup_template('profile_edlink.tpl'),array(
  79. '$editprofile' => t('Edit profile'),
  80. '$profid' => $a->profile['id']
  81. ));
  82. }
  83. $block = (((get_config('system','block_public')) && (! local_user()) && (! remote_user())) ? true : false);
  84. /**
  85. * @todo
  86. * By now, the contact block isn't shown, when a different profile is given
  87. * But: When this profile was on the same server, then we could display the contacts
  88. */
  89. if ($profiledata)
  90. $a->page['aside'] .= profile_sidebar($profiledata, true);
  91. else
  92. $a->page['aside'] .= profile_sidebar($a->profile, $block);
  93. /*if (! $block)
  94. $a->page['aside'] .= contact_block();*/
  95. return;
  96. }
  97. /**
  98. * @brief Get all profil data of a local user
  99. *
  100. * If the viewer is an authenticated remote viewer, the profile displayed is the
  101. * one that has been configured for his/her viewing in the Contact manager.
  102. * Passing a non-zero profile ID can also allow a preview of a selected profile
  103. * by the owner
  104. *
  105. * @param string $nickname
  106. * @param int $uid
  107. * @param int $profile
  108. * ID of the profile
  109. * @returns array
  110. * Includes all available profile data
  111. */
  112. function get_profiledata_by_nick($nickname, $uid = 0, $profile = 0) {
  113. if (remote_user() && count($_SESSION['remote'])) {
  114. foreach ($_SESSION['remote'] as $visitor) {
  115. if ($visitor['uid'] == $uid) {
  116. $r = dba::select('contact', array('profile-id'), array('id' => $visitor['cid']), array('limit' => 1));
  117. if (dbm::is_result($r)) {
  118. $profile = $r['profile-id'];
  119. }
  120. break;
  121. }
  122. }
  123. }
  124. $r = null;
  125. if ($profile) {
  126. $profile_int = intval($profile);
  127. $r = dba::fetch_first("SELECT `contact`.`id` AS `contact_id`, `contact`.`photo` AS `contact_photo`,
  128. `contact`.`thumb` AS `contact_thumb`, `contact`.`micro` AS `contact_micro`,
  129. `profile`.`uid` AS `profile_uid`, `profile`.*,
  130. `contact`.`avatar-date` AS picdate, `contact`.`addr`, `user`.*
  131. FROM `profile`
  132. INNER JOIN `contact` on `contact`.`uid` = `profile`.`uid` AND `contact`.`self`
  133. INNER JOIN `user` ON `profile`.`uid` = `user`.`uid`
  134. WHERE `user`.`nickname` = ? AND `profile`.`id` = ? LIMIT 1",
  135. $nickname,
  136. $profile_int
  137. );
  138. }
  139. if (!dbm::is_result($r)) {
  140. $r = dba::fetch_first("SELECT `contact`.`id` AS `contact_id`, `contact`.`photo` as `contact_photo`,
  141. `contact`.`thumb` AS `contact_thumb`, `contact`.`micro` AS `contact_micro`,
  142. `profile`.`uid` AS `profile_uid`, `profile`.*,
  143. `contact`.`avatar-date` AS picdate, `contact`.`addr`, `user`.*
  144. FROM `profile`
  145. INNER JOIN `contact` ON `contact`.`uid` = `profile`.`uid` AND `contact`.`self`
  146. INNER JOIN `user` ON `profile`.`uid` = `user`.`uid`
  147. WHERE `user`.`nickname` = ? AND `profile`.`is-default` LIMIT 1",
  148. $nickname
  149. );
  150. }
  151. return $r;
  152. }
  153. /**
  154. * @brief Formats a profile for display in the sidebar.
  155. *
  156. * It is very difficult to templatise the HTML completely
  157. * because of all the conditional logic.
  158. *
  159. * @param array $profile
  160. * @param int $block
  161. *
  162. * @return HTML string stuitable for sidebar inclusion
  163. *
  164. * @note Returns empty string if passed $profile is wrong type or not populated
  165. *
  166. * @hooks 'profile_sidebar_enter'
  167. * array $profile - profile data
  168. * @hooks 'profile_sidebar'
  169. * array $arr
  170. */
  171. function profile_sidebar($profile, $block = 0) {
  172. $a = get_app();
  173. $o = '';
  174. $location = false;
  175. $address = false;
  176. // $pdesc = true;
  177. // This function can also use contact information in $profile
  178. $is_contact = x($profile, 'cid');
  179. if ((! is_array($profile)) && (! count($profile))) {
  180. return $o;
  181. }
  182. $profile['picdate'] = urlencode($profile['picdate']);
  183. if (($profile['network'] != "") && ($profile['network'] != NETWORK_DFRN)) {
  184. $profile['network_name'] = format_network_name($profile['network'], $profile['url']);
  185. } else {
  186. $profile['network_name'] = "";
  187. }
  188. call_hooks('profile_sidebar_enter', $profile);
  189. // don't show connect link to yourself
  190. $connect = (($profile['uid'] != local_user()) ? t('Connect') : False);
  191. // don't show connect link to authenticated visitors either
  192. if (remote_user() && count($_SESSION['remote'])) {
  193. foreach ($_SESSION['remote'] as $visitor) {
  194. if ($visitor['uid'] == $profile['uid']) {
  195. $connect = false;
  196. break;
  197. }
  198. }
  199. }
  200. // Is the local user already connected to that user?
  201. if ($connect && local_user()) {
  202. if (isset($profile["url"])) {
  203. $profile_url = normalise_link($profile["url"]);
  204. } else {
  205. $profile_url = normalise_link(App::get_baseurl()."/profile/".$profile["nickname"]);
  206. }
  207. $connect = !dba::exists('contact', array('pending' => false, 'uid' => local_user(), 'nurl' => $profile_url));
  208. }
  209. if ($connect && ($profile['network'] != NETWORK_DFRN) && !isset($profile['remoteconnect']))
  210. $connect = false;
  211. $remoteconnect = NULL;
  212. if (isset($profile['remoteconnect']))
  213. $remoteconnect = $profile['remoteconnect'];
  214. if ($connect && ($profile['network'] == NETWORK_DFRN) && !isset($remoteconnect))
  215. $subscribe_feed = t("Atom feed");
  216. else
  217. $subscribe_feed = false;
  218. if (remote_user() || (get_my_url() && $profile['unkmail'] && ($profile['uid'] != local_user()))) {
  219. $wallmessage = t('Message');
  220. $wallmessage_link = "wallmessage/".$profile["nickname"];
  221. if (remote_user()) {
  222. $r = q("SELECT `url` FROM `contact` WHERE `uid` = %d AND `id` = '%s' AND `rel` = %d",
  223. intval($profile['uid']),
  224. intval(remote_user()),
  225. intval(CONTACT_IS_FRIEND));
  226. } else {
  227. $r = q("SELECT `url` FROM `contact` WHERE `uid` = %d AND `nurl` = '%s' AND `rel` = %d",
  228. intval($profile['uid']),
  229. dbesc(normalise_link(get_my_url())),
  230. intval(CONTACT_IS_FRIEND));
  231. }
  232. if ($r) {
  233. $remote_url = $r[0]["url"];
  234. $message_path = preg_replace("=(.*)/profile/(.*)=ism", "$1/message/new/", $remote_url);
  235. $wallmessage_link = $message_path.base64_encode($profile["addr"]);
  236. }
  237. } else {
  238. $wallmessage = false;
  239. $wallmessage_link = false;
  240. }
  241. // show edit profile to yourself
  242. if (!$is_contact && $profile['uid'] == local_user() && feature_enabled(local_user(),'multi_profiles')) {
  243. $profile['edit'] = array(App::get_baseurl(). '/profiles', t('Profiles'),"", t('Manage/edit profiles'));
  244. $r = q("SELECT * FROM `profile` WHERE `uid` = %d",
  245. local_user());
  246. $profile['menu'] = array(
  247. 'chg_photo' => t('Change profile photo'),
  248. 'cr_new' => t('Create New Profile'),
  249. 'entries' => array(),
  250. );
  251. if (dbm::is_result($r)) {
  252. foreach ($r as $rr) {
  253. $profile['menu']['entries'][] = array(
  254. 'photo' => $rr['thumb'],
  255. 'id' => $rr['id'],
  256. 'alt' => t('Profile Image'),
  257. 'profile_name' => $rr['profile-name'],
  258. 'isdefault' => $rr['is-default'],
  259. 'visibile_to_everybody' => t('visible to everybody'),
  260. 'edit_visibility' => t('Edit visibility'),
  261. );
  262. }
  263. }
  264. }
  265. if (!$is_contact && $profile['uid'] == local_user() && !feature_enabled(local_user(),'multi_profiles')) {
  266. $profile['edit'] = array(App::get_baseurl(). '/profiles/'.$profile['id'], t('Edit profile'),"", t('Edit profile'));
  267. $profile['menu'] = array(
  268. 'chg_photo' => t('Change profile photo'),
  269. 'cr_new' => null,
  270. 'entries' => array(),
  271. );
  272. }
  273. // Fetch the account type
  274. $account_type = account_type($profile);
  275. if ((x($profile,'address') == 1)
  276. || (x($profile,'location') == 1)
  277. || (x($profile,'locality') == 1)
  278. || (x($profile,'region') == 1)
  279. || (x($profile,'postal-code') == 1)
  280. || (x($profile,'country-name') == 1))
  281. $location = t('Location:');
  282. $gender = ((x($profile,'gender') == 1) ? t('Gender:') : False);
  283. $marital = ((x($profile,'marital') == 1) ? t('Status:') : False);
  284. $homepage = ((x($profile,'homepage') == 1) ? t('Homepage:') : False);
  285. $about = ((x($profile,'about') == 1) ? t('About:') : False);
  286. $xmpp = ((x($profile,'xmpp') == 1) ? t('XMPP:') : False);
  287. if (($profile['hidewall'] || $block) && (! local_user()) && (! remote_user())) {
  288. $location = $pdesc = $gender = $marital = $homepage = $about = False;
  289. }
  290. $firstname = ((strpos($profile['name'],' '))
  291. ? trim(substr($profile['name'],0,strpos($profile['name'],' '))) : $profile['name']);
  292. $lastname = (($firstname === $profile['name']) ? '' : trim(substr($profile['name'],strlen($firstname))));
  293. if ($profile['guid'] != "")
  294. $diaspora = array(
  295. 'guid' => $profile['guid'],
  296. 'podloc' => App::get_baseurl(),
  297. 'searchable' => (($profile['publish'] && $profile['net-publish']) ? 'true' : 'false' ),
  298. 'nickname' => $profile['nickname'],
  299. 'fullname' => $profile['name'],
  300. 'firstname' => $firstname,
  301. 'lastname' => $lastname,
  302. 'photo300' => $profile['contact_photo'],
  303. 'photo100' => $profile['contact_thumb'],
  304. 'photo50' => $profile['contact_micro'],
  305. );
  306. else
  307. $diaspora = false;
  308. if (!$block) {
  309. $contact_block = contact_block();
  310. if (is_array($a->profile) && !$a->profile['hide-friends']) {
  311. $r = q("SELECT `gcontact`.`updated` FROM `contact` INNER JOIN `gcontact` WHERE `gcontact`.`nurl` = `contact`.`nurl` AND `self` AND `uid` = %d LIMIT 1",
  312. intval($a->profile['uid']));
  313. if (dbm::is_result($r))
  314. $updated = date("c", strtotime($r[0]['updated']));
  315. $r = q("SELECT COUNT(*) AS `total` FROM `contact`
  316. WHERE `uid` = %d
  317. AND NOT `self` AND NOT `blocked` AND NOT `pending`
  318. AND NOT `hidden` AND NOT `archive`
  319. AND `network` IN ('%s', '%s', '%s', '')",
  320. intval($profile['uid']),
  321. dbesc(NETWORK_DFRN),
  322. dbesc(NETWORK_DIASPORA),
  323. dbesc(NETWORK_OSTATUS)
  324. );
  325. if (dbm::is_result($r))
  326. $contacts = intval($r[0]['total']);
  327. }
  328. }
  329. $p = array();
  330. foreach ($profile as $k => $v) {
  331. $k = str_replace('-','_',$k);
  332. $p[$k] = $v;
  333. }
  334. if (isset($p["about"]))
  335. $p["about"] = bbcode($p["about"]);
  336. if (isset($p["address"]))
  337. $p["address"] = bbcode($p["address"]);
  338. else
  339. $p["address"] = bbcode($p["location"]);
  340. if (isset($p["photo"])) {
  341. $p["photo"] = proxy_url($p["photo"], false, PROXY_SIZE_SMALL);
  342. }
  343. if ($a->theme['template_engine'] === 'internal')
  344. $location = template_escape($location);
  345. $tpl = get_markup_template('profile_vcard.tpl');
  346. $o .= replace_macros($tpl, array(
  347. '$profile' => $p,
  348. '$xmpp' => $xmpp,
  349. '$connect' => $connect,
  350. '$remoteconnect' => $remoteconnect,
  351. '$subscribe_feed' => $subscribe_feed,
  352. '$wallmessage' => $wallmessage,
  353. '$wallmessage_link' => $wallmessage_link,
  354. '$account_type' => $account_type,
  355. '$location' => $location,
  356. '$gender' => $gender,
  357. // '$pdesc' => $pdesc,
  358. '$marital' => $marital,
  359. '$homepage' => $homepage,
  360. '$about' => $about,
  361. '$network' => t('Network:'),
  362. '$contacts' => $contacts,
  363. '$updated' => $updated,
  364. '$diaspora' => $diaspora,
  365. '$contact_block' => $contact_block,
  366. ));
  367. $arr = array('profile' => &$profile, 'entry' => &$o);
  368. call_hooks('profile_sidebar', $arr);
  369. return $o;
  370. }
  371. function get_birthdays() {
  372. $a = get_app();
  373. $o = '';
  374. if (! local_user() || $a->is_mobile || $a->is_tablet)
  375. return $o;
  376. // $mobile_detect = new Mobile_Detect();
  377. // $is_mobile = $mobile_detect->isMobile() || $mobile_detect->isTablet();
  378. // if ($is_mobile)
  379. // return $o;
  380. $bd_format = t('g A l F d') ; // 8 AM Friday January 18
  381. $bd_short = t('F d');
  382. $cachekey = "get_birthdays:".local_user();
  383. $r = Cache::get($cachekey);
  384. if (is_null($r)) {
  385. $s = dba::p("SELECT `event`.*, `event`.`id` AS `eid`, `contact`.* FROM `event`
  386. INNER JOIN `contact` ON `contact`.`id` = `event`.`cid`
  387. WHERE `event`.`uid` = ? AND `type` = 'birthday' AND `start` < ? AND `finish` > ?
  388. ORDER BY `start` ASC ",
  389. local_user(),
  390. datetime_convert('UTC','UTC','now + 6 days'),
  391. datetime_convert('UTC','UTC','now')
  392. );
  393. if (dbm::is_result($s)) {
  394. $r = dba::inArray($s);
  395. Cache::set($cachekey, $r, CACHE_HOUR);
  396. }
  397. }
  398. if (dbm::is_result($r)) {
  399. $total = 0;
  400. $now = strtotime('now');
  401. $cids = array();
  402. $istoday = false;
  403. foreach ($r as $rr) {
  404. if (strlen($rr['name']))
  405. $total ++;
  406. if ((strtotime($rr['start'] . ' +00:00') < $now) && (strtotime($rr['finish'] . ' +00:00') > $now))
  407. $istoday = true;
  408. }
  409. $classtoday = $istoday ? ' birthday-today ' : '';
  410. if ($total) {
  411. foreach ($r as &$rr) {
  412. if (! strlen($rr['name']))
  413. continue;
  414. // avoid duplicates
  415. if (in_array($rr['cid'],$cids))
  416. continue;
  417. $cids[] = $rr['cid'];
  418. $today = (((strtotime($rr['start'] . ' +00:00') < $now) && (strtotime($rr['finish'] . ' +00:00') > $now)) ? true : false);
  419. $sparkle = '';
  420. $url = $rr['url'];
  421. if ($rr['network'] === NETWORK_DFRN) {
  422. $sparkle = " sparkle";
  423. $url = App::get_baseurl() . '/redir/' . $rr['cid'];
  424. }
  425. $rr['link'] = $url;
  426. $rr['title'] = $rr['name'];
  427. $rr['date'] = day_translate(datetime_convert('UTC', $a->timezone, $rr['start'], $rr['adjust'] ? $bd_format : $bd_short)) . (($today) ? ' ' . t('[today]') : '');
  428. $rr['startime'] = Null;
  429. $rr['today'] = $today;
  430. }
  431. }
  432. }
  433. $tpl = get_markup_template("birthdays_reminder.tpl");
  434. return replace_macros($tpl, array(
  435. '$baseurl' => App::get_baseurl(),
  436. '$classtoday' => $classtoday,
  437. '$count' => $total,
  438. '$event_reminders' => t('Birthday Reminders'),
  439. '$event_title' => t('Birthdays this week:'),
  440. '$events' => $r,
  441. '$lbr' => '{', // raw brackets mess up if/endif macro processing
  442. '$rbr' => '}'
  443. ));
  444. }
  445. function get_events() {
  446. require_once 'include/bbcode.php';
  447. $a = get_app();
  448. if (! local_user() || $a->is_mobile || $a->is_tablet) {
  449. return $o;
  450. }
  451. // $mobile_detect = new Mobile_Detect();
  452. // $is_mobile = $mobile_detect->isMobile() || $mobile_detect->isTablet();
  453. // if ($is_mobile)
  454. // return $o;
  455. $bd_format = t('g A l F d') ; // 8 AM Friday January 18
  456. $bd_short = t('F d');
  457. $r = dba::p("SELECT `event`.* FROM `event`
  458. WHERE `event`.`uid` = ? AND `type` != 'birthday' AND `start` < ? AND `start` >= ?
  459. ORDER BY `start` ASC ",
  460. local_user(),
  461. datetime_convert('UTC','UTC','now + 7 days'),
  462. datetime_convert('UTC','UTC','now - 1 days')
  463. );
  464. if (dbm::is_result($r)) {
  465. $now = strtotime('now');
  466. $istoday = false;
  467. $skip = 0;
  468. while ($rr = dba::fetch($r)) {
  469. if (strlen($rr['name'])) {
  470. $total ++;
  471. }
  472. $strt = datetime_convert('UTC',$rr['convert'] ? $a->timezone : 'UTC',$rr['start'],'Y-m-d');
  473. if ($strt === datetime_convert('UTC',$a->timezone,'now','Y-m-d')) {
  474. $istoday = true;
  475. }
  476. $title = strip_tags(html_entity_decode(bbcode($rr['summary']),ENT_QUOTES,'UTF-8'));
  477. if (strlen($title) > 35) {
  478. $title = substr($title,0,32) . '... ';
  479. }
  480. $description = substr(strip_tags(bbcode($rr['desc'])),0,32) . '... ';
  481. if (! $description) {
  482. $description = t('[No description]');
  483. }
  484. $strt = datetime_convert('UTC',$rr['convert'] ? $a->timezone : 'UTC',$rr['start']);
  485. if (substr($strt,0,10) < datetime_convert('UTC',$a->timezone,'now','Y-m-d')) {
  486. $skip++;
  487. continue;
  488. }
  489. $today = ((substr($strt,0,10) === datetime_convert('UTC',$a->timezone,'now','Y-m-d')) ? true : false);
  490. $rr['title'] = $title;
  491. $rr['description'] = $desciption;
  492. $rr['date'] = day_translate(datetime_convert('UTC', $rr['adjust'] ? $a->timezone : 'UTC', $rr['start'], $bd_format)) . (($today) ? ' ' . t('[today]') : '');
  493. $rr['startime'] = $strt;
  494. $rr['today'] = $today;
  495. }
  496. dba::close($r);
  497. $classtoday = (($istoday) ? 'event-today' : '');
  498. }
  499. $tpl = get_markup_template("events_reminder.tpl");
  500. return replace_macros($tpl, array(
  501. '$baseurl' => App::get_baseurl(),
  502. '$classtoday' => $classtoday,
  503. '$count' => count($r) - $skip,
  504. '$event_reminders' => t('Event Reminders'),
  505. '$event_title' => t('Events this week:'),
  506. '$events' => $r,
  507. ));
  508. }
  509. function advanced_profile(App $a) {
  510. $o = '';
  511. $uid = $a->profile['uid'];
  512. $o .= replace_macros(get_markup_template('section_title.tpl'),array(
  513. '$title' => t('Profile')
  514. ));
  515. if ($a->profile['name']) {
  516. $tpl = get_markup_template('profile_advanced.tpl');
  517. $profile = array();
  518. $profile['fullname'] = array( t('Full Name:'), $a->profile['name'] ) ;
  519. if ($a->profile['gender']) {
  520. $profile['gender'] = array( t('Gender:'), $a->profile['gender'] );
  521. }
  522. if (($a->profile['dob']) && ($a->profile['dob'] > '0001-01-01')) {
  523. $year_bd_format = t('j F, Y');
  524. $short_bd_format = t('j F');
  525. $val = ((intval($a->profile['dob']))
  526. ? day_translate(datetime_convert('UTC','UTC',$a->profile['dob'] . ' 00:00 +00:00',$year_bd_format))
  527. : day_translate(datetime_convert('UTC','UTC','2001-' . substr($a->profile['dob'],5) . ' 00:00 +00:00',$short_bd_format)));
  528. $profile['birthday'] = array( t('Birthday:'), $val);
  529. }
  530. if (!empty($a->profile['dob'])
  531. && $a->profile['dob'] > '0001-01-01'
  532. && $age = age($a->profile['dob'], $a->profile['timezone'], '')
  533. ) {
  534. $profile['age'] = array( t('Age:'), $age );
  535. }
  536. if ($a->profile['marital']) {
  537. $profile['marital'] = array( t('Status:'), $a->profile['marital']);
  538. }
  539. /// @TODO Maybe use x() here, plus below?
  540. if ($a->profile['with']) {
  541. $profile['marital']['with'] = $a->profile['with'];
  542. }
  543. if (strlen($a->profile['howlong']) && $a->profile['howlong'] >= NULL_DATE) {
  544. $profile['howlong'] = relative_date($a->profile['howlong'], t('for %1$d %2$s'));
  545. }
  546. if ($a->profile['sexual']) {
  547. $profile['sexual'] = array( t('Sexual Preference:'), $a->profile['sexual'] );
  548. }
  549. if ($a->profile['homepage']) {
  550. $profile['homepage'] = array( t('Homepage:'), linkify($a->profile['homepage']) );
  551. }
  552. if ($a->profile['hometown']) {
  553. $profile['hometown'] = array( t('Hometown:'), linkify($a->profile['hometown']) );
  554. }
  555. if ($a->profile['pub_keywords']) {
  556. $profile['pub_keywords'] = array( t('Tags:'), $a->profile['pub_keywords']);
  557. }
  558. if ($a->profile['politic']) {
  559. $profile['politic'] = array( t('Political Views:'), $a->profile['politic']);
  560. }
  561. if ($a->profile['religion']) {
  562. $profile['religion'] = array( t('Religion:'), $a->profile['religion']);
  563. }
  564. if ($txt = prepare_text($a->profile['about'])) {
  565. $profile['about'] = array( t('About:'), $txt );
  566. }
  567. if ($txt = prepare_text($a->profile['interest'])) {
  568. $profile['interest'] = array( t('Hobbies/Interests:'), $txt);
  569. }
  570. if ($txt = prepare_text($a->profile['likes'])) {
  571. $profile['likes'] = array( t('Likes:'), $txt);
  572. }
  573. if ($txt = prepare_text($a->profile['dislikes'])) {
  574. $profile['dislikes'] = array( t('Dislikes:'), $txt);
  575. }
  576. if ($txt = prepare_text($a->profile['contact'])) {
  577. $profile['contact'] = array( t('Contact information and Social Networks:'), $txt);
  578. }
  579. if ($txt = prepare_text($a->profile['music'])) {
  580. $profile['music'] = array( t('Musical interests:'), $txt);
  581. }
  582. if ($txt = prepare_text($a->profile['book'])) {
  583. $profile['book'] = array( t('Books, literature:'), $txt);
  584. }
  585. if ($txt = prepare_text($a->profile['tv'])) {
  586. $profile['tv'] = array( t('Television:'), $txt);
  587. }
  588. if ($txt = prepare_text($a->profile['film'])) {
  589. $profile['film'] = array( t('Film/dance/culture/entertainment:'), $txt);
  590. }
  591. if ($txt = prepare_text($a->profile['romance'])) {
  592. $profile['romance'] = array( t('Love/Romance:'), $txt);
  593. }
  594. if ($txt = prepare_text($a->profile['work'])) {
  595. $profile['work'] = array( t('Work/employment:'), $txt);
  596. }
  597. if ($txt = prepare_text($a->profile['education'])) {
  598. $profile['education'] = array( t('School/education:'), $txt );
  599. }
  600. //show subcribed forum if it is enabled in the usersettings
  601. if (feature_enabled($uid,'forumlist_profile')) {
  602. $profile['forumlist'] = array( t('Forums:'), ForumManager::profile_advanced($uid));
  603. }
  604. if ($a->profile['uid'] == local_user()) {
  605. $profile['edit'] = array(App::get_baseurl(). '/profiles/'.$a->profile['id'], t('Edit profile'),"", t('Edit profile'));
  606. }
  607. return replace_macros($tpl, array(
  608. '$title' => t('Profile'),
  609. '$basic' => t('Basic'),
  610. '$advanced' => t('Advanced'),
  611. '$profile' => $profile
  612. ));
  613. }
  614. return '';
  615. }
  616. function profile_tabs($a, $is_owner=False, $nickname=Null) {
  617. //echo "<pre>"; var_dump($a->user); killme();
  618. if (is_null($nickname)) {
  619. $nickname = $a->user['nickname'];
  620. }
  621. if (x($_GET,'tab')) {
  622. $tab = notags(trim($_GET['tab']));
  623. }
  624. $url = App::get_baseurl() . '/profile/' . $nickname;
  625. $tabs = array(
  626. array(
  627. 'label'=>t('Status'),
  628. 'url' => $url,
  629. 'sel' => ((!isset($tab) && $a->argv[0]=='profile') ? 'active' : ''),
  630. 'title' => t('Status Messages and Posts'),
  631. 'id' => 'status-tab',
  632. 'accesskey' => 'm',
  633. ),
  634. array(
  635. 'label' => t('Profile'),
  636. 'url' => $url.'/?tab=profile',
  637. 'sel' => ((isset($tab) && $tab=='profile') ? 'active' : ''),
  638. 'title' => t('Profile Details'),
  639. 'id' => 'profile-tab',
  640. 'accesskey' => 'r',
  641. ),
  642. array(
  643. 'label' => t('Photos'),
  644. 'url' => App::get_baseurl() . '/photos/' . $nickname,
  645. 'sel' => ((!isset($tab) && $a->argv[0]=='photos') ? 'active' : ''),
  646. 'title' => t('Photo Albums'),
  647. 'id' => 'photo-tab',
  648. 'accesskey' => 'h',
  649. ),
  650. array(
  651. 'label' => t('Videos'),
  652. 'url' => App::get_baseurl() . '/videos/' . $nickname,
  653. 'sel' => ((!isset($tab) && $a->argv[0]=='videos') ? 'active' : ''),
  654. 'title' => t('Videos'),
  655. 'id' => 'video-tab',
  656. 'accesskey' => 'v',
  657. ),
  658. );
  659. // the calendar link for the full featured events calendar
  660. if ($is_owner && $a->theme_events_in_profile) {
  661. $tabs[] = array(
  662. 'label' => t('Events'),
  663. 'url' => App::get_baseurl() . '/events',
  664. 'sel' =>((!isset($tab) && $a->argv[0]=='events') ? 'active' : ''),
  665. 'title' => t('Events and Calendar'),
  666. 'id' => 'events-tab',
  667. 'accesskey' => 'e',
  668. );
  669. // if the user is not the owner of the calendar we only show a calendar
  670. // with the public events of the calendar owner
  671. } elseif (! $is_owner) {
  672. $tabs[] = array(
  673. 'label' => t('Events'),
  674. 'url' => App::get_baseurl() . '/cal/' . $nickname,
  675. 'sel' =>((!isset($tab) && $a->argv[0]=='cal') ? 'active' : ''),
  676. 'title' => t('Events and Calendar'),
  677. 'id' => 'events-tab',
  678. 'accesskey' => 'e',
  679. );
  680. }
  681. if ($is_owner) {
  682. $tabs[] = array(
  683. 'label' => t('Personal Notes'),
  684. 'url' => App::get_baseurl() . '/notes',
  685. 'sel' =>((!isset($tab) && $a->argv[0]=='notes') ? 'active' : ''),
  686. 'title' => t('Only You Can See This'),
  687. 'id' => 'notes-tab',
  688. 'accesskey' => 't',
  689. );
  690. }
  691. if ((! $is_owner) && ((count($a->profile)) || (! $a->profile['hide-friends']))) {
  692. $tabs[] = array(
  693. 'label' => t('Contacts'),
  694. 'url' => App::get_baseurl() . '/viewcontacts/' . $nickname,
  695. 'sel' => ((!isset($tab) && $a->argv[0]=='viewcontacts') ? 'active' : ''),
  696. 'title' => t('Contacts'),
  697. 'id' => 'viewcontacts-tab',
  698. 'accesskey' => 'k',
  699. );
  700. }
  701. $arr = array('is_owner' => $is_owner, 'nickname' => $nickname, 'tab' => (($tab) ? $tab : false), 'tabs' => $tabs);
  702. call_hooks('profile_tabs', $arr);
  703. $tpl = get_markup_template('common_tabs.tpl');
  704. return replace_macros($tpl,array('$tabs' => $arr['tabs']));
  705. }
  706. function get_my_url() {
  707. if (x($_SESSION, 'my_url')) {
  708. return $_SESSION['my_url'];
  709. }
  710. return false;
  711. }
  712. function zrl_init(App $a) {
  713. $tmp_str = get_my_url();
  714. if (validate_url($tmp_str)) {
  715. // Is it a DDoS attempt?
  716. // The check fetches the cached value from gprobe to reduce the load for this system
  717. $urlparts = parse_url($tmp_str);
  718. $result = Cache::get("gprobe:" . $urlparts["host"]);
  719. if ((!is_null($result)) && (in_array($result["network"], array(NETWORK_FEED, NETWORK_PHANTOM)))) {
  720. logger("DDoS attempt detected for " . $urlparts["host"] . " by " . $_SERVER["REMOTE_ADDR"] . ". server data: " . print_r($_SERVER, true), LOGGER_DEBUG);
  721. return;
  722. }
  723. proc_run(PRIORITY_LOW, 'include/gprobe.php', $tmp_str);
  724. $arr = array('zrl' => $tmp_str, 'url' => $a->cmd);
  725. call_hooks('zrl_init', $arr);
  726. }
  727. }
  728. function zrl($s, $force = false) {
  729. if (! strlen($s)) {
  730. return $s;
  731. }
  732. if ((! strpos($s, '/profile/')) && (! $force)) {
  733. return $s;
  734. }
  735. if ($force && substr($s, -1, 1) !== '/') {
  736. $s = $s . '/';
  737. }
  738. $achar = strpos($s, '?') ? '&' : '?';
  739. $mine = get_my_url();
  740. if ($mine && ! link_compare($mine, $s)) {
  741. return $s . $achar . 'zrl=' . urlencode($mine);
  742. }
  743. return $s;
  744. }
  745. /**
  746. * @brief Get the user ID of the page owner
  747. *
  748. * Used from within PCSS themes to set theme parameters. If there's a
  749. * puid request variable, that is the "page owner" and normally their theme
  750. * settings take precedence; unless a local user sets the "always_my_theme"
  751. * system pconfig, which means they don't want to see anybody else's theme
  752. * settings except their own while on this site.
  753. *
  754. * @return int user ID
  755. *
  756. * @note Returns local_user instead of user ID if "always_my_theme"
  757. * is set to true
  758. */
  759. function get_theme_uid() {
  760. $uid = ((!empty($_REQUEST['puid'])) ? intval($_REQUEST['puid']) : 0);
  761. if ((local_user()) && ((get_pconfig(local_user(), 'system', 'always_my_theme')) || (! $uid))) {
  762. return local_user();
  763. }
  764. return $uid;
  765. }