diff options
Diffstat (limited to 'include/ItemObject.php')
-rw-r--r-- | include/ItemObject.php | 403 |
1 files changed, 207 insertions, 196 deletions
diff --git a/include/ItemObject.php b/include/ItemObject.php index 45ea6860a..a5870ef91 100644 --- a/include/ItemObject.php +++ b/include/ItemObject.php @@ -1,20 +1,22 @@ -<?php +<?php /** @file */ + if(class_exists('Item')) return; -require_once('object/BaseObject.php'); +require_once('include/BaseObject.php'); require_once('include/text.php'); require_once('boot.php'); /** * An item */ + class Item extends BaseObject { - private $data = array(); + public $data = array(); private $template = 'conv_item.tpl'; private $comment_box_template = 'comment_item.tpl'; + private $commentable = false; private $toplevel = false; - private $writable = false; private $children = array(); private $parent = null; private $conversation = null; @@ -25,46 +27,27 @@ class Item extends BaseObject { private $wall_to_wall = false; private $threaded = false; private $visiting = false; - private $observer = null; private $channel = null; + public function __construct($data) { $a = $this->get_app(); $this->data = $data; - $this->channel = $a->get_channel(); - $this->observer = $a->get_observer(); - $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; -// } -// } -// } - -// fixme - $this->writable = ($this->get_data_value('writable') || $this->get_data_value('self')); -// FIXME - base this on observer permissions - $this->writable = ((local_user() && $channel['channel_hash'] === $item['owner_xchan']) ? true : false); - - - - 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 + * Only add those that will be displayed */ - if(! visible_activity($item)) { + + if((! visible_activity($item)) || array_key_exists('author_blocked',$item)) { continue; } + $child = new Item($item); $this->add_child($child); } @@ -80,10 +63,12 @@ class Item extends BaseObject { */ public function get_template_data($alike, $dlike, $thread_level=1) { + + $t1 = dba_timer(); + $result = array(); $a = $this->get_app(); - $observer = $this->observer; $item = $this->get_data(); $commentww = ''; @@ -91,28 +76,30 @@ class Item extends BaseObject { $buttons = ''; $dropping = false; $star = false; - $isstarred = "unstarred"; + $isstarred = "unstarred icon-star-empty"; $indent = ''; $osparkle = ''; $total_children = $this->count_descendants(); $conv = $this->get_conversation(); + $observer = $conv->get_observer(); - $lock = ((($item['private'] == 1) || (($item['uid'] == local_user()) && (strlen($item['allow_cid']) || strlen($item['allow_gid']) + $lock = ((($item['item_private'] == 1) || (($item['uid'] == local_user()) && (strlen($item['allow_cid']) || strlen($item['allow_gid']) || strlen($item['deny_cid']) || strlen($item['deny_gid'])))) ? t('Private Message') : false); - $shareable = ((($conv->get_profile_owner() == local_user()) && ($item['private'] != 1)) ? true : false); + $shareable = ((($conv->get_profile_owner() == local_user()) && ($item['item_private'] != 1)) ? true : false); + + $mode = $conv->get_mode(); - if(local_user() && link_compare($a->contact['url'],$item['author-link'])) + if(local_user() && $observer['xchan_hash'] === $item['author_xchan']) $edpost = array($a->get_baseurl($ssl_state)."/editpost/".$item['id'], t("Edit")); else $edpost = false; -// FIXME - this is wrong. -// if(($this->get_data_value('uid') == local_user()) || $this->is_visiting()) - - if($this->get_data_value('uid') == local_user()) + if($observer['xchan_hash'] == $this->get_data_value('author_xchan') + || $observer['xchan_hash'] == $this->get_data_value('owner_xchan') + || $this->get_data_value('uid') == local_user()) $dropping = true; if($dropping) { @@ -121,131 +108,185 @@ class Item extends BaseObject { 'delete' => t('Delete'), ); } - +// FIXME if($observer_is_pageowner) { $multidrop = array( 'select' => t('Select'), ); } - $filer = (($conv->get_profile_owner() == local_user()) ? t("save to folder") : false); - - $diff_author = ((link_compare($item['url'],$item['author-link'])) ? false : true); - $profile_name = (((strlen($item['author-name'])) && $diff_author) ? $item['author-name'] : $item['name']); - - $profile_avatar = $item['author']['xchan_photo_m']; - $profile_link = $a->get_baseurl() . '/chanview/?f=&url=' . $item['author']['xchan_url']; - $profile_name = $item['author']['xchan_name']; - -// if($item['author-link'] && (! $item['author-name'])) -// $profile_name = $item['author-link']; - + $filer = (($conv->get_profile_owner() == local_user()) ? t("Save to Folder") : false); $profile_avatar = $item['author']['xchan_photo_m']; + $profile_link = chanlink_url($item['author']['xchan_url']); + $profile_name = $item['author']['xchan_name']; - $locate = array('location' => $item['location'], 'coord' => $item['coord'], 'html' => ''); - call_hooks('render_location',$locate); - $location = ((strlen($locate['html'])) ? $locate['html'] : render_location_google($locate)); + $location = format_location($item); - $tags=array(); - foreach(explode(',',$item['tag']) as $tag){ - $tag = trim($tag); - if ($tag!="") $tags[] = bbcode($tag); + $like_count = ((x($alike,$item['mid'])) ? $alike[$item['mid']] : ''); + $like_list = ((x($alike,$item['mid'])) ? $alike[$item['mid'] . '-l'] : ''); + if (count($like_list) > MAX_LIKERS) { + $like_list_part = array_slice($like_list, 0, MAX_LIKERS); + array_push($like_list_part, '<a href="#" data-toggle="modal" data-target="#likeModal-' . $this->get_id() . '"><b>' . t('View all') . '</b></a>'); + } else { + $like_list_part = ''; + } + $like_button_label = tt('Like','Likes',$like_count,'noun'); + + if (feature_enabled($conv->get_profile_owner(),'dislike')) { + $dislike_count = ((x($dlike,$item['mid'])) ? $dlike[$item['mid']] : ''); + $dislike_list = ((x($dlike,$item['mid'])) ? $dlike[$item['mid'] . '-l'] : ''); + $dislike_button_label = tt('Dislike','Dislikes',$dislike_count,'noun'); + if (count($dislike_list) > MAX_LIKERS) { + $dislike_list_part = array_slice($dislike_list, 0, MAX_LIKERS); + array_push($dislike_list_part, '<a href="#" data-toggle="modal" data-target="#dislikeModal-' . $this->get_id() . '"><b>' . t('View all') . '</b></a>'); + } else { + $dislike_list_part = ''; + } } - $showlike = ((x($alike,$item['uri'])) ? format_like($alike[$item['uri']],$alike[$item['uri'] . '-l'],'like',$item['uri']) : ''); - $showdislike = ((x($dlike,$item['uri']) && feature_enabled($conv->get_profile_owner(),'dislike')) ? format_like($dlike[$item['uri']],$dlike[$item['uri'] . '-l'],'dislike',$item['uri']) : ''); + $showlike = ((x($alike,$item['mid'])) ? format_like($alike[$item['mid']],$alike[$item['mid'] . '-l'],'like',$item['mid']) : ''); + $showdislike = ((x($dlike,$item['mid']) && feature_enabled($conv->get_profile_owner(),'dislike')) + ? format_like($dlike[$item['mid']],$dlike[$item['mid'] . '-l'],'dislike',$item['mid']) : ''); /* * We should avoid doing this all the time, but it depends on the conversation mode * And the conv mode may change when we change the conv, or it changes its mode * Maybe we should establish a way to be notified about conversation changes */ + $this->check_wall_to_wall(); - if($this->is_wall_to_wall() && ($this->get_owner_url() == $this->get_redirect_url())) - $osparkle = ' sparkle'; - if($this->is_toplevel()) { + // FIXME check this permission if($conv->get_profile_owner() == local_user()) { // FIXME we don't need all this stuff, some can be done in the template $star = array( - 'do' => t("add star"), - 'undo' => t("remove star"), - 'toggle' => t("toggle star status"), + 'do' => t("Add Star"), + 'undo' => t("Remove Star"), + 'toggle' => t("Toggle Star Status"), 'classdo' => (($item['item_flags'] & ITEM_STARRED) ? "hidden" : ""), 'classundo' => (($item['item_flags'] & ITEM_STARRED) ? "" : "hidden"), - 'isstarred' => (($item['item_flags'] & ITEM_STARRED) ? "starred" : "unstarred"), + 'isstarred' => (($item['item_flags'] & ITEM_STARRED) ? "starred icon-star" : "unstarred icon-star-empty"), 'starred' => t('starred'), ); - $tagger = array( - 'tagit' => t("add tag"), - 'classtagger' => "", - ); } } else { $indent = 'comment'; } - if($conv->is_writable()) { + + $verified = (($item['item_flags'] & ITEM_VERIFIED) ? t('Message is verified') : ''); + $unverified = '' ; // (($this->is_wall_to_wall() && (! ($item['item_flags'] & ITEM_VERIFIED))) ? t('Message cannot be verified') : ''); + + + + // FIXME - check this permission + if($conv->get_profile_owner() == local_user()) { + $tagger = array( + 'tagit' => t("Add Tag"), + 'classtagger' => "", + ); + } + + $has_bookmarks = false; + if(is_array($item['term'])) { + foreach($item['term'] as $t) { + if($t['type'] == TERM_BOOKMARK) + $has_bookmarks = true; + } + } + + $has_event = false; + if(($item['obj_type'] === ACTIVITY_OBJ_EVENT) && $conv->get_profile_owner() == local_user()) + $has_event = true; + + if($this->is_commentable()) { $like = array( t("I like this \x28toggle\x29"), t("like")); $dislike = array( t("I don't like this \x28toggle\x29"), t("dislike")); if ($shareable) - $share = array( t('Share this'), t('share')); + $share = array( t('Share This'), t('share')); } if(strcmp(datetime_convert('UTC','UTC',$item['created']),datetime_convert('UTC','UTC','now - 12 hours')) > 0) $indent .= ' shiny'; + $t2 = dba_timer(); + localize_item($item); + $t3 = dba_timer(); + $body = prepare_body($item,true); + $t4 = dba_timer(); + $tmp_item = array( 'template' => $this->get_template(), - + 'mode' => $mode, 'type' => implode("",array_slice(explode("/",$item['verb']),-1)), - 'tags' => $tags, + 'tags' => array(), 'body' => $body, - 'text' => strip_tags(template_escape($body)), + 'text' => strip_tags($body), 'id' => $this->get_id(), - 'linktitle' => sprintf( t('View %s\'s profile @ %s'), $profile_name, ((strlen($item['author-link'])) ? $item['author-link'] : $item['url'])), - 'olinktitle' => sprintf( t('View %s\'s profile @ %s'), $this->get_owner_name(), ((strlen($item['owner-link'])) ? $item['owner-link'] : $item['url'])), + 'linktitle' => sprintf( t('View %s\'s profile - %s'), $profile_name, $item['author']['xchan_addr']), + 'olinktitle' => sprintf( t('View %s\'s profile - %s'), $this->get_owner_name(), $item['owner']['xchan_addr']), 'to' => t('to'), + 'via' => t('via'), 'wall' => t('Wall-to-Wall'), 'vwall' => t('via Wall-To-Wall:'), 'profile_url' => $profile_link, 'item_photo_menu' => item_photo_menu($item), - 'name' => template_escape($profile_name), + 'name' => $profile_name, 'thumb' => $profile_avatar, 'osparkle' => $osparkle, 'sparkle' => $sparkle, - 'title' => template_escape($item['title']), + 'title' => $item['title'], + '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'), - 'ago' => (($item['app']) ? sprintf( t('%s from %s'),relative_date($item['created']),$item['app']) : relative_date($item['created'])), + 'editedtime' => (($item['edited'] != $item['created']) ? sprintf( t('last edited: %s'), datetime_convert('UTC', date_default_timezone_get(), $item['edited'], 'r')) : ''), + 'expiretime' => (($item['expires'] !== '0000-00-00 00:00:00') ? sprintf( t('Expires: %s'), datetime_convert('UTC', date_default_timezone_get(), $item['expires'], 'r')):''), 'lock' => $lock, - 'location' => template_escape($location), + 'verified' => $verified, + 'unverified' => $unverified, + 'location' => $location, 'indent' => $indent, 'owner_url' => $this->get_owner_url(), 'owner_photo' => $this->get_owner_photo(), - 'owner_name' => template_escape($this->get_owner_name()), + 'owner_name' => $this->get_owner_name(), // Item toolbar buttons 'like' => $like, 'dislike' => ((feature_enabled($conv->get_profile_owner(),'dislike')) ? $dislike : ''), 'share' => $share, + 'rawmid' => $item['mid'], 'plink' => get_plink($item), 'edpost' => ((feature_enabled($conv->get_profile_owner(),'edit_posts')) ? $edpost : ''), 'star' => ((feature_enabled($conv->get_profile_owner(),'star_posts')) ? $star : ''), 'tagger' => ((feature_enabled($conv->get_profile_owner(),'commtag')) ? $tagger : ''), 'filer' => ((feature_enabled($conv->get_profile_owner(),'filing')) ? $filer : ''), + 'bookmark' => (($conv->get_profile_owner() == local_user() && $has_bookmarks) ? t('Save Bookmarks') : ''), + 'addtocal' => (($has_event) ? t('Add to Calendar') : ''), 'drop' => $drop, 'multidrop' => ((feature_enabled($conv->get_profile_owner(),'multi_delete')) ? $multidrop : ''), // end toolbar buttons - + 'like_count' => $like_count, + 'like_list' => $like_list, + 'like_list_part' => $like_list_part, + 'like_button_label' => $like_button_label, + 'like_modal_title' => t('Likes','noun'), + 'dislike_modal_title' => t('Dislikes','noun'), + 'dislike_count' => ((feature_enabled($conv->get_profile_owner(),'dislike')) ? $dislike_count : ''), + 'dislike_list' => ((feature_enabled($conv->get_profile_owner(),'dislike')) ? $dislike_list : ''), + 'dislike_list_part' => ((feature_enabled($conv->get_profile_owner(),'dislike')) ? $dislike_list_part : ''), + 'dislike_button_label' => ((feature_enabled($conv->get_profile_owner(),'dislike')) ? $dislike_button_label : ''), + 'modal_dismiss' => t('Close'), 'showlike' => $showlike, 'showdislike' => $showdislike, 'comment' => $this->get_comment_box($indent), @@ -254,6 +295,8 @@ class Item extends BaseObject { 'thread_level' => $thread_level ); + $t5 = dba_timer(); + $arr = array('item' => $item, 'output' => $tmp_item); call_hooks('display_item', $arr); @@ -270,7 +313,7 @@ class Item extends BaseObject { if(($nb_children > 2) || ($thread_level > 1)) { $result['children'][0]['comment_firstcollapsed'] = true; $result['children'][0]['num_comments'] = sprintf( tt('%d comment','%d comments',$total_children),$total_children ); - $result['children'][0]['hide_text'] = t('show more'); + $result['children'][0]['hide_text'] = t('[+] show all'); if($thread_level > 1) { $result['children'][$nb_children - 1]['comment_lastcollapsed'] = true; } @@ -280,7 +323,7 @@ class Item extends BaseObject { } } - $result['private'] = $item['private']; + $result['private'] = $item['item_private']; $result['toplevel'] = ($this->is_toplevel() ? 'toplevel_item' : ''); if($this->is_threaded()) { @@ -291,6 +334,14 @@ class Item extends BaseObject { $result['flatten'] = true; $result['threaded'] = false; } + $t6 = dba_timer(); + +// profiler($t1,$t2,'t2'); +// profiler($t2,$t3,'t3'); +// profiler($t3,$t4,'t4'); +// profiler($t4,$t5,'t5'); +// profiler($t5,$t6,'t6'); +// profiler($t1,$t6,'item total'); return $result; } @@ -303,6 +354,16 @@ class Item extends BaseObject { return $this->threaded; } + public function set_commentable($val) { + $this->commentable = $val; + foreach($this->get_children() as $child) + $child->set_commentable($val); + } + + public function is_commentable() { + return $this->commentable; + } + /** * Add a child item */ @@ -444,6 +505,11 @@ class Item extends BaseObject { return $this->template; } + + private function set_template($t) { + $this->template = $t; + } + /** * Check if this is a toplevel post */ @@ -452,22 +518,6 @@ class Item extends BaseObject { } /** - * Check if this is writable - */ - private function is_writable() { - $conv = $this->get_conversation(); - - return true; - - if($conv) { - // This will allow us to comment on wall-to-wall items owned by our friends - // and community forums even if somebody else wrote the post. - return ($this->writable || ($this->is_visiting() && $conv->get_mode() == 'channel')); - } - return $this->writable; - } - - /** * Count the total of our descendants */ private function count_descendants() { @@ -496,57 +546,57 @@ class Item extends BaseObject { * _ false on failure */ private function get_comment_box($indent) { + if(!$this->is_toplevel() && !get_config('system','thread_allow')) { return ''; } $comment_box = ''; $conv = $this->get_conversation(); + +// logger('Commentable conv: ' . $conv->is_commentable()); + + if(! $this->is_commentable()) + return; + $template = get_markup_template($this->get_comment_box_template()); - $ww = ''; - if( ($conv->get_mode() === 'network') && $this->is_wall_to_wall() ) - $ww = 'ww'; - - if($conv->is_writable() && $this->is_writable()) { - $a = $this->get_app(); - $qc = $qcomment = null; - - /* - * Hmmm, code depending on the presence of a particular plugin? - * This should be better if done by a hook - */ - if(in_array('qcomment',$a->plugins)) { - $qc = ((local_user()) ? get_pconfig(local_user(),'qcomment','words') : null); - $qcomment = (($qc) ? explode("\n",$qc) : null); - } - $comment_box = replace_macros($template,array( - '$return_path' => '', - '$threaded' => $this->is_threaded(), - '$jsreload' => (($conv->get_mode() === 'display') ? $_SESSION['return_url'] : ''), - '$type' => (($conv->get_mode() === 'channel') ? 'wall-comment' : 'net-comment'), - '$id' => $this->get_id(), - '$parent' => $this->get_id(), - '$qcomment' => $qcomment, - '$profile_uid' => $conv->get_profile_owner(), - '$mylink' => $this->observer['xchan_url'], - '$mytitle' => t('This is you'), - '$myphoto' => $this->observer['xchan_photo_s'], - '$comment' => t('Comment'), - '$submit' => t('Submit'), - '$edbold' => t('Bold'), - '$editalic' => t('Italic'), - '$eduline' => t('Underline'), - '$edquote' => t('Quote'), - '$edcode' => t('Code'), - '$edimg' => t('Image'), - '$edurl' => t('Link'), - '$edvideo' => t('Video'), - '$preview' => ((feature_enabled($conv->get_profile_owner(),'preview')) ? t('Preview') : ''), - '$indent' => $indent, - '$sourceapp' => t($a->sourcename), - '$ww' => (($conv->get_mode() === 'network') ? $ww : '') - )); - } + + $a = $this->get_app(); + $observer = $conv->get_observer(); + + $qc = ((local_user()) ? get_pconfig(local_user(),'system','qcomment') : null); + $qcomment = (($qc) ? explode("\n",$qc) : null); + + $comment_box = replace_macros($template,array( + '$return_path' => '', + '$threaded' => $this->is_threaded(), + '$jsreload' => (($conv->get_mode() === 'display') ? $_SESSION['return_url'] : ''), + '$type' => (($conv->get_mode() === 'channel') ? 'wall-comment' : 'net-comment'), + '$id' => $this->get_id(), + '$parent' => $this->get_id(), + '$qcomment' => $qcomment, + '$profile_uid' => $conv->get_profile_owner(), + '$mylink' => $observer['xchan_url'], + '$mytitle' => t('This is you'), + '$myphoto' => $observer['xchan_photo_s'], + '$comment' => t('Comment'), + '$submit' => t('Submit'), + '$edbold' => t('Bold'), + '$editalic' => t('Italic'), + '$eduline' => t('Underline'), + '$edquote' => t('Quote'), + '$edcode' => t('Code'), + '$edimg' => t('Image'), + '$edurl' => t('Link'), + '$edvideo' => t('Video'), + '$preview' => ((feature_enabled($conv->get_profile_owner(),'preview')) ? t('Preview') : ''), + '$indent' => $indent, + '$feature_encrypt' => ((feature_enabled($conv->get_profile_owner(),'content_encrypt')) ? true : false), + '$encrypt' => t('Encrypt text'), + '$cipher' => $conv->get_cipher(), + '$sourceapp' => get_app()->sourcename + + )); return $comment_box; } @@ -559,59 +609,20 @@ class Item extends BaseObject { * Check if we are a wall to wall item and set the relevant properties */ protected function check_wall_to_wall() { - $a = $this->get_app(); $conv = $this->get_conversation(); $this->wall_to_wall = false; - - if($this->is_toplevel()) { - if( (! $this->get_data_value('self')) && ($conv->get_mode() !== 'channel')) { - if($this->get_data_value('wall')) { - - // On the network page, I am the owner. On the display page it will be the profile owner. - // This will have been stored in $a->page_contact by our calling page. - // Put this person as the wall owner of the wall-to-wall notice. + $this->owner_url = ''; + $this->owner_photo = ''; + $this->owner_name = ''; - $this->owner_url = zid($a->page_contact['url']); - $this->owner_photo = $a->page_contact['thumb']; - $this->owner_name = $a->page_contact['name']; - $this->wall_to_wall = true; - } - else if($this->get_data_value('owner-link')) { - - $owner_linkmatch = (($this->get_data_value('owner-link')) && link_compare($this->get_data_value('owner-link'),$this->get_data_value('author-link'))); - $alias_linkmatch = (($this->get_data_value('alias')) && link_compare($this->get_data_value('alias'),$this->get_data_value('author-link'))); - $owner_namematch = (($this->get_data_value('owner-name')) && $this->get_data_value('owner-name') == $this->get_data_value('author-name')); - if((! $owner_linkmatch) && (! $alias_linkmatch) && (! $owner_namematch)) { - - // The author url doesn't match the owner (typically the contact) - // and also doesn't match the contact alias. - // The name match is a hack to catch several weird cases where URLs are - // all over the park. It can be tricked, but this prevents you from - // seeing "Bob Smith to Bob Smith via Wall-to-wall" and you know darn - // well that it's the same Bob Smith. - - // But it could be somebody else with the same name. It just isn't highly likely. - - - $this->owner_photo = $this->get_data_value('owner-avatar'); - $this->owner_name = $this->get_data_value('owner-name'); - $this->wall_to_wall = true; - // If it is our contact, use a friendly redirect link - if((link_compare($this->get_data_value('owner-link'),$this->get_data_value('url'))) - && ($this->get_data_value('network') === NETWORK_DFRN)) { - $this->owner_url = $this->get_redirect_url(); - } - else - $this->owner_url = zid($this->get_data_value('owner-link')); - } - } - } - } - - if(!$this->wall_to_wall) { - $this->owner_url = ''; - $this->owner_photo = ''; - $this->owner_name = ''; + if($conv->get_mode() === 'channel') + return; + + if($this->is_toplevel() && ($this->get_data_value('author_xchan') != $this->get_data_value('owner_xchan'))) { + $this->owner_url = chanlink_url($this->data['owner']['xchan_url']); + $this->owner_photo = $this->data['owner']['xchan_photo_m']; + $this->owner_name = $this->data['owner']['xchan_name']; + $this->wall_to_wall = true; } } |