X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;ds=sidebyside;f=include%2Fitems.php;h=5c797424bfc634819707791adbfe5b844a0a877b;hb=d908c9dd7196276e1364f77abb053aba3dce77af;hp=c6d852fe7315266ca6c82ff963db4b9378dd1f60;hpb=24b58af68938558baa2ddc6809401ec528ff1176;p=friendica.git diff --git a/include/items.php b/include/items.php old mode 100644 new mode 100755 index c6d852fe73..5c797424bf --- a/include/items.php +++ b/include/items.php @@ -22,8 +22,6 @@ function get_feed_for(&$a, $dfrn_id, $owner_nick, $last_update, $direction = 0) if($a->argv[$x] === 'category' && $a->argc > ($x + 1) && strlen($a->argv[$x+1])) $category = $a->argv[$x+1]; } - - } @@ -180,6 +178,10 @@ function get_feed_for(&$a, $dfrn_id, $owner_nick, $last_update, $direction = 0) foreach($items as $item) { + // prevent private email from leaking. + if($item['network'] === NETWORK_MAIL) + continue; + // public feeds get html, our own nodes use bbcode if($public_feed) { @@ -689,6 +691,8 @@ function encode_rel_links($links) { return xmlify($o); } + + function item_store($arr,$force_parent = false) { // If a Diaspora signature structure was passed in, pull it out of the @@ -802,6 +806,14 @@ function item_store($arr,$force_parent = false) { $deny_cid = $r[0]['deny_cid']; $deny_gid = $r[0]['deny_gid']; $arr['wall'] = $r[0]['wall']; + + // if the parent is private, force privacy for the entire conversation + // This differs from the above settings as it subtly allows comments from + // email correspondents to be private even if the overall thread is not. + + if($r[0]['private']) + $arr['private'] = 1; + } else { @@ -896,6 +908,16 @@ function item_store($arr,$force_parent = false) { intval($current_post) ); + $arr['id'] = $current_post; + $arr['parent'] = $parent_id; + $arr['allow_cid'] = $allow_cid; + $arr['allow_gid'] = $allow_gid; + $arr['deny_cid'] = $deny_cid; + $arr['deny_gid'] = $deny_gid; + $arr['private'] = $private; + $arr['deleted'] = $parent_deleted; + call_hooks('post_remote_end',$arr); + // update the commented timestamp on the parent q("UPDATE `item` set `commented` = '%s', `changed` = '%s' WHERE `id` = %d LIMIT 1", @@ -1300,6 +1322,7 @@ function consume_feed($xml,$importer,&$contact, &$hub, $datedir = 0, $pass = 0) $birthday = ''; $hubs = $feed->get_links('hub'); + logger('consume_feed: hubs: ' . print_r($hubs,true), LOGGER_DATA); if(count($hubs)) $hub = implode(',', $hubs); @@ -1342,7 +1365,11 @@ function consume_feed($xml,$importer,&$contact, &$hub, $datedir = 0, $pass = 0) } $img_str = fetch_url($photo_url,true); - $img = new Photo($img_str); + // guess mimetype from headers or filename + $type = guess_image_type($photo_url,true); + + + $img = new Photo($img_str, $type); if($img->is_valid()) { if($have_photo) { q("DELETE FROM `photo` WHERE `resource-id` = '%s' AND `contact-id` = %d AND `uid` = %d", @@ -1368,9 +1395,9 @@ function consume_feed($xml,$importer,&$contact, &$hub, $datedir = 0, $pass = 0) 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.jpg'), - dbesc($a->get_baseurl() . '/photo/' . $hash . '-5.jpg'), - dbesc($a->get_baseurl() . '/photo/' . $hash . '-6.jpg'), + dbesc($a->get_baseurl() . '/photo/' . $hash . '-4.'.$img->getExt()), + dbesc($a->get_baseurl() . '/photo/' . $hash . '-5.'.$img->getExt()), + dbesc($a->get_baseurl() . '/photo/' . $hash . '-6.'.$img->getExt()), intval($contact['uid']), intval($contact['id']) ); @@ -1626,6 +1653,11 @@ function consume_feed($xml,$importer,&$contact, &$hub, $datedir = 0, $pass = 0) if(count($r)) { 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; + $r = q("UPDATE `item` SET `title` = '%s', `body` = '%s', `tag` = '%s', `edited` = '%s' WHERE `uri` = '%s' AND `uid` = %d LIMIT 1", dbesc($datarray['title']), dbesc($datarray['body']), @@ -1772,6 +1804,11 @@ function consume_feed($xml,$importer,&$contact, &$hub, $datedir = 0, $pass = 0) if(count($r)) { 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; + $r = q("UPDATE `item` SET `title` = '%s', `body` = '%s', `tag` = '%s', `edited` = '%s' WHERE `uri` = '%s' AND `uid` = %d LIMIT 1", dbesc($datarray['title']), dbesc($datarray['body']), @@ -1827,9 +1864,11 @@ function consume_feed($xml,$importer,&$contact, &$hub, $datedir = 0, $pass = 0) } if(($contact['network'] === NETWORK_FEED) || (! strlen($contact['notify']))) { - // one way feed - no remote comment ability - $datarray['last-child'] = 0; + // one way feed - no remote comment ability + $datarray['last-child'] = 0; } + if($contact['network'] === NETWORK_FEED) + $datarray['private'] = 1; // This is my contact on another system, but it's really me. // Turn this into a wall post. @@ -2255,7 +2294,12 @@ 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'])) { + 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']), @@ -2434,6 +2478,11 @@ function local_delivery($importer,$data) { if(count($r)) { 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; + $r = q("UPDATE `item` SET `title` = '%s', `body` = '%s', `tag` = '%s', `edited` = '%s' WHERE `uri` = '%s' AND `uid` = %d LIMIT 1", dbesc($datarray['title']), dbesc($datarray['body']), @@ -2600,6 +2649,11 @@ function local_delivery($importer,$data) { if(count($r)) { 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; + $r = q("UPDATE `item` SET `title` = '%s', `body` = '%s', `tag` = '%s', `edited` = '%s' WHERE `uri` = '%s' AND `uid` = %d LIMIT 1", dbesc($datarray['title']), dbesc($datarray['body']), @@ -2773,6 +2827,8 @@ function lose_sharer($importer,$contact,$datarray,$item) { function subscribe_to_hub($url,$importer,$contact,$hubmode = 'subscribe') { + $a = get_app(); + if(is_array($importer)) { $r = q("SELECT `nickname` FROM `user` WHERE `uid` = %d LIMIT 1", intval($importer['uid']) @@ -2803,7 +2859,10 @@ function subscribe_to_hub($url,$importer,$contact,$hubmode = 'subscribe') { ); } - post_url($url,$params); + post_url($url,$params); + + logger('subscribe_to_hub: returns: ' . $a->get_curl_code(), LOGGER_DEBUG); + return; } @@ -2933,13 +2992,13 @@ function fix_private_photos($s,$uid, $item = null, $cid = 0) { logger('fix_private_photos', LOGGER_DEBUG); $site = substr($a->get_baseurl(),strpos($a->get_baseurl(),'://')); - if(preg_match("/\[img\](.*?)\[\/img\]/is",$s,$matches)) { - $image = $matches[1]; + if(preg_match("/\[img(.*?)\](.*?)\[\/img\]/is",$s,$matches)) { + $image = $matches[2]; logger('fix_private_photos: found photo ' . $image, LOGGER_DEBUG); if(stristr($image , $site . '/photo/')) { $replace = false; $i = basename($image); - $i = str_replace('.jpg','',$i); + $i = str_replace(array('.jpg','.png'),array('',''),$i); $x = strpos($i,'-'); if($x) { $res = substr($i,$x+1); @@ -2981,7 +3040,7 @@ function fix_private_photos($s,$uid, $item = null, $cid = 0) { } if($replace) { logger('fix_private_photos: replacing photo', LOGGER_DEBUG); - $s = str_replace($image, 'data:image/jpg;base64,' . base64_encode($r[0]['data']), $s); + $s = str_replace($image, 'data:' . $r[0]['type'] . ';base64,' . base64_encode($r[0]['data']), $s); logger('fix_private_photos: replaced: ' . $s, LOGGER_DATA); } } @@ -3274,7 +3333,42 @@ function drop_item($id,$interactive = true) { q("UPDATE `item` SET `last-child` = 1 WHERE `id` = %d LIMIT 1", intval($r[0]['id']) ); - } + } + + // Add a relayable_retraction signature for Diaspora. Note that we can't add a target_author_signature + // if the comment was deleted by a remote user. That should be ok, because if a remote user is deleting + // the comment, that means we're the home of the post, and Diaspora will only + // check the parent_author_signature of retractions that it doesn't have to relay further + // + // I don't think this function gets called for an "unlike," but I'll check anyway + $signed_text = $item['guid'] . ';' . ( ($item['verb'] === ACTIVITY_LIKE) ? 'Like' : 'Comment'); + + if(local_user() == $item['uid']) { + + $handle = $a->user['nickname'] . '@' . substr($a->get_baseurl(), strpos($a->get_baseurl(),'://') + 3); + $authorsig = base64_encode(rsa_sign($signed_text,$a->user['prvkey'],'sha256')); + } + else { + $r = q("SELECT `nick`, `url` FROM `contact` WHERE `id` = '%d' LIMIT 1", + $item['contact-id'] + ); + if(count($r)) { + // The below handle only works for NETWORK_DFRN. I think that's ok, because this function + // only handles DFRN deletes + $handle_baseurl_start = strpos($r['url'],'://') + 3; + $handle_baseurl_length = strpos($r['url'],'/profile') - $handle_baseurl_start; + $handle = $r['nick'] . '@' . substr($r['url'], $handle_baseurl_start, $handle_baseurl_length); + $authorsig = ''; + } + } + + if(isset($handle)) + q("insert into sign (`retract_iid`,`signed_text`,`signature`,`signer`) values (%d,'%s','%s','%s') ", + intval($item['id']), + dbesc($signed_text), + dbesc($authorsig), + dbesc($handle) + ); } $drop_id = intval($item['id']); @@ -3296,3 +3390,73 @@ function drop_item($id,$interactive = true) { } } + + +function first_post_date($uid,$wall = false) { + $r = q("select id, created from item + where uid = %d and wall = %d and deleted = 0 and visible = 1 AND moderated = 0 + and id = parent + order by created asc limit 1", + intval($uid), + intval($wall ? 1 : 0) + ); + if(count($r)) { +// logger('first_post_date: ' . $r[0]['id'] . ' ' . $r[0]['created'], LOGGER_DATA); + return substr(datetime_convert('',date_default_timezone_get(),$r[0]['created']),0,10); + } + return false; +} + +function posted_dates($uid,$wall) { + $dnow = datetime_convert('',date_default_timezone_get(),'now','Y-m-d'); + + $dthen = first_post_date($uid,$wall); + if(! $dthen) + return array(); + + // If it's near the end of a long month, backup to the 28th so that in + // consecutive loops we'll always get a whole month difference. + + if(intval(substr($dnow,8)) > 28) + $dnow = substr($dnow,0,8) . '28'; + if(intval(substr($dthen,8)) > 28) + $dnow = substr($dthen,0,8) . '28'; + + $ret = array(); + while($dnow >= $dthen) { + $start_month = datetime_convert('','','first day of ' . $dnow,'Y-m-d'); + $end_month = datetime_convert('','','last day of ' . $dnow,'Y-m-d'); + $str = day_translate(datetime_convert('','',$dnow,'F Y')); + $ret[] = array($str,$end_month,$start_month); + $dnow = datetime_convert('','',$dnow . ' -1 month', 'Y-m-d'); + } + return $ret; +} + + +function posted_date_widget($url,$uid,$wall) { + $o = ''; + + // "first day of " constructs were added in php 5.3 + // TODO: emulate posted_dates() logic for prior releases + + if(version_compare(PHP_VERSION, '5.3.0') < 0) + return $o; + + // For former Facebook folks that left because of "timeline" + + if($wall && intval(get_pconfig($uid,'system','no_wall_archive_widget'))) + return $o; + + $ret = posted_dates($uid,$wall); + if(! count($ret)) + return $o; + + $o = replace_macros(get_markup_template('posted_date_widget.tpl'),array( + '$title' => t('Archives'), + '$size' => ((count($ret) > 6) ? 6 : count($ret)), + '$url' => $url, + '$dates' => $ret + )); + return $o; +} \ No newline at end of file