Example #1
0
 public function __construct($data)
 {
     $a = $this->get_app();
     $this->data = $data;
     $this->toplevel = $this->get_id() == $this->get_data_value('parent');
     // Prepare the children
     if (count($data['children'])) {
         foreach ($data['children'] as $item) {
             /*
              * Only add those that will be displayed
              */
             if (!visible_activity($item) || array_key_exists('author_blocked', $item)) {
                 continue;
             }
             $child = new Item($item);
             $this->add_child($child);
         }
     }
 }
Example #2
0
 public function __construct($data)
 {
     $a = $this->get_app();
     $this->data = $data;
     $this->set_template('wall');
     $this->toplevel = $this->get_id() == $this->get_data_value('parent');
     if (is_array($_SESSION['remote'])) {
         foreach ($_SESSION['remote'] as $visitor) {
             if ($visitor['cid'] == $this->get_data_value('contact-id')) {
                 $this->visiting = true;
                 break;
             }
         }
     }
     $this->writable = $this->get_data_value('writable') || $this->get_data_value('self');
     $ssl_state = local_user() ? true : false;
     $this->redirect_url = $a->get_baseurl($ssl_state) . '/redir/' . $this->get_data_value('cid');
     if (get_config('system', 'thread_allow') && $a->theme_thread_allow && !$this->is_toplevel()) {
         $this->threaded = true;
     }
     // Prepare the children
     if (count($data['children'])) {
         foreach ($data['children'] as $item) {
             /*
              * Only add will be displayed
              */
             if ($item['network'] === NETWORK_MAIL && local_user() != $item['uid']) {
                 continue;
             }
             if (!visible_activity($item)) {
                 continue;
             }
             $item['pagedrop'] = $data['pagedrop'];
             $child = new Item($item);
             $this->add_child($child);
         }
     }
 }
Example #3
0
 /**
  * @brief
  *
  * @param array $params an assoziative array with:
  *  * \e string \b from_xchan sender xchan hash
  *  * \e string \b to_xchan recipient xchan hash
  *  * \e array \b item an assoziative array
  *  * \e int \b type one of the NOTIFY_* constants from boot.php
  *  * \e string \b link
  *  * \e string \b parent_mid
  *  * \e string \b otype
  *  * \e string \b verb
  *  * \e string \b activity
  */
 public static function submit($params)
 {
     logger('notification: entry', LOGGER_DEBUG);
     // throw a small amount of entropy into the system to breakup duplicates arriving at the same precise instant.
     usleep(mt_rand(0, 10000));
     if ($params['from_xchan']) {
         $x = q("select * from xchan where xchan_hash = '%s' limit 1", dbesc($params['from_xchan']));
     }
     if ($params['to_xchan']) {
         $y = q("select channel.*, account.* from channel left join account on channel_account_id = account_id\n\t\t\t\twhere channel_hash = '%s' and channel_removed = 0 limit 1", dbesc($params['to_xchan']));
     }
     if ($x & $y) {
         $sender = $x[0];
         $recip = $y[0];
     } else {
         logger('notification: no sender or recipient.');
         logger('sender: ' . $params['from_xchan']);
         logger('recip: ' . $params['to_xchan']);
         return;
     }
     // from here on everything is in the recipients language
     push_lang($recip['account_language']);
     // should probably have a channel language
     $banner = t('$Projectname Notification');
     $product = t('$projectname');
     // PLATFORM_NAME;
     $siteurl = z_root();
     $thanks = t('Thank You,');
     $sitename = get_config('system', 'sitename');
     $site_admin = sprintf(t('%s Administrator'), $sitename);
     $sender_name = $product;
     $hostname = \App::get_hostname();
     if (strpos($hostname, ':')) {
         $hostname = substr($hostname, 0, strpos($hostname, ':'));
     }
     // Do not translate 'noreply' as it must be a legal 7-bit email address
     $reply_email = get_config('system', 'reply_address');
     if (!$reply_email) {
         $reply_email = 'noreply' . '@' . $hostname;
     }
     $sender_email = get_config('system', 'from_email');
     if (!$sender_email) {
         $sender_email = 'Administrator' . '@' . \App::get_hostname();
     }
     $sender_name = get_config('system', 'from_email_name');
     if (!$sender_name) {
         $sender_name = \Zotlabs\Lib\System::get_site_name();
     }
     $additional_mail_header = "";
     if (array_key_exists('item', $params)) {
         require_once 'include/conversation.php';
         // if it's a normal item...
         if (array_key_exists('verb', $params['item'])) {
             // localize_item() alters the original item so make a copy first
             $i = $params['item'];
             logger('calling localize');
             localize_item($i);
             $title = $i['title'];
             $body = $i['body'];
             $private = $i['item_private'] || intval($i['item_obscured']);
         } else {
             $title = $params['item']['title'];
             $body = $params['item']['body'];
         }
     } else {
         $title = $body = '';
     }
     // e.g. "your post", "David's photo", etc.
     $possess_desc = t('%s <!item_type!>');
     if ($params['type'] == NOTIFY_MAIL) {
         logger('notification: mail');
         $subject = sprintf(t('[$Projectname:Notify] New mail received at %s'), $sitename);
         $preamble = sprintf(t('%1$s, %2$s sent you a new private message at %3$s.'), $recip['channel_name'], $sender['xchan_name'], $sitename);
         $epreamble = sprintf(t('%1$s sent you %2$s.'), '[zrl=' . $sender['xchan_url'] . ']' . $sender['xchan_name'] . '[/zrl]', '[zrl=$itemlink]' . t('a private message') . '[/zrl]');
         $sitelink = t('Please visit %s to view and/or reply to your private messages.');
         $tsitelink = sprintf($sitelink, $siteurl . '/mail/' . $params['item']['id']);
         $hsitelink = sprintf($sitelink, '<a href="' . $siteurl . '/mail/' . $params['item']['id'] . '">' . $sitename . '</a>');
         $itemlink = $siteurl . '/mail/' . $params['item']['id'];
     }
     if ($params['type'] == NOTIFY_COMMENT) {
         //		logger("notification: params = " . print_r($params, true), LOGGER_DEBUG);
         $itemlink = $params['link'];
         // ignore like/unlike activity on posts - they probably require a separate notification preference
         if (array_key_exists('item', $params) && !visible_activity($params['item'])) {
             logger('notification: not a visible activity. Ignoring.');
             pop_lang();
             return;
         }
         $parent_mid = $params['parent_mid'];
         // Check to see if there was already a notify for this post.
         // If so don't create a second notification
         $p = null;
         $p = q("select id from notify where link = '%s' and uid = %d limit 1", dbesc($params['link']), intval($recip['channel_id']));
         if ($p) {
             logger('notification: comment already notified');
             pop_lang();
             return;
         }
         // if it's a post figure out who's post it is.
         $p = null;
         if ($params['otype'] === 'item' && $parent_mid) {
             $p = q("select * from item where mid = '%s' and uid = %d limit 1", dbesc($parent_mid), intval($recip['channel_id']));
         }
         xchan_query($p);
         $item_post_type = item_post_type($p[0]);
         //		$private = $p[0]['item_private'];
         $parent_id = $p[0]['id'];
         $parent_item = $p[0];
         //$possess_desc = str_replace('<!item_type!>',$possess_desc);
         // "a post"
         $dest_str = sprintf(t('%1$s, %2$s commented on [zrl=%3$s]a %4$s[/zrl]'), $recip['channel_name'], '[zrl=' . $sender['xchan_url'] . ']' . $sender['xchan_name'] . '[/zrl]', $itemlink, $item_post_type);
         // "George Bull's post"
         if ($p) {
             $dest_str = sprintf(t('%1$s, %2$s commented on [zrl=%3$s]%4$s\'s %5$s[/zrl]'), $recip['channel_name'], '[zrl=' . $sender['xchan_url'] . ']' . $sender['xchan_name'] . '[/zrl]', $itemlink, $p[0]['author']['xchan_name'], $item_post_type);
         }
         // "your post"
         if ($p[0]['owner']['xchan_name'] == $p[0]['author']['xchan_name'] && intval($p[0]['item_wall'])) {
             $dest_str = sprintf(t('%1$s, %2$s commented on [zrl=%3$s]your %4$s[/zrl]'), $recip['channel_name'], '[zrl=' . $sender['xchan_url'] . ']' . $sender['xchan_name'] . '[/zrl]', $itemlink, $item_post_type);
         }
         // Some mail softwares relies on subject field for threading.
         // So, we cannot have different subjects for notifications of the same thread.
         // Before this we have the name of the replier on the subject rendering
         // differents subjects for messages on the same thread.
         $subject = sprintf(t('[$Projectname:Notify] Comment to conversation #%1$d by %2$s'), $parent_id, $sender['xchan_name']);
         $preamble = sprintf(t('%1$s, %2$s commented on an item/conversation you have been following.'), $recip['channel_name'], $sender['xchan_name']);
         $epreamble = $dest_str;
         $sitelink = t('Please visit %s to view and/or reply to the conversation.');
         $tsitelink = sprintf($sitelink, $siteurl);
         $hsitelink = sprintf($sitelink, '<a href="' . $siteurl . '">' . $sitename . '</a>');
     }
     if ($params['type'] == NOTIFY_WALL) {
         $subject = sprintf(t('[$Projectname:Notify] %s posted to your profile wall'), $sender['xchan_name']);
         $preamble = sprintf(t('%1$s, %2$s posted to your profile wall at %3$s'), $recip['channel_name'], $sender['xchan_name'], $sitename);
         $epreamble = sprintf(t('%1$s, %2$s posted to [zrl=%3$s]your wall[/zrl]'), $recip['channel_name'], '[zrl=' . $sender['xchan_url'] . ']' . $sender['xchan_name'] . '[/zrl]', $params['link']);
         $sitelink = t('Please visit %s to view and/or reply to the conversation.');
         $tsitelink = sprintf($sitelink, $siteurl);
         $hsitelink = sprintf($sitelink, '<a href="' . $siteurl . '">' . $sitename . '</a>');
         $itemlink = $params['link'];
     }
     if ($params['type'] == NOTIFY_TAGSELF) {
         $p = null;
         $p = q("select id from notify where link = '%s' and uid = %d limit 1", dbesc($params['link']), intval($recip['channel_id']));
         if ($p) {
             logger('enotify: tag: already notified about this post');
             pop_lang();
             return;
         }
         $subject = sprintf(t('[$Projectname:Notify] %s tagged you'), $sender['xchan_name']);
         $preamble = sprintf(t('%1$s, %2$s tagged you at %3$s'), $recip['channel_name'], $sender['xchan_name'], $sitename);
         $epreamble = sprintf(t('%1$s, %2$s [zrl=%3$s]tagged you[/zrl].'), $recip['channel_name'], '[zrl=' . $sender['xchan_url'] . ']' . $sender['xchan_name'] . '[/zrl]', $params['link']);
         $sitelink = t('Please visit %s to view and/or reply to the conversation.');
         $tsitelink = sprintf($sitelink, $siteurl);
         $hsitelink = sprintf($sitelink, '<a href="' . $siteurl . '">' . $sitename . '</a>');
         $itemlink = $params['link'];
     }
     if ($params['type'] == NOTIFY_POKE) {
         $subject = sprintf(t('[$Projectname:Notify] %1$s poked you'), $sender['xchan_name']);
         $preamble = sprintf(t('%1$s, %2$s poked you at %3$s'), $recip['channel_name'], $sender['xchan_name'], $sitename);
         $epreamble = sprintf(t('%1$s, %2$s [zrl=%2$s]poked you[/zrl].'), $recip['channel_name'], '[zrl=' . $sender['xchan_url'] . ']' . $sender['xchan_name'] . '[/zrl]', $params['link']);
         $subject = str_replace('poked', t($params['activity']), $subject);
         $preamble = str_replace('poked', t($params['activity']), $preamble);
         $epreamble = str_replace('poked', t($params['activity']), $epreamble);
         $sitelink = t('Please visit %s to view and/or reply to the conversation.');
         $tsitelink = sprintf($sitelink, $siteurl);
         $hsitelink = sprintf($sitelink, '<a href="' . $siteurl . '">' . $sitename . '</a>');
         $itemlink = $params['link'];
     }
     if ($params['type'] == NOTIFY_TAGSHARE) {
         $subject = sprintf(t('[$Projectname:Notify] %s tagged your post'), $sender['xchan_name']);
         $preamble = sprintf(t('%1$s, %2$s tagged your post at %3$s'), $recip['channel_name'], $sender['xchan_name'], $sitename);
         $epreamble = sprintf(t('%1$s, %2$s tagged [zrl=%3$s]your post[/zrl]'), $recip['channel_name'], '[zrl=' . $sender['xchan_url'] . ']' . $sender['xchan_name'] . '[/zrl]', $itemlink);
         $sitelink = t('Please visit %s to view and/or reply to the conversation.');
         $tsitelink = sprintf($sitelink, $siteurl);
         $hsitelink = sprintf($sitelink, '<a href="' . $siteurl . '">' . $sitename . '</a>');
         $itemlink = $params['link'];
     }
     if ($params['type'] == NOTIFY_INTRO) {
         $subject = sprintf(t('[$Projectname:Notify] Introduction received'));
         $preamble = sprintf(t('%1$s, you\'ve received an new connection request from \'%2$s\' at %3$s'), $recip['channel_name'], $sender['xchan_name'], $sitename);
         $epreamble = sprintf(t('%1$s, you\'ve received [zrl=%2$s]a new connection request[/zrl] from %3$s.'), $recip['channel_name'], $siteurl . '/connections/ifpending', '[zrl=' . $sender['xchan_url'] . ']' . $sender['xchan_name'] . '[/zrl]');
         $body = sprintf(t('You may visit their profile at %s'), $sender['xchan_url']);
         $sitelink = t('Please visit %s to approve or reject the connection request.');
         $tsitelink = sprintf($sitelink, $siteurl . '/connections/ifpending');
         $hsitelink = sprintf($sitelink, '<a href="' . $siteurl . '/connections/ifpending">' . $sitename . '</a>');
         $itemlink = $params['link'];
     }
     if ($params['type'] == NOTIFY_SUGGEST) {
         $subject = sprintf(t('[$Projectname:Notify] Friend suggestion received'));
         $preamble = sprintf(t('%1$s, you\'ve received a friend suggestion from \'%2$s\' at %3$s'), $recip['channel_name'], $sender['xchan_name'], $sitename);
         $epreamble = sprintf(t('%1$s, you\'ve received [zrl=%2$s]a friend suggestion[/zrl] for %3$s from %4$s.'), $recip['channel_name'], $itemlink, '[zrl=' . $params['item']['url'] . ']' . $params['item']['name'] . '[/zrl]', '[zrl=' . $sender['xchan_url'] . ']' . $sender['xchan_name'] . '[/zrl]');
         $body = t('Name:') . ' ' . $params['item']['name'] . "\n";
         $body .= t('Photo:') . ' ' . $params['item']['photo'] . "\n";
         $body .= sprintf(t('You may visit their profile at %s'), $params['item']['url']);
         $sitelink = t('Please visit %s to approve or reject the suggestion.');
         $tsitelink = sprintf($sitelink, $siteurl);
         $hsitelink = sprintf($sitelink, '<a href="' . $siteurl . '">' . $sitename . '</a>');
         $itemlink = $params['link'];
     }
     if ($params['type'] == NOTIFY_CONFIRM) {
         // ?
     }
     if ($params['type'] == NOTIFY_SYSTEM) {
         // ?
     }
     $h = array('params' => $params, 'subject' => $subject, 'preamble' => $preamble, 'epreamble' => $epreamble, 'body' => $body, 'sitelink' => $sitelink, 'sitename' => $sitename, 'tsitelink' => $tsitelink, 'hsitelink' => $hsitelink, 'itemlink' => $itemlink, 'sender' => $sender, 'recipient' => $recip);
     call_hooks('enotify', $h);
     $subject = $h['subject'];
     $preamble = $h['preamble'];
     $epreamble = $h['epreamble'];
     $body = $h['body'];
     $sitelink = $h['sitelink'];
     $tsitelink = $h['tsitelink'];
     $hsitelink = $h['hsitelink'];
     $itemlink = $h['itemlink'];
     require_once 'include/html2bbcode.php';
     do {
         $dups = false;
         $hash = random_string();
         $r = q("SELECT `id` FROM `notify` WHERE `hash` = '%s' LIMIT 1", dbesc($hash));
         if ($r) {
             $dups = true;
         }
     } while ($dups === true);
     $datarray = array();
     $datarray['hash'] = $hash;
     $datarray['sender_hash'] = $sender['xchan_hash'];
     $datarray['xname'] = $sender['xchan_name'];
     $datarray['url'] = $sender['xchan_url'];
     $datarray['photo'] = $sender['xchan_photo_s'];
     $datarray['created'] = datetime_convert();
     $datarray['aid'] = $recip['channel_account_id'];
     $datarray['uid'] = $recip['channel_id'];
     $datarray['link'] = $itemlink;
     $datarray['parent'] = $parent_mid;
     $datarray['parent_item'] = $parent_item;
     $datarray['ntype'] = $params['type'];
     $datarray['verb'] = $params['verb'];
     $datarray['otype'] = $params['otype'];
     $datarray['abort'] = false;
     $datarray['item'] = $params['item'];
     call_hooks('enotify_store', $datarray);
     if ($datarray['abort']) {
         pop_lang();
         return;
     }
     // create notification entry in DB
     $seen = 0;
     // Mark some notifications as seen right away
     // Note! The notification have to be created, because they are used to send emails
     // So easiest solution to hide them from Notices is to mark them as seen right away.
     // Another option would be to not add them to the DB, and change how emails are handled
     // (probably would be better that way)
     $always_show_in_notices = get_pconfig($recip['channel_id'], 'system', 'always_show_in_notices');
     if (!$always_show_in_notices) {
         if ($params['type'] == NOTIFY_WALL || $params['type'] == NOTIFY_MAIL || $params['type'] == NOTIFY_INTRO) {
             $seen = 1;
         }
     }
     $r = q("insert into notify (hash,xname,url,photo,created,aid,uid,link,parent,seen,ntype,verb,otype)\n\t\tvalues('%s','%s','%s','%s','%s',%d,%d,'%s','%s',%d,%d,'%s','%s')", dbesc($datarray['hash']), dbesc($datarray['xname']), dbesc($datarray['url']), dbesc($datarray['photo']), dbesc($datarray['created']), intval($datarray['aid']), intval($datarray['uid']), dbesc($datarray['link']), dbesc($datarray['parent']), intval($seen), intval($datarray['ntype']), dbesc($datarray['verb']), dbesc($datarray['otype']));
     $r = q("select id from notify where hash = '%s' and uid = %d limit 1", dbesc($hash), intval($recip['channel_id']));
     if ($r) {
         $notify_id = $r[0]['id'];
     } else {
         logger('notification not found.');
         pop_lang();
         return;
     }
     $itemlink = z_root() . '/notify/view/' . $notify_id;
     $msg = str_replace('$itemlink', $itemlink, $epreamble);
     // wretched hack, but we don't want to duplicate all the preamble variations and we also don't want to screw up a translation
     if ((\App::$language === 'en' || !\App::$language) && strpos($msg, ', ')) {
         $msg = substr($msg, strpos($msg, ', ') + 1);
     }
     $r = q("update notify set msg = '%s' where id = %d and uid = %d", dbesc($msg), intval($notify_id), intval($datarray['uid']));
     // send email notification if notification preferences permit
     require_once 'bbcode.php';
     if (intval($recip['channel_notifyflags']) & intval($params['type']) || $params['type'] == NOTIFY_SYSTEM) {
         logger('notification: sending notification email');
         $hn = get_pconfig($recip['channel_id'], 'system', 'email_notify_host');
         if ($hn && !stristr(\App::get_hostname(), $hn)) {
             // this isn't the email notification host
             pop_lang();
             return;
         }
         $textversion = strip_tags(html_entity_decode(bbcode(stripslashes(str_replace(array("\\r", "\\n"), array("", "\n"), $body))), ENT_QUOTES, 'UTF-8'));
         $htmlversion = bbcode(stripslashes(str_replace(array("\\r", "\\n"), array("", "<br />\n"), $body)));
         // use $_SESSION['zid_override'] to force zid() to use
         // the recipient address instead of the current observer
         $_SESSION['zid_override'] = channel_reddress($recip);
         $_SESSION['zrl_override'] = z_root() . '/channel/' . $recip['channel_address'];
         $textversion = zidify_links($textversion);
         $htmlversion = zidify_links($htmlversion);
         // unset when done to revert to normal behaviour
         unset($_SESSION['zid_override']);
         unset($_SESSION['zrl_override']);
         $datarray = array();
         $datarray['banner'] = $banner;
         $datarray['product'] = $product;
         $datarray['preamble'] = $preamble;
         $datarray['sitename'] = $sitename;
         $datarray['siteurl'] = $siteurl;
         $datarray['type'] = $params['type'];
         $datarray['parent'] = $params['parent_mid'];
         $datarray['source_name'] = $sender['xchan_name'];
         $datarray['source_link'] = $sender['xchan_url'];
         $datarray['source_photo'] = $sender['xchan_photo_s'];
         $datarray['uid'] = $recip['channel_id'];
         $datarray['username'] = $recip['channel_name'];
         $datarray['hsitelink'] = $hsitelink;
         $datarray['tsitelink'] = $tsitelink;
         $datarray['hitemlink'] = '<a href="' . $itemlink . '">' . $itemlink . '</a>';
         $datarray['titemlink'] = $itemlink;
         $datarray['thanks'] = $thanks;
         $datarray['site_admin'] = $site_admin;
         $datarray['title'] = stripslashes($title);
         $datarray['htmlversion'] = $htmlversion;
         $datarray['textversion'] = $textversion;
         $datarray['subject'] = $subject;
         $datarray['headers'] = $additional_mail_header;
         $datarray['email_secure'] = false;
         call_hooks('enotify_mail', $datarray);
         // Default to private - don't disclose message contents over insecure channels (such as email)
         // Might be interesting to use GPG,PGP,S/MIME encryption instead
         // but we'll save that for a clever plugin developer to implement
         $private_activity = false;
         if (!$datarray['email_secure']) {
             switch ($params['type']) {
                 case NOTIFY_WALL:
                 case NOTIFY_TAGSELF:
                 case NOTIFY_POKE:
                 case NOTIFY_COMMENT:
                     if (!$private) {
                         break;
                     }
                     $private_activity = true;
                 case NOTIFY_MAIL:
                     $datarray['textversion'] = $datarray['htmlversion'] = $datarray['title'] = '';
                     $datarray['subject'] = preg_replace('/' . preg_quote(t('[$Projectname:Notify]')) . '/', '$0*', $datarray['subject']);
                     break;
                 default:
                     break;
             }
         }
         if ($private_activity && intval(get_pconfig($datarray['uid'], 'system', 'ignore_private_notifications'))) {
             pop_lang();
             return;
         }
         // load the template for private message notifications
         $tpl = get_markup_template('email_notify_html.tpl');
         $email_html_body = replace_macros($tpl, array('$banner' => $datarray['banner'], '$notify_icon' => \Zotlabs\Lib\System::get_notify_icon(), '$product' => $datarray['product'], '$preamble' => $datarray['preamble'], '$sitename' => $datarray['sitename'], '$siteurl' => $datarray['siteurl'], '$source_name' => $datarray['source_name'], '$source_link' => $datarray['source_link'], '$source_photo' => $datarray['source_photo'], '$username' => $datarray['to_name'], '$hsitelink' => $datarray['hsitelink'], '$hitemlink' => $datarray['hitemlink'], '$thanks' => $datarray['thanks'], '$site_admin' => $datarray['site_admin'], '$title' => $datarray['title'], '$htmlversion' => $datarray['htmlversion']));
         // load the template for private message notifications
         $tpl = get_markup_template('email_notify_text.tpl');
         $email_text_body = replace_macros($tpl, array('$banner' => $datarray['banner'], '$product' => $datarray['product'], '$preamble' => $datarray['preamble'], '$sitename' => $datarray['sitename'], '$siteurl' => $datarray['siteurl'], '$source_name' => $datarray['source_name'], '$source_link' => $datarray['source_link'], '$source_photo' => $datarray['source_photo'], '$username' => $datarray['to_name'], '$tsitelink' => $datarray['tsitelink'], '$titemlink' => $datarray['titemlink'], '$thanks' => $datarray['thanks'], '$site_admin' => $datarray['site_admin'], '$title' => $datarray['title'], '$textversion' => $datarray['textversion']));
         //		logger('text: ' . $email_text_body);
         // use the EmailNotification library to send the message
         self::send(array('fromName' => $sender_name, 'fromEmail' => $sender_email, 'replyTo' => $reply_email, 'toEmail' => $recip['account_email'], 'messageSubject' => $datarray['subject'], 'htmlVersion' => $email_html_body, 'textVersion' => $email_text_body, 'additionalMailHeader' => $datarray['headers']));
     }
     pop_lang();
 }
Example #4
0
 private function count_unseen_descendants()
 {
     $children = $this->get_children();
     $total = count($children);
     if ($total > 0) {
         $total = 0;
         foreach ($children as $child) {
             if (!visible_activity($child->data) || array_key_exists('author_blocked', $child->data)) {
                 continue;
             }
             if (intval($child->data['item_unseen'])) {
                 $total++;
             }
         }
     }
     return $total;
 }
Example #5
0
 function conversation(&$a, $items, $mode, $update, $preview = false)
 {
     require_once 'include/bbcode.php';
     require_once 'mod/proxy.php';
     $ssl_state = local_user() ? true : false;
     $profile_owner = 0;
     $page_writeable = false;
     $live_update_div = '';
     $arr_blocked = null;
     if (local_user()) {
         $str_blocked = get_pconfig(local_user(), 'system', 'blocked');
         if ($str_blocked) {
             $arr_blocked = explode(',', $str_blocked);
             for ($x = 0; $x < count($arr_blocked); $x++) {
                 $arr_blocked[$x] = trim($arr_blocked[$x]);
             }
         }
     }
     $previewing = $preview ? ' preview ' : '';
     if ($mode === 'network') {
         $profile_owner = local_user();
         $page_writeable = true;
         if (!$update) {
             // The special div is needed for liveUpdate to kick in for this page.
             // We only launch liveUpdate if you aren't filtering in some incompatible
             // way and also you aren't writing a comment (discovered in javascript).
             $live_update_div = '<div id="live-network"></div>' . "\r\n" . "<script> var profile_uid = " . $_SESSION['uid'] . "; var netargs = '" . substr($a->cmd, 8) . '?f=' . (x($_GET, 'cid') ? '&cid=' . $_GET['cid'] : '') . (x($_GET, 'search') ? '&search=' . $_GET['search'] : '') . (x($_GET, 'star') ? '&star=' . $_GET['star'] : '') . (x($_GET, 'order') ? '&order=' . $_GET['order'] : '') . (x($_GET, 'bmark') ? '&bmark=' . $_GET['bmark'] : '') . (x($_GET, 'liked') ? '&liked=' . $_GET['liked'] : '') . (x($_GET, 'conv') ? '&conv=' . $_GET['conv'] : '') . (x($_GET, 'spam') ? '&spam=' . $_GET['spam'] : '') . (x($_GET, 'nets') ? '&nets=' . $_GET['nets'] : '') . (x($_GET, 'cmin') ? '&cmin=' . $_GET['cmin'] : '') . (x($_GET, 'cmax') ? '&cmax=' . $_GET['cmax'] : '') . (x($_GET, 'file') ? '&file=' . $_GET['file'] : '') . "'; var profile_page = " . $a->pager['page'] . "; </script>\r\n";
         }
     } else {
         if ($mode === 'profile') {
             $profile_owner = $a->profile['profile_uid'];
             $page_writeable = can_write_wall($a, $profile_owner);
             if (!$update) {
                 $tab = notags(trim($_GET['tab']));
                 $tab = $tab ? $tab : 'posts';
                 if ($tab === 'posts') {
                     // This is ugly, but we can't pass the profile_uid through the session to the ajax updater,
                     // because browser prefetching might change it on us. We have to deliver it with the page.
                     $live_update_div = '<div id="live-profile"></div>' . "\r\n" . "<script> var profile_uid = " . $a->profile['profile_uid'] . "; var netargs = '?f='; var profile_page = " . $a->pager['page'] . "; </script>\r\n";
                 }
             }
         } else {
             if ($mode === 'notes') {
                 $profile_owner = local_user();
                 $page_writeable = true;
                 if (!$update) {
                     $live_update_div = '<div id="live-notes"></div>' . "\r\n" . "<script> var profile_uid = " . local_user() . "; var netargs = '/?f='; var profile_page = " . $a->pager['page'] . "; </script>\r\n";
                 }
             } else {
                 if ($mode === 'display') {
                     $profile_owner = $a->profile['uid'];
                     $page_writeable = can_write_wall($a, $profile_owner);
                     if (!$update) {
                         $live_update_div = '<div id="live-display"></div>' . "\r\n" . "<script> var profile_uid = " . $_SESSION['uid'] . ";" . " var profile_page = 1; </script>";
                     }
                 } else {
                     if ($mode === 'community') {
                         $profile_owner = 0;
                         $page_writeable = false;
                         if (!$update) {
                             $live_update_div = '<div id="live-community"></div>' . "\r\n" . "<script> var profile_uid = -1; var netargs = '/?f='; var profile_page = " . $a->pager['page'] . "; </script>\r\n";
                         }
                     } else {
                         if ($mode === 'search') {
                             $live_update_div = '<div id="live-search"></div>' . "\r\n";
                         }
                     }
                 }
             }
         }
     }
     $page_dropping = local_user() && local_user() == $profile_owner ? true : false;
     if ($update) {
         $return_url = $_SESSION['return_url'];
     } else {
         $return_url = $_SESSION['return_url'] = $a->query_string;
     }
     load_contact_links(local_user());
     $cb = array('items' => $items, 'mode' => $mode, 'update' => $update, 'preview' => $preview);
     call_hooks('conversation_start', $cb);
     $items = $cb['items'];
     $cmnt_tpl = get_markup_template('comment_item.tpl');
     $hide_comments_tpl = get_markup_template('hide_comments.tpl');
     $alike = array();
     $dlike = array();
     // array with html for each thread (parent+comments)
     $threads = array();
     $threadsid = -1;
     $page_template = get_markup_template("conversation.tpl");
     if ($items && count($items)) {
         if ($mode === 'network-new' || $mode === 'search' || $mode === 'community') {
             // "New Item View" on network page or search page results
             // - just loop through the items and format them minimally for display
             //			$tpl = get_markup_template('search_item.tpl');
             $tpl = 'search_item.tpl';
             foreach ($items as $item) {
                 if ($arr_blocked) {
                     $blocked = false;
                     foreach ($arr_blocked as $b) {
                         if ($b && link_compare($item['author-link'], $b)) {
                             $blocked = true;
                             break;
                         }
                     }
                     if ($blocked) {
                         continue;
                     }
                 }
                 $threadsid++;
                 $comment = '';
                 $owner_url = '';
                 $owner_photo = '';
                 $owner_name = '';
                 $sparkle = '';
                 if ($mode === 'search' || $mode === 'community') {
                     if ((activity_match($item['verb'], ACTIVITY_LIKE) || activity_match($item['verb'], ACTIVITY_DISLIKE)) && $item['id'] != $item['parent']) {
                         continue;
                     }
                     $nickname = $item['nickname'];
                 } else {
                     $nickname = $a->user['nickname'];
                 }
                 // prevent private email from leaking.
                 if ($item['network'] === NETWORK_MAIL && local_user() != $item['uid']) {
                     continue;
                 }
                 $profile_name = strlen($item['author-name']) ? $item['author-name'] : $item['name'];
                 if ($item['author-link'] && !$item['author-name']) {
                     $profile_name = $item['author-link'];
                 }
                 $tags = array();
                 $hashtags = array();
                 $mentions = array();
                 $taglist = q("SELECT `type`, `term`, `url` FROM `term` WHERE `otype` = %d AND `oid` = %d AND `type` IN (%d, %d) ORDER BY `tid`", intval(TERM_OBJ_POST), intval($item['id']), intval(TERM_HASHTAG), intval(TERM_MENTION));
                 foreach ($taglist as $tag) {
                     if ($tag["url"] == "") {
                         $tag["url"] = $searchpath . strtolower($tag["term"]);
                     }
                     if ($tag["type"] == TERM_HASHTAG) {
                         $hashtags[] = "#<a href=\"" . $tag["url"] . "\" target=\"_blank\">" . $tag["term"] . "</a>";
                         $prefix = "#";
                     } elseif ($tag["type"] == TERM_MENTION) {
                         $mentions[] = "@<a href=\"" . $tag["url"] . "\" target=\"_blank\">" . $tag["term"] . "</a>";
                         $prefix = "@";
                     }
                     $tags[] = $prefix . "<a href=\"" . $tag["url"] . "\" target=\"_blank\">" . $tag["term"] . "</a>";
                 }
                 /*foreach(explode(',',$item['tag']) as $tag){
                 			$tag = trim($tag);
                 			if ($tag!="") {
                 				$t = bbcode($tag);
                 				$tags[] = $t;
                 				if($t[0] == '#')
                 					$hashtags[] = $t;
                 				elseif($t[0] == '@')
                 					$mentions[] = $t;
                 			}
                 		}*/
                 $sp = false;
                 $profile_link = best_link_url($item, $sp);
                 if ($profile_link === 'mailbox') {
                     $profile_link = '';
                 }
                 if ($sp) {
                     $sparkle = ' sparkle';
                 } else {
                     $profile_link = zrl($profile_link);
                 }
                 $normalised = normalise_link(strlen($item['author-link']) ? $item['author-link'] : $item['url']);
                 if ($normalised != 'mailbox' && x($a->contacts[$normalised])) {
                     $profile_avatar = $a->contacts[$normalised]['thumb'];
                 } else {
                     $profile_avatar = strlen($item['author-avatar']) ? $a->get_cached_avatar_image($item['author-avatar']) : $item['thumb'];
                 }
                 $locate = array('location' => $item['location'], 'coord' => $item['coord'], 'html' => '');
                 call_hooks('render_location', $locate);
                 $location = strlen($locate['html']) ? $locate['html'] : render_location_google($locate);
                 localize_item($item);
                 if ($mode === 'network-new') {
                     $dropping = true;
                 } else {
                     $dropping = false;
                 }
                 $drop = array('dropping' => $dropping, 'pagedrop' => $page_dropping, 'select' => t('Select'), 'delete' => t('Delete'));
                 $star = false;
                 $isstarred = "unstarred";
                 $lock = false;
                 $likebuttons = false;
                 $shareable = false;
                 $body = prepare_body($item, true, $preview);
                 list($categories, $folders) = get_cats_and_terms($item);
                 if ($a->theme['template_engine'] === 'internal') {
                     $profile_name_e = template_escape($profile_name);
                     $item['title_e'] = template_escape($item['title']);
                     $body_e = template_escape($body);
                     $tags_e = template_escape($tags);
                     $hashtags_e = template_escape($hashtags);
                     $mentions_e = template_escape($mentions);
                     $location_e = template_escape($location);
                     $owner_name_e = template_escape($owner_name);
                 } else {
                     $profile_name_e = $profile_name;
                     $item['title_e'] = $item['title'];
                     $body_e = $body;
                     $tags_e = $tags;
                     $hashtags_e = $hashtags;
                     $mentions_e = $mentions;
                     $location_e = $location;
                     $owner_name_e = $owner_name;
                 }
                 $tmp_item = array('template' => $tpl, 'id' => $preview ? 'P0' : $item['item_id'], 'network' => $item['item_network'], 'linktitle' => sprintf(t('View %s\'s profile @ %s'), $profile_name, strlen($item['author-link']) ? $item['author-link'] : $item['url']), 'profile_url' => $profile_link, 'item_photo_menu' => item_photo_menu($item), 'name' => $profile_name_e, 'sparkle' => $sparkle, 'lock' => $lock, 'thumb' => proxy_url($profile_avatar), 'title' => $item['title_e'], 'body' => $body_e, 'tags' => $tags_e, 'hashtags' => $hashtags_e, 'mentions' => $mentions_e, 'txt_cats' => t('Categories:'), 'txt_folders' => t('Filed under:'), 'has_cats' => count($categories) ? 'true' : '', 'has_folders' => count($folders) ? 'true' : '', 'categories' => $categories, 'folders' => $folders, 'text' => strip_tags($body_e), 'localtime' => datetime_convert('UTC', date_default_timezone_get(), $item['created'], 'r'), 'ago' => $item['app'] ? sprintf(t('%s from %s'), relative_date($item['created']), $item['app']) : relative_date($item['created']), 'location' => $location_e, 'indent' => '', 'owner_name' => $owner_name_e, 'owner_url' => $owner_url, 'owner_photo' => proxy_url($owner_photo), 'plink' => get_plink($item), 'edpost' => false, 'isstarred' => $isstarred, 'star' => $star, 'drop' => $drop, 'vote' => $likebuttons, 'like' => '', 'dislike' => '', 'comment' => '', 'conv' => $preview ? '' : array('href' => $a->get_baseurl($ssl_state) . '/display/' . $item['guid'], 'title' => t('View in context')), 'previewing' => $previewing, 'wait' => t('Please wait'), 'thread_level' => 1);
                 $arr = array('item' => $item, 'output' => $tmp_item);
                 call_hooks('display_item', $arr);
                 $threads[$threadsid]['id'] = $item['item_id'];
                 $threads[$threadsid]['network'] = $item['item_network'];
                 $threads[$threadsid]['items'] = array($arr['output']);
             }
         } else {
             // Normal View
             $page_template = get_markup_template("threaded_conversation.tpl");
             require_once 'object/Conversation.php';
             require_once 'object/Item.php';
             $conv = new Conversation($mode, $preview);
             // get all the topmost parents
             // this shouldn't be needed, as we should have only them in our array
             // But for now, this array respects the old style, just in case
             $threads = array();
             foreach ($items as $item) {
                 if ($arr_blocked) {
                     $blocked = false;
                     foreach ($arr_blocked as $b) {
                         if ($b && link_compare($item['author-link'], $b)) {
                             $blocked = true;
                             break;
                         }
                     }
                     if ($blocked) {
                         continue;
                     }
                 }
                 // Can we put this after the visibility check?
                 like_puller($a, $item, $alike, 'like');
                 like_puller($a, $item, $dlike, 'dislike');
                 // Only add what is visible
                 if ($item['network'] === NETWORK_MAIL && local_user() != $item['uid']) {
                     continue;
                 }
                 if (!visible_activity($item)) {
                     continue;
                 }
                 call_hooks('display_item', $arr);
                 $item['pagedrop'] = $page_dropping;
                 if ($item['id'] == $item['parent']) {
                     $item_object = new Item($item);
                     $conv->add_thread($item_object);
                 }
             }
             $threads = $conv->get_template_data($alike, $dlike);
             if (!$threads) {
                 logger('[ERROR] conversation : Failed to get template data.', LOGGER_DEBUG);
                 $threads = array();
             }
         }
     }
     $o = replace_macros($page_template, array('$baseurl' => $a->get_baseurl($ssl_state), '$return_path' => $a->query_string, '$live_update' => $live_update_div, '$remove' => t('remove'), '$mode' => $mode, '$user' => $a->user, '$threads' => $threads, '$dropping' => $page_dropping && feature_enabled(local_user(), 'multi_delete') ? t('Delete Selected Items') : False));
     return $o;
 }
Example #6
0
/**
 * @brief "Render" a conversation or list of items for HTML display.
 *
 * There are two major forms of display:
 *  - Sequential or unthreaded ("New Item View" or search results)
 *  - conversation view
 *
 * The $mode parameter decides between the various renderings and also
 * figures out how to determine page owner and other contextual items
 * that are based on unique features of the calling module.
 *
 * @param App &$a
 * @param array $items
 * @param string $mode
 * @param boolean $update
 * @param string $page_mode default traditional
 * @param string $prepared_item
 * @return string
 */
function conversation(&$a, $items, $mode, $update, $page_mode = 'traditional', $prepared_item = '')
{
    $content_html = '';
    $o = '';
    require_once 'bbcode.php';
    $ssl_state = local_channel() ? true : false;
    if (local_channel()) {
        load_pconfig(local_channel(), '');
    }
    $arr_blocked = null;
    if (local_channel()) {
        $str_blocked = get_pconfig(local_channel(), 'system', 'blocked');
    }
    if (!local_channel() && $mode == 'network') {
        $sys = get_sys_channel();
        $id = $sys['channel_id'];
        $str_blocked = get_pconfig($id, 'system', 'blocked');
    }
    if ($str_blocked) {
        $arr_blocked = explode(',', $str_blocked);
        for ($x = 0; $x < count($arr_blocked); $x++) {
            $arr_blocked[$x] = trim($arr_blocked[$x]);
        }
    }
    $profile_owner = 0;
    $page_writeable = false;
    $live_update_div = '';
    $preview = $page_mode === 'preview' ? true : false;
    $previewing = $preview ? ' preview ' : '';
    if ($mode === 'network') {
        $profile_owner = local_channel();
        $page_writeable = true;
        if (!$update) {
            // The special div is needed for liveUpdate to kick in for this page.
            // We only launch liveUpdate if you aren't filtering in some incompatible
            // way and also you aren't writing a comment (discovered in javascript).
            $live_update_div = '<div id="live-network"></div>' . "\r\n" . "<script> var profile_uid = " . $_SESSION['uid'] . "; var netargs = '" . substr($a->cmd, 8) . '?f=' . (x($_GET, 'cid') ? '&cid=' . $_GET['cid'] : '') . (x($_GET, 'search') ? '&search=' . $_GET['search'] : '') . (x($_GET, 'star') ? '&star=' . $_GET['star'] : '') . (x($_GET, 'order') ? '&order=' . $_GET['order'] : '') . (x($_GET, 'bmark') ? '&bmark=' . $_GET['bmark'] : '') . (x($_GET, 'liked') ? '&liked=' . $_GET['liked'] : '') . (x($_GET, 'conv') ? '&conv=' . $_GET['conv'] : '') . (x($_GET, 'spam') ? '&spam=' . $_GET['spam'] : '') . (x($_GET, 'nets') ? '&nets=' . $_GET['nets'] : '') . (x($_GET, 'cmin') ? '&cmin=' . $_GET['cmin'] : '') . (x($_GET, 'cmax') ? '&cmax=' . $_GET['cmax'] : '') . (x($_GET, 'file') ? '&file=' . $_GET['file'] : '') . (x($_GET, 'uri') ? '&uri=' . $_GET['uri'] : '') . "'; var profile_page = " . $a->pager['page'] . "; </script>\r\n";
        }
    } elseif ($mode === 'channel') {
        $profile_owner = $a->profile['profile_uid'];
        $page_writeable = $profile_owner == local_channel();
        if (!$update) {
            $tab = notags(trim($_GET['tab']));
            if ($tab === 'posts') {
                // This is ugly, but we can't pass the profile_uid through the session to the ajax updater,
                // because browser prefetching might change it on us. We have to deliver it with the page.
                $live_update_div = '<div id="live-channel"></div>' . "\r\n" . "<script> var profile_uid = " . $a->profile['profile_uid'] . "; var netargs = '?f='; var profile_page = " . $a->pager['page'] . "; </script>\r\n";
            }
        }
    } elseif ($mode === 'display') {
        $profile_owner = local_channel();
        $page_writeable = false;
        $live_update_div = '<div id="live-display"></div>' . "\r\n";
    } elseif ($mode === 'page') {
        $profile_owner = $a->profile['uid'];
        $page_writeable = $profile_owner == local_channel();
        $live_update_div = '<div id="live-page"></div>' . "\r\n";
    } elseif ($mode === 'search') {
        $live_update_div = '<div id="live-search"></div>' . "\r\n";
    } elseif ($mode === 'photos') {
        $profile_onwer = $a->profile['profile_uid'];
        $page_writeable = $profile_owner == local_channel();
        $live_update_div = '<div id="live-photos"></div>' . "\r\n";
        // for photos we've already formatted the top-level item (the photo)
        $content_html = $a->data['photo_html'];
    }
    $page_dropping = local_channel() && local_channel() == $profile_owner ? true : false;
    if (!feature_enabled($profile_owner, 'multi_delete')) {
        $page_dropping = false;
    }
    $channel = $a->get_channel();
    $observer = $a->get_observer();
    if ($update) {
        $return_url = $_SESSION['return_url'];
    } else {
        $return_url = $_SESSION['return_url'] = $a->query_string;
    }
    load_contact_links(local_channel());
    $cb = array('items' => $items, 'mode' => $mode, 'update' => $update, 'preview' => $preview);
    call_hooks('conversation_start', $cb);
    $items = $cb['items'];
    $conv_responses = array('like' => array('title' => t('Likes', 'title')), 'dislike' => array('title' => t('Dislikes', 'title')), 'agree' => array('title' => t('Agree', 'title')), 'disagree' => array('title' => t('Disagree', 'title')), 'abstain' => array('title' => t('Abstain', 'title')), 'attendyes' => array('title' => t('Attending', 'title')), 'attendno' => array('title' => t('Not attending', 'title')), 'attendmaybe' => array('title' => t('Might attend', 'title')));
    // array with html for each thread (parent+comments)
    $threads = array();
    $threadsid = -1;
    $page_template = get_markup_template("conversation.tpl");
    if ($items) {
        if ($mode === 'network-new' || $mode === 'search' || $mode === 'community') {
            // "New Item View" on network page or search page results
            // - just loop through the items and format them minimally for display
            //$tpl = get_markup_template('search_item.tpl');
            $tpl = 'search_item.tpl';
            foreach ($items as $item) {
                if ($arr_blocked) {
                    $blocked = false;
                    foreach ($arr_blocked as $b) {
                        if ($b && $item['author_xchan'] == $b) {
                            $blocked = true;
                            break;
                        }
                    }
                    if ($blocked) {
                        continue;
                    }
                }
                $threadsid++;
                $comment = '';
                $owner_url = '';
                $owner_photo = '';
                $owner_name = '';
                $sparkle = '';
                if ($mode === 'search' || $mode === 'community') {
                    if ((activity_match($item['verb'], ACTIVITY_LIKE) || activity_match($item['verb'], ACTIVITY_DISLIKE)) && $item['id'] != $item['parent']) {
                        continue;
                    }
                    $nickname = $item['nickname'];
                } else {
                    $nickname = $a->user['nickname'];
                }
                $profile_name = strlen($item['author-name']) ? $item['author-name'] : $item['name'];
                if ($item['author-link'] && !$item['author-name']) {
                    $profile_name = $item['author-link'];
                }
                $tags = array();
                $hashtags = array();
                $mentions = array();
                $sp = false;
                $profile_link = best_link_url($item, $sp);
                if ($sp) {
                    $sparkle = ' sparkle';
                } else {
                    $profile_link = zid($profile_link);
                }
                $normalised = normalise_link(strlen($item['author-link']) ? $item['author-link'] : $item['url']);
                $profile_name = $item['author']['xchan_name'];
                $profile_link = $item['author']['xchan_url'];
                $profile_avatar = $item['author']['xchan_photo_m'];
                $location = format_location($item);
                localize_item($item);
                if ($mode === 'network-new') {
                    $dropping = true;
                } else {
                    $dropping = false;
                }
                $drop = array('pagedropping' => $page_dropping, 'dropping' => $dropping, 'select' => t('Select'), 'delete' => t('Delete'));
                $star = false;
                $isstarred = "unstarred icon-star-empty";
                $lock = $item['item_private'] || strlen($item['allow_cid']) || strlen($item['allow_gid']) || strlen($item['deny_cid']) || strlen($item['deny_gid']) ? t('Private Message') : false;
                $likebuttons = false;
                $shareable = false;
                $verified = $item['item_flags'] & ITEM_VERIFIED ? t('Message signature validated') : '';
                $forged = $item['sig'] && !($item['item_flags'] & ITEM_VERIFIED) ? t('Message signature incorrect') : '';
                $unverified = '';
                $tags = array();
                $terms = get_terms_oftype($item['term'], array(TERM_HASHTAG, TERM_MENTION, TERM_UNKNOWN));
                if (count($terms)) {
                    foreach ($terms as $tag) {
                        $tags[] = format_term_for_display($tag);
                    }
                }
                $body = prepare_body($item, true);
                $tmp_item = array('template' => $tpl, 'toplevel' => 'toplevel_item', 'mode' => $mode, 'id' => $preview ? 'P0' : $item['item_id'], 'linktitle' => sprintf(t('View %s\'s profile @ %s'), $profile_name, $profile_url), 'profile_url' => $profile_link, 'item_photo_menu' => item_photo_menu($item), 'name' => $profile_name, 'sparkle' => $sparkle, 'lock' => $lock, 'thumb' => $profile_avatar, 'title' => $item['title'], 'body' => $body, 'tags' => $tags, 'hashtags' => $hashtags, 'mentions' => $mentions, 'verified' => $verified, 'unverified' => $unverified, 'forged' => $forged, 'txt_cats' => t('Categories:'), 'txt_folders' => t('Filed under:'), 'has_cats' => count($categories) ? 'true' : '', 'has_folders' => count($folders) ? 'true' : '', 'categories' => $categories, 'folders' => $folders, 'text' => strip_tags($body), 'ago' => relative_date($item['created']), 'app' => $item['app'], 'str_app' => sprintf(t(' from %s'), $item['app']), 'isotime' => datetime_convert('UTC', date_default_timezone_get(), $item['created'], 'c'), 'localtime' => datetime_convert('UTC', date_default_timezone_get(), $item['created'], 'r'), 'editedtime' => $item['edited'] != $item['created'] ? sprintf(t('last edited: %s'), datetime_convert('UTC', date_default_timezone_get(), $item['edited'], 'r')) : '', 'expiretime' => $item['expires'] !== NULL_DATE ? sprintf(t('Expires: %s'), datetime_convert('UTC', date_default_timezone_get(), $item['expires'], 'r')) : '', 'location' => $location, 'indent' => '', 'owner_name' => $owner_name, 'owner_url' => $owner_url, 'owner_photo' => $owner_photo, 'plink' => get_plink($item, false), 'edpost' => false, 'isstarred' => $isstarred, 'star' => $star, 'drop' => $drop, 'vote' => $likebuttons, 'like' => '', 'dislike' => '', 'comment' => '', 'conv' => $preview ? '' : array('href' => z_root() . '/display/' . $item['mid'], 'title' => t('View in context')), 'previewing' => $previewing, 'wait' => t('Please wait'), 'thread_level' => 1);
                $arr = array('item' => $item, 'output' => $tmp_item);
                call_hooks('display_item', $arr);
                //				$threads[$threadsid]['id'] = $item['item_id'];
                $threads[] = $arr['output'];
            }
        } else {
            // Normal View
            //			logger('conv: items: ' . print_r($items,true));
            require_once 'include/ConversationObject.php';
            require_once 'include/ItemObject.php';
            $conv = new Conversation($mode, $preview, $prepared_item);
            // In the display mode we don't have a profile owner.
            if ($mode === 'display' && $items) {
                $conv->set_profile_owner($items[0]['uid']);
            }
            // get all the topmost parents
            // this shouldn't be needed, as we should have only them in our array
            // But for now, this array respects the old style, just in case
            $threads = array();
            foreach ($items as $item) {
                // Check for any blocked authors
                if ($arr_blocked) {
                    $blocked = false;
                    foreach ($arr_blocked as $b) {
                        if ($b && $item['author_xchan'] == $b) {
                            $blocked = true;
                            break;
                        }
                    }
                    if ($blocked) {
                        continue;
                    }
                }
                // Check all the kids too
                if ($arr_blocked && $item['children']) {
                    for ($d = 0; $d < count($item['children']); $d++) {
                        foreach ($arr_blocked as $b) {
                            if ($b && $item['children'][$d]['author_xchan'] == $b) {
                                $item['children'][$d]['author_blocked'] = true;
                            }
                        }
                    }
                }
                builtin_activity_puller($item, $conv_responses);
                if (!visible_activity($item)) {
                    continue;
                }
                $item['pagedrop'] = $page_dropping;
                if ($item['id'] == $item['parent']) {
                    $item_object = new Item($item);
                    $conv->add_thread($item_object);
                    if ($page_mode === 'list') {
                        $item_object->set_template('conv_list.tpl');
                        $item_object->set_display_mode('list');
                    }
                }
            }
            $threads = $conv->get_template_data($conv_responses);
            if (!$threads) {
                logger('[ERROR] conversation : Failed to get template data.', LOGGER_DEBUG);
                $threads = array();
            }
        }
    }
    if ($page_mode === 'traditional' || $page_mode === 'preview') {
        $page_template = get_markup_template("threaded_conversation.tpl");
    } elseif ($update) {
        $page_template = get_markup_template("convobj.tpl");
    } else {
        $page_template = get_markup_template("conv_frame.tpl");
        $threads = null;
    }
    //	if($page_mode === 'preview')
    //		logger('preview: ' . print_r($threads,true));
    //  Do not un-comment if smarty3 is in use
    //	logger('page_template: ' . $page_template);
    //	logger('nouveau: ' . print_r($threads,true));
    $o .= replace_macros($page_template, array('$baseurl' => $a->get_baseurl($ssl_state), '$photo_item' => $content_html, '$live_update' => $live_update_div, '$remove' => t('remove'), '$mode' => $mode, '$user' => $a->user, '$threads' => $threads, '$wait' => t('Loading...'), '$dropping' => $page_dropping ? t('Delete Selected Items') : False));
    return $o;
}