X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=include%2Fitems.php;h=475980d2dc972584aaef409cbf64134566b53c1a;hb=b795bf2935f4eee38bb1b9a75630cd8d6212e597;hp=95ff40714f0e2d2809130ddcc3334909e85b21cd;hpb=9bdd41b77402487e9992fa87e50b222d7f707cf4;p=friendica.git diff --git a/include/items.php b/include/items.php index 95ff40714f..475980d2dc 100644 --- a/include/items.php +++ b/include/items.php @@ -9,11 +9,16 @@ require_once('include/tags.php'); require_once('include/files.php'); require_once('include/text.php'); require_once('include/email.php'); -require_once('include/ostatus_conversation.php'); require_once('include/threads.php'); require_once('include/socgraph.php'); +require_once('include/plaintext.php'); +require_once('include/ostatus.php'); +require_once('mod/share.php'); -function get_feed_for(&$a, $dfrn_id, $owner_nick, $last_update, $direction = 0) { +require_once('library/defuse/php-encryption-1.2.1/Crypto.php'); + + +function get_feed_for(&$a, $dfrn_id, $owner_nick, $last_update, $direction = 0, $forpubsub = false) { $sitefeed = ((strlen($owner_nick)) ? false : true); // not yet implemented, need to rewrite huge chunks of following logic @@ -36,7 +41,7 @@ function get_feed_for(&$a, $dfrn_id, $owner_nick, $last_update, $direction = 0) // default permissions - anonymous user - $sql_extra = " AND `allow_cid` = '' AND `allow_gid` = '' AND `deny_cid` = '' AND `deny_gid` = '' "; + $sql_extra = " AND `item`.`allow_cid` = '' AND `item`.`allow_gid` = '' AND `item`.`deny_cid` = '' AND `item`.`deny_gid` = '' "; $r = q("SELECT `contact`.*, `user`.`uid` AS `user_uid`, `user`.`nickname`, `user`.`timezone`, `user`.`page-flags` FROM `contact` INNER JOIN `user` ON `user`.`uid` = `contact`.`uid` @@ -54,6 +59,7 @@ function get_feed_for(&$a, $dfrn_id, $owner_nick, $last_update, $direction = 0) $birthday = feed_birthday($owner_id,$owner['timezone']); $sql_post_table = ""; + $visibility = ""; if(! $public_feed) { @@ -113,6 +119,19 @@ function get_feed_for(&$a, $dfrn_id, $owner_nick, $last_update, $direction = 0) else $sort = 'ASC'; + // Include answers to status.net posts in pubsub feeds + if($forpubsub) { + $sql_post_table = "INNER JOIN `thread` ON `thread`.`iid` = `item`.`parent` + LEFT JOIN `item` AS `thritem` ON `thritem`.`uri`=`item`.`thr-parent` AND `thritem`.`uid`=`item`.`uid`"; + $visibility = sprintf("AND (`item`.`parent` = `item`.`id`) OR (`item`.`network` = '%s' AND ((`thread`.`network`='%s') OR (`thritem`.`network` = '%s')))", + dbesc(NETWORK_DFRN), dbesc(NETWORK_OSTATUS), dbesc(NETWORK_OSTATUS)); + $date_field = "`received`"; + $sql_order = "`item`.`received` DESC"; + } else { + $date_field = "`changed`"; + $sql_order = "`item`.`parent` ".$sort.", `item`.`created` ASC"; + } + if(! strlen($last_update)) $last_update = 'now -30 days'; @@ -132,7 +151,7 @@ function get_feed_for(&$a, $dfrn_id, $owner_nick, $last_update, $direction = 0) // AND ( `item`.`edited` > '%s' OR `item`.`changed` > '%s' ) // dbesc($check_date), - $r = q("SELECT `item`.*, `item`.`id` AS `item_id`, + $r = q("SELECT STRAIGHT_JOIN `item`.*, `item`.`id` AS `item_id`, `contact`.`name`, `contact`.`network`, `contact`.`photo`, `contact`.`url`, `contact`.`name-date`, `contact`.`uri-date`, `contact`.`avatar-date`, `contact`.`thumb`, `contact`.`dfrn-id`, `contact`.`self`, @@ -143,9 +162,9 @@ function get_feed_for(&$a, $dfrn_id, $owner_nick, $last_update, $direction = 0) AND `contact`.`blocked` = 0 AND `contact`.`pending` = 0 LEFT JOIN `sign` ON `sign`.`iid` = `item`.`id` WHERE `item`.`uid` = %d AND `item`.`visible` = 1 and `item`.`moderated` = 0 AND `item`.`parent` != 0 - AND `item`.`wall` = 1 AND `item`.`changed` > '%s' + AND ((`item`.`wall` = 1) $visibility) AND `item`.$date_field > '%s' $sql_extra - ORDER BY `parent` %s, `created` ASC LIMIT 0, 300", + ORDER BY $sql_order LIMIT 0, 300", intval($owner_id), dbesc($check_date), dbesc($sort) @@ -463,12 +482,26 @@ function get_atom_elements($feed, $item, $contact = array()) { // look for a photo. We should check media size and find the best one, // but for now let's just find any author photo + // Additionally we look for an alternate author link. On OStatus this one is the one we want. + + $authorlinks = $item->feed->data["child"][SIMPLEPIE_NAMESPACE_ATOM_10]["feed"][0]["child"][SIMPLEPIE_NAMESPACE_ATOM_10]["author"][0]["child"]["http://www.w3.org/2005/Atom"]["link"]; + if (is_array($authorlinks)) { + foreach ($authorlinks as $link) { + $linkdata = array_shift($link["attribs"]); + + if ($linkdata["rel"] == "alternate") + $res["author-link"] = $linkdata["href"]; + }; + } $rawauthor = $item->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10,'author'); if($rawauthor && $rawauthor[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['link']) { $base = $rawauthor[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['link']; foreach($base as $link) { + if($link['attribs']['']['rel'] === 'alternate') + $res['author-link'] = unxmlify($link['attribs']['']['href']); + if(!x($res, 'author-avatar') || !$res['author-avatar']) { if($link['attribs']['']['rel'] === 'photo' || $link['attribs']['']['rel'] === 'avatar') $res['author-avatar'] = unxmlify($link['attribs']['']['href']); @@ -827,7 +860,7 @@ function get_atom_elements($feed, $item, $contact = array()) { 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"]; + $orig_id = ostatus_convert_href($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"]; @@ -835,13 +868,10 @@ function get_atom_elements($feed, $item, $contact = array()) { $avatar = $avatar["href"]; if (($name != "") and ($uri != "") and ($avatar != "") and ($message != "")) { - logger('get_atom_elements: fixing sender of repeated message.'); + logger('get_atom_elements: fixing sender of repeated message. '.$orig_id, LOGGER_DEBUG); 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_link); $res["body"] = $prefix.html2bbcode($message)."[/share]"; } else { @@ -858,20 +888,6 @@ function get_atom_elements($feed, $item, $contact = array()) { } } - // 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"]); - } - }; - } - if (isset($contact["network"]) AND ($contact["network"] == NETWORK_FEED) AND $contact['fetch_further_information']) { $preview = ""; @@ -1070,7 +1086,15 @@ function encode_rel_links($links) { return xmlify($o); } +function add_guid($item) { + $r = q("SELECT `guid` FROM `guid` WHERE `guid` = '%s' LIMIT 1", dbesc($item["guid"])); + if ($r) + return; + q("INSERT INTO `guid` (`guid`,`plink`,`uri`,`network`) VALUES ('%s','%s','%s','%s')", + dbesc($item["guid"]), dbesc($item["plink"]), + dbesc($item["uri"]), dbesc($item["network"])); +} function item_store($arr,$force_parent = false, $notify = false, $dontcache = false) { @@ -1092,13 +1116,12 @@ function item_store($arr,$force_parent = false, $notify = false, $dontcache = fa 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"]); + // Converting the plink + if ($arr['network'] == NETWORK_OSTATUS) { + if (isset($arr['plink'])) + $arr['plink'] = ostatus_convert_href($arr['plink']); + elseif (isset($arr['uri'])) + $arr['plink'] = ostatus_convert_href($arr['uri']); } if(x($arr, 'gravity')) @@ -1117,7 +1140,7 @@ function item_store($arr,$force_parent = false, $notify = false, $dontcache = fa /* check for create date and expire time */ $uid = intval($arr['uid']); - $r = q("SELECT expire FROM user WHERE uid = %d", $uid); + $r = q("SELECT expire FROM user WHERE uid = %d", intval($uid)); if(count($r)) { $expire_interval = $r[0]['expire']; if ($expire_interval>0) { @@ -1131,11 +1154,10 @@ function item_store($arr,$force_parent = false, $notify = false, $dontcache = fa } // If there is no guid then take the same guid that was taken before for the same uri - if ((trim($arr['guid']) == "") AND (trim($arr['uri']) != "")) { + if ((trim($arr['guid']) == "") AND (trim($arr['uri']) != "") AND (trim($arr['network']) != "")) { logger('item_store: checking for an existing guid for uri '.$arr['uri'], LOGGER_DEBUG); - $r = q("SELECT `guid` FROM `item` WHERE `uri` = '%s' AND `guid` != '' LIMIT 1", - dbesc(trim($arr['uri'])) - ); + $r = q("SELECT `guid` FROM `guid` WHERE `uri` = '%s' AND `network` = '%s' LIMIT 1", + dbesc(trim($arr['uri'])), dbesc(trim($arr['network']))); if(count($r)) { $arr['guid'] = $r[0]["guid"]; @@ -1143,6 +1165,21 @@ function item_store($arr,$force_parent = false, $notify = false, $dontcache = fa } } + // If there is no guid then take the same guid that was taken before for the same plink + if ((trim($arr['guid']) == "") AND (trim($arr['plink']) != "") AND (trim($arr['network']) != "")) { + logger('item_store: checking for an existing guid for plink '.$arr['plink'], LOGGER_DEBUG); + $r = q("SELECT `guid`, `uri` FROM `guid` WHERE `plink` = '%s' AND `network` = '%s' LIMIT 1", + dbesc(trim($arr['plink'])), dbesc(trim($arr['network']))); + + if(count($r)) { + $arr['guid'] = $r[0]["guid"]; + logger('item_store: found guid '.$arr['guid'].' for plink '.$arr['plink'], LOGGER_DEBUG); + + if ($r[0]["uri"] != $arr['uri']) + logger('Different uri for same guid: '.$arr['uri'].' and '.$r[0]["uri"].' - this shouldnt happen!', LOGGER_DEBUG); + } + } + // Shouldn't happen but we want to make absolutely sure it doesn't leak from a plugin. // Deactivated, since the bbcode parser can handle with it - and it destroys posts with some smileys that contain "<" //if((strpos($arr['body'],'<') !== false) || (strpos($arr['body'],'>') !== false)) @@ -1183,9 +1220,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'])) : ''); @@ -1239,6 +1276,18 @@ function item_store($arr,$force_parent = false, $notify = false, $dontcache = fa logger("item_store: Set network to ".$arr["network"]." for ".$arr["uri"], LOGGER_DEBUG); } + if ($arr['guid'] != "") { + // Checking if there is already an item with the same guid + logger('checking for an item for user '.$arr['uid'].' on network '.$arr['network'].' with the guid '.$arr['guid'], LOGGER_DEBUG); + $r = q("SELECT `guid` FROM `item` WHERE `guid` = '%s' AND `network` = '%s' AND `uid` = '%d' LIMIT 1", + dbesc($arr['guid']), dbesc($arr['network']), intval($arr['uid'])); + + if(count($r)) { + logger('found item with guid '.$arr['guid'].' for user '.$arr['uid'].' on network '.$arr['network'], LOGGER_DEBUG); + return 0; + } + } + // Check for hashtags in the body and repair or add hashtag links item_body_set_hashtags($arr); @@ -1329,7 +1378,7 @@ function item_store($arr,$force_parent = false, $notify = false, $dontcache = fa $arr['gravity'] = 0; } else { - logger('item_store: item parent was not found - ignoring item'); + logger('item_store: item parent '.$arr['parent-uri'].' for '.$arr['uid'].' was not found - ignoring item'); return 0; } @@ -1337,12 +1386,26 @@ function item_store($arr,$force_parent = false, $notify = false, $dontcache = fa } } - $r = q("SELECT `id` FROM `item` WHERE `uri` = '%s' AND `uid` = %d LIMIT 1", + $r = q("SELECT `id` FROM `item` WHERE `uri` = '%s' AND `network` = '%s' AND `uid` = %d LIMIT 1", dbesc($arr['uri']), + dbesc($arr['network']), + intval($arr['uid']) + ); + if($r && count($r)) { + logger('duplicated item with the same uri found. ' . print_r($arr,true)); + return 0; + } + + // Check for an existing post with the same content. There seems to be a problem with OStatus. + $r = q("SELECT `id` FROM `item` WHERE `body` = '%s' AND `network` = '%s' AND `created` = '%s' AND `contact-id` = %d AND `uid` = %d LIMIT 1", + dbesc($arr['body']), + dbesc($arr['network']), + dbesc($arr['created']), + intval($arr['contact-id']), intval($arr['uid']) ); if($r && count($r)) { - logger('item-store: duplicate item ignored. ' . print_r($arr,true)); + logger('duplicated item with the same body found. ' . print_r($arr,true)); return 0; } @@ -1390,15 +1453,31 @@ function item_store($arr,$force_parent = false, $notify = false, $dontcache = fa ); if(count($r)) { + + // Store the guid and other relevant data + add_guid($arr); + $current_post = $r[0]['id']; logger('item_store: created item ' . $current_post); - // 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. + // Set "success_update" and "last-item" to the date of the last time we heard from this contact + // This can be used to filter for inactive contacts. // Only do this for public postings to avoid privacy problems, since poco data is public. // Don't set this value if it isn't from the owner (could be an author that we don't know) - if (!$arr['private'] AND (($arr["author-link"] === $arr["owner-link"]) OR ($arr["parent-uri"] === $arr["uri"]))) - q("UPDATE `contact` SET `success_update` = '%s' WHERE `id` = %d", + + $update = (!$arr['private'] AND (($arr["author-link"] === $arr["owner-link"]) OR ($arr["parent-uri"] === $arr["uri"]))); + + // Is it a forum? Then we don't care about the rules from above + if (!$update AND ($arr["network"] == NETWORK_DFRN) AND ($arr["parent-uri"] === $arr["uri"])) { + $isforum = q("SELECT `forum` FROM `contact` WHERE `id` = %d AND `forum`", + intval($arr['contact-id'])); + if ($isforum) + $update = true; + } + + if ($update) + q("UPDATE `contact` SET `success_update` = '%s', `last-item` = '%s' WHERE `id` = %d", + dbesc($arr['received']), dbesc($arr['received']), intval($arr['contact-id']) ); @@ -1437,10 +1516,6 @@ function item_store($arr,$force_parent = false, $notify = false, $dontcache = fa intval($current_post) ); - // Complete ostatus threads - if ($ostatus_conversation) - complete_conversation($current_post, $ostatus_conversation); - $arr['id'] = $current_post; $arr['parent'] = $parent_id; $arr['allow_cid'] = $allow_cid; @@ -1557,12 +1632,15 @@ function item_store($arr,$force_parent = false, $notify = false, $dontcache = fa 'source_link' => $item[0]['author-link'], 'source_photo' => $item[0]['author-avatar'], 'verb' => ACTIVITY_TAG, - 'otype' => 'item' + 'otype' => 'item', + 'parent' => $arr['parent'] )); logger('item_store: Notification sent for contact '.$arr['contact-id'].' and post '.$current_post, LOGGER_DEBUG); } - } else + } else { update_thread($parent_id); + add_shadow_entry($arr); + } if ($notify) proc_run('php', "include/notifier.php", $notify_type, $current_post); @@ -1596,12 +1674,12 @@ function item_body_set_hashtags(&$item) { // 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]"); + return("[url=".str_replace("#", "#", $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]"); + return("[bookmark=".str_replace("#", "#", $match[1])."]".str_replace("#", "#", $match[2])."[/bookmark]"); },$item["body"]); $item["body"] = preg_replace_callback("/\[attachment (.*)\](.*?)\[\/attachment\]/ism", @@ -1613,6 +1691,7 @@ function item_body_set_hashtags(&$item) { $item["body"] = preg_replace("/#\[url\=([$URLSearchString]*)\](.*?)\[\/url\]/ism", "#$2", $item["body"]); + foreach($tags as $tag) { if(strpos($tag,'#') !== 0) continue; @@ -1907,13 +1986,13 @@ function dfrn_deliver($owner,$contact,$atom, $dissolve = false) { if($contact['duplex'] && $contact['issued-id']) $idtosend = '1:' . $orig_id; - $rino = ((function_exists('mcrypt_encrypt')) ? 1 : 0); + + $rino = get_config('system','rino_encrypt'); + $rino = intval($rino); - $rino_enable = get_config('system','rino_encrypt'); - - if(! $rino_enable) - $rino = 0; + + $ssl_val = intval(get_config('system','ssl_policy')); $ssl_policy = ''; @@ -1930,7 +2009,7 @@ function dfrn_deliver($owner,$contact,$atom, $dissolve = false) { break; } - $url = $contact['notify'] . '&dfrn_id=' . $idtosend . '&dfrn_version=' . DFRN_PROTOCOL_VERSION . (($rino) ? '&rino=1' : ''); + $url = $contact['notify'] . '&dfrn_id=' . $idtosend . '&dfrn_version=' . DFRN_PROTOCOL_VERSION . (($rino) ? '&rino='.$rino : ''); logger('dfrn_deliver: ' . $url); @@ -1961,7 +2040,7 @@ function dfrn_deliver($owner,$contact,$atom, $dissolve = false) { $challenge = hex2bin((string) $res->challenge); $perm = (($res->perm) ? $res->perm : null); $dfrn_version = (float) (($res->dfrn_version) ? $res->dfrn_version : 2.0); - $rino_allowed = ((intval($res->rino) === 1) ? 1 : 0); + $rino_remote_version = intval($res->rino); $page = (($owner['page-flags'] == PAGE_COMMUNITY) ? 1 : 0); if($owner['page-flags'] == PAGE_PRVGROUP) @@ -2022,11 +2101,46 @@ function dfrn_deliver($owner,$contact,$atom, $dissolve = false) { if($page) $postvars['page'] = $page; - if($rino && $rino_allowed && (! $dissolve)) { - $key = substr(random_string(),0,16); - $data = bin2hex(aes_encrypt($postvars['data'],$key)); - $postvars['data'] = $data; - logger('rino: sent key = ' . $key, LOGGER_DEBUG); + + if($rino>0 && $rino_remote_version>0 && (! $dissolve)) { + logger('rino version: '. $rino_remote_version); + + switch($rino_remote_version) { + case 1: + // Deprecated rino version! + $key = substr(random_string(),0,16); + $data = aes_encrypt($postvars['data'],$key); + break; + case 2: + // RINO 2 based on php-encryption + try { + $key = Crypto::createNewRandomKey(); + } catch (CryptoTestFailed $ex) { + logger('Cannot safely create a key'); + return -1; + } catch (CannotPerformOperation $ex) { + logger('Cannot safely create a key'); + return -1; + } + try { + $data = Crypto::encrypt($postvars['data'], $key); + } catch (CryptoTestFailed $ex) { + logger('Cannot safely perform encryption'); + return -1; + } catch (CannotPerformOperation $ex) { + logger('Cannot safely perform encryption'); + return -1; + } + break; + default: + logger("rino: invalid requested verision '$rino_remote_version'"); + return -1; + } + + $postvars['rino'] = $rino_remote_version; + $postvars['data'] = bin2hex($data); + + #logger('rino: sent key = ' . $key, LOGGER_DEBUG); if($dfrn_version >= 2.1) { @@ -2053,6 +2167,7 @@ function dfrn_deliver($owner,$contact,$atom, $dissolve = false) { $postvars['key'] = bin2hex($postvars['key']); } + logger('dfrn_deliver: ' . "SENDING: " . print_r($postvars,true), LOGGER_DATA); @@ -2133,6 +2248,17 @@ function edited_timestamp_is_newer($existing, $update) { */ function consume_feed($xml,$importer,&$contact, &$hub, $datedir = 0, $pass = 0) { + if ($contact['network'] === NETWORK_OSTATUS) { + if ($pass < 2) { + // Test - remove before flight + //$tempfile = tempnam(get_temppath(), "ostatus"); + //file_put_contents($tempfile, $xml); + + logger("Consume OStatus messages ", LOGGER_DEBUG); + ostatus_import($xml,$importer,$contact, $hub); + } + return; + } require_once('library/simplepie/simplepie.inc'); require_once('include/contact_selectors.php'); @@ -3647,6 +3773,9 @@ function local_delivery($importer,$data) { $parent = 0; if($posted_id) { + + $datarray["id"] = $posted_id; + $r = q("SELECT `parent`, `parent-uri` FROM `item` WHERE `id` = %d AND `uid` = %d LIMIT 1", intval($posted_id), intval($importer['importer_uid']) @@ -4009,7 +4138,7 @@ function local_delivery($importer,$data) { 'verb' => $datarray['verb'], 'otype' => 'person', 'activity' => $verb, - + 'parent' => $datarray['parent'] )); } } @@ -4094,9 +4223,7 @@ function new_follower($importer,$contact,$datarray,$item,$sharing = false) { } if(($r[0]['notify-flags'] & NOTIFY_INTRO) && - (($r[0]['page-flags'] == PAGE_NORMAL) OR ($r[0]['page-flags'] == PAGE_SOAPBOX))) { - - + in_array($r[0]['page-flags'], array(PAGE_NORMAL, PAGE_SOAPBOX, PAGE_FREELOVE))) { notification(array( 'type' => NOTIFY_INTRO, @@ -4113,7 +4240,6 @@ function new_follower($importer,$contact,$datarray,$item,$sharing = false) { 'otype' => 'intro' )); - } } } @@ -4201,10 +4327,48 @@ function atom_author($tag,$name,$uri,$h,$w,$photo) { $o .= "<$tag>\r\n"; - $o .= "$name\r\n"; - $o .= "$uri\r\n"; - $o .= '' . "\r\n"; - $o .= '' . "\r\n"; + $o .= "\t$name\r\n"; + $o .= "\t$uri\r\n"; + $o .= "\t".'' . "\r\n"; + $o .= "\t".'' . "\r\n"; + + if ($tag == "author") { + $r = q("SELECT `profile`.`locality`, `profile`.`region`, `profile`.`country-name`, + `profile`.`name`, `profile`.`pub_keywords`, `profile`.`about`, + `profile`.`homepage`,`contact`.`nick` FROM `profile` + INNER JOIN `contact` ON `contact`.`uid` = `profile`.`uid` + INNER JOIN `user` ON `user`.`uid` = `profile`.`uid` + WHERE `profile`.`is-default` AND `contact`.`self` AND + NOT `user`.`hidewall` AND `contact`.`nurl`='%s'", + dbesc(normalise_link($uri))); + if ($r) { + $location = ''; + if($r[0]['locality']) + $location .= $r[0]['locality']; + if($r[0]['region']) { + if($location) + $location .= ', '; + $location .= $r[0]['region']; + } + if($r[0]['country-name']) { + if($location) + $location .= ', '; + $location .= $r[0]['country-name']; + } + + $o .= "\t".xmlify($r[0]["nick"])."\r\n"; + $o .= "\t".xmlify($r[0]["name"])."\r\n"; + $o .= "\t".xmlify($r[0]["about"])."\r\n"; + $o .= "\t\r\n"; + $o .= "\t\t".xmlify($location)."\r\n"; + $o .= "\t\r\n"; + $o .= "\t\r\n"; + $o .= "\thomepage\r\n"; + $o .= "\t\t".xmlify($r[0]["homepage"])."\r\n"; + $o .= "\t\ttrue\r\n"; + $o .= "\t\r\n"; + } + } call_hooks('atom_author', $o); @@ -4248,7 +4412,8 @@ function atom_entry($item,$type,$author,$owner,$comment = false,$cid = 0) { if ($item['title'] != "") $htmlbody = "[b]".$item['title']."[/b]\n\n".$htmlbody; - $htmlbody = bbcode(bb_remove_share_information($htmlbody), false, false, 7); + //$htmlbody = bbcode(bb_remove_share_information($htmlbody), false, false, 7); + $htmlbody = bbcode($htmlbody, false, false, 7); $o .= '' . xmlify($item['uri']) . '' . "\r\n"; $o .= '' . xmlify($item['title']) . '' . "\r\n"; @@ -4259,6 +4424,8 @@ function atom_entry($item,$type,$author,$owner,$comment = false,$cid = 0) { $o .= '' . "\r\n"; + $o .= ''."\r\n"; + if($comment) $o .= '' . intval($item['last-child']) . '' . "\r\n"; @@ -4300,11 +4467,19 @@ function atom_entry($item,$type,$author,$owner,$comment = false,$cid = 0) { $tags = item_getfeedtags($item); if(count($tags)) { - foreach($tags as $t) { - $o .= '' . "\r\n"; - } + foreach($tags as $t) + if (($type != 'html') OR ($t[0] != "@")) + $o .= '' . "\r\n"; } + // To-Do: + // To support these elements, the API needs to be enhanced + //$o .= ''."\r\n"; + //$o .= "\t".''."\r\n"; + //$o .= "\t".''."\r\n"; + + $o .= item_get_attachment($item); + $o .= item_getfeedattach($item); $mentioned = get_mentions($item); @@ -4482,6 +4657,28 @@ function item_getfeedtags($item) { return $ret; } +function item_get_attachment($item) { + $o = ""; + $siteinfo = get_attached_data($item["body"]); + + switch($siteinfo["type"]) { + case 'link': + $o = ''."\r\n"; + break; + case 'photo': + $imgdata = get_photo_info($siteinfo["image"]); + $o = ''."\r\n"; + break; + case 'video': + $o = ''."\r\n"; + break; + default: + break; + } + + return $o; +} + function item_getfeedattach($item) { $ret = ''; $arr = explode('[/attach],',$item['attach']); @@ -4720,6 +4917,18 @@ function drop_item($id,$interactive = true) { // ignore the result } + // If item has attachments, drop them + + foreach(explode(",",$item['attach']) as $attach){ + preg_match("|attach/(\d+)|", $attach, $matches); + q("DELETE FROM `attach` WHERE `id` = %d AND `uid` = %d", + intval($matches[1]), + local_user() + ); + // ignore the result + } + + // clean up item_id and sign meta-data tables /* @@ -4796,6 +5005,7 @@ function drop_item($id,$interactive = true) { // Add a relayable_retraction signature for Diaspora. store_diaspora_retract_sig($item, $a->user, $a->get_baseurl()); } + $drop_id = intval($item['id']); // send the notification upstream/downstream as the case may be @@ -4833,6 +5043,37 @@ function first_post_date($uid,$wall = false) { return false; } +/* modified posted_dates() {below} to arrange the list in years */ +function list_post_dates($uid, $wall) { + $dnow = datetime_convert('',date_default_timezone_get(),'now','Y-m-d'); + + $dthen = first_post_date($uid, $wall); + if(! $dthen) + return array(); + + // Set the start and end date to the beginning of the month + $dnow = substr($dnow,0,8).'01'; + $dthen = substr($dthen,0,8).'01'; + + $ret = array(); + + // Starting with the current month, get the first and last days of every + // month down to and including the month of the first post + while(substr($dnow, 0, 7) >= substr($dthen, 0, 7)) { + $dyear = intval(substr($dnow,0,4)); + $dstart = substr($dnow,0,8) . '01'; + $dend = substr($dnow,0,8) . get_dim(intval($dnow),intval(substr($dnow,5))); + $start_month = datetime_convert('','',$dstart,'Y-m-d'); + $end_month = datetime_convert('','',$dend,'Y-m-d'); + $str = day_translate(datetime_convert('','',$dnow,'F')); + if(! $ret[$dyear]) + $ret[$dyear] = array(); + $ret[$dyear][] = array($str,$end_month,$start_month); + $dnow = datetime_convert('','',$dnow . ' -1 month', 'Y-m-d'); + } + return $ret; +} + function posted_dates($uid,$wall) { $dnow = datetime_convert('',date_default_timezone_get(),'now','Y-m-d'); @@ -4871,15 +5112,27 @@ function posted_date_widget($url,$uid,$wall) { /* if($wall && intval(get_pconfig($uid,'system','no_wall_archive_widget'))) return $o;*/ - $ret = posted_dates($uid,$wall); + $visible_years = get_pconfig($uid,'system','archive_visible_years'); + if(! $visible_years) + $visible_years = 5; + + $ret = list_post_dates($uid,$wall); + if(! count($ret)) return $o; + $cutoff_year = intval(datetime_convert('',date_default_timezone_get(),'now','Y')) - $visible_years; + $cutoff = ((array_key_exists($cutoff_year,$ret))? true : false); + $o = replace_macros(get_markup_template('posted_date_widget.tpl'),array( '$title' => t('Archives'), - '$size' => ((count($ret) > 6) ? 6 : count($ret)), + '$size' => $visible_years, + '$cutoff_year' => $cutoff_year, + '$cutoff' => $cutoff, '$url' => $url, - '$dates' => $ret + '$dates' => $ret, + '$showmore' => t('show more') + )); return $o; }