X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=include%2Fitems.php;h=3832b80b318f30f51a0f8b716d87c752f65ac855;hb=26eceaacbe883b7ece20c0cfb5c724c8ba1a7d99;hp=9927223514c483447396d2b5a6f02b0ee6a2ce66;hpb=597ef20b71ff7950262d54e0374399fae1400d61;p=friendica.git diff --git a/include/items.php b/include/items.php index 9927223514..3832b80b31 100644 --- a/include/items.php +++ b/include/items.php @@ -12,6 +12,7 @@ require_once('include/email.php'); require_once('include/ostatus_conversation.php'); require_once('include/threads.php'); require_once('include/socgraph.php'); +require_once('mod/share.php'); function get_feed_for(&$a, $dfrn_id, $owner_nick, $last_update, $direction = 0) { @@ -838,10 +839,7 @@ function get_atom_elements($feed, $item, $contact = array()) { logger('get_atom_elements: fixing sender of repeated message.'); if (!intval(get_config('system','wall-to-wall_share'))) { - $prefix = "[share author='".str_replace("'", "'",$name). - "' profile='".$uri. - "' avatar='".$avatar. - "' link='".$orig_uri."']"; + $prefix = share_header($name, $uri, $avatar, "", "", $orig_uri); $res["body"] = $prefix.html2bbcode($message)."[/share]"; } else { @@ -1183,9 +1181,9 @@ function item_store($arr,$force_parent = false, $notify = false, $dontcache = fa $arr['owner-avatar'] = ((x($arr,'owner-avatar')) ? notags(trim($arr['owner-avatar'])) : ''); $arr['created'] = ((x($arr,'created') !== false) ? datetime_convert('UTC','UTC',$arr['created']) : datetime_convert()); $arr['edited'] = ((x($arr,'edited') !== false) ? datetime_convert('UTC','UTC',$arr['edited']) : datetime_convert()); - $arr['commented'] = datetime_convert(); - $arr['received'] = datetime_convert(); - $arr['changed'] = datetime_convert(); + $arr['commented'] = ((x($arr,'commented') !== false) ? datetime_convert('UTC','UTC',$arr['commented']) : datetime_convert()); + $arr['received'] = ((x($arr,'received') !== false) ? datetime_convert('UTC','UTC',$arr['received']) : datetime_convert()); + $arr['changed'] = ((x($arr,'changed') !== false) ? datetime_convert('UTC','UTC',$arr['changed']) : datetime_convert()); $arr['title'] = ((x($arr,'title')) ? notags(trim($arr['title'])) : ''); $arr['location'] = ((x($arr,'location')) ? notags(trim($arr['location'])) : ''); $arr['coord'] = ((x($arr,'coord')) ? notags(trim($arr['coord'])) : ''); @@ -1210,8 +1208,8 @@ function item_store($arr,$force_parent = false, $notify = false, $dontcache = fa $arr['attach'] = ((x($arr,'attach')) ? notags(trim($arr['attach'])) : ''); $arr['app'] = ((x($arr,'app')) ? notags(trim($arr['app'])) : ''); $arr['origin'] = ((x($arr,'origin')) ? intval($arr['origin']) : 0 ); - $arr['guid'] = ((x($arr,'guid')) ? notags(trim($arr['guid'])) : get_guid(30)); $arr['network'] = ((x($arr,'network')) ? trim($arr['network']) : ''); + $arr['guid'] = ((x($arr,'guid')) ? notags(trim($arr['guid'])) : get_guid(32, $arr['network'])); $arr['postopts'] = ((x($arr,'postopts')) ? trim($arr['postopts']) : ''); $arr['resource-id'] = ((x($arr,'resource-id')) ? trim($arr['resource-id']) : ''); $arr['event-id'] = ((x($arr,'event-id')) ? intval($arr['event-id']) : 0 ); @@ -1239,6 +1237,9 @@ function item_store($arr,$force_parent = false, $notify = false, $dontcache = fa logger("item_store: Set network to ".$arr["network"]." for ".$arr["uri"], LOGGER_DEBUG); } + // Check for hashtags in the body and repair or add hashtag links + item_body_set_hashtags($arr); + $arr['thr-parent'] = $arr['parent-uri']; if($arr['parent-uri'] === $arr['uri']) { $parent_id = 0; @@ -1343,6 +1344,20 @@ function item_store($arr,$force_parent = false, $notify = false, $dontcache = fa return 0; } + // Is this item available in the global items (with uid=0)? + if ($arr["uid"] == 0) { + $arr["global"] = true; + + q("UPDATE `item` SET `global` = 1 WHERE `guid` = '%s'", dbesc($arr["guid"])); + } else { + $isglobal = q("SELECT `global` FROM `item` WHERE `uid` = 0 AND `guid` = '%s'", dbesc($arr["guid"])); + + $arr["global"] = (count($isglobal) > 0); + } + + // Fill the cache field + put_item_in_cache($arr); + call_hooks('post_remote',$arr); if(x($arr,'cancel')) { @@ -1376,16 +1391,6 @@ function item_store($arr,$force_parent = false, $notify = false, $dontcache = fa $current_post = $r[0]['id']; logger('item_store: created item ' . $current_post); - // Add every contact to the global contact table - // Contacts from the statusnet connector are also added since you could add them in OStatus as well. - if (!$arr['private'] AND in_array($arr["network"], - array(NETWORK_DFRN, NETWORK_DIASPORA, NETWORK_OSTATUS, NETWORK_STATUSNET, ""))) { - poco_check($arr["author-link"], $arr["author-name"], $arr["network"], $arr["author-avatar"], "", "", "", $arr["received"], $arr["contact-id"], $arr["uid"]); - - // Maybe its a body with a shared item? Then extract a global contact from it. - poco_contact_from_body($arr["body"], $arr["received"], $arr["contact-id"], $arr["uid"]); - } - // Set "success_update" to the date of the last time we heard from this contact // This can be used to filter for inactive contacts and poco. // Only do this for public postings to avoid privacy problems, since poco data is public. @@ -1395,56 +1400,12 @@ function item_store($arr,$force_parent = false, $notify = false, $dontcache = fa dbesc($arr['received']), intval($arr['contact-id']) ); - - // Only check for notifications on start posts - if ($arr['parent-uri'] === $arr['uri']) { - add_thread($r[0]['id']); - logger('item_store: Check notification for contact '.$arr['contact-id'].' and post '.$current_post, LOGGER_DEBUG); - - // Send a notification for every new post? - $r = q("SELECT `notify_new_posts` FROM `contact` WHERE `id` = %d AND `uid` = %d AND `notify_new_posts` LIMIT 1", - intval($arr['contact-id']), - intval($arr['uid']) - ); - - if(count($r)) { - logger('item_store: Send notification for contact '.$arr['contact-id'].' and post '.$current_post, LOGGER_DEBUG); - $u = q("SELECT * FROM user WHERE uid = %d LIMIT 1", - intval($arr['uid'])); - - $item = q("SELECT * FROM `item` WHERE `id` = %d AND `uid` = %d", - intval($current_post), - intval($arr['uid']) - ); - - $a = get_app(); - - require_once('include/enotify.php'); - notification(array( - 'type' => NOTIFY_SHARE, - 'notify_flags' => $u[0]['notify-flags'], - 'language' => $u[0]['language'], - 'to_name' => $u[0]['username'], - 'to_email' => $u[0]['email'], - 'uid' => $u[0]['uid'], - 'item' => $item[0], - 'link' => $a->get_baseurl().'/display/'.urlencode($arr['guid']), - 'source_name' => $item[0]['author-name'], - 'source_link' => $item[0]['author-link'], - 'source_photo' => $item[0]['author-avatar'], - 'verb' => ACTIVITY_TAG, - 'otype' => 'item' - )); - logger('item_store: Notification sent for contact '.$arr['contact-id'].' and post '.$current_post, LOGGER_DEBUG); - } - } - } else { logger('item_store: could not locate created item'); return 0; } if(count($r) > 1) { - logger('item_store: duplicated post occurred. Removing duplicates.'); + logger('item_store: duplicated post occurred. Removing duplicates. uri = '.$arr['uri'].' uid = '.$arr['uid']); q("DELETE FROM `item` WHERE `uri` = '%s' AND `uid` = %d AND `id` != %d ", dbesc($arr['uri']), intval($arr['uid']), @@ -1488,13 +1449,18 @@ function item_store($arr,$force_parent = false, $notify = false, $dontcache = fa $arr['deleted'] = $parent_deleted; // update the commented timestamp on the parent - - q("UPDATE `item` set `commented` = '%s', `changed` = '%s' WHERE `id` = %d", - dbesc(datetime_convert()), - dbesc(datetime_convert()), - intval($parent_id) - ); - update_thread($parent_id); + // Only update "commented" if it is really a comment + if (($arr['verb'] == ACTIVITY_POST) OR !get_config("system", "like_no_comment")) + q("UPDATE `item` SET `commented` = '%s', `changed` = '%s' WHERE `id` = %d", + dbesc(datetime_convert()), + dbesc(datetime_convert()), + intval($parent_id) + ); + else + q("UPDATE `item` SET `changed` = '%s' WHERE `id` = %d", + dbesc(datetime_convert()), + intval($parent_id) + ); if($dsprsig) { q("insert into sign (`iid`,`signed_text`,`signature`,`signer`) values (%d,'%s','%s','%s') ", @@ -1520,39 +1486,157 @@ function item_store($arr,$force_parent = false, $notify = false, $dontcache = fa $deleted = tag_deliver($arr['uid'],$current_post); - // current post can be deleted if is for a communuty page and no mention are + // current post can be deleted if is for a community page and no mention are // in it. if (!$deleted AND !$dontcache) { - // Store the fresh generated item into the cache - $cachefile = get_cachefile(urlencode($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); - } - $r = q('SELECT * FROM `item` WHERE id = %d', intval($current_post)); if (count($r) == 1) { call_hooks('post_remote_end', $r[0]); - } else { + } else logger('item_store: new item not found in DB, id ' . $current_post); - } } - create_tags_from_item($current_post, $dontcache); + // Add every contact of the post to the global contact table + poco_store($arr); + + create_tags_from_item($current_post); create_files_from_item($current_post); + // Only check for notifications on start posts + if ($arr['parent-uri'] === $arr['uri']) { + add_thread($current_post); + logger('item_store: Check notification for contact '.$arr['contact-id'].' and post '.$current_post, LOGGER_DEBUG); + + // Send a notification for every new post? + $r = q("SELECT `notify_new_posts` FROM `contact` WHERE `id` = %d AND `uid` = %d AND `notify_new_posts` LIMIT 1", + intval($arr['contact-id']), + intval($arr['uid']) + ); + $send_notification = count($r); + + if (!$send_notification) { + $tags = q("SELECT `url` FROM `term` WHERE `otype` = %d AND `oid` = %d AND `type` = %d AND `uid` = %d", + intval(TERM_OBJ_POST), intval($current_post), intval(TERM_MENTION), intval($arr['uid'])); + + if (count($tags)) { + foreach ($tags AS $tag) { + $r = q("SELECT `id` FROM `contact` WHERE `nurl` = '%s' AND `uid` = %d AND `notify_new_posts`", + normalise_link($tag["url"]), intval($arr['uid'])); + if (count($r)) + $send_notification = true; + } + } + } + + if ($send_notification) { + logger('item_store: Send notification for contact '.$arr['contact-id'].' and post '.$current_post, LOGGER_DEBUG); + $u = q("SELECT * FROM user WHERE uid = %d LIMIT 1", + intval($arr['uid'])); + + $item = q("SELECT * FROM `item` WHERE `id` = %d AND `uid` = %d", + intval($current_post), + intval($arr['uid']) + ); + + $a = get_app(); + + require_once('include/enotify.php'); + notification(array( + 'type' => NOTIFY_SHARE, + 'notify_flags' => $u[0]['notify-flags'], + 'language' => $u[0]['language'], + 'to_name' => $u[0]['username'], + 'to_email' => $u[0]['email'], + 'uid' => $u[0]['uid'], + 'item' => $item[0], + 'link' => $a->get_baseurl().'/display/'.urlencode($arr['guid']), + 'source_name' => $item[0]['author-name'], + 'source_link' => $item[0]['author-link'], + 'source_photo' => $item[0]['author-avatar'], + 'verb' => ACTIVITY_TAG, + 'otype' => 'item' + )); + logger('item_store: Notification sent for contact '.$arr['contact-id'].' and post '.$current_post, LOGGER_DEBUG); + } + } else { + update_thread($parent_id); + add_shadow_entry($arr); + } + if ($notify) proc_run('php', "include/notifier.php", $notify_type, $current_post); return $current_post; } +function item_body_set_hashtags(&$item) { + + $tags = get_tags($item["body"]); + + // No hashtags? + if(!count($tags)) + return(false); + + // This sorting is important when there are hashtags that are part of other hashtags + // Otherwise there could be problems with hashtags like #test and #test2 + rsort($tags); + + $a = get_app(); + + $URLSearchString = "^\[\]"; + + // All hashtags should point to the home server + //$item["body"] = preg_replace("/#\[url\=([$URLSearchString]*)\](.*?)\[\/url\]/ism", + // "#[url=".$a->get_baseurl()."/search?tag=$2]$2[/url]", $item["body"]); + + //$item["tag"] = preg_replace("/#\[url\=([$URLSearchString]*)\](.*?)\[\/url\]/ism", + // "#[url=".$a->get_baseurl()."/search?tag=$2]$2[/url]", $item["tag"]); + + // mask hashtags inside of url, bookmarks and attachments to avoid urls in urls + $item["body"] = preg_replace_callback("/\[url\=([$URLSearchString]*)\](.*?)\[\/url\]/ism", + function ($match){ + return("[url=".$match[1]."]".str_replace("#", "#", $match[2])."[/url]"); + },$item["body"]); + + $item["body"] = preg_replace_callback("/\[bookmark\=([$URLSearchString]*)\](.*?)\[\/bookmark\]/ism", + function ($match){ + return("[bookmark=".$match[1]."]".str_replace("#", "#", $match[2])."[/bookmark]"); + },$item["body"]); + + $item["body"] = preg_replace_callback("/\[attachment (.*)\](.*?)\[\/attachment\]/ism", + function ($match){ + return("[attachment ".str_replace("#", "#", $match[1])."]".$match[2]."[/attachment]"); + },$item["body"]); + + // Repair recursive urls + $item["body"] = preg_replace("/#\[url\=([$URLSearchString]*)\](.*?)\[\/url\]/ism", + "#$2", $item["body"]); + + foreach($tags as $tag) { + if(strpos($tag,'#') !== 0) + continue; + + if(strpos($tag,'[url=')) + continue; + + $basetag = str_replace('_',' ',substr($tag,1)); + + $newtag = '#[url='.$a->get_baseurl().'/search?tag='.rawurlencode($basetag).']'.$basetag.'[/url]'; + + $item["body"] = str_replace($tag, $newtag, $item["body"]); + + if(!stristr($item["tag"],"/search?tag=".$basetag."]".$basetag."[/url]")) { + if(strlen($item["tag"])) + $item["tag"] = ','.$item["tag"]; + $item["tag"] = $newtag.$item["tag"]; + } + } + + // Convert back the masked hashtags + $item["body"] = str_replace("#", "#", $item["body"]); +} + function get_item_guid($id) { $r = q("SELECT `guid` FROM `item` WHERE `id` = %d LIMIT 1", intval($id)); if (count($r)) @@ -2078,6 +2162,7 @@ function consume_feed($xml,$importer,&$contact, &$hub, $datedir = 0, $pass = 0) $photo_timestamp = ''; $photo_url = ''; $birthday = ''; + $contact_updated = ''; $hubs = $feed->get_links('hub'); logger('consume_feed: hubs: ' . print_r($hubs,true), LOGGER_DATA); @@ -2093,9 +2178,16 @@ 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']; + + // Manually checking for changed contact names + if (($new_name != $contact['name']) AND ($new_name != "") AND ($name_updated <= $contact['name-date'])) { + $name_updated = date("c"); + $photo_timestamp = date("c"); + } } 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']); + if ($photo_timestamp == "") + $photo_timestamp = datetime_convert('UTC','UTC',$elems['link'][0]['attribs'][NAMESPACE_DFRN]['updated']); $photo_url = $elems['link'][0]['attribs']['']['href']; } @@ -2106,6 +2198,9 @@ 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'].' from '.$photo_url.' uid: '.$contact['uid']); + + $contact_updated = $photo_timestamp; + require_once("include/Photo.php"); $photo_failure = false; $have_photo = false; @@ -2163,6 +2258,9 @@ function consume_feed($xml,$importer,&$contact, &$hub, $datedir = 0, $pass = 0) } if((is_array($contact)) && ($name_updated) && (strlen($new_name)) && ($name_updated > $contact['name-date'])) { + if ($name_updated > $contact_updated) + $contact_updated = $name_updated; + $r = q("select * from contact where uid = %d and id = %d limit 1", intval($contact['uid']), intval($contact['id']) @@ -2187,6 +2285,9 @@ function consume_feed($xml,$importer,&$contact, &$hub, $datedir = 0, $pass = 0) } } + if ($contact_updated AND $new_name AND $photo_url) + poco_check($contact['url'], $new_name, NETWORK_DFRN, $photo_url, "", "", "", "", "", $contact_updated, 2, $contact['id'], $contact['uid']); + if(strlen($birthday)) { if(substr($birthday,0,4) != $contact['bdyear']) { logger('consume_feed: updating birthday: ' . $birthday); @@ -2233,7 +2334,6 @@ function consume_feed($xml,$importer,&$contact, &$hub, $datedir = 0, $pass = 0) $contact['bdyear'] = substr($birthday,0,4); } - } $community_page = 0; @@ -2715,6 +2815,10 @@ function item_is_remote_self($contact, &$datarray) { if ($datarray["app"] == $a->get_hostname()) return false; + // Only forward posts + if ($datarray["verb"] != ACTIVITY_POST) + return false; + if (($contact['network'] != NETWORK_FEED) AND $datarray['private']) return false; @@ -2795,6 +2899,7 @@ function local_delivery($importer,$data) { $new_name = ''; $photo_timestamp = ''; $photo_url = ''; + $contact_updated = ''; $rawtags = $feed->get_feed_tags( NAMESPACE_DFRN, 'owner'); @@ -2808,14 +2913,24 @@ function local_delivery($importer,$data) { if($elems['name'][0]['attribs'][NAMESPACE_DFRN]['updated']) { $name_updated = $elems['name'][0]['attribs'][NAMESPACE_DFRN]['updated']; $new_name = $elems['name'][0]['data']; + + // Manually checking for changed contact names + if (($new_name != $importer['name']) AND ($new_name != "") AND ($name_updated <= $importer['name-date'])) { + $name_updated = date("c"); + $photo_timestamp = date("c"); + } } 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']); + if ($photo_timestamp == "") + $photo_timestamp = datetime_convert('UTC','UTC',$elems['link'][0]['attribs'][NAMESPACE_DFRN]['updated']); $photo_url = $elems['link'][0]['attribs']['']['href']; } } if(($photo_timestamp) && (strlen($photo_url)) && ($photo_timestamp > $importer['avatar-date'])) { + + $contact_updated = $photo_timestamp; + logger('local_delivery: Updating photo for ' . $importer['name']); require_once("include/Photo.php"); $photo_failure = false; @@ -2874,6 +2989,9 @@ function local_delivery($importer,$data) { } if(($name_updated) && (strlen($new_name)) && ($name_updated > $importer['name-date'])) { + if ($name_updated > $contact_updated) + $contact_updated = $name_updated; + $r = q("select * from contact where uid = %d and id = %d limit 1", intval($importer['importer_uid']), intval($importer['id']) @@ -2898,7 +3016,8 @@ function local_delivery($importer,$data) { } } - + if ($contact_updated AND $new_name AND $photo_url) + poco_check($importer['url'], $new_name, NETWORK_DFRN, $photo_url, "", "", "", "", "", $contact_updated, 2, $importer['id'], $importer['importer_uid']); // Currently unsupported - needs a lot of work $reloc = $feed->get_feed_tags( NAMESPACE_DFRN, 'relocate' ); @@ -2937,6 +3056,7 @@ function local_delivery($importer,$data) { thumb = '%s', micro = '%s', url = '%s', + nurl = '%s', request = '%s', confirm = '%s', notify = '%s', @@ -2948,6 +3068,7 @@ function local_delivery($importer,$data) { dbesc($newloc['thumb']), dbesc($newloc['micro']), dbesc($newloc['url']), + dbesc(normalise_link($newloc['url'])), dbesc($newloc['request']), dbesc($newloc['confirm']), dbesc($newloc['notify']), @@ -4649,8 +4770,8 @@ function drop_item($id,$interactive = true) { dbesc($item['parent-uri']), intval($item['uid']) ); - create_tags_from_item($item['parent-uri'], $item['uid']); - create_files_from_item($item['parent-uri'], $item['uid']); + create_tags_from_itemuri($item['parent-uri'], $item['uid']); + create_files_from_itemuri($item['parent-uri'], $item['uid']); delete_thread_uri($item['parent-uri'], $item['uid']); // ignore the result }