]> git.mxchange.org Git - friendica.git/blobdiff - include/items.php
PuSH: Publishing moved to a new process. OStatus comments are now published to all...
[friendica.git] / include / items.php
index 5a0aa9ed51649921a2206ebdc4512946dce8f82e..44eb18ccd1326dcba63dc5bc4303366c2efe1c01 100644 (file)
@@ -14,7 +14,7 @@ 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) {
+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
@@ -55,6 +55,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) {
 
@@ -114,6 +115,17 @@ function get_feed_for(&$a, $dfrn_id, $owner_nick, $last_update, $direction = 0)
        else
                $sort = 'ASC';
 
+       // Include answers to status.net posts in public feeds
+       if($forpubsub) {
+               $sql_post_table = "INNER JOIN `thread` ON `thread`.`iid` = `item`.`parent` ";
+               $visibility = "OR (`item`.`network` = 'dfrn' AND `thread`.`network`='stat')";
+               $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';
 
@@ -133,7 +145,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`,
@@ -144,9 +156,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)
@@ -464,12 +476,27 @@ 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.
+
+       // Search for ostatus conversation url
+       $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']);
@@ -828,7 +855,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"];
@@ -836,10 +863,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_header($name, $uri, $avatar, "", "", $orig_uri);
+                               $prefix = share_header($name, $uri, $avatar, "", "", $orig_link);
 
                                $res["body"] = $prefix.html2bbcode($message)."[/share]";
                        } else {
@@ -864,8 +891,11 @@ function get_atom_elements($feed, $item, $contact = array()) {
                        $conversation = array_shift($link["attribs"]);
 
                        if ($conversation["rel"] == "ostatus:conversation") {
-                               $res["ostatus_conversation"] = $conversation["href"];
+                               $res["ostatus_conversation"] = ostatus_convert_href($conversation["href"]);
                                logger('get_atom_elements: found conversation url '.$res["ostatus_conversation"]);
+                       } elseif ($conversation["rel"] == "alternate") {
+                               $res["plink"] = $conversation["href"];
+                               logger('get_atom_elements: found plink '.$res["plink"]);
                        }
                };
        }
@@ -1090,6 +1120,14 @@ function item_store($arr,$force_parent = false, $notify = false, $dontcache = fa
                unset($arr['dsprsig']);
        }
 
+       // 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 an OStatus conversation url was passed in, it is stored and then
        // removed from the array.
        $ostatus_conversation = null;
@@ -1115,7 +1153,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) {
@@ -1141,6 +1179,19 @@ 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']) != "")) {
+               logger('item_store: checking for an existing guid for plink '.$arr['plink'], LOGGER_DEBUG);
+               $r = q("SELECT `guid` FROM `item` WHERE `plink` = '%s' AND `guid` != '' LIMIT 1",
+                       dbesc(trim($arr['plink']))
+               );
+
+               if(count($r)) {
+                       $arr['guid'] = $r[0]["guid"];
+                       logger('item_store: found guid '.$arr['guid'].' for plink '.$arr['plink'], 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))
@@ -1347,12 +1398,36 @@ 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;
+       }
+
+       $r = q("SELECT `id` FROM `item` WHERE `plink` = '%s' AND `network` = '%s' AND `uid` = %d LIMIT 1",
+               dbesc($arr['plink']),
+               dbesc($arr['network']),
+               intval($arr['uid'])
+       );
+       if($r && count($r)) {
+               logger('duplicated item with the same plink 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;
        }
 
@@ -2167,6 +2242,12 @@ function consume_feed($xml,$importer,&$contact, &$hub, $datedir = 0, $pass = 0)
                return;
        }
 
+       // Test - remove before flight
+//     if ($contact['network'] === NETWORK_OSTATUS) {
+//             $tempfile = tempnam(get_temppath(), "ostatus");
+//             file_put_contents($tempfile, $xml);
+//     }
+
        $feed = new SimplePie();
        $feed->set_raw_data($xml);
        if($datedir)
@@ -4745,6 +4826,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
 
                /*
@@ -4821,6 +4914,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
@@ -4858,6 +4952,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');
 
@@ -4895,16 +5020,28 @@ 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;
 }