X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=include%2Fitems.php;h=b7863f838d104f2e333dac20523946da7e0de234;hb=a5e0190f23a9b3ee840e98f9a819d688f6326781;hp=153debd7d321f803f2fa11a5fc934f0647092ae4;hpb=9f1f9da89bb98d768b7a41b388e9c5c0d28ec946;p=friendica.git diff --git a/include/items.php b/include/items.php index 153debd7d3..b7863f838d 100644 --- a/include/items.php +++ b/include/items.php @@ -180,7 +180,7 @@ function construct_activity_object($item) { if($item['object']) { $o = '' . "\r\n"; - $r = @simplexml_load_string($item['object']); + $r = parse_xml_string($item['object']); if($r->type) $o .= '' . xmlify($r->type) . '' . "\r\n"; if($r->id) @@ -206,7 +206,7 @@ function construct_activity_target($item) { if($item['target']) { $o = '' . "\r\n"; - $r = @simplexml_load_string($item['target']); + $r = parse_xml_string($item['target']); if($r->type) $o .= '' . xmlify($r->type) . '' . "\r\n"; if($r->id) @@ -241,8 +241,14 @@ function get_atom_elements($feed,$item) { $res = array(); $author = $item->get_author(); - $res['author-name'] = unxmlify($author->get_name()); - $res['author-link'] = unxmlify($author->get_link()); + if($author) { + $res['author-name'] = unxmlify($author->get_name()); + $res['author-link'] = unxmlify($author->get_link()); + } + else { + $res['author-name'] = unxmlify($feed->get_title()); + $res['author-link'] = unxmlify($feed->get_permalink()); + } $res['uri'] = unxmlify($item->get_id()); $res['title'] = unxmlify($item->get_title()); $res['body'] = unxmlify($item->get_content()); @@ -343,14 +349,13 @@ function get_atom_elements($feed,$item) { // the wild, by sanitising it and converting supported tags to bbcode before we rip out any remaining // html. - if((strpos($res['body'],'<') !== false) || (strpos($res['body'],'>') !== false)) { $res['body'] = preg_replace('#]+>.+?' . 'http://www.youtube.com/((?:v|cp)/[A-Za-z0-9\-_=]+).+?#s', '[youtube]$1[/youtube]', $res['body']); $res['body'] = oembed_html2bbcode($res['body']); - + $config = HTMLPurifier_Config::createDefault(); $config->set('Cache.DefinitionImpl', null); @@ -363,7 +368,7 @@ function get_atom_elements($feed,$item) { $res['body'] = html2bbcode($res['body']); } - + $allow = $item->get_item_tags(NAMESPACE_DFRN,'comment-allow'); if($allow && $allow[0]['data'] == 1) $res['last-child'] = 1; @@ -401,6 +406,17 @@ function get_atom_elements($feed,$item) { $res['edited'] = $item->get_date('c'); + // Disallow time travelling posts + + $d1 = strtotime($res['created']); + $d2 = strtotime($res['edited']); + $d3 = strtotime('now'); + + if($d1 > $d3) + $res['created'] = datetime_convert(); + if($d2 > $d3) + $res['edited'] = datetime_convert(); + $rawowner = $item->get_item_tags(NAMESPACE_DFRN, 'owner'); if($rawowner[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data']) $res['owner-name'] = unxmlify($rawowner[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data']); @@ -440,7 +456,45 @@ function get_atom_elements($feed,$item) { if((x($res,'verb')) && ($res['verb'] === 'http://ostatus.org/schema/1.0/unfollow')) $res['verb'] = ACTIVITY_UNFOLLOW; - + + $cats = $item->get_categories(); + if($cats) { + $tag_arr = array(); + foreach($cats as $cat) { + $term = $cat->get_term(); + if(! $term) + $term = $cat->get_label(); + $scheme = $cat->get_scheme(); + if($scheme && $term && stristr($scheme,'X-DFRN:')) + $tag_arr[] = substr($scheme,7,1) . '[url=' . unxmlify(substr($scheme,9)) . ']' . unxmlify($term) . '[/url]'; + elseif($term) + $tag_arr[] = notags(trim($term)); + } + $res['tag'] = implode(',', $tag_arr); + } + + $attach = $item->get_enclosures(); + if($attach) { + $att_arr = array(); + foreach($attach as $att) { + $len = intval($att->get_length()); + $link = str_replace(array(',','"'),array('%2D','%22'),notags(trim(unxmlify($att->get_link())))); + $title = str_replace(array(',','"'),array('%2D','%22'),notags(trim(unxmlify($att->get_title())))); + $type = str_replace(array(',','"'),array('%2D','%22'),notags(trim(unxmlify($att->get_type())))); + if(strpos($type,';')) + $type = substr($type,0,strpos($type,';')); + if((! $link) || (strpos($link,'http') !== 0)) + continue; + + if(! $title) + $title = ' '; + if(! $type) + $type = 'application/octet-stream'; + + $att_arr[] = '[attach]href="' . $link . '" size="' . $len . '" type="' . $type . '" title="' . $title . '"[/attach]'; + } + $res['attach'] = implode(',', $att_arr); + } $rawobj = $item->get_item_tags(NAMESPACE_ACTIVITY, 'object'); @@ -598,6 +652,8 @@ function item_store($arr,$force_parent = false) { $arr['deny_gid'] = ((x($arr,'deny_gid')) ? trim($arr['deny_gid']) : ''); $arr['private'] = ((x($arr,'private')) ? intval($arr['private']) : 0 ); $arr['body'] = ((x($arr,'body')) ? trim($arr['body']) : ''); + $arr['tag'] = ((x($arr,'tag')) ? notags(trim($arr['tag'])) : ''); + $arr['attach'] = ((x($arr,'attach')) ? notags(trim($arr['attach'])) : ''); if($arr['parent-uri'] === $arr['uri']) { $parent_id = 0; @@ -609,6 +665,7 @@ function item_store($arr,$force_parent = false) { else { // find the parent and snarf the item id and ACL's + // and anything else we need to inherit $r = q("SELECT * FROM `item` WHERE `uri` = '%s' AND `uid` = %d LIMIT 1", dbesc($arr['parent-uri']), @@ -632,6 +689,7 @@ function item_store($arr,$force_parent = false) { $allow_gid = $r[0]['allow_gid']; $deny_cid = $r[0]['deny_cid']; $deny_gid = $r[0]['deny_gid']; + $arr['wall'] = $r[0]['wall']; } else { @@ -643,6 +701,7 @@ function item_store($arr,$force_parent = false) { $parent_id = 0; $arr['thr-parent'] = $arr['parent-uri']; $arr['parent-uri'] = $arr['uri']; + $arr['gravity'] = 0; } else { logger('item_store: item parent was not found - ignoring item'); @@ -700,6 +759,18 @@ function item_store($arr,$force_parent = false) { intval($current_post) ); + /** + * If this is now the last-child, force all _other_ children of this parent to *not* be last-child + */ + + if($arr['last-child']) { + $r = q("UPDATE `item` SET `last-child` = 0 WHERE `parent-uri` = '%s' AND `uid` = %d AND `id` != %d", + dbesc($arr['uri']), + intval($arr['uid']), + intval($current_post) + ); + } + return $current_post; } @@ -737,7 +808,7 @@ function dfrn_deliver($owner,$contact,$atom, $dissolve = false) { if(! $rino_enable) $rino = 0; - $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=1' : ''); logger('dfrn_deliver: ' . $url); @@ -758,7 +829,7 @@ function dfrn_deliver($owner,$contact,$atom, $dissolve = false) { return 3; } - $res = simplexml_load_string($xml); + $res = parse_xml_string($xml); if((intval($res->status) != 0) || (! strlen($res->challenge)) || (! strlen($res->dfrn_id))) return (($res->status) ? $res->status : 3); @@ -797,14 +868,14 @@ function dfrn_deliver($owner,$contact,$atom, $dissolve = false) { if($dissolve) $postvars['dissolve'] = '1'; - if(($contact['rel']) && ($contact['rel'] != REL_FAN) && (! $contact['blocked']) && (! $contact['readonly'])) { - $postvars['data'] = $atom; - } - elseif($owner['page-flags'] == PAGE_COMMUNITY) { + + if((($contact['rel']) && ($contact['rel'] != REL_FAN) && (! $contact['blocked'])) || ($owner['page-flags'] == PAGE_COMMUNITY)) { $postvars['data'] = $atom; + $postvars['perm'] = 'rw'; } else { $postvars['data'] = str_replace('1','0',$atom); + $postvars['perm'] = 'r'; } if($rino && $rino_allowed && (! $dissolve)) { @@ -846,17 +917,15 @@ function dfrn_deliver($owner,$contact,$atom, $dissolve = false) { if((! $curl_stat) || (! strlen($xml))) return(-1); // timed out - if(strpos($xml,'status; - + return $res->status; } @@ -876,7 +945,7 @@ function dfrn_deliver($owner,$contact,$atom, $dissolve = false) { * */ -function consume_feed($xml,$importer,&$contact, &$hub, $datedir = 0) { +function consume_feed($xml,$importer,&$contact, &$hub, $datedir = 0, $secure_feed = false) { require_once('simplepie/simplepie.inc'); @@ -891,6 +960,7 @@ function consume_feed($xml,$importer,&$contact, &$hub, $datedir = 0) { if($feed->error()) logger('consume_feed: Error parsing XML: ' . $feed->error()); + $permalink = $feed->get_permalink(); // Check at the feed level for updated contact name and/or photo @@ -1132,15 +1202,35 @@ function consume_feed($xml,$importer,&$contact, &$hub, $datedir = 0) { // Have we seen it? If not, import it. - $item_id = $item->get_id(); + $item_id = $item->get_id(); + $datarray = get_atom_elements($feed,$item); - $r = q("SELECT `uid`, `last-child`, `edited` FROM `item` WHERE `uri` = '%s' AND `uid` = %d LIMIT 1", + if(! x($datarray,'author-name')) + $datarray['author-name'] = $contact['name']; + if(! x($datarray,'author-link')) + $datarray['author-link'] = $contact['url']; + if(! x($datarray,'author-avatar')) + $datarray['author-avatar'] = $contact['thumb']; + + $r = q("SELECT `uid`, `last-child`, `edited`, `body` FROM `item` WHERE `uri` = '%s' AND `uid` = %d LIMIT 1", dbesc($item_id), intval($importer['uid']) ); - // FIXME update content if 'updated' changes + // Update content if 'updated' changes + if(count($r)) { + if((x($datarray,'edited') !== false) && (datetime_convert('UTC','UTC',$datarray['edited']) !== $r[0]['edited'])) { + $r = q("UPDATE `item` SET `body` = '%s', `edited` = '%s' WHERE `uri` = '%s' AND `uid` = %d LIMIT 1", + dbesc($datarray['body']), + dbesc(datetime_convert('UTC','UTC',$datarray['edited'])), + dbesc($item_id), + intval($importer['uid']) + ); + } + + // update last-child if it changes + $allow = $item->get_item_tags( NAMESPACE_DFRN, 'comment-allow'); if(($allow) && ($allow[0]['data'] != $r[0]['last-child'])) { $r = q("UPDATE `item` SET `last-child` = 0, `changed` = '%s' WHERE `parent-uri` = '%s' AND `uid` = %d", @@ -1158,7 +1248,6 @@ function consume_feed($xml,$importer,&$contact, &$hub, $datedir = 0) { continue; } - $datarray = get_atom_elements($feed,$item); $force_parent = false; if($contact['network'] === 'stat') { $force_parent = true; @@ -1189,14 +1278,41 @@ function consume_feed($xml,$importer,&$contact, &$hub, $datedir = 0) { } else { + // Head post of a conversation. Have we seen it? If not, import it. - $item_id = $item->get_id(); - $r = q("SELECT `uid`, `last-child`, `edited` FROM `item` WHERE `uri` = '%s' AND `uid` = %d LIMIT 1", + $item_id = $item->get_id(); + + $datarray = get_atom_elements($feed,$item); + + if(is_array($contact)) { + if(! x($datarray,'author-name')) + $datarray['author-name'] = $contact['name']; + if(! x($datarray,'author-link')) + $datarray['author-link'] = $contact['url']; + if(! x($datarray,'author-avatar')) + $datarray['author-avatar'] = $contact['thumb']; + } + + $r = q("SELECT `uid`, `last-child`, `edited`, `body` FROM `item` WHERE `uri` = '%s' AND `uid` = %d LIMIT 1", dbesc($item_id), intval($importer['uid']) ); + + // Update content if 'updated' changes + if(count($r)) { + if((x($datarray,'edited') !== false) && (datetime_convert('UTC','UTC',$datarray['edited']) !== $r[0]['edited'])) { + $r = q("UPDATE `item` SET `body` = '%s', `edited` = '%s' WHERE `uri` = '%s' AND `uid` = %d LIMIT 1", + dbesc($datarray['body']), + dbesc(datetime_convert('UTC','UTC',$datarray['edited'])), + dbesc($item_id), + intval($importer['uid']) + ); + } + + // update last-child if it changes + $allow = $item->get_item_tags( NAMESPACE_DFRN, 'comment-allow'); if($allow && $allow[0]['data'] != $r[0]['last-child']) { $r = q("UPDATE `item` SET `last-child` = %d , `changed` = '%s' WHERE `uri` = '%s' AND `uid` = %d LIMIT 1", @@ -1208,7 +1324,6 @@ function consume_feed($xml,$importer,&$contact, &$hub, $datedir = 0) { } continue; } - $datarray = get_atom_elements($feed,$item); if(activity_match($datarray['verb'],ACTIVITY_FOLLOW)) { logger('consume-feed: New follower'); @@ -1222,7 +1337,7 @@ function consume_feed($xml,$importer,&$contact, &$hub, $datedir = 0) { if(! is_array($contact)) return; - if($contact['network'] === 'stat') { + if($contact['network'] === 'stat' || stristr($permalink,'twitter.com')) { if(strlen($datarray['title'])) unset($datarray['title']); $datarray['last-child'] = 1; @@ -1269,8 +1384,8 @@ function new_follower($importer,$contact,$datarray,$item) { // create contact record - set to readonly $r = q("INSERT INTO `contact` ( `uid`, `created`, `url`, `name`, `nick`, `photo`, `network`, `rel`, - `blocked`, `readonly`, `pending` ) - VALUES ( %d, '%s', '%s', '%s', '%s', '%s', '%s', %d, 0, 1, 1 ) ", + `blocked`, `readonly`, `pending`, `writable` ) + VALUES ( %d, '%s', '%s', '%s', '%s', '%s', '%s', %d, 0, 1, 1, 1 ) ", intval($importer['uid']), dbesc(datetime_convert()), dbesc($url), @@ -1317,7 +1432,9 @@ function new_follower($importer,$contact,$datarray,$item) { $res = mail($r[0]['email'], t("You have a new follower at ") . $a->config['sitename'], $email, - 'From: ' . t('Administrator') . '@' . $_SERVER['SERVER_NAME'] ); + 'From: ' . t('Administrator') . '@' . $_SERVER['SERVER_NAME'] . "\n" + . 'Content-type: text/plain; charset=UTF-8' . "\n" + . 'Content-transfer-encoding: 8bit' ); } } @@ -1396,10 +1513,17 @@ function atom_author($tag,$name,$uri,$h,$w,$photo) { function atom_entry($item,$type,$author,$owner,$comment = false) { + $a = get_app(); + if($item['deleted']) return '' . "\r\n"; - $a = get_app(); + + if($item['allow_cid'] || $item['allow_gid'] || $item['deny_cid'] || $item['deny_gid']) + $body = fix_private_photos($item['body'],$owner['uid']); + else + $body = $item['body']; + $o = "\r\n\r\n\r\n"; @@ -1417,8 +1541,8 @@ function atom_entry($item,$type,$author,$owner,$comment = false) { $o .= '' . xmlify($item['title']) . '' . "\r\n"; $o .= '' . xmlify(datetime_convert('UTC','UTC',$item['created'] . '+00:00',ATOM_TIME)) . '' . "\r\n"; $o .= '' . xmlify(datetime_convert('UTC','UTC',$item['edited'] . '+00:00',ATOM_TIME)) . '' . "\r\n"; - $o .= '' . base64url_encode($item['body'], true) . '' . "\r\n"; - $o .= '' . xmlify(($type === 'html') ? bbcode($item['body']) : $item['body']) . '' . "\r\n"; + $o .= '' . base64url_encode($body, true) . '' . "\r\n"; + $o .= '' . xmlify(($type === 'html') ? bbcode($body) : $body) . '' . "\r\n"; $o .= '' . "\r\n"; if($comment) $o .= '' . intval($item['last-child']) . '' . "\r\n"; @@ -1443,6 +1567,15 @@ function atom_entry($item,$type,$author,$owner,$comment = false) { if(strlen($actarg)) $o .= $actarg; + $tags = item_getfeedtags($item); + if(count($tags)) { + foreach($tags as $t) { + $o .= '' . "\r\n"; + } + } + + $o .= item_getfeedattach($item); + $mentioned = get_mentions($item); if($mentioned) $o .= $mentioned; @@ -1453,4 +1586,125 @@ function atom_entry($item,$type,$author,$owner,$comment = false) { return $o; } + +function fix_private_photos($s,$uid) { + $a = get_app(); + logger('fix_private_photos'); + + if(preg_match("/\[img\](.+?)\[\/img\]/is",$s,$matches)) { + $image = $matches[1]; + logger('fix_private_photos: found photo ' . $image); + if(stristr($image ,$a->get_baseurl() . '/photo/')) { + $i = basename($image); + $i = str_replace('.jpg','',$i); + $x = strpos($i,'-'); + if($x) { + $res = substr($i,$x+1); + $i = substr($i,0,$x); + $r = q("SELECT * FROM `photo` WHERE `resource-id` = '%s' AND `scale` = %d AND `uid` = %d", + dbesc($i), + intval($res), + intval($uid) + ); + if(count($r)) { + logger('replacing photo'); + $s = str_replace($image, 'data:image/jpg;base64,' . base64_encode($r[0]['data']), $s); + } + } + logger('fix_private_photos: replaced: ' . $s, LOGGER_DATA); + } + } + return($s); +} + + + +function item_getfeedtags($item) { + $ret = array(); + $matches = false; + $cnt = preg_match_all('|\#\[url\=(.+?)\](.+?)\[\/url\]|',$item['tag'],$matches); + if($cnt) { + for($x = 0; $x < count($matches); $x ++) { + if($matches[1][$x]) + $ret[] = array('#',$matches[1][$x], $matches[2][$x]); + } + } + $matches = false; + $cnt = preg_match_all('|\@\[url\=(.+?)\](.+?)\[\/url\]|',$item['tag'],$matches); + if($cnt) { + for($x = 0; $x < count($matches); $x ++) { + if($matches[1][$x]) + $ret[] = array('#',$matches[1][$x], $matches[2][$x]); + } + } + return $ret; +} + +function item_getfeedattach($item) { + $ret = ''; + $arr = explode(',',$item['attach']); + if(count($arr)) { + foreach($arr as $r) { + $matches = false; + $cnt = preg_match('|\[attach\]href=\"(.+?)\" size=\"(.+?)\" type=\"(.+?)\" title=\"(.+?)\"\[\/attach\]|',$r,$matches); + if($cnt) { + $ret .= '