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.

840 lines
25 KiB

  1. <?php
  2. if(class_exists('Item'))
  3. return;
  4. require_once('object/BaseObject.php');
  5. require_once('include/text.php');
  6. require_once('include/diaspora.php');
  7. require_once('boot.php');
  8. /**
  9. * An item
  10. */
  11. class Item extends BaseObject {
  12. private $data = array();
  13. private $template = null;
  14. private $available_templates = array(
  15. 'wall' => 'wall_thread.tpl',
  16. 'wall2wall' => 'wallwall_thread.tpl'
  17. );
  18. private $comment_box_template = 'comment_item.tpl';
  19. private $toplevel = false;
  20. private $writable = false;
  21. private $children = array();
  22. private $parent = null;
  23. private $conversation = null;
  24. private $redirect_url = null;
  25. private $owner_url = '';
  26. private $owner_photo = '';
  27. private $owner_name = '';
  28. private $wall_to_wall = false;
  29. private $threaded = false;
  30. private $visiting = false;
  31. public function __construct($data) {
  32. $a = $this->get_app();
  33. $this->data = $data;
  34. $this->set_template('wall');
  35. $this->toplevel = ($this->get_id() == $this->get_data_value('parent'));
  36. if(is_array($_SESSION['remote'])) {
  37. foreach($_SESSION['remote'] as $visitor) {
  38. if($visitor['cid'] == $this->get_data_value('contact-id')) {
  39. $this->visiting = true;
  40. break;
  41. }
  42. }
  43. }
  44. $this->writable = ($this->get_data_value('writable') || $this->get_data_value('self'));
  45. $ssl_state = ((local_user()) ? true : false);
  46. $this->redirect_url = 'redir/' . $this->get_data_value('cid') ;
  47. if (get_config('system','thread_allow') && $a->theme_thread_allow && !$this->is_toplevel()) {
  48. $this->threaded = true;
  49. }
  50. // Prepare the children
  51. if (count($data['children'])) {
  52. foreach ($data['children'] as $item) {
  53. /*
  54. * Only add will be displayed
  55. */
  56. if ($item['network'] === NETWORK_MAIL && local_user() != $item['uid']) {
  57. continue;
  58. } elseif (! visible_activity($item)) {
  59. continue;
  60. }
  61. $item['pagedrop'] = $data['pagedrop'];
  62. $child = new Item($item);
  63. $this->add_child($child);
  64. }
  65. }
  66. }
  67. /**
  68. * Get data in a form usable by a conversation template
  69. *
  70. * Returns:
  71. * _ The data requested on success
  72. * _ false on failure
  73. */
  74. public function get_template_data($conv_responses, $thread_level=1) {
  75. require_once("mod/proxy.php");
  76. $result = array();
  77. $a = $this->get_app();
  78. $item = $this->get_data();
  79. $edited = false;
  80. if (strcmp($item['created'], $item['edited'])<>0) {
  81. $edited = array(
  82. 'label' => t('This entry was edited'),
  83. 'date' => datetime_convert('UTC', date_default_timezone_get(), $item['edited'], 'r'),
  84. 'relative' => relative_date($item['edited'])
  85. );
  86. }
  87. $commentww = '';
  88. $sparkle = '';
  89. $buttons = '';
  90. $dropping = false;
  91. $star = false;
  92. $ignore = false;
  93. $isstarred = "unstarred";
  94. $indent = '';
  95. $shiny = '';
  96. $osparkle = '';
  97. $total_children = $this->count_descendants();
  98. $conv = $this->get_conversation();
  99. $lock = ((($item['private'] == 1) || (($item['uid'] == local_user()) && (strlen($item['allow_cid']) || strlen($item['allow_gid'])
  100. || strlen($item['deny_cid']) || strlen($item['deny_gid']))))
  101. ? t('Private Message')
  102. : false);
  103. $shareable = ((($conv->get_profile_owner() == local_user()) && ($item['private'] != 1)) ? true : false);
  104. if (local_user() && link_compare($a->contact['url'],$item['author-link'])) {
  105. if ($item["event-id"] != 0) {
  106. $edpost = array("events/event/".$item['event-id'], t("Edit"));
  107. } else {
  108. $edpost = array("editpost/".$item['id'], t("Edit"));
  109. }
  110. } else {
  111. $edpost = false;
  112. }
  113. if (($this->get_data_value('uid') == local_user()) || $this->is_visiting()) {
  114. $dropping = true;
  115. }
  116. $drop = array(
  117. 'dropping' => $dropping,
  118. 'pagedrop' => ((feature_enabled($conv->get_profile_owner(),'multi_delete')) ? $item['pagedrop'] : ''),
  119. 'select' => t('Select'),
  120. 'delete' => t('Delete'),
  121. );
  122. $filer = (($conv->get_profile_owner() == local_user()) ? t("save to folder") : false);
  123. $diff_author = ((link_compare($item['url'],$item['author-link'])) ? false : true);
  124. $profile_name = htmlentities(((strlen($item['author-name'])) && $diff_author) ? $item['author-name'] : $item['name']);
  125. if ($item['author-link'] && (! $item['author-name'])) {
  126. $profile_name = $item['author-link'];
  127. }
  128. $sp = false;
  129. $profile_link = best_link_url($item,$sp);
  130. if ($profile_link === 'mailbox') {
  131. $profile_link = '';
  132. }
  133. if ($sp) {
  134. $sparkle = ' sparkle';
  135. } else {
  136. $profile_link = zrl($profile_link);
  137. }
  138. if (!isset($item['author-thumb']) OR ($item['author-thumb'] == "")) {
  139. $author_contact = get_contact_details_by_url($item['author-link'], $conv->get_profile_owner());
  140. if ($author_contact["thumb"]) {
  141. $item['author-thumb'] = $author_contact["thumb"];
  142. } else {
  143. $item['author-thumb'] = $item['author-avatar'];
  144. }
  145. }
  146. if (!isset($item['owner-thumb']) OR ($item['owner-thumb'] == "")) {
  147. $owner_contact = get_contact_details_by_url($item['owner-link'], $conv->get_profile_owner());
  148. if ($owner_contact["thumb"]) {
  149. $item['owner-thumb'] = $owner_contact["thumb"];
  150. } else {
  151. $item['owner-thumb'] = $item['owner-avatar'];
  152. }
  153. }
  154. $locate = array('location' => $item['location'], 'coord' => $item['coord'], 'html' => '');
  155. call_hooks('render_location',$locate);
  156. $location = ((strlen($locate['html'])) ? $locate['html'] : render_location_dummy($locate));
  157. $searchpath = "search?tag=";
  158. $tags=array();
  159. $hashtags = array();
  160. $mentions = array();
  161. /*foreach(explode(',',$item['tag']) as $tag){
  162. $tag = trim($tag);
  163. if ($tag!="") {
  164. $t = bbcode($tag);
  165. $tags[] = $t;
  166. if($t[0] == '#')
  167. $hashtags[] = $t;
  168. elseif($t[0] == '@')
  169. $mentions[] = $t;
  170. }
  171. }*/
  172. // process action responses - e.g. like/dislike/attend/agree/whatever
  173. $response_verbs = array('like');
  174. if (feature_enabled($conv->get_profile_owner(),'dislike')) {
  175. $response_verbs[] = 'dislike';
  176. }
  177. if ($item['object-type'] === ACTIVITY_OBJ_EVENT) {
  178. $response_verbs[] = 'attendyes';
  179. $response_verbs[] = 'attendno';
  180. $response_verbs[] = 'attendmaybe';
  181. if ($conv->is_writable()) {
  182. $isevent = true;
  183. $attend = array( t('I will attend'), t('I will not attend'), t('I might attend'));
  184. }
  185. }
  186. $responses = get_responses($conv_responses,$response_verbs,$this,$item);
  187. foreach ($response_verbs as $value=>$verbs) {
  188. $responses[$verbs]['output'] = ((x($conv_responses[$verbs],$item['uri'])) ? format_like($conv_responses[$verbs][$item['uri']],$conv_responses[$verbs][$item['uri'] . '-l'],$verbs,$item['uri']) : '');
  189. }
  190. /*
  191. * We should avoid doing this all the time, but it depends on the conversation mode
  192. * And the conv mode may change when we change the conv, or it changes its mode
  193. * Maybe we should establish a way to be notified about conversation changes
  194. */
  195. $this->check_wall_to_wall();
  196. if ($this->is_wall_to_wall() && ($this->get_owner_url() == $this->get_redirect_url())) {
  197. $osparkle = ' sparkle';
  198. }
  199. if ($this->is_toplevel()) {
  200. if ($conv->get_profile_owner() == local_user()) {
  201. $isstarred = (($item['starred']) ? "starred" : "unstarred");
  202. $star = array(
  203. 'do' => t("add star"),
  204. 'undo' => t("remove star"),
  205. 'toggle' => t("toggle star status"),
  206. 'classdo' => (($item['starred']) ? "hidden" : ""),
  207. 'classundo' => (($item['starred']) ? "" : "hidden"),
  208. 'starred' => t('starred'),
  209. );
  210. $r = q("SELECT `ignored` FROM `thread` WHERE `uid` = %d AND `iid` = %d LIMIT 1",
  211. intval($item['uid']),
  212. intval($item['id'])
  213. );
  214. if (dbm::is_result($r)) {
  215. $ignore = array(
  216. 'do' => t("ignore thread"),
  217. 'undo' => t("unignore thread"),
  218. 'toggle' => t("toggle ignore status"),
  219. 'classdo' => (($r[0]['ignored']) ? "hidden" : ""),
  220. 'classundo' => (($r[0]['ignored']) ? "" : "hidden"),
  221. 'ignored' => t('ignored'),
  222. );
  223. }
  224. $tagger = '';
  225. if(feature_enabled($conv->get_profile_owner(),'commtag')) {
  226. $tagger = array(
  227. 'add' => t("add tag"),
  228. 'class' => "",
  229. );
  230. }
  231. }
  232. } else {
  233. $indent = 'comment';
  234. }
  235. if ($conv->is_writable()) {
  236. $buttons = array(
  237. 'like' => array( t("I like this \x28toggle\x29"), t("like")),
  238. 'dislike' => ((feature_enabled($conv->get_profile_owner(),'dislike')) ? array( t("I don't like this \x28toggle\x29"), t("dislike")) : ''),
  239. );
  240. if ($shareable) {
  241. $buttons['share'] = array( t('Share this'), t('share'));
  242. }
  243. }
  244. $comment = $this->get_comment_box($indent);
  245. if (strcmp(datetime_convert('UTC','UTC',$item['created']),datetime_convert('UTC','UTC','now - 12 hours')) > 0){
  246. $shiny = 'shiny';
  247. }
  248. localize_item($item);
  249. if ($item["postopts"] and !get_config("system", "suppress_language")) {
  250. //$langdata = explode(";", $item["postopts"]);
  251. //$langstr = substr($langdata[0], 5)." (".round($langdata[1]*100, 1)."%)";
  252. $langstr = "";
  253. if (substr($item["postopts"], 0, 5) == "lang=") {
  254. $postopts = substr($item["postopts"], 5);
  255. $languages = explode(":", $postopts);
  256. if (sizeof($languages) == 1) {
  257. $languages = array();
  258. $languages[] = $postopts;
  259. }
  260. foreach ($languages as $language) {
  261. $langdata = explode(";", $language);
  262. if ($langstr != "") {
  263. $langstr .= ", ";
  264. }
  265. //$langstr .= $langdata[0]." (".round($langdata[1]*100, 1)."%)";
  266. $langstr .= round($langdata[1]*100, 1)."% ".$langdata[0];
  267. }
  268. }
  269. }
  270. $body = prepare_body($item,true);
  271. list($categories, $folders) = get_cats_and_terms($item);
  272. if ($a->theme['template_engine'] === 'internal') {
  273. $body_e = template_escape($body);
  274. $text_e = strip_tags(template_escape($body));
  275. $name_e = template_escape($profile_name);
  276. $title_e = template_escape($item['title']);
  277. $location_e = template_escape($location);
  278. $owner_name_e = template_escape($this->get_owner_name());
  279. } else {
  280. $body_e = $body;
  281. $text_e = strip_tags($body);
  282. $name_e = $profile_name;
  283. $title_e = $item['title'];
  284. $location_e = $location;
  285. $owner_name_e = $this->get_owner_name();
  286. }
  287. // Disable features that aren't available in several networks
  288. if (($item["item_network"] != NETWORK_DFRN) AND isset($buttons["dislike"])) {
  289. unset($buttons["dislike"],$isevent);
  290. $tagger = '';
  291. }
  292. if (($item["item_network"] == NETWORK_FEED) AND isset($buttons["like"])) {
  293. unset($buttons["like"]);
  294. }
  295. if (($item["item_network"] == NETWORK_MAIL) AND isset($buttons["like"])) {
  296. unset($buttons["like"]);
  297. }
  298. // Diaspora isn't able to do likes on comments - but red does
  299. if (($item["item_network"] == NETWORK_DIASPORA) AND ($indent == 'comment') AND
  300. !diaspora::is_redmatrix($item["owner-link"]) AND isset($buttons["like"])) {
  301. unset($buttons["like"]);
  302. }
  303. // Diaspora doesn't has multithreaded comments
  304. if (($item["item_network"] == NETWORK_DIASPORA) AND ($indent == 'comment')) {
  305. unset($comment);
  306. }
  307. // Facebook can like comments - but it isn't programmed in the connector yet.
  308. if (($item["item_network"] == NETWORK_FACEBOOK) AND ($indent == 'comment') AND isset($buttons["like"])) {
  309. unset($buttons["like"]);
  310. }
  311. $tmp_item = array(
  312. 'template' => $this->get_template(),
  313. 'type' => implode("",array_slice(explode("/",$item['verb']),-1)),
  314. 'tags' => $item['tags'],
  315. 'hashtags' => $item['hashtags'],
  316. 'mentions' => $item['mentions'],
  317. 'txt_cats' => t('Categories:'),
  318. 'txt_folders' => t('Filed under:'),
  319. 'has_cats' => ((count($categories)) ? 'true' : ''),
  320. 'has_folders' => ((count($folders)) ? 'true' : ''),
  321. 'categories' => $categories,
  322. 'folders' => $folders,
  323. 'body' => $body_e,
  324. 'text' => $text_e,
  325. 'id' => $this->get_id(),
  326. 'guid' => urlencode($item['guid']),
  327. 'isevent' => $isevent,
  328. 'attend' => $attend,
  329. 'linktitle' => sprintf( t('View %s\'s profile @ %s'), $profile_name, ((strlen($item['author-link'])) ? $item['author-link'] : $item['url'])),
  330. 'olinktitle' => sprintf( t('View %s\'s profile @ %s'), htmlentities($this->get_owner_name()), ((strlen($item['owner-link'])) ? $item['owner-link'] : $item['url'])),
  331. 'to' => t('to'),
  332. 'via' => t('via'),
  333. 'wall' => t('Wall-to-Wall'),
  334. 'vwall' => t('via Wall-To-Wall:'),
  335. 'profile_url' => $profile_link,
  336. 'item_photo_menu' => item_photo_menu($item),
  337. 'name' => $name_e,
  338. 'thumb' => $a->remove_baseurl(proxy_url($item['author-thumb'], false, PROXY_SIZE_THUMB)),
  339. 'osparkle' => $osparkle,
  340. 'sparkle' => $sparkle,
  341. 'title' => $title_e,
  342. 'localtime' => datetime_convert('UTC', date_default_timezone_get(), $item['created'], 'r'),
  343. 'ago' => (($item['app']) ? sprintf( t('%s from %s'),relative_date($item['created']),$item['app']) : relative_date($item['created'])),
  344. 'app' => $item['app'],
  345. 'created' => relative_date($item['created']),
  346. 'lock' => $lock,
  347. 'location' => $location_e,
  348. 'indent' => $indent,
  349. 'shiny' => $shiny,
  350. 'owner_url' => $this->get_owner_url(),
  351. 'owner_photo' => $a->remove_baseurl(proxy_url($item['owner-thumb'], false, PROXY_SIZE_THUMB)),
  352. 'owner_name' => htmlentities($owner_name_e),
  353. 'plink' => get_plink($item),
  354. 'edpost' => ((feature_enabled($conv->get_profile_owner(),'edit_posts')) ? $edpost : ''),
  355. 'isstarred' => $isstarred,
  356. 'star' => ((feature_enabled($conv->get_profile_owner(),'star_posts')) ? $star : ''),
  357. 'ignore' => ((feature_enabled($conv->get_profile_owner(),'ignore_posts')) ? $ignore : ''),
  358. 'tagger' => $tagger,
  359. 'filer' => ((feature_enabled($conv->get_profile_owner(),'filing')) ? $filer : ''),
  360. 'drop' => $drop,
  361. 'vote' => $buttons,
  362. 'like' => $responses['like']['output'],
  363. 'dislike' => $responses['dislike']['output'],
  364. 'responses' => $responses,
  365. 'switchcomment' => t('Comment'),
  366. 'comment' => $comment,
  367. 'previewing' => ($conv->is_preview() ? ' preview ' : ''),
  368. 'wait' => t('Please wait'),
  369. 'thread_level' => $thread_level,
  370. 'postopts' => $langstr,
  371. 'edited' => $edited,
  372. 'network' => $item["item_network"],
  373. 'network_name' => network_to_name($item['item_network'], $profile_link),
  374. );
  375. $arr = array('item' => $item, 'output' => $tmp_item);
  376. call_hooks('display_item', $arr);
  377. $result = $arr['output'];
  378. $result['children'] = array();
  379. $children = $this->get_children();
  380. $nb_children = count($children);
  381. if ($nb_children > 0) {
  382. foreach ($children as $child) {
  383. $result['children'][] = $child->get_template_data($conv_responses, $thread_level + 1);
  384. }
  385. // Collapse
  386. if (($nb_children > 2) || ($thread_level > 1)) {
  387. $result['children'][0]['comment_firstcollapsed'] = true;
  388. $result['children'][0]['num_comments'] = sprintf( tt('%d comment','%d comments',$total_children),$total_children );
  389. $result['children'][0]['hidden_comments_num'] = $total_children;
  390. $result['children'][0]['hidden_comments_text'] = tt('comment', 'comments', $total_children);
  391. $result['children'][0]['hide_text'] = t('show more');
  392. if ($thread_level > 1) {
  393. $result['children'][$nb_children - 1]['comment_lastcollapsed'] = true;
  394. } else {
  395. $result['children'][$nb_children - 3]['comment_lastcollapsed'] = true;
  396. }
  397. }
  398. }
  399. if ($this->is_toplevel()) {
  400. $result['total_comments_num'] = "$total_children";
  401. $result['total_comments_text'] = tt('comment', 'comments', $total_children);
  402. }
  403. $result['private'] = $item['private'];
  404. $result['toplevel'] = ($this->is_toplevel() ? 'toplevel_item' : '');
  405. if ($this->is_threaded()) {
  406. $result['flatten'] = false;
  407. $result['threaded'] = true;
  408. } else {
  409. $result['flatten'] = true;
  410. $result['threaded'] = false;
  411. }
  412. return $result;
  413. }
  414. public function get_id() {
  415. return $this->get_data_value('id');
  416. }
  417. public function is_threaded() {
  418. return $this->threaded;
  419. }
  420. /**
  421. * Add a child item
  422. */
  423. public function add_child(Item $item) {
  424. $item_id = $item->get_id();
  425. if (!$item_id) {
  426. logger('[ERROR] Item::add_child : Item has no ID!!', LOGGER_DEBUG);
  427. return false;
  428. } elseif ($this->get_child($item->get_id())) {
  429. logger('[WARN] Item::add_child : Item already exists ('. $item->get_id() .').', LOGGER_DEBUG);
  430. return false;
  431. }
  432. /*
  433. * Only add what will be displayed
  434. */
  435. if ($item->get_data_value('network') === NETWORK_MAIL && local_user() != $item->get_data_value('uid')) {
  436. return false;
  437. } elseif (activity_match($item->get_data_value('verb'),ACTIVITY_LIKE) || activity_match($item->get_data_value('verb'),ACTIVITY_DISLIKE)) {
  438. return false;
  439. }
  440. $item->set_parent($this);
  441. $this->children[] = $item;
  442. return end($this->children);
  443. }
  444. /**
  445. * Get a child by its ID
  446. */
  447. public function get_child($id) {
  448. foreach ($this->get_children() as $child) {
  449. if ($child->get_id() == $id) {
  450. return $child;
  451. }
  452. }
  453. return null;
  454. }
  455. /**
  456. * Get all ou children
  457. */
  458. public function get_children() {
  459. return $this->children;
  460. }
  461. /**
  462. * Set our parent
  463. */
  464. protected function set_parent($item) {
  465. $parent = $this->get_parent();
  466. if($parent) {
  467. $parent->remove_child($this);
  468. }
  469. $this->parent = $item;
  470. $this->set_conversation($item->get_conversation());
  471. }
  472. /**
  473. * Remove our parent
  474. */
  475. protected function remove_parent() {
  476. $this->parent = null;
  477. $this->conversation = null;
  478. }
  479. /**
  480. * Remove a child
  481. */
  482. public function remove_child($item) {
  483. $id = $item->get_id();
  484. foreach ($this->get_children() as $key => $child) {
  485. if ($child->get_id() == $id) {
  486. $child->remove_parent();
  487. unset($this->children[$key]);
  488. // Reindex the array, in order to make sure there won't be any trouble on loops using count()
  489. $this->children = array_values($this->children);
  490. return true;
  491. }
  492. }
  493. logger('[WARN] Item::remove_child : Item is not a child ('. $id .').', LOGGER_DEBUG);
  494. return false;
  495. }
  496. /**
  497. * Get parent item
  498. */
  499. protected function get_parent() {
  500. return $this->parent;
  501. }
  502. /**
  503. * set conversation
  504. */
  505. public function set_conversation($conv) {
  506. $previous_mode = ($this->conversation ? $this->conversation->get_mode() : '');
  507. $this->conversation = $conv;
  508. // Set it on our children too
  509. foreach ($this->get_children() as $child) {
  510. $child->set_conversation($conv);
  511. }
  512. }
  513. /**
  514. * get conversation
  515. */
  516. public function get_conversation() {
  517. return $this->conversation;
  518. }
  519. /**
  520. * Get raw data
  521. *
  522. * We shouldn't need this
  523. */
  524. public function get_data() {
  525. return $this->data;
  526. }
  527. /**
  528. * Get a data value
  529. *
  530. * Returns:
  531. * _ value on success
  532. * _ false on failure
  533. */
  534. public function get_data_value($name) {
  535. if (!isset($this->data[$name])) {
  536. // logger('[ERROR] Item::get_data_value : Item has no value name "'. $name .'".', LOGGER_DEBUG);
  537. return false;
  538. }
  539. return $this->data[$name];
  540. }
  541. /**
  542. * Set template
  543. */
  544. private function set_template($name) {
  545. if (!x($this->available_templates, $name)) {
  546. logger('[ERROR] Item::set_template : Template not available ("'. $name .'").', LOGGER_DEBUG);
  547. return false;
  548. }
  549. $this->template = $this->available_templates[$name];
  550. }
  551. /**
  552. * Get template
  553. */
  554. private function get_template() {
  555. return $this->template;
  556. }
  557. /**
  558. * Check if this is a toplevel post
  559. */
  560. private function is_toplevel() {
  561. return $this->toplevel;
  562. }
  563. /**
  564. * Check if this is writable
  565. */
  566. private function is_writable() {
  567. $conv = $this->get_conversation();
  568. if ($conv) {
  569. // This will allow us to comment on wall-to-wall items owned by our friends
  570. // and community forums even if somebody else wrote the post.
  571. // bug #517 - this fixes for conversation owner
  572. if ($conv->get_mode() == 'profile' && $conv->get_profile_owner() == local_user()) {
  573. return true;
  574. }
  575. // this fixes for visitors
  576. return ($this->writable || ($this->is_visiting() && $conv->get_mode() == 'profile'));
  577. }
  578. return $this->writable;
  579. }
  580. /**
  581. * Count the total of our descendants
  582. */
  583. private function count_descendants() {
  584. $children = $this->get_children();
  585. $total = count($children);
  586. if ($total > 0) {
  587. foreach ($children as $child) {
  588. $total += $child->count_descendants();
  589. }
  590. }
  591. return $total;
  592. }
  593. /**
  594. * Get the template for the comment box
  595. */
  596. private function get_comment_box_template() {
  597. return $this->comment_box_template;
  598. }
  599. /**
  600. * Get the comment box
  601. *
  602. * Returns:
  603. * _ The comment box string (empty if no comment box)
  604. * _ false on failure
  605. */
  606. private function get_comment_box($indent) {
  607. $a = $this->get_app();
  608. if (!$this->is_toplevel() && !(get_config('system','thread_allow') && $a->theme_thread_allow)) {
  609. return '';
  610. }
  611. $comment_box = '';
  612. $conv = $this->get_conversation();
  613. $template = get_markup_template($this->get_comment_box_template());
  614. $ww = '';
  615. if ( ($conv->get_mode() === 'network') && $this->is_wall_to_wall() )
  616. $ww = 'ww';
  617. if ($conv->is_writable() && $this->is_writable()) {
  618. $qc = $qcomment = null;
  619. /*
  620. * Hmmm, code depending on the presence of a particular plugin?
  621. * This should be better if done by a hook
  622. */
  623. if (in_array('qcomment',$a->plugins)) {
  624. $qc = ((local_user()) ? get_pconfig(local_user(),'qcomment','words') : null);
  625. $qcomment = (($qc) ? explode("\n",$qc) : null);
  626. }
  627. $comment_box = replace_macros($template,array(
  628. '$return_path' => $a->query_string,
  629. '$threaded' => $this->is_threaded(),
  630. // '$jsreload' => (($conv->get_mode() === 'display') ? $_SESSION['return_url'] : ''),
  631. '$jsreload' => '',
  632. '$type' => (($conv->get_mode() === 'profile') ? 'wall-comment' : 'net-comment'),
  633. '$id' => $this->get_id(),
  634. '$parent' => $this->get_id(),
  635. '$qcomment' => $qcomment,
  636. '$profile_uid' => $conv->get_profile_owner(),
  637. '$mylink' => $a->remove_baseurl($a->contact['url']),
  638. '$mytitle' => t('This is you'),
  639. '$myphoto' => $a->remove_baseurl($a->contact['thumb']),
  640. '$comment' => t('Comment'),
  641. '$submit' => t('Submit'),
  642. '$edbold' => t('Bold'),
  643. '$editalic' => t('Italic'),
  644. '$eduline' => t('Underline'),
  645. '$edquote' => t('Quote'),
  646. '$edcode' => t('Code'),
  647. '$edimg' => t('Image'),
  648. '$edurl' => t('Link'),
  649. '$edvideo' => t('Video'),
  650. '$preview' => ((feature_enabled($conv->get_profile_owner(),'preview')) ? t('Preview') : ''),
  651. '$indent' => $indent,
  652. '$sourceapp' => t($a->sourcename),
  653. '$ww' => (($conv->get_mode() === 'network') ? $ww : ''),
  654. '$rand_num' => random_digits(12)
  655. ));
  656. }
  657. return $comment_box;
  658. }
  659. private function get_redirect_url() {
  660. return $this->redirect_url;
  661. }
  662. /**
  663. * Check if we are a wall to wall item and set the relevant properties
  664. */
  665. protected function check_wall_to_wall() {
  666. $a = $this->get_app();
  667. $conv = $this->get_conversation();
  668. $this->wall_to_wall = false;
  669. if($this->is_toplevel()) {
  670. if($conv->get_mode() !== 'profile') {
  671. if($this->get_data_value('wall') AND !$this->get_data_value('self')) {
  672. // On the network page, I am the owner. On the display page it will be the profile owner.
  673. // This will have been stored in $a->page_contact by our calling page.
  674. // Put this person as the wall owner of the wall-to-wall notice.
  675. $this->owner_url = zrl($a->page_contact['url']);
  676. $this->owner_photo = $a->page_contact['thumb'];
  677. $this->owner_name = $a->page_contact['name'];
  678. $this->wall_to_wall = true;
  679. } elseif($this->get_data_value('owner-link')) {
  680. $owner_linkmatch = (($this->get_data_value('owner-link')) && link_compare($this->get_data_value('owner-link'),$this->get_data_value('author-link')));
  681. $alias_linkmatch = (($this->get_data_value('alias')) && link_compare($this->get_data_value('alias'),$this->get_data_value('author-link')));
  682. $owner_namematch = (($this->get_data_value('owner-name')) && $this->get_data_value('owner-name') == $this->get_data_value('author-name'));
  683. if ((! $owner_linkmatch) && (! $alias_linkmatch) && (! $owner_namematch)) {
  684. // The author url doesn't match the owner (typically the contact)
  685. // and also doesn't match the contact alias.
  686. // The name match is a hack to catch several weird cases where URLs are
  687. // all over the park. It can be tricked, but this prevents you from
  688. // seeing "Bob Smith to Bob Smith via Wall-to-wall" and you know darn
  689. // well that it's the same Bob Smith.
  690. // But it could be somebody else with the same name. It just isn't highly likely.
  691. $this->owner_photo = $this->get_data_value('owner-avatar');
  692. $this->owner_name = $this->get_data_value('owner-name');
  693. $this->wall_to_wall = true;
  694. // If it is our contact, use a friendly redirect link
  695. if ((link_compare($this->get_data_value('owner-link'),$this->get_data_value('url')))
  696. && ($this->get_data_value('network') === NETWORK_DFRN)) {
  697. $this->owner_url = $this->get_redirect_url();
  698. } else {
  699. $this->owner_url = zrl($this->get_data_value('owner-link'));
  700. }
  701. }
  702. }
  703. }
  704. }
  705. if (!$this->wall_to_wall) {
  706. $this->set_template('wall');
  707. $this->owner_url = '';
  708. $this->owner_photo = '';
  709. $this->owner_name = '';
  710. }
  711. }
  712. private function is_wall_to_wall() {
  713. return $this->wall_to_wall;
  714. }
  715. private function get_owner_url() {
  716. return $this->owner_url;
  717. }
  718. private function get_owner_photo() {
  719. return $this->owner_photo;
  720. }
  721. private function get_owner_name() {
  722. return $this->owner_name;
  723. }
  724. private function is_visiting() {
  725. return $this->visiting;
  726. }
  727. }
  728. /// @TODO These are discouraged and should be removed:
  729. ?>