X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=include%2Fitems.php;h=29f4d7256feb548d292539b68490233102964fdf;hb=8bb6b51967a3fa5e461ea3cb51e5033604e26426;hp=ff7da286e28ef738c612e98849979b7620fcf38a;hpb=bfec28f1fe1e13c73d255447546354df63ac1b33;p=friendica.git diff --git a/include/items.php b/include/items.php index ff7da286e2..29f4d7256f 100755 --- a/include/items.php +++ b/include/items.php @@ -5,7 +5,10 @@ require_once('include/oembed.php'); require_once('include/salmon.php'); require_once('include/crypto.php'); require_once('include/Photo.php'); - +require_once('include/tags.php'); +require_once('include/text.php'); +require_once('include/email.php'); +require_once('include/ostatus_conversation.php'); function get_feed_for(&$a, $dfrn_id, $owner_nick, $last_update, $direction = 0) { @@ -26,7 +29,7 @@ function get_feed_for(&$a, $dfrn_id, $owner_nick, $last_update, $direction = 0) } } - + // default permissions - anonymous user @@ -76,6 +79,7 @@ function get_feed_for(&$a, $dfrn_id, $owner_nick, $last_update, $direction = 0) killme(); $contact = $r[0]; + require_once('include/security.php'); $groups = init_groups_visitor($contact['id']); if(count($groups)) { @@ -237,7 +241,7 @@ function construct_activity_object($item) { $r->link = str_replace('&','&', $r->link); $r->link = preg_replace('/\/','',$r->link); $o .= $r->link; - } + } else $o .= '' . "\r\n"; } @@ -269,7 +273,7 @@ function construct_activity_target($item) { $r->link = str_replace('&','&', $r->link); $r->link = preg_replace('/\/','',$r->link); $o .= $r->link; - } + } else $o .= '' . "\r\n"; } @@ -378,10 +382,12 @@ function title_is_body($title, $body) { $title = strip_tags($title); $title = trim($title); + $title = html_entity_decode($title, ENT_QUOTES, 'UTF-8'); $title = str_replace(array("\n", "\r", "\t", " "), array("","","",""), $title); $body = strip_tags($body); $body = trim($body); + $body = html_entity_decode($body, ENT_QUOTES, 'UTF-8'); $body = str_replace(array("\n", "\r", "\t", " "), array("","","",""), $body); if (strlen($title) < strlen($body)) @@ -667,7 +673,7 @@ function get_atom_elements($feed,$item) { } // translate OStatus unfollow to activity streams if it happened to get selected - + if((x($res,'verb')) && ($res['verb'] === 'http://ostatus.org/schema/1.0/unfollow')) $res['verb'] = ACTIVITY_UNFOLLOW; @@ -718,7 +724,7 @@ function get_atom_elements($feed,$item) { if($child[NAMESPACE_ACTIVITY]['object-type'][0]['data']) { $res['object-type'] = $child[NAMESPACE_ACTIVITY]['object-type'][0]['data']; $res['object'] .= '' . $child[NAMESPACE_ACTIVITY]['object-type'][0]['data'] . '' . "\n"; - } + } if(x($child[SIMPLEPIE_NAMESPACE_ATOM_10], 'id') && $child[SIMPLEPIE_NAMESPACE_ATOM_10]['id'][0]['data']) $res['object'] .= '' . $child[SIMPLEPIE_NAMESPACE_ATOM_10]['id'][0]['data'] . '' . "\n"; if(x($child[SIMPLEPIE_NAMESPACE_ATOM_10], 'link') && $child[SIMPLEPIE_NAMESPACE_ATOM_10]['link']) @@ -756,7 +762,7 @@ function get_atom_elements($feed,$item) { $child = $rawobj[0]['child']; if($child[NAMESPACE_ACTIVITY]['object-type'][0]['data']) { $res['target'] .= '' . $child[NAMESPACE_ACTIVITY]['object-type'][0]['data'] . '' . "\n"; - } + } if(x($child[SIMPLEPIE_NAMESPACE_ATOM_10], 'id') && $child[SIMPLEPIE_NAMESPACE_ATOM_10]['id'][0]['data']) $res['target'] .= '' . $child[SIMPLEPIE_NAMESPACE_ATOM_10]['id'][0]['data'] . '' . "\n"; if(x($child[SIMPLEPIE_NAMESPACE_ATOM_10], 'link') && $child[SIMPLEPIE_NAMESPACE_ATOM_10]['link']) @@ -792,7 +798,10 @@ function get_atom_elements($feed,$item) { // There is some better way to parse this array - but it didn't worked for me. $child = $item->feed->data["child"][SIMPLEPIE_NAMESPACE_ATOM_10]["feed"][0]["child"][SIMPLEPIE_NAMESPACE_ATOM_10]["entry"][0]["child"]["http://activitystrea.ms/spec/1.0/"][object][0]["child"]; if (is_array($child)) { + logger('get_atom_elements: Looking for status.net repeated message'); + $message = $child["http://activitystrea.ms/spec/1.0/"]["object"][0]["child"][SIMPLEPIE_NAMESPACE_ATOM_10]["content"][0]["data"]; + $orig_uri = $child["http://activitystrea.ms/spec/1.0/"]["object"][0]["child"][SIMPLEPIE_NAMESPACE_ATOM_10]["id"][0]["data"]; $author = $child[SIMPLEPIE_NAMESPACE_ATOM_10]["author"][0]["child"][SIMPLEPIE_NAMESPACE_ATOM_10]; $uri = $author["uri"][0]["data"]; $name = $author["name"][0]["data"]; @@ -800,27 +809,53 @@ function get_atom_elements($feed,$item) { $avatar = $avatar["href"]; if (($name != "") and ($uri != "") and ($avatar != "") and ($message != "")) { - $res["owner-name"] = $res["author-name"]; - $res["owner-link"] = $res["author-link"]; - $res["owner-avatar"] = $res["author-avatar"]; + logger('get_atom_elements: fixing sender of repeated message.'); + + if (intval(get_config('system','new_share'))) { + $prefix = "[share author='".str_replace("'", "'",$name). + "' profile='".$uri. + "' avatar='".$avatar. + "' link='".$orig_uri."']"; + + $res["body"] = $prefix.html2bbcode($message)."[/share]"; + } else { + $res["owner-name"] = $res["author-name"]; + $res["owner-link"] = $res["author-link"]; + $res["owner-avatar"] = $res["author-avatar"]; - $res["author-name"] = $name; - $res["author-link"] = $uri; - $res["author-avatar"] = $avatar; + $res["author-name"] = $name; + $res["author-link"] = $uri; + $res["author-avatar"] = $avatar; - $res["body"] = html2bbcode($message); + $res["body"] = html2bbcode($message); + } } } + // Search for ostatus conversation url + $links = $item->feed->data["child"][SIMPLEPIE_NAMESPACE_ATOM_10]["feed"][0]["child"][SIMPLEPIE_NAMESPACE_ATOM_10]["entry"][0]["child"]["http://www.w3.org/2005/Atom"]["link"]; + + if (is_array($links)) { + foreach ($links as $link) { + $conversation = array_shift($link["attribs"]); + + if ($conversation["rel"] == "ostatus:conversation") { + $res["ostatus_conversation"] = $conversation["href"]; + logger('get_atom_elements: found conversation url '.$res["ostatus_conversation"]); + } + }; + } + $arr = array('feed' => $feed, 'item' => $item, 'result' => $res); call_hooks('parse_atom', $arr); //if (($res["title"] != "") or (strpos($res["body"], "RT @") > 0)) { //if (strpos($res["body"], "RT @") !== false) { - // $debugfile = tempnam("/home/ike/log", "item-res2-"); - // file_put_contents($debugfile, serialize($arr)); - //} + /*if (strpos($res["body"], "@") !== false) { + $debugfile = tempnam("/var/www/virtual/pirati.ca/phptmp/", "item-res2-"); + file_put_contents($debugfile, serialize($arr)); + }*/ return $res; } @@ -859,13 +894,22 @@ function item_store($arr,$force_parent = false) { unset($arr['dsprsig']); } + // if an OStatus conversation url was passed in, it is stored and then + // removed from the array. + $ostatus_conversation = null; + + if (isset($arr["ostatus_conversation"])) { + $ostatus_conversation = $arr["ostatus_conversation"]; + unset($arr["ostatus_conversation"]); + } + if(x($arr, 'gravity')) $arr['gravity'] = intval($arr['gravity']); elseif($arr['parent-uri'] === $arr['uri']) $arr['gravity'] = 0; elseif(activity_match($arr['verb'],ACTIVITY_POST)) $arr['gravity'] = 6; - else + else $arr['gravity'] = 6; // extensible catchall if(! x($arr,'type')) @@ -878,11 +922,26 @@ function item_store($arr,$force_parent = false) { if (version_compare(PHP_VERSION, '5.3.0', '>=')) { - require_once('Text/LanguageDetect.php'); + require_once('library/langdet/Text/LanguageDetect.php'); $naked_body = preg_replace('/\[(.+?)\]/','',$arr['body']); $l = new Text_LanguageDetect; - $lng = $l->detectConfidence($naked_body); - $arr['postopts'] = (($lng['language']) ? 'lang=' . $lng['language'] . ';' . $lng['confidence'] : ''); + //$lng = $l->detectConfidence($naked_body); + //$arr['postopts'] = (($lng['language']) ? 'lang=' . $lng['language'] . ';' . $lng['confidence'] : ''); + $lng = $l->detect($naked_body, 3); + + if (sizeof($lng) > 0) { + $postopts = ""; + + foreach ($lng as $language => $score) { + if ($postopts == "") + $postopts = "lang="; + else + $postopts .= ":"; + + $postopts .= $language.";".$score; + } + $arr['postopts'] = $postopts; + } } $arr['wall'] = ((x($arr,'wall')) ? intval($arr['wall']) : 0); @@ -935,9 +994,9 @@ function item_store($arr,$force_parent = false) { $deny_cid = $arr['deny_cid']; $deny_gid = $arr['deny_gid']; } - else { + else { - // find the parent and snarf the item id and ACL's + // find the parent and snarf the item id and ACLs // and anything else we need to inherit $r = q("SELECT * FROM `item` WHERE `uri` = '%s' AND `uid` = %d ORDER BY `id` ASC LIMIT 1", @@ -1000,7 +1059,7 @@ function item_store($arr,$force_parent = false) { logger('item_store: item parent was not found - ignoring item'); return 0; } - + $parent_deleted = 0; } } @@ -1041,8 +1100,8 @@ function item_store($arr,$force_parent = false) { if(count($r)) { $current_post = $r[0]['id']; logger('item_store: created item ' . $current_post); - } - else { + create_tags_from_item($r[0]['id']); + } else { logger('item_store: could not locate created item'); return 0; } @@ -1055,7 +1114,7 @@ function item_store($arr,$force_parent = false) { ); } - if((! $parent_id) || ($arr['parent-uri'] === $arr['uri'])) + if((! $parent_id) || ($arr['parent-uri'] === $arr['uri'])) $parent_id = $current_post; if(strlen($allow_cid) || strlen($allow_gid) || strlen($deny_cid) || strlen($deny_gid)) @@ -1076,6 +1135,11 @@ function item_store($arr,$force_parent = false) { intval($parent_deleted), intval($current_post) ); + create_tags_from_item($current_post); + + // Complete ostatus threads + if ($ostatus_conversation) + complete_conversation($current_post, $ostatus_conversation); $arr['id'] = $current_post; $arr['parent'] = $parent_id; @@ -1119,6 +1183,18 @@ function item_store($arr,$force_parent = false) { tag_deliver($arr['uid'],$current_post); + // Store the fresh generated item into the cache + $cachefile = get_cachefile($arr["guid"]."-".hash("md5", $arr['body'])); + + if (($cachefile != '') AND !file_exists($cachefile)) { + $s = prepare_text($arr['body']); + $a = get_app(); + $stamp1 = microtime(true); + file_put_contents($cachefile, $s); + $a->save_timestamp($stamp1, "file"); + logger('item_store: put item '.$current_post.' into cachefile '.$cachefile); + } + return $current_post; } @@ -1184,6 +1260,15 @@ function tag_deliver($uid,$item_id) { // send a notification + // use a local photo if we have one + + $r = q("select * from contact where uid = %d and nurl = '%s' limit 1", + intval($u[0]['uid']), + dbesc(normalise_link($item['author-link'])) + ); + $photo = (($r && count($r)) ? $r[0]['thumb'] : $item['author-avatar']); + + require_once('include/enotify.php'); notification(array( 'type' => NOTIFY_TAGSELF, @@ -1196,11 +1281,16 @@ function tag_deliver($uid,$item_id) { 'link' => $a->get_baseurl() . '/display/' . $u[0]['nickname'] . '/' . $item['id'], 'source_name' => $item['author-name'], 'source_link' => $item['author-link'], - 'source_photo' => $item['author-avatar'], + 'source_photo' => $photo, 'verb' => ACTIVITY_TAG, 'otype' => 'item' )); + + $arr = array('item' => $item, 'user' => $u[0], 'contact' => $r[0]); + + call_hooks('tagged', $arr); + if((! $community_page) && (! $prvgroup)) return; @@ -1241,7 +1331,60 @@ function tag_deliver($uid,$item_id) { intval($item_id) ); - proc_run('php','include/notifier.php','tgroup',$item_id); + proc_run('php','include/notifier.php','tgroup',$item_id); + +} + + + +function tgroup_check($uid,$item) { + + $a = get_app(); + + $mention = false; + + // check that the message originated elsewhere and is a top-level post + + if(($item['wall']) || ($item['origin']) || ($item['uri'] != $item['parent-uri'])) + return false; + + + $u = q("select * from user where uid = %d limit 1", + intval($uid) + ); + if(! count($u)) + return false; + + $community_page = (($u[0]['page-flags'] == PAGE_COMMUNITY) ? true : false); + $prvgroup = (($u[0]['page-flags'] == PAGE_PRVGROUP) ? true : false); + + + $link = normalise_link($a->get_baseurl() . '/profile/' . $u[0]['nickname']); + + // Diaspora uses their own hardwired link URL in @-tags + // instead of the one we supply with webfinger + + $dlink = normalise_link($a->get_baseurl() . '/u/' . $u[0]['nickname']); + + $cnt = preg_match_all('/[\@\!]\[url\=(.*?)\](.*?)\[\/url\]/ism',$item['body'],$matches,PREG_SET_ORDER); + if($cnt) { + foreach($matches as $mtch) { + if(link_compare($link,$mtch[1]) || link_compare($dlink,$mtch[1])) { + $mention = true; + logger('tgroup_check: mention found: ' . $mtch[2]); + } + } + } + + if(! $mention) + return false; + + if((! $community_page) && (! $prvgroup)) + return false; + + + + return true; } @@ -1259,7 +1402,7 @@ function dfrn_deliver($owner,$contact,$atom, $dissolve = false) { if($contact['duplex'] && $contact['dfrn-id']) $idtosend = '0:' . $orig_id; if($contact['duplex'] && $contact['issued-id']) - $idtosend = '1:' . $orig_id; + $idtosend = '1:' . $orig_id; $rino = ((function_exists('mcrypt_encrypt')) ? 1 : 0); @@ -1277,7 +1420,7 @@ function dfrn_deliver($owner,$contact,$atom, $dissolve = false) { break; case SSL_POLICY_SELFSIGN: $ssl_policy = 'self'; - break; + break; case SSL_POLICY_NONE: default: $ssl_policy = 'none'; @@ -1330,7 +1473,7 @@ function dfrn_deliver($owner,$contact,$atom, $dissolve = false) { intval(($perm == 'rw') ? 1 : 0), intval($contact['id']) ); - $contact['writable'] = (string) 1 - intval($contact['writable']); + $contact['writable'] = (string) 1 - intval($contact['writable']); } } @@ -1474,7 +1617,7 @@ function consume_feed($xml,$importer,&$contact, &$hub, $datedir = 0, $pass = 0) logger('consume_feed: empty input'); return; } - + $feed = new SimplePie(); $feed->set_raw_data($xml); if($datedir) @@ -1510,7 +1653,7 @@ function consume_feed($xml,$importer,&$contact, &$hub, $datedir = 0, $pass = 0) if($elems['name'][0]['attribs'][NAMESPACE_DFRN]['updated']) { $name_updated = $elems['name'][0]['attribs'][NAMESPACE_DFRN]['updated']; $new_name = $elems['name'][0]['data']; - } + } if((x($elems,'link')) && ($elems['link'][0]['attribs']['']['rel'] === 'photo') && ($elems['link'][0]['attribs'][NAMESPACE_DFRN]['updated'])) { $photo_timestamp = datetime_convert('UTC','UTC',$elems['link'][0]['attribs'][NAMESPACE_DFRN]['updated']); $photo_url = $elems['link'][0]['attribs']['']['href']; @@ -1523,7 +1666,7 @@ function consume_feed($xml,$importer,&$contact, &$hub, $datedir = 0, $pass = 0) if((is_array($contact)) && ($photo_timestamp) && (strlen($photo_url)) && ($photo_timestamp > $contact['avatar-date'])) { logger('consume_feed: Updating photo for ' . $contact['name']); - require_once("Photo.php"); + require_once("include/Photo.php"); $photo_failure = false; $have_photo = false; @@ -1553,12 +1696,12 @@ function consume_feed($xml,$importer,&$contact, &$hub, $datedir = 0, $pass = 0) intval($contact['uid']) ); } - + $img->scaleImageSquare(175); - + $hash = $resource_id; $r = $img->store($contact['uid'], $contact['id'], $hash, basename($photo_url), 'Contact Photos', 4); - + $img->scaleImage(80); $r = $img->store($contact['uid'], $contact['id'], $hash, basename($photo_url), 'Contact Photos', 5); @@ -1567,7 +1710,7 @@ function consume_feed($xml,$importer,&$contact, &$hub, $datedir = 0, $pass = 0) $a = get_app(); - q("UPDATE `contact` SET `avatar-date` = '%s', `photo` = '%s', `thumb` = '%s', `micro` = '%s' + q("UPDATE `contact` SET `avatar-date` = '%s', `photo` = '%s', `thumb` = '%s', `micro` = '%s' WHERE `uid` = %d AND `id` = %d LIMIT 1", dbesc(datetime_convert()), dbesc($a->get_baseurl() . '/photo/' . $hash . '-4.'.$img->getExt()), @@ -1617,7 +1760,7 @@ function consume_feed($xml,$importer,&$contact, &$hub, $datedir = 0, $pass = 0) * to contain a sparkle link and perhaps a photo. * */ - + $bdtext = sprintf( t('%s\'s birthday'), $contact['name']); $bdtext2 = sprintf( t('Happy Birthday %s'), ' [url=' . $contact['url'] . ']' . $contact['name'] . '[/url]' ) ; @@ -1634,7 +1777,7 @@ function consume_feed($xml,$importer,&$contact, &$hub, $datedir = 0, $pass = 0) dbesc($bdtext2), dbesc('birthday') ); - + // update bdyear @@ -1726,6 +1869,7 @@ function consume_feed($xml,$importer,&$contact, &$hub, $datedir = 0, $pass = 0) dbesc(implode(',',$newtags)), intval($i[0]['id']) ); + create_tags_from_item($i[0]['id']); } } } @@ -1740,6 +1884,7 @@ function consume_feed($xml,$importer,&$contact, &$hub, $datedir = 0, $pass = 0) dbesc($item['uri']), intval($importer['uid']) ); + create_tags_from_itemuri($item['uri'], $importer['uid']); } else { $r = q("UPDATE `item` SET `deleted` = 1, `edited` = '%s', `changed` = '%s', @@ -1750,6 +1895,7 @@ function consume_feed($xml,$importer,&$contact, &$hub, $datedir = 0, $pass = 0) dbesc($uri), intval($importer['uid']) ); + create_tags_from_itemuri($uri, $importer['uid']); if($item['last-child']) { // ensure that last-child is set in case the comment that had it just got wiped. q("UPDATE `item` SET `last-child` = 0, `changed` = '%s' WHERE `parent-uri` = '%s' AND `uid` = %d ", @@ -1803,6 +1949,12 @@ function consume_feed($xml,$importer,&$contact, &$hub, $datedir = 0, $pass = 0) if($pass == 1) continue; + // not allowed to post + + if($contact['rel'] == CONTACT_IS_FOLLOWER) + continue; + + // Have we seen it? If not, import it. $item_id = $item->get_id(); @@ -1857,6 +2009,7 @@ function consume_feed($xml,$importer,&$contact, &$hub, $datedir = 0, $pass = 0) dbesc($item_id), intval($importer['uid']) ); + create_tags_from_itemuri($item_id, $importer['uid']); } // update last-child if it changes @@ -1898,7 +2051,7 @@ function consume_feed($xml,$importer,&$contact, &$hub, $datedir = 0, $pass = 0) dbesc($parent_uri) ); if($r && count($r)) - continue; + continue; } if(($datarray['verb'] === ACTIVITY_TAG) && ($datarray['object-type'] === ACTIVITY_OBJ_TAGTERM)) { @@ -1921,6 +2074,7 @@ function consume_feed($xml,$importer,&$contact, &$hub, $datedir = 0, $pass = 0) dbesc($r[0]['tag'] . (strlen($r[0]['tag']) ? ',' : '') . $newtag), intval($r[0]['id']) ); + create_tags_from_item($r[0]['id']); } } } @@ -2004,6 +2158,7 @@ function consume_feed($xml,$importer,&$contact, &$hub, $datedir = 0, $pass = 0) dbesc($item_id), intval($importer['uid']) ); + create_tags_from_itemuri($item_id, $importer['uid']); } // update last-child if it changes @@ -2077,6 +2232,14 @@ function consume_feed($xml,$importer,&$contact, &$hub, $datedir = 0, $pass = 0) $datarray['owner-avatar'] = $contact['thumb']; } + // We've allowed "followers" to reach this point so we can decide if they are + // posting an @-tag delivery, which followers are allowed to do for certain + // page types. Now that we've parsed the post, let's check if it is legit. Otherwise ignore it. + + if(($contact['rel'] == CONTACT_IS_FOLLOWER) && (! tgroup_check($importer['uid'],$datarray))) + continue; + + $r = item_store($datarray); continue; @@ -2086,9 +2249,10 @@ function consume_feed($xml,$importer,&$contact, &$hub, $datedir = 0, $pass = 0) } function local_delivery($importer,$data) { - $a = get_app(); + logger(__function__, LOGGER_TRACE); + if($importer['readonly']) { // We aren't receiving stuff from this person. But we will quietly ignore them // rather than a blatant "go away" message. @@ -2122,14 +2286,17 @@ function local_delivery($importer,$data) { $rawtags = $feed->get_feed_tags( NAMESPACE_DFRN, 'owner'); - if(! $rawtags) - $rawtags = $feed->get_feed_tags( SIMPLEPIE_NAMESPACE_ATOM_10, 'author'); + +// Fallback should not be needed here. If it isn't DFRN it won't have DFRN updated tags +// if(! $rawtags) +// $rawtags = $feed->get_feed_tags( SIMPLEPIE_NAMESPACE_ATOM_10, 'author'); + if($rawtags) { $elems = $rawtags[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10]; if($elems['name'][0]['attribs'][NAMESPACE_DFRN]['updated']) { $name_updated = $elems['name'][0]['attribs'][NAMESPACE_DFRN]['updated']; $new_name = $elems['name'][0]['data']; - } + } if((x($elems,'link')) && ($elems['link'][0]['attribs']['']['rel'] === 'photo') && ($elems['link'][0]['attribs'][NAMESPACE_DFRN]['updated'])) { $photo_timestamp = datetime_convert('UTC','UTC',$elems['link'][0]['attribs'][NAMESPACE_DFRN]['updated']); $photo_url = $elems['link'][0]['attribs']['']['href']; @@ -2138,7 +2305,7 @@ function local_delivery($importer,$data) { if(($photo_timestamp) && (strlen($photo_url)) && ($photo_timestamp > $importer['avatar-date'])) { logger('local_delivery: Updating photo for ' . $importer['name']); - require_once("Photo.php"); + require_once("include/Photo.php"); $photo_failure = false; $have_photo = false; @@ -2168,12 +2335,12 @@ function local_delivery($importer,$data) { intval($importer['importer_uid']) ); } - + $img->scaleImageSquare(175); - + $hash = $resource_id; $r = $img->store($importer['importer_uid'], $importer['id'], $hash, basename($photo_url), 'Contact Photos', 4); - + $img->scaleImage(80); $r = $img->store($importer['importer_uid'], $importer['id'], $hash, basename($photo_url), 'Contact Photos', 5); @@ -2182,7 +2349,7 @@ function local_delivery($importer,$data) { $a = get_app(); - q("UPDATE `contact` SET `avatar-date` = '%s', `photo` = '%s', `thumb` = '%s', `micro` = '%s' + q("UPDATE `contact` SET `avatar-date` = '%s', `photo` = '%s', `thumb` = '%s', `micro` = '%s' WHERE `uid` = %d AND `id` = %d LIMIT 1", dbesc(datetime_convert()), dbesc($a->get_baseurl() . '/photo/' . $hash . '-4.'.$img->getExt()), @@ -2220,7 +2387,7 @@ function local_delivery($importer,$data) { } -/* + // Currently unsupported - needs a lot of work $reloc = $feed->get_feed_tags( NAMESPACE_DFRN, 'relocate' ); if(isset($reloc[0]['child'][NAMESPACE_DFRN])) { @@ -2230,23 +2397,79 @@ function local_delivery($importer,$data) { $newloc['cid'] = $importer['id']; $newloc['name'] = notags(unxmlify($base['name'][0]['data'])); $newloc['photo'] = notags(unxmlify($base['photo'][0]['data'])); + $newloc['thumb'] = notags(unxmlify($base['thumb'][0]['data'])); + $newloc['micro'] = notags(unxmlify($base['micro'][0]['data'])); $newloc['url'] = notags(unxmlify($base['url'][0]['data'])); $newloc['request'] = notags(unxmlify($base['request'][0]['data'])); $newloc['confirm'] = notags(unxmlify($base['confirm'][0]['data'])); $newloc['notify'] = notags(unxmlify($base['notify'][0]['data'])); $newloc['poll'] = notags(unxmlify($base['poll'][0]['data'])); - $newloc['site-pubkey'] = notags(unxmlify($base['site-pubkey'][0]['data'])); - $newloc['pubkey'] = notags(unxmlify($base['pubkey'][0]['data'])); - $newloc['prvkey'] = notags(unxmlify($base['prvkey'][0]['data'])); - + $newloc['sitepubkey'] = notags(unxmlify($base['sitepubkey'][0]['data'])); + /** relocated user must have original key pair */ + /*$newloc['pubkey'] = notags(unxmlify($base['pubkey'][0]['data'])); + $newloc['prvkey'] = notags(unxmlify($base['prvkey'][0]['data']));*/ + + logger("items:relocate contact ".print_r($newloc, true).print_r($importer, true), LOGGER_DEBUG); + + // update contact + $r = q("SELECT photo, url FROM contact WHERE id=%d AND uid=%d;", + intval($importer['id']), + intval($importer['importer_uid'])); + if ($r === false) + return 1; + $old = $r[0]; + + $x = q("UPDATE contact SET + name = '%s', + photo = '%s', + thumb = '%s', + micro = '%s', + url = '%s', + request = '%s', + confirm = '%s', + notify = '%s', + poll = '%s', + `site-pubkey` = '%s' + WHERE id=%d AND uid=%d;", + dbesc($newloc['name']), + dbesc($newloc['photo']), + dbesc($newloc['thumb']), + dbesc($newloc['micro']), + dbesc($newloc['url']), + dbesc($newloc['request']), + dbesc($newloc['confirm']), + dbesc($newloc['notify']), + dbesc($newloc['poll']), + dbesc($newloc['sitepubkey']), + intval($importer['id']), + intval($importer['importer_uid'])); + + if ($x === false) + return 1; + // update items + $fields = array( + 'owner-link' => array($old['url'], $newloc['url']), + 'author-link' => array($old['url'], $newloc['url']), + 'owner-avatar' => array($old['photo'], $newloc['photo']), + 'author-avatar' => array($old['photo'], $newloc['photo']), + ); + foreach ($fields as $n=>$f){ + $x = q("UPDATE item SET `%s`='%s' WHERE `%s`='%s' AND uid=%d", + $n, dbesc($f[1]), + $n, dbesc($f[0]), + intval($importer['importer_uid'])); + if ($x === false) + return 1; + } + // TODO // merge with current record, current contents have priority // update record, set url-updated // update profile photos // schedule a scan? - + return 0; } -*/ + // handle friend suggestion notification @@ -2312,7 +2535,7 @@ function local_delivery($importer,$data) { $hash = random_string(); - + $r = q("INSERT INTO `intro` ( `uid`, `fid`, `contact-id`, `note`, `hash`, `datetime`, `blocked` ) VALUES( %d, %d, %d, '%s', '%s', '%s', %d )", intval($fsugg['uid']), @@ -2366,7 +2589,7 @@ function local_delivery($importer,$data) { $msg['uri'] = notags(unxmlify($base['id'][0]['data'])); $msg['parent-uri'] = notags(unxmlify($base['in-reply-to'][0]['data'])); $msg['created'] = datetime_convert(notags(unxmlify('UTC','UTC',$base['sentdate'][0]['data']))); - + dbesc_array($msg); $r = dbq("INSERT INTO `mail` (`" . implode("`, `", array_keys($msg)) @@ -2390,12 +2613,12 @@ function local_delivery($importer,$data) { 'verb' => ACTIVITY_POST, 'otype' => 'mail' ); - + notification($notif_params); return 0; // NOTREACHED - } + } $community_page = 0; $rawtags = $feed->get_feed_tags( NAMESPACE_DFRN, 'community'); @@ -2409,7 +2632,7 @@ function local_delivery($importer,$data) { ); $importer['forum'] = (string) $community_page; } - + logger('local_delivery: feed item count = ' . $feed->get_item_quantity()); // process any deleted entries @@ -2519,14 +2742,14 @@ function local_delivery($importer,$data) { if(count($i)) { // For tags, the owner cannot remove the tag on the author's copy of the post. - + $owner_remove = (($item['contact-id'] == $i[0]['contact-id']) ? true: false); $author_remove = (($item['origin'] && $item['self']) ? true : false); - $author_copy = (($item['origin']) ? true : false); + $author_copy = (($item['origin']) ? true : false); if($owner_remove && $author_copy) continue; - if($author_remove || $owner_remove) { + if($author_remove || $owner_remove) { $tags = explode(',',$i[0]['tag']); $newtags = array(); if(count($tags)) { @@ -2538,6 +2761,7 @@ function local_delivery($importer,$data) { dbesc(implode(',',$newtags)), intval($i[0]['id']) ); + create_tags_from_item($i[0]['id']); } } } @@ -2552,6 +2776,7 @@ function local_delivery($importer,$data) { dbesc($item['uri']), intval($importer['importer_uid']) ); + create_tags_from_itemuri($item['uri'], $importer['importer_uid']); } else { $r = q("UPDATE `item` SET `deleted` = 1, `edited` = '%s', `changed` = '%s', @@ -2562,6 +2787,7 @@ function local_delivery($importer,$data) { dbesc($uri), intval($importer['importer_uid']) ); + create_tags_from_itemuri($uri, $importer['importer_uid']); if($item['last-child']) { // ensure that last-child is set in case the comment that had it just got wiped. q("UPDATE `item` SET `last-child` = 0, `changed` = '%s' WHERE `parent-uri` = '%s' AND `uid` = %d ", @@ -2569,7 +2795,7 @@ function local_delivery($importer,$data) { dbesc($item['parent-uri']), intval($item['uid']) ); - // who is the last child now? + // who is the last child now? $r = q("SELECT `id` FROM `item` WHERE `parent-uri` = '%s' AND `type` != 'activity' AND `deleted` = 0 AND `uid` = %d ORDER BY `created` DESC LIMIT 1", dbesc($item['parent-uri']), @@ -2579,7 +2805,7 @@ function local_delivery($importer,$data) { q("UPDATE `item` SET `last-child` = 1 WHERE `id` = %d LIMIT 1", intval($r[0]['id']) ); - } + } } // if this is a relayed delete, propagate it to other recipients @@ -2617,22 +2843,32 @@ function local_delivery($importer,$data) { // Specifically, the recipient? $is_a_remote_comment = false; - - // POSSIBLE CLEANUP --> Why select so many fields when only forum_mode and wall are used? - $r = q("select `item`.`id`, `item`.`uri`, `item`.`tag`, `item`.`forum_mode`,`item`.`origin`,`item`.`wall`, - `contact`.`name`, `contact`.`url`, `contact`.`thumb` from `item` - LEFT JOIN `contact` ON `contact`.`id` = `item`.`contact-id` - WHERE `item`.`uri` = '%s' AND (`item`.`parent-uri` = '%s' or `item`.`thr-parent` = '%s') - AND `item`.`uid` = %d - $sql_extra + $top_uri = $parent_uri; + + $r = q("select `item`.`parent-uri` from `item` + WHERE `item`.`uri` = '%s' LIMIT 1", - dbesc($parent_uri), - dbesc($parent_uri), - dbesc($parent_uri), - intval($importer['importer_uid']) + dbesc($parent_uri) ); - if($r && count($r)) - $is_a_remote_comment = true; + if($r && count($r)) { + $top_uri = $r[0]['parent-uri']; + + // POSSIBLE CLEANUP --> Why select so many fields when only forum_mode and wall are used? + $r = q("select `item`.`id`, `item`.`uri`, `item`.`tag`, `item`.`forum_mode`,`item`.`origin`,`item`.`wall`, + `contact`.`name`, `contact`.`url`, `contact`.`thumb` from `item` + LEFT JOIN `contact` ON `contact`.`id` = `item`.`contact-id` + WHERE `item`.`uri` = '%s' AND (`item`.`parent-uri` = '%s' or `item`.`thr-parent` = '%s') + AND `item`.`uid` = %d + $sql_extra + LIMIT 1", + dbesc($top_uri), + dbesc($top_uri), + dbesc($top_uri), + intval($importer['importer_uid']) + ); + if($r && count($r)) + $is_a_remote_comment = true; + } // Does this have the characteristics of a community or private group comment? // If it's a reply to a wall post on a community/prvgroup page it's a @@ -2663,11 +2899,11 @@ function local_delivery($importer,$data) { if(count($r)) { $iid = $r[0]['id']; if((x($datarray,'edited') !== false) && (datetime_convert('UTC','UTC',$datarray['edited']) !== $r[0]['edited'])) { - + // do not accept (ignore) an earlier edit than one we currently have. if(datetime_convert('UTC','UTC',$datarray['edited']) < $r[0]['edited']) continue; - + logger('received updated comment' , LOGGER_DEBUG); $r = q("UPDATE `item` SET `title` = '%s', `body` = '%s', `tag` = '%s', `edited` = '%s' WHERE `uri` = '%s' AND `uid` = %d LIMIT 1", dbesc($datarray['title']), @@ -2677,6 +2913,7 @@ function local_delivery($importer,$data) { dbesc($item_id), intval($importer['importer_uid']) ); + create_tags_from_itemuri($item_id, $importer['importer_uid']); proc_run('php',"include/notifier.php","comment-import",$iid); @@ -2686,15 +2923,6 @@ function local_delivery($importer,$data) { } - // TODO: make this next part work against both delivery threads of a community post - -// if((! link_compare($datarray['author-link'],$importer['url'])) && (! $community)) { -// logger('local_delivery: received relay claiming to be from ' . $importer['url'] . ' however comment author url is ' . $datarray['author-link'] ); - // they won't know what to do so don't report an error. Just quietly die. -// return 0; -// } - - // our user with $importer['importer_uid'] is the owner $own = q("select name,url,thumb from contact where uid = %d and self = 1 limit 1", intval($importer['importer_uid']) @@ -2722,14 +2950,14 @@ function local_delivery($importer,$data) { dbesc($datarray['verb']), dbesc($datarray['parent-uri']), dbesc($datarray['parent-uri']) - + ); if($r && count($r)) - continue; + continue; } if(($datarray['verb'] === ACTIVITY_TAG) && ($datarray['object-type'] === ACTIVITY_OBJ_TAGTERM)) { - + $xo = parse_xml_string($datarray['object'],false); $xt = parse_xml_string($datarray['target'],false); @@ -2742,9 +2970,9 @@ function local_delivery($importer,$data) { intval($importer['importer_uid']) ); if(! count($tagp)) - continue; + continue; - // extract tag, if not duplicate, and this user allows tags, add to parent item + // extract tag, if not duplicate, and this user allows tags, add to parent item if($xo->id && $xo->content) { $newtag = '#[url=' . $xo->id . ']'. $xo->content . '[/url]'; @@ -2758,33 +2986,27 @@ function local_delivery($importer,$data) { intval($tagp[0]['id']), dbesc(datetime_convert()) ); + create_tags_from_item($tagp[0]['id']); } } - } + } } } -// if($community) { -// $newtag = '@[url=' . $a->get_baseurl() . '/profile/' . $importer['nickname'] . ']' . $importer['username'] . '[/url]'; -// if(! stristr($datarray['tag'],$newtag)) { -// if(strlen($datarray['tag'])) -// $datarray['tag'] .= ','; -// $datarray['tag'] .= $newtag; -// } -// } - $posted_id = item_store($datarray); $parent = 0; if($posted_id) { - $r = q("SELECT `parent` FROM `item` WHERE `id` = %d AND `uid` = %d LIMIT 1", + $r = q("SELECT `parent`, `parent-uri` FROM `item` WHERE `id` = %d AND `uid` = %d LIMIT 1", intval($posted_id), intval($importer['importer_uid']) ); - if(count($r)) + if(count($r)) { $parent = $r[0]['parent']; - + $parent_uri = $r[0]['parent-uri']; + } + if(! $is_like) { $r1 = q("UPDATE `item` SET `last-child` = 0, `changed` = '%s' WHERE `uid` = %d AND `parent` = %d", dbesc(datetime_convert()), @@ -2802,7 +3024,7 @@ function local_delivery($importer,$data) { if($posted_id && $parent) { proc_run('php',"include/notifier.php","comment-import","$posted_id"); - + if((! $is_like) && (! $importer['self'])) { require_once('include/enotify.php'); @@ -2823,7 +3045,7 @@ function local_delivery($importer,$data) { 'verb' => ACTIVITY_POST, 'otype' => 'item', 'parent' => $parent, - + 'parent_uri' => $parent_uri, )); } @@ -2840,6 +3062,9 @@ function local_delivery($importer,$data) { $item_id = $item->get_id(); $datarray = get_atom_elements($feed,$item); + if($importer['rel'] == CONTACT_IS_FOLLOWER) + continue; + $r = q("SELECT `uid`, `last-child`, `edited`, `body` FROM `item` WHERE `uri` = '%s' AND `uid` = %d LIMIT 1", dbesc($item_id), intval($importer['importer_uid']) @@ -2862,6 +3087,7 @@ function local_delivery($importer,$data) { dbesc($item_id), intval($importer['importer_uid']) ); + create_tags_from_itemuri($item_id, $importer['importer_uid']); } // update last-child if it changes @@ -2898,7 +3124,7 @@ function local_delivery($importer,$data) { dbesc($parent_uri) ); if($r && count($r)) - continue; + continue; } @@ -2913,28 +3139,29 @@ function local_delivery($importer,$data) { intval($importer['importer_uid']) ); if(! count($r)) - continue; + continue; - // extract tag, if not duplicate, add to parent item + // extract tag, if not duplicate, add to parent item if($xo->content) { if(! (stristr($r[0]['tag'],trim($xo->content)))) { q("UPDATE item SET tag = '%s' WHERE id = %d LIMIT 1", dbesc($r[0]['tag'] . (strlen($r[0]['tag']) ? ',' : '') . '#[url=' . $xo->id . ']'. $xo->content . '[/url]'), intval($r[0]['id']) ); + create_tags_from_item($r[0]['id']); } - } + } } } $posted_id = item_store($datarray); // find out if our user is involved in this conversation and wants to be notified. - + if(!x($datarray['type']) || $datarray['type'] != 'activity') { $myconv = q("SELECT `author-link`, `author-avatar`, `parent` FROM `item` WHERE `parent-uri` = '%s' AND `uid` = %d AND `parent` != 0 AND `deleted` = 0", - dbesc($parent_uri), + dbesc($top_uri), intval($importer['importer_uid']) ); @@ -2944,11 +3171,11 @@ function local_delivery($importer,$data) { // 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)) { - + 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; @@ -2972,6 +3199,7 @@ function local_delivery($importer,$data) { 'verb' => ACTIVITY_POST, 'otype' => 'item', 'parent' => $conv_parent, + 'parent_uri' => $parent_uri )); @@ -3035,6 +3263,7 @@ function local_delivery($importer,$data) { dbesc($item_id), intval($importer['importer_uid']) ); + create_tags_from_itemuri($item_id, $importer['importer_uid']); } // update last-child if it changes @@ -3073,6 +3302,9 @@ function local_delivery($importer,$data) { $datarray['owner-avatar'] = $importer['thumb']; } + if(($importer['rel'] == CONTACT_IS_FOLLOWER) && (! tgroup_check($importer['importer_uid'],$datarray))) + continue; + $posted_id = item_store($datarray); if(stristr($datarray['verb'],ACTIVITY_POKE)) { @@ -3146,7 +3378,7 @@ function new_follower($importer,$contact,$datarray,$item,$sharing = false) { if(is_array($contact)) { if(($contact['network'] == NETWORK_OSTATUS && $contact['rel'] == CONTACT_IS_SHARING) || ($sharing && $contact['rel'] == CONTACT_IS_FOLLOWER)) { - $r = q("UPDATE `contact` SET `rel` = %d WHERE `id` = %d AND `uid` = %d LIMIT 1", + $r = q("UPDATE `contact` SET `rel` = %d, `writable` = 1 WHERE `id` = %d AND `uid` = %d LIMIT 1", intval(CONTACT_IS_FRIEND), intval($contact['id']), intval($importer['uid']) @@ -3155,7 +3387,7 @@ function new_follower($importer,$contact,$datarray,$item,$sharing = false) { // send email notification to owner? } else { - + // create contact record $r = q("INSERT INTO `contact` ( `uid`, `created`, `url`, `nurl`, `name`, `nick`, `photo`, `network`, `rel`, @@ -3178,7 +3410,7 @@ function new_follower($importer,$contact,$datarray,$item,$sharing = false) { if(count($r)) $contact_record = $r[0]; - // create notification + // create notification $hash = random_string(); if(is_array($contact_record)) { @@ -3211,12 +3443,12 @@ function new_follower($importer,$contact,$datarray,$item,$sharing = false) { '$sitename' => $a->config['sitename'] )); $res = mail($r[0]['email'], - (($sharing) ? t('A new person is sharing with you at ') : t("You have a new follower at ")) . $a->config['sitename'], + email_header_encode((($sharing) ? t('A new person is sharing with you at ') : t("You have a new follower at ")) . $a->config['sitename'],'UTF-8'), $email, - 'From: ' . t('Administrator') . '@' . $_SERVER['SERVER_NAME'] . "\n" + 'From: ' . 'Administrator' . '@' . $_SERVER['SERVER_NAME'] . "\n" . 'Content-type: text/plain; charset=UTF-8' . "\n" . 'Content-transfer-encoding: 8bit' ); - + } } } @@ -3286,7 +3518,7 @@ function subscribe_to_hub($url,$importer,$contact,$hubmode = 'subscribe') { post_url($url,$params); logger('subscribe_to_hub: returns: ' . $a->get_curl_code(), LOGGER_DEBUG); - + return; } @@ -3412,9 +3644,13 @@ function atom_entry($item,$type,$author,$owner,$comment = false,$cid = 0) { } function fix_private_photos($s, $uid, $item = null, $cid = 0) { + + if(get_config('system','disable_embedded')) + return $s; + $a = get_app(); - logger('fix_private_photos', LOGGER_DEBUG); + logger('fix_private_photos: check for photos', LOGGER_DEBUG); $site = substr($a->get_baseurl(),strpos($a->get_baseurl(),'://')); $orig_body = $s; @@ -3435,7 +3671,7 @@ function fix_private_photos($s, $uid, $item = null, $cid = 0) { // Only embed locally hosted photos $replace = false; $i = basename($image); - $i = str_replace(array('.jpg','.png'),array('',''),$i); + $i = str_replace(array('.jpg','.png','.gif'),array('','',''),$i); $x = strpos($i,'-'); if($x) { @@ -3446,7 +3682,7 @@ function fix_private_photos($s, $uid, $item = null, $cid = 0) { intval($res), intval($uid) ); - if(count($r)) { + if($r) { // Check to see if we should replace this photo link with an embedded image // 1. No need to do so if the photo is public @@ -3573,11 +3809,11 @@ function item_getfeedtags($item) { function item_getfeedattach($item) { $ret = ''; - $arr = explode(',',$item['attach']); + $arr = explode('[/attach],',$item['attach']); if(count($arr)) { foreach($arr as $r) { $matches = false; - $cnt = preg_match('|\[attach\]href=\"(.*?)\" length=\"(.*?)\" type=\"(.*?)\" title=\"(.*?)\"\[\/attach\]|',$r,$matches); + $cnt = preg_match('|\[attach\]href=\"(.*?)\" length=\"(.*?)\" type=\"(.*?)\" title=\"(.*?)\"|',$r,$matches); if($cnt) { $ret .= ' can't take arguments in its "action" parameter + // so add any arguments as hidden inputs + $query = explode_querystring($a->query_string); + $inputs = array(); + foreach($query['args'] as $arg) { + if(strpos($arg, 'confirm=') === false) { + $arg_parts = explode('=', $arg); + $inputs[] = array('name' => $arg_parts[0], 'value' => $arg_parts[1]); + } + } + + return replace_macros(get_markup_template('confirm.tpl'), array( + '$method' => 'get', + '$message' => t('Do you really want to delete this item?'), + '$extra_inputs' => $inputs, + '$confirm' => t('Yes'), + '$confirm_url' => $query['base'], + '$confirm_name' => 'confirmed', + '$cancel' => t('Cancel'), + )); + } + // Now check how the user responded to the confirmation query + if($_REQUEST['canceled']) { + goaway($a->get_baseurl() . '/' . $_SESSION['return_url']); + } logger('delete item: ' . $item['id'], LOGGER_DEBUG); // delete the item @@ -3711,6 +3987,7 @@ function drop_item($id,$interactive = true) { dbesc(datetime_convert()), intval($item['id']) ); + create_tags_from_item($item['id']); // clean up categories and tags so they don't end up as orphans @@ -3776,6 +4053,7 @@ function drop_item($id,$interactive = true) { dbesc($item['parent-uri']), intval($item['uid']) ); + create_tags_from_item($item['parent-uri'], $item['uid']); // ignore the result } else { @@ -3785,7 +4063,7 @@ function drop_item($id,$interactive = true) { dbesc($item['parent-uri']), intval($item['uid']) ); - // who is the last child now? + // who is the last child now? $r = q("SELECT `id` FROM `item` WHERE `parent-uri` = '%s' AND `type` != 'activity' AND `deleted` = 0 AND `uid` = %d ORDER BY `edited` DESC LIMIT 1", dbesc($item['parent-uri']), intval($item['uid']) @@ -3803,10 +4081,10 @@ function drop_item($id,$interactive = true) { // send the notification upstream/downstream as the case may be + proc_run('php',"include/notifier.php","drop","$drop_id"); + if(! $interactive) return $owner; - - proc_run('php',"include/notifier.php","drop","$drop_id"); goaway($a->get_baseurl() . '/' . $_SESSION['return_url']); //NOTREACHED } @@ -3817,7 +4095,7 @@ function drop_item($id,$interactive = true) { goaway($a->get_baseurl() . '/' . $_SESSION['return_url']); //NOTREACHED } - + } @@ -3870,10 +4148,13 @@ function posted_dates($uid,$wall) { function posted_date_widget($url,$uid,$wall) { $o = ''; + if(! feature_enabled($uid,'archives')) + return $o; + // For former Facebook folks that left because of "timeline" - if($wall && intval(get_pconfig($uid,'system','no_wall_archive_widget'))) - return $o; +/* if($wall && intval(get_pconfig($uid,'system','no_wall_archive_widget'))) + return $o;*/ $ret = posted_dates($uid,$wall); if(! count($ret))