Exemple #1
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;
}