diff options
Diffstat (limited to 'include')
-rwxr-xr-x | include/Scrape.php | 5 | ||||
-rwxr-xr-x | include/acl_selectors.php | 7 | ||||
-rwxr-xr-x | include/conversation.php | 230 | ||||
-rwxr-xr-x | include/enotify.php | 36 | ||||
-rwxr-xr-x | include/html2bbcode.php | 4 | ||||
-rwxr-xr-x | include/items.php | 108 | ||||
-rwxr-xr-x | include/nav.php | 3 | ||||
-rwxr-xr-x | include/notifier.php | 2 | ||||
-rwxr-xr-x | include/security.php | 86 | ||||
-rwxr-xr-x | include/template_processor.php | 87 | ||||
-rw-r--r--[-rwxr-xr-x] | include/text.php | 43 |
11 files changed, 405 insertions, 206 deletions
diff --git a/include/Scrape.php b/include/Scrape.php index 4c4ad3cdb..8344aa737 100755 --- a/include/Scrape.php +++ b/include/Scrape.php @@ -255,6 +255,11 @@ function scrape_feed($url) { } } } + // perhaps an RSS version 1 feed with a generic or incorrect content-type? + if(stristr($s,'</item>')) { + $ret['feed_rss'] = $url; + return $ret; + } } try { diff --git a/include/acl_selectors.php b/include/acl_selectors.php index 6070b7db2..67d8cebde 100755 --- a/include/acl_selectors.php +++ b/include/acl_selectors.php @@ -1,6 +1,11 @@ <?php +/** + * + */ - +/** + * @package acl_selectors + */ function group_select($selname,$selclass,$preselected = false,$size = 4) { $a = get_app(); diff --git a/include/conversation.php b/include/conversation.php index bd9b11bee..4b2ca316b 100755 --- a/include/conversation.php +++ b/include/conversation.php @@ -6,11 +6,6 @@ function localize_item(&$item){ $Text = $item['body']; - - - // find private image (w/data url) if present and convert image - // link to a magic-auth redirect. - $saved_image = ''; $img_start = strpos($Text,'[img]data:'); $img_end = strpos($Text,'[/img]'); @@ -184,8 +179,11 @@ function localize_item(&$item){ * that are based on unique features of the calling module. * */ + +if(!function_exists('conversation')) { function conversation(&$a, $items, $mode, $update, $preview = false) { + require_once('bbcode.php'); $profile_owner = 0; @@ -221,7 +219,7 @@ function conversation(&$a, $items, $mode, $update, $preview = false) { if($update) $return_url = $_SESSION['return_url']; else - $return_url = $_SESSION['return_url'] = $a->cmd; + $return_url = $_SESSION['return_url'] = $a->query_string; load_contact_links(local_user()); @@ -231,13 +229,13 @@ function conversation(&$a, $items, $mode, $update, $preview = false) { $items = $cb['items']; $cmnt_tpl = get_markup_template('comment_item.tpl'); - $tpl = get_markup_template('wall_item.tpl'); - $wallwall = get_markup_template('wallwall_item.tpl'); + $tpl = 'wall_item.tpl'; + $wallwall = 'wallwall_item.tpl'; $hide_comments_tpl = get_markup_template('hide_comments.tpl'); $alike = array(); $dlike = array(); - $o = ""; + // array with html for each thread (parent+comments) $threads = array(); @@ -250,7 +248,8 @@ function conversation(&$a, $items, $mode, $update, $preview = false) { // "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 = get_markup_template('search_item.tpl'); + $tpl = 'search_item.tpl'; foreach($items as $item) { $threadsid++; @@ -316,43 +315,46 @@ function conversation(&$a, $items, $mode, $update, $preview = false) { $body = prepare_body($item,true); - $tmp_item = replace_macros($tpl,array( - '$id' => (($preview) ? 'P0' : $item['item_id']), - '$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' => template_escape($profile_name), - '$sparkle' => $sparkle, - '$lock' => $lock, - '$thumb' => $profile_avatar, - '$title' => template_escape($item['title']), - '$body' => template_escape($body), - '$ago' => (($item['app']) ? sprintf( t('%s from %s'),relative_date($item['created']),$item['app']) : relative_date($item['created'])), - '$lock' => $lock, - '$location' => template_escape($location), - '$indent' => '', - '$owner_name' => template_escape($owner_name), - '$owner_url' => $owner_url, - '$owner_photo' => $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() . '/display/' . $nickname . '/' . $item['id'], 'title'=> t('View in context'))), - '$previewing' => $previewing, - '$wait' => t('Please wait'), - )); + //$tmp_item = replace_macros($tpl,array( + $tmp_item = array( + 'template' => $tpl, + 'id' => (($preview) ? 'P0' : $item['item_id']), + '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' => template_escape($profile_name), + 'sparkle' => $sparkle, + 'lock' => $lock, + 'thumb' => $profile_avatar, + 'title' => template_escape($item['title']), + 'body' => template_escape($body), + 'text' => strip_tags(template_escape($body)), + 'ago' => (($item['app']) ? sprintf( t('%s from %s'),relative_date($item['created']),$item['app']) : relative_date($item['created'])), + 'lock' => $lock, + 'location' => template_escape($location), + 'indent' => '', + 'owner_name' => template_escape($owner_name), + 'owner_url' => $owner_url, + 'owner_photo' => $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() . '/display/' . $nickname . '/' . $item['id'], 'title'=> t('View in context'))), + 'previewing' => $previewing, + 'wait' => t('Please wait'), + ); $arr = array('item' => $item, 'output' => $tmp_item); call_hooks('display_item', $arr); $threads[$threadsid]['id'] = $item['item_id']; - $threads[$threadsid]['html'] .= $arr['output']; + $threads[$threadsid]['items'] = array($arr['output']); } @@ -386,6 +388,8 @@ function conversation(&$a, $items, $mode, $update, $preview = false) { } $comments_collapsed = false; + $comment_lastcollapsed = false; + $comment_firstcollapsed = false; $blowhard = 0; $blowhard_count = 0; @@ -417,39 +421,26 @@ function conversation(&$a, $items, $mode, $update, $preview = false) { $toplevelprivate = (($toplevelpost && $item['private']) ? true : false); $item_writeable = (($item['writable'] || $item['self']) ? true : false); - // DISABLED - /* - if($blowhard == $item['cid'] && (! $item['self']) && ($mode != 'profile') && ($mode != 'notes')) { - $blowhard_count ++; - if($blowhard_count == 3) { - $o .= '<div class="icollapse-wrapper fakelink" id="icollapse-wrapper-' . $item['parent'] - . '" onclick="openClose(' . '\'icollapse-' . $item['parent'] . '\'); $(\'#icollapse-wrapper-' . $item['parent'] . '\').hide();" >' - . t('See more posts like this') . '</div>' . '<div class="icollapse" id="icollapse-' - . $item['parent'] . '" style="display: none;" >'; - } - } - else { - $blowhard = $item['cid']; - if($blowhard_count >= 3) - $o .= '</div>'; - $blowhard_count = 0; - } - // END DISABLED - */ - $comments_seen = 0; $comments_collapsed = false; + $comment_lastcollapsed = false; + $comment_firstcollapsed = false; $threadsid++; $threads[$threadsid]['id'] = $item['item_id']; - $threads[$threadsid]['html'] = ""; + $threads[$threadsid]['private'] = $item['private']; + $threads[$threadsid]['items'] = array(); } else { - // prevent private email from leaking into public conversation - if((! $toplevelpost) && (! $toplevelprivate) && ($item['private']) && ($profile_owner != local_user())) + + // prevent private email reply to public conversation from leaking. + if($item['private'] && ! $threads[$threadsid]['private']) continue; + $comments_seen ++; + $comment_lastcollapsed = false; + $comment_firstcollapsed = false; } $override_comment_box = ((($page_writeable) && ($item_writeable)) ? true : false); @@ -457,23 +448,17 @@ function conversation(&$a, $items, $mode, $update, $preview = false) { if(($comments[$item['parent']] > 2) && ($comments_seen <= ($comments[$item['parent']] - 2)) && ($item['gravity'] == 6)) { - if(! $comments_collapsed) { - // IMPORTANT: the closing </div> in the hide_comments template - // is supplied below in code. - - $threads[$threadsid]['html'] .= replace_macros($hide_comments_tpl,array( - '$id' => $item['parent'], - '$num_comments' => sprintf( tt('%d comment','%d comments',$comments[$item['parent']]), - $comments[$item['parent']]), - '$display' => 'none', - '$hide_text' => t('show more') - )); + if (!$comments_collapsed){ + $threads[$threadsid]['num_comments'] = sprintf( tt('%d comment','%d comments',$comments[$item['parent']]),$comments[$item['parent']] ); + $threads[$threadsid]['hide_text'] = t('show more'); $comments_collapsed = true; + $comment_firstcollapsed = true; } } if(($comments[$item['parent']] > 2) && ($comments_seen == ($comments[$item['parent']] - 1))) { - $threads[$threadsid]['html'] .= '</div>'; + + $comment_lastcollapsed = true; } $redirect_url = $a->get_baseurl() . '/redir/' . $item['cid'] ; @@ -503,7 +488,7 @@ function conversation(&$a, $items, $mode, $update, $preview = false) { $template = $wallwall; $commentww = 'ww'; } - if((! $item['wall']) && (strlen($item['owner-link'])) && ($item['owner-link'] != $item['author-link'])) { + if((! $item['wall']) && (strlen($item['owner-link'])) && (! link_compare($item['owner-link'],$item['author-link']))) { // Could be anybody. @@ -650,63 +635,72 @@ function conversation(&$a, $items, $mode, $update, $preview = false) { // Build the HTML $body = prepare_body($item,true); + //$tmp_item = replace_macros($template, + $tmp_item = array( + // collapse comments in template. I don't like this much... + 'comment_firstcollapsed' => $comment_firstcollapsed, + 'comment_lastcollapsed' => $comment_lastcollapsed, + // template to use to render item (wall, walltowall, search) + 'template' => $template, + + 'type' => implode("",array_slice(split("/",$item['verb']),-1)), + 'tags' => $tags, + 'body' => template_escape($body), + 'text' => strip_tags(template_escape($body)), + 'id' => $item['item_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'), $profile_name, ((strlen($item['owner-link'])) ? $item['owner-link'] : $item['url'])), + 'to' => t('to'), + '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), + 'thumb' => $profile_avatar, + 'osparkle' => $osparkle, + 'sparkle' => $sparkle, + 'title' => template_escape($item['title']), + 'ago' => (($item['app']) ? sprintf( t('%s from %s'),relative_date($item['created']),$item['app']) : relative_date($item['created'])), + 'lock' => $lock, + 'location' => template_escape($location), + 'indent' => $indent, + 'owner_url' => $owner_url, + 'owner_photo' => $owner_photo, + 'owner_name' => template_escape($owner_name), + 'plink' => get_plink($item), + 'edpost' => $edpost, + 'isstarred' => $isstarred, + 'star' => $star, + 'drop' => $drop, + 'vote' => $likebuttons, + 'like' => $like, + 'dislike' => $dislike, + 'comment' => $comment, + 'previewing' => $previewing, + 'wait' => t('Please wait'), - $tmp_item = replace_macros($template,array( - '$type' => implode("",array_slice(explode("/",$item['verb']),-1)), - '$tags' => $tags, - '$body' => template_escape($body), - '$id' => $item['item_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'), $profile_name, ((strlen($item['owner-link'])) ? $item['owner-link'] : $item['url'])), - '$to' => t('to'), - '$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), - '$thumb' => $profile_avatar, - '$osparkle' => $osparkle, - '$sparkle' => $sparkle, - '$title' => template_escape($item['title']), - '$ago' => (($item['app']) ? sprintf( t('%s from %s'),relative_date($item['created']),$item['app']) : relative_date($item['created'])), - '$lock' => $lock, - '$location' => template_escape($location), - '$indent' => $indent, - '$owner_url' => $owner_url, - '$owner_photo' => $owner_photo, - '$owner_name' => template_escape($owner_name), - '$plink' => get_plink($item), - '$edpost' => $edpost, - '$isstarred' => $isstarred, - '$star' => $star, - '$drop' => $drop, - '$vote' => $likebuttons, - '$like' => $like, - '$dislike' => $dislike, - '$comment' => $comment, - '$previewing' => $previewing, - '$wait' => t('Please wait'), - - )); + ); $arr = array('item' => $item, 'output' => $tmp_item); call_hooks('display_item', $arr); - $threads[$threadsid]['html'] .= $arr['output']; + $threads[$threadsid]['items'][] = $arr['output']; } } } - $page_template = get_markup_template("conversation.tpl"); $o .= replace_macros($page_template, array( + '$baseurl' => $a->get_baseurl(), + '$mode' => $mode, + '$user' => $a->user, '$threads' => $threads, '$dropping' => ($dropping?t('Delete Selected Items'):False), )); return $o; -} +}} function best_link_url($item,&$sparkle) { diff --git a/include/enotify.php b/include/enotify.php index 76e7eb9dc..a505f1f04 100755 --- a/include/enotify.php +++ b/include/enotify.php @@ -25,6 +25,9 @@ function notification($params) { $title = $body = ''; } + // e.g. "your post", "David's photo", etc. + $possess_desc = t('%s <!item_type!>'); + if($params['type'] == NOTIFY_MAIL) { $subject = sprintf( t('[Friendica:Notify] New mail received at %s'),$sitename); @@ -41,7 +44,32 @@ function notification($params) { // logger("notification: params = " . print_r($params, true), LOGGER_DEBUG); $parent_id = $params['parent']; + + + // if it's a post figure out who's post it is. + + $p = null; + + if($params['otype'] === 'item' && $parent_id) { + $p = q("select * from item where id = %d and uid = %d limit 1", + intval($parent_id), + intval($params['uid']) + ); + } + + $possess_desc = str_replace('<!item_type!>',item_post_type($p[0]),$possess_desc); + + // "a post" + $dest_str = sprintf($possess_desc,'a'); + + // "George Bull's post" + if($p) + $dest_str = sprintf($possess_desc,sprintf( t("%s's"),$p[0]['author-name'])); + // "your post" + if($p[0]['owner-name'] == $p[0]['author-name'] && $p[0]['wall']) + $dest_str = sprintf($possess_desc, t('your') ); + // 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 @@ -49,7 +77,7 @@ function notification($params) { $subject = sprintf( t('[Friendica:Notify] Comment to conversation #%d by %s'), $parent_id, $params['source_name']); $preamble = sprintf( t('%s commented on an item/conversation you have been following.'), $params['source_name']); - $epreamble = sprintf( t('%s commented in %s.'), '[url=' . $params['source_link'] . ']' . $params['source_name'] . '[/url]', '[url=$itemlink]' . t('a watched conversation') . '[/url]'); + $epreamble = sprintf( t('%s commented on %s.'), '[url=' . $params['source_link'] . ']' . $params['source_name'] . '[/url]', '[url=$itemlink]' . $dest_str . '[/url]'); $sitelink = t('Please visit %s to view and/or reply to the conversation.'); $tsitelink = sprintf( $sitelink, $siteurl ); @@ -149,6 +177,7 @@ function notification($params) { $datarray['date'] = datetime_convert(); $datarray['uid'] = $params['uid']; $datarray['link'] = $itemlink; + $datarray['parent'] = $parent_id; $datarray['type'] = $params['type']; $datarray['verb'] = $params['verb']; $datarray['otype'] = $params['otype']; @@ -157,8 +186,8 @@ function notification($params) { // create notification entry in DB - $r = q("insert into notify (hash,name,url,photo,date,uid,link,type,verb,otype) - values('%s','%s','%s','%s','%s',%d,'%s',%d,'%s','%s')", + $r = q("insert into notify (hash,name,url,photo,date,uid,link,parent,type,verb,otype) + values('%s','%s','%s','%s','%s',%d,'%s',%d,%d,'%s','%s')", dbesc($datarray['hash']), dbesc($datarray['name']), dbesc($datarray['url']), @@ -166,6 +195,7 @@ function notification($params) { dbesc($datarray['date']), intval($datarray['uid']), dbesc($datarray['link']), + intval($datarray['parent']), intval($datarray['type']), dbesc($datarray['verb']), dbesc($datarray['otype']) diff --git a/include/html2bbcode.php b/include/html2bbcode.php index 65920380b..32a90d7d6 100755 --- a/include/html2bbcode.php +++ b/include/html2bbcode.php @@ -10,7 +10,7 @@ Originally made for the syncom project: http://wiki.piratenpartei.de/Syncom function node2bbcode(&$doc, $oldnode, $attributes, $startbb, $endbb) { do { - $done = node2bbcodesub(&$doc, $oldnode, $attributes, $startbb, $endbb); + $done = node2bbcodesub($doc, $oldnode, $attributes, $startbb, $endbb); } while ($done); } @@ -212,7 +212,7 @@ function html2bbcode($message) node2bbcode($doc, 'audio', array('src'=>'/(.+)/'), '[audio]$1', '[/audio]'); node2bbcode($doc, 'iframe', array('src'=>'/(.+)/'), '[iframe]$1', '[/iframe]'); - node2bbcode($doc, 'code', array(), '[code]$1', '[/code]'); + node2bbcode($doc, 'code', array(), '[code]', '[/code]'); $message = $doc->saveHTML(); diff --git a/include/items.php b/include/items.php index 5268dfc1d..70c72ae16 100755 --- a/include/items.php +++ b/include/items.php @@ -1598,6 +1598,14 @@ function consume_feed($xml,$importer,&$contact, &$hub, $datedir = 0, $pass = 0) if((activity_match($datarray['verb'],ACTIVITY_LIKE)) || (activity_match($datarray['verb'],ACTIVITY_DISLIKE))) { $datarray['type'] = 'activity'; $datarray['gravity'] = GRAVITY_LIKE; + // only one like or dislike per person + $r = q("select id from item where uid = %d and `contact-id` = %d and verb ='%s' and deleted = 0 limit 1", + intval($datarray['uid']), + intval($datarray['contact-id']), + dbesc($datarray['verb']) + ); + if($r && count($r)) + continue; } if(($datarray['verb'] === ACTIVITY_TAG) && ($datarray['object-type'] === ACTIVITY_OBJ_TAGTERM)) { @@ -1750,6 +1758,18 @@ function consume_feed($xml,$importer,&$contact, &$hub, $datedir = 0, $pass = 0) $datarray['parent-uri'] = $item_id; $datarray['uid'] = $importer['uid']; $datarray['contact-id'] = $contact['id']; + + if(! link_compare($datarray['owner-link'],$contact['url'])) { + // The item owner info is not our contact. It's OK and is to be expected if this is a tgroup delivery, + // but otherwise there's a possible data mixup on the sender's system. + // the tgroup delivery code called from item_store will correct it if it's a forum, + // but we're going to unconditionally correct it here so that the post will always be owned by our contact. + logger('local_delivery: Correcting item owner.', LOGGER_DEBUG); + $datarray['owner-name'] = $contact['name']; + $datarray['owner-link'] = $contact['url']; + $datarray['owner-avatar'] = $contact['thumb']; + } + $r = item_store($datarray); continue; @@ -2139,6 +2159,14 @@ function local_delivery($importer,$data) { $datarray['type'] = 'activity'; $datarray['gravity'] = GRAVITY_LIKE; $datarray['last-child'] = 0; + // only one like or dislike per person + $r = q("select id from item where uid = %d and `contact-id` = %d and verb ='%s' and deleted = 0 limit 1", + intval($datarray['uid']), + intval($datarray['contact-id']), + dbesc($datarray['verb']) + ); + if($r && count($r)) + continue; } if(($datarray['verb'] === ACTIVITY_TAG) && ($datarray['object-type'] === ACTIVITY_OBJ_TAGTERM)) { @@ -2288,6 +2316,15 @@ function local_delivery($importer,$data) { if(($datarray['verb'] == ACTIVITY_LIKE) || ($datarray['verb'] == ACTIVITY_DISLIKE)) { $datarray['type'] = 'activity'; $datarray['gravity'] = GRAVITY_LIKE; + // only one like or dislike per person + $r = q("select id from item where uid = %d and `contact-id` = %d and verb ='%s' and deleted = 0 limit 1", + intval($datarray['uid']), + intval($datarray['contact-id']), + dbesc($datarray['verb']) + ); + if($r && count($r)) + continue; + } if(($datarray['verb'] === ACTIVITY_TAG) && ($datarray['object-type'] === ACTIVITY_OBJ_TAGTERM)) { @@ -2328,35 +2365,44 @@ function local_delivery($importer,$data) { if(count($myconv)) { $importer_url = $a->get_baseurl() . '/profile/' . $importer['nickname']; - foreach($myconv as $conv) { - if(! link_compare($conv['author-link'],$importer_url)) - continue; + // first make sure this isn't our own post coming back to us from a wall-to-wall event + if(! link_compare($datarray['author-link'],$importer_url)) { - require_once('include/enotify.php'); - $conv_parent = $conv['parent']; - - notification(array( - 'type' => NOTIFY_COMMENT, - 'notify_flags' => $importer['notify-flags'], - 'language' => $importer['language'], - 'to_name' => $importer['username'], - 'to_email' => $importer['email'], - 'uid' => $importer['importer_uid'], - 'item' => $datarray, - 'link' => $a->get_baseurl() . '/display/' . $importer['nickname'] . '/' . $posted_id, - 'source_name' => stripslashes($datarray['author-name']), - 'source_link' => $datarray['author-link'], - 'source_photo' => ((link_compare($datarray['author-link'],$importer['url'])) - ? $importer['thumb'] : $datarray['author-avatar']), - 'verb' => ACTIVITY_POST, - 'otype' => 'item', - 'parent' => $conv_parent, + foreach($myconv as $conv) { - )); + // now if we find a match, it means we're in this conversation + + if(! link_compare($conv['author-link'],$importer_url)) + continue; - break; + require_once('include/enotify.php'); + + $conv_parent = $conv['parent']; + + notification(array( + 'type' => NOTIFY_COMMENT, + 'notify_flags' => $importer['notify-flags'], + 'language' => $importer['language'], + 'to_name' => $importer['username'], + 'to_email' => $importer['email'], + 'uid' => $importer['importer_uid'], + 'item' => $datarray, + 'link' => $a->get_baseurl() . '/display/' . $importer['nickname'] . '/' . $posted_id, + 'source_name' => stripslashes($datarray['author-name']), + 'source_link' => $datarray['author-link'], + 'source_photo' => ((link_compare($datarray['author-link'],$importer['url'])) + ? $importer['thumb'] : $datarray['author-avatar']), + 'verb' => ACTIVITY_POST, + 'otype' => 'item', + 'parent' => $conv_parent, + + )); + + // only send one notification + break; + } } } } @@ -2427,12 +2473,24 @@ function local_delivery($importer,$data) { // This is my contact on another system, but it's really me. // Turn this into a wall post. - if($contact['remote_self']) + if($importer['remote_self']) $datarray['wall'] = 1; $datarray['parent-uri'] = $item_id; $datarray['uid'] = $importer['importer_uid']; $datarray['contact-id'] = $importer['id']; + + if(! link_compare($datarray['owner-link'],$contact['url'])) { + // The item owner info is not our contact. It's OK and is to be expected if this is a tgroup delivery, + // but otherwise there's a possible data mixup on the sender's system. + // the tgroup delivery code called from item_store will correct it if it's a forum, + // but we're going to unconditionally correct it here so that the post will always be owned by our contact. + logger('local_delivery: Correcting item owner.', LOGGER_DEBUG); + $datarray['owner-name'] = $importer['senderName']; + $datarray['owner-link'] = $importer['url']; + $datarray['owner-avatar'] = $importer['thumb']; + } + $r = item_store($datarray); continue; } diff --git a/include/nav.php b/include/nav.php index 511ca07fc..aadfa82fd 100755 --- a/include/nav.php +++ b/include/nav.php @@ -122,6 +122,9 @@ function nav(&$a) { } $nav['messages'] = array('message', t('Messages'), "", t('Private mail')); + $nav['messages']['inbox'] = array('message', t('Inbox'), "", t('Inbox')); + $nav['messages']['outbox']= array('message/sent', t('Outbox'), "", t('Outbox')); + $nav['messages']['new'] = array('message/new', t('New Message'), "", t('New Message')); if(is_array($a->identities) && count($a->identities) > 1) { $nav['manage'] = array('manage', t('Manage'), "", t('Manage other pages')); diff --git a/include/notifier.php b/include/notifier.php index 4765cca06..5b23406fc 100755 --- a/include/notifier.php +++ b/include/notifier.php @@ -201,7 +201,7 @@ function notifier_run($argv, $argc){ // by stringing togther an array of retractions and sending them onward. - $localhost = $a->get_hostname(); + $localhost = str_replace('www.','',$a->get_hostname()); if(strpos($localhost,':')) $localhost = substr($localhost,0,strpos($localhost,':')); diff --git a/include/security.php b/include/security.php index bc2c9f0bf..8c536b656 100755 --- a/include/security.php +++ b/include/security.php @@ -108,14 +108,18 @@ function can_write_wall(&$a,$owner) { if(remote_user()) { - // user remembered decision and avoid a DB lookup for each and every display item + // use remembered decision and avoid a DB lookup for each and every display item // DO NOT use this function if there are going to be multiple owners + // We have a contact-id for an authenticated remote user, this block determines if the contact + // belongs to this page owner, and has the necessary permissions to post content + if($verified === 2) return true; elseif($verified === 1) return false; else { + $r = q("SELECT `contact`.*, `user`.`page-flags` FROM `contact` LEFT JOIN `user` on `user`.`uid` = `contact`.`uid` WHERE `contact`.`uid` = %d AND `contact`.`id` = %d AND `contact`.`blocked` = 0 AND `contact`.`pending` = 0 AND `user`.`blockwall` = 0 AND `readonly` = 0 AND ( `contact`.`rel` IN ( %d , %d ) OR `user`.`page-flags` = %d ) LIMIT 1", @@ -125,6 +129,7 @@ function can_write_wall(&$a,$owner) { intval(CONTACT_IS_FRIEND), intval(PAGE_COMMUNITY) ); + if(count($r)) { $verified = 2; return true; @@ -197,7 +202,7 @@ function permissions_sql($owner_id,$remote_verified = false,$groups = null) { " AND ( allow_cid = '' OR allow_cid REGEXP '<%d>' ) AND ( deny_cid = '' OR NOT deny_cid REGEXP '<%d>' ) AND ( allow_gid = '' OR allow_gid REGEXP '%s' ) - AND ( deny_gid = '' OR NOT deny_gid REGEXP '%s') + AND ( deny_gid = '' OR NOT deny_gid REGEXP '%s') ", intval($remote_user), intval($remote_user), @@ -207,4 +212,79 @@ function permissions_sql($owner_id,$remote_verified = false,$groups = null) { } } return $sql; -}
\ No newline at end of file +} + + +function item_permissions_sql($owner_id,$remote_verified = false,$groups = null) { + + $local_user = local_user(); + $remote_user = remote_user(); + + /** + * Construct permissions + * + * default permissions - anonymous user + */ + + $sql = " AND allow_cid = '' + AND allow_gid = '' + AND deny_cid = '' + AND deny_gid = '' + AND private = 0 + "; + + /** + * Profile owner - everything is visible + */ + + if(($local_user) && ($local_user == $owner_id)) { + $sql = ''; + } + + /** + * Authenticated visitor. Unless pre-verified, + * check that the contact belongs to this $owner_id + * and load the groups the visitor belongs to. + * If pre-verified, the caller is expected to have already + * done this and passed the groups into this function. + */ + + elseif($remote_user) { + + if(! $remote_verified) { + $r = q("SELECT id FROM contact WHERE id = %d AND uid = %d AND blocked = 0 LIMIT 1", + intval($remote_user), + intval($owner_id) + ); + if(count($r)) { + $remote_verified = true; + $groups = init_groups_visitor($remote_user); + } + } + if($remote_verified) { + + $gs = '<<>>'; // should be impossible to match + + if(is_array($groups) && count($groups)) { + foreach($groups as $g) + $gs .= '|<' . intval($g) . '>'; + } + + $sql = sprintf( + " AND ( private = 0 OR ( private = 1 AND wall = 1 AND ( allow_cid = '' OR allow_cid REGEXP '<%d>' ) + AND ( deny_cid = '' OR NOT deny_cid REGEXP '<%d>' ) + AND ( allow_gid = '' OR allow_gid REGEXP '%s' ) + AND ( deny_gid = '' OR NOT deny_gid REGEXP '%s'))) + ", + intval($remote_user), + intval($remote_user), + dbesc($gs), + dbesc($gs) + ); + } + } + + return $sql; +} + + diff --git a/include/template_processor.php b/include/template_processor.php index 7a4cba64e..7f7b0b55b 100755 --- a/include/template_processor.php +++ b/include/template_processor.php @@ -1,5 +1,5 @@ <?php - + define ("KEY_NOT_EXISTS", '^R_key_not_Exists^'); class Template { var $r; @@ -28,30 +28,18 @@ die(); } - private function _build_replace($r, $prefix){ - - if(is_array($r) && count($r)) { - foreach ($r as $k => $v ) { - if (is_array($v)) { - $this->_build_replace($v, "$prefix$k."); - } else { - $this->search[] = $prefix . $k; - $this->replace[] = $v; - } - } - } - } private function _push_stack(){ - $this->stack[] = array($this->r, $this->search, $this->replace, $this->nodes); + $this->stack[] = array($this->r, $this->nodes); } private function _pop_stack(){ - list($this->r, $this->search, $this->replace, $this->nodes) = array_pop($this->stack); + list($this->r, $this->nodes) = array_pop($this->stack); } - private function _get_var($name){ - $keys = array_map('trim',explode(".",$name)); + private function _get_var($name, $retNoKey=false){ + $keys = array_map('trim',explode(".",$name)); + if ($retNoKey && !array_key_exists($keys[0], $this->r)) return KEY_NOT_EXISTS; $val = $this->r; foreach($keys as $k) { $val = (isset($val[$k]) ? $val[$k] : null); @@ -121,7 +109,15 @@ * {{ inc <templatefile> [with $var1=$var2] }}{{ endinc }} */ private function _replcb_inc($args){ - list($tplfile, $newctx) = array_map('trim', explode("with",$args[2])); + if (strpos($args[2],"with")) { + list($tplfile, $newctx) = array_map('trim', explode("with",$args[2])); + } else { + $tplfile = trim($args[2]); + $newctx = null; + } + + if ($tplfile[0]=="$") $tplfile = $this->_get_var($tplfile); + $this->_push_stack(); $r = $this->r; if (!is_null($newctx)) { @@ -166,40 +162,33 @@ return $s; } - /* - private function _str_replace($str){ - #$this->search,$this->replace, - $searchs = $this->search; - foreach($searchs as $search){ - $search = "|".preg_quote($search)."(\|[a-zA-Z0-9_]*)*|"; - $m = array(); - if (preg_match_all($search, $str,$m)){ - foreach ($m[0] as $match){ - $toks = explode("|",$match); - $val = $this->_get_var($toks[0]); - for($k=1; $k<count($toks); $k++){ - $func = $toks[$k]; - if (function_exists($func)) $val = $func($val); - } - if (count($toks)>1){ - $str = str_replace( $match, $val, $str); - } - } - } + + private function var_replace($s){ + $m = array(); + /** regexp: + * \$ literal $ + * (\[)? optional open square bracket + * ([a-zA-Z0-9-_]+\.?)+ var name, followed by optional + * dot, repeated at least 1 time + * (?(1)\]) if there was opened square bracket + * (subgrup 1), match close bracket + */ + if (preg_match_all('/\$(\[)?([a-zA-Z0-9-_]+\.?)+(?(1)\])/', $s,$m)){ + foreach($m[0] as $var){ + $varn = str_replace(array("[","]"), array("",""), $var); + $val = $this->_get_var($varn, true); + if ($val!=KEY_NOT_EXISTS) + $s = str_replace($var, $val, $s); + } } - return str_replace($this->search,$this->replace, $str); - }*/ - + + return $s; + } public function replace($s, $r) { $this->r = $r; - $this->search = array(); - $this->replace = array(); - - $this->_build_replace($r, ""); - #$s = str_replace(array("\n","\r"),array("§n§","§r§"),$s); $s = $this->_build_nodes($s); $s = preg_replace_callback('/\|\|([0-9]+)\|\|/', array($this, "_replcb_node"), $s); @@ -207,12 +196,12 @@ // remove comments block $s = preg_replace('/{#[^#]*#}/', "" , $s); + // replace strings recursively (limit to 10 loops) $os = ""; $count=0; while($os!=$s && $count<10){ $os=$s; $count++; - //$s = $this->_str_replace($s); - $s = str_replace($this->search, $this->replace, $s); + $s = $this->var_replace($s); } return template_unescape($s); } diff --git a/include/text.php b/include/text.php index 1f5d4a3e1..5ad0154d7 100755..100644 --- a/include/text.php +++ b/include/text.php @@ -14,7 +14,13 @@ if(! function_exists('replace_macros')) { function replace_macros($s,$r) { global $t; - return $t->replace($s,$r); + //$ts = microtime(); + $r = $t->replace($s,$r); + //$tt = microtime() - $ts; + + //$a = get_app(); + //$a->page['debug'] .= "$tt <br>\n"; + return $r; }} @@ -731,7 +737,10 @@ function smilies($s, $sample = false) { ':headdesk', '~friendika', '~friendica', - 'Diaspora*' +// 'Diaspora*' + ':beard', + ':whitebeard' + ); $icons = array( @@ -772,8 +781,9 @@ function smilies($s, $sample = false) { '<img src="' . $a->get_baseurl() . '/images/smiley-bangheaddesk.gif" alt=":headdesk" />', '<a href="http://project.friendika.com">~friendika <img src="' . $a->get_baseurl() . '/images/friendika-16.png" alt="~friendika" /></a>', '<a href="http://friendica.com">~friendica <img src="' . $a->get_baseurl() . '/images/friendica-16.png" alt="~friendica" /></a>', - '<a href="http://diasporafoundation.org">Diaspora<img src="' . $a->get_baseurl() . '/images/diaspora.png" alt="Diaspora*" /></a>', - +// '<a href="http://diasporafoundation.org">Diaspora<img src="' . $a->get_baseurl() . '/images/diaspora.png" alt="Diaspora*" /></a>', + '<img src="' . $a->get_baseurl() . '/images/smiley-beard.png" alt=":beard" />', + '<img src="' . $a->get_baseurl() . '/images/smiley-whitebeard.png" alt=":whitebeard" />' ); $params = array('texts' => $texts, 'icons' => $icons, 'string' => $s); @@ -786,6 +796,7 @@ function smilies($s, $sample = false) { } } else { + $params['string'] = preg_replace_callback('/<(3+)/','preg_heart',$params['string']); $s = str_replace($params['texts'],$params['icons'],$params['string']); } @@ -804,7 +815,18 @@ function smile_decode($m) { return(str_replace($m[1],base64url_decode($m[1]),$m[0])); } +// expand <3333 to the correct number of hearts +function preg_heart($x) { + $a = get_app(); + if(strlen($x[1]) == 1) + return $x[0]; + $t = ''; + for($cnt = 0; $cnt < strlen($x[1]); $cnt ++) + $t .= '<img src="' . $a->get_baseurl() . '/images/smiley-heart.gif" alt="<3" />'; + $r = str_replace($x[0],$t,$x[0]); + return $r; +} if(! function_exists('day_translate')) { @@ -1201,3 +1223,16 @@ function reltoabs($text, $base) return $text; } +function item_post_type($item) { + if(intval($item['event-id'])) + return t('event'); + if(strlen($item['resource-id'])) + return t('photo'); + if(strlen($item['verb']) && $item['verb'] !== ACTIVITY_POST) + return t('activity'); + if($item['id'] != $item['parent']) + return t('comment'); + return t('post'); +} + + |