]> git.mxchange.org Git - friendica-addons.git/blobdiff - facebook/facebook.php
Merge remote branch 'upstream/master'
[friendica-addons.git] / facebook / facebook.php
index 5c06ef7192a3e629616e945f374d882e4f99482e..b6e40654cd41c536b8905731cde3221a78d9fbc3 100755 (executable)
  *   e.g. the app_access_token
  */
 
-define('FACEBOOK_MAXPOSTLEN', 420);
+// Size of maximum post length increased
+// see http://www.facebook.com/schrep/posts/203969696349811
+// define('FACEBOOK_MAXPOSTLEN', 420);
+define('FACEBOOK_MAXPOSTLEN', 63206);
 define('FACEBOOK_SESSION_ERR_NOTIFICATION_INTERVAL', 259200); // 3 days
 define('FACEBOOK_DEFAULT_POLL_INTERVAL', 60); // given in minutes
 define('FACEBOOK_MIN_POLL_INTERVAL', 5);
 
+require_once('include/security.php');
+
 function facebook_install() {
        register_hook('post_local',       'addon/facebook/facebook.php', 'facebook_post_local');
        register_hook('notifier_normal',  'addon/facebook/facebook.php', 'facebook_post_hook');
@@ -264,6 +269,10 @@ function fb_get_friends_sync_full($uid, $access_token, $person) {
 
                $jp->link = 'http://facebook.com/profile.php?id=' . $person->id;
 
+               // If its a page then set the first name from the username
+               if (!$jp->first_name and $jp->username)
+                       $jp->first_name = $jp->username;
+
                // check if we already have a contact
 
                $r = q("SELECT * FROM `contact` WHERE `uid` = %d AND `url` = '%s' LIMIT 1",
@@ -640,6 +649,8 @@ function facebook_plugin_settings(&$a,&$b) {
 
 
 function facebook_plugin_admin(&$a, &$o){
+
+
        $o = '<input type="hidden" name="form_security_token" value="' . get_form_security_token("fbsave") . '">';
        
        $o .= '<h4>' . t('Facebook API Key') . '</h4>';
@@ -649,6 +660,10 @@ function facebook_plugin_admin(&$a, &$o){
        $poll_interval = get_config('facebook', 'poll_interval' );
        if (!$poll_interval) $poll_interval = FACEBOOK_DEFAULT_POLL_INTERVAL;
        
+       $ret1 = q("SELECT `v` FROM `config` WHERE `cat` = 'facebook' AND `k` = 'appid' LIMIT 1");
+       $ret2 = q("SELECT `v` FROM `config` WHERE `cat` = 'facebook' AND `k` = 'appsecret' LIMIT 1");
+       if ((count($ret1) > 0 && $ret1[0]['v'] != $appid) || (count($ret2) > 0 && $ret2[0]['v'] != $appsecret)) $o .= t('Error: it appears that you have specified the App-ID and -Secret in your .htconfig.php file. As long as they are specified there, they cannot be set using this form.<br><br>');
+       
        $working_connection = false;
        if ($appid && $appsecret) {
                $subs = facebook_subscriptions_get();
@@ -656,7 +671,7 @@ function facebook_plugin_admin(&$a, &$o){
                elseif (is_array($subs)) {
                        $o .= t('The given API Key seems to work correctly.') . '<br>';
                        $working_connection = true;
-               } else $o .= t('The correctness of the API Key could not be detected. Somthing strang\'s going on.') . '<br>';
+               } else $o .= t('The correctness of the API Key could not be detected. Somthing strange\'s going on.') . '<br>';
        }
        
        $o .= '<label for="fb_appid">' . t('App-ID / API-Key') . '</label><input name="appid" type="text" value="' . escape_tags($appid ? $appid : "") . '"><br style="clear: both;">';
@@ -842,6 +857,7 @@ function facebook_post_hook(&$a,&$b) {
                                if($b['verb'] == ACTIVITY_DISLIKE)
                                        $msg = trim(strip_tags(bbcode($msg)));
 
+                               // Old code
                                /*$search_str = $a->get_baseurl() . '/search';
 
                                if(preg_match("/\[url=(.*?)\](.*?)\[\/url\]/is",$msg,$matches)) {
@@ -873,23 +889,47 @@ function facebook_post_hook(&$a,&$b) {
 
                                $msg = trim(strip_tags(bbcode($msg)));*/
 
-                               // Test
+                               // New code
 
-                               // Looking for images
+                               // Looking for the first image
+                               $image = '';
                                if(preg_match("/\[img\=([0-9]*)x([0-9]*)\](.*?)\[\/img\]/is",$b['body'],$matches))
                                        $image = $matches[3];
 
-                               if(preg_match("/\[img\](.*?)\[\/img\]/is",$b['body'],$matches))
-                                       $image = $matches[1];
+                               if ($image != '')
+                                       if(preg_match("/\[img\](.*?)\[\/img\]/is",$b['body'],$matches))
+                                               $image = $matches[1];
+
+                               // Checking for a bookmark element
+                               $body = $b['body'];
+                               if (strpos($body, "[bookmark") !== false) {
+                                       // splitting the text in two parts:
+                                       // before and after the bookmark
+                                       $pos = strpos($body, "[bookmark");
+                                       $body1 = substr($body, 0, $pos);
+                                       $body2 = substr($body, $pos);
+
+                                       // Removing the bookmark and all quotes after the bookmark
+                                       // they are mostly only the content after the bookmark.
+                                       $body2 = preg_replace("/\[bookmark\=([^\]]*)\](.*?)\[\/bookmark\]/ism",'',$body2);
+                                       $body2 = preg_replace("/\[quote\=([^\]]*)\](.*?)\[\/quote\]/ism",'',$body2);
+                                       $body2 = preg_replace("/\[quote\](.*?)\[\/quote\]/ism",'',$body2);
+
+                                       $body = $body1.$body2;
+                               }
 
-                               $html = bbcode($b['body']);
-                               $msg = trim($b['title']." \n".html2plain($html, 0, true));
+                               // At first convert the text to html
+                               $html = bbcode($body);
+
+                               // Then convert it to plain text
+                               $msg = trim($b['title']." \n\n".html2plain($html, 0, true));
                                $msg = html_entity_decode($msg,ENT_QUOTES,'UTF-8');
 
-                               $toolong = false;
+                               // Removing multiple newlines
+                               while (strpos($msg, "\n\n\n") !== false)
+                                       $msg = str_replace("\n\n\n", "\n\n", $msg);
 
                                // add any attachments as text urls
-
                                $arr = explode(',',$b['attach']);
 
                                if(count($arr)) {
@@ -903,19 +943,28 @@ function facebook_post_hook(&$a,&$b) {
                                        }
                                }
 
-                               // To-Do: look for bookmark-bbcode and handle it with priority
+                               $link = '';
+                               $linkname = '';
+                               // look for bookmark-bbcode and handle it with priority
+                               if(preg_match("/\[bookmark\=([^\]]*)\](.*?)\[\/bookmark\]/is",$b['body'],$matches)) {
+                                       $link = $matches[1];
+                                       $linkname = $matches[2];
+                               }
 
-                               $links = collecturls($html);
-                               if (sizeof($links) > 0) {
-                                       reset($links);
-                                       $link = current($links);
-                                       /*if (strlen($msg."\n".$link) <= FACEBOOK_MAXPOSTLEN)
-                                               $msg .= "\n".$link;
-                                       else
-                                               $toolong = true;*/
+                               // If there is no bookmark element then take the first link
+                               if ($link == '') {
+                                       $links = collecturls($html);
+                                       if (sizeof($links) > 0) {
+                                               reset($links);
+                                               $link = current($links);
+                                       }
                                }
 
-                               if ((strlen($msg) > FACEBOOK_MAXPOSTLEN) or $toolong) {
+                               // Remove trailing and leading spaces
+                               $msg = trim($msg);
+
+                               // Since facebook increased the maxpostlen massively this never should happen again :)
+                               if (strlen($msg) > FACEBOOK_MAXPOSTLEN) {
                                        $shortlink = "";
                                        require_once('library/slinky.php');
 
@@ -932,7 +981,19 @@ function facebook_post_hook(&$a,&$b) {
                                        $msg = substr($msg, 0, FACEBOOK_MAXPOSTLEN - strlen($shortlink) - 4);
                                        $msg .= '... ' . $shortlink;
                                }
-                               if(! strlen($msg))
+
+                               // Fallback - if message is empty
+                               if(!strlen($msg))
+                                       $msg = $link;
+
+                               if(!strlen($msg))
+                                       $msg = $image;
+
+                               if(!strlen($msg))
+                                       $msg = $linkname;
+
+                               // If there is nothing to post then exit
+                               if(!strlen($msg))
                                        return;
 
                                logger('Facebook post: msg=' . $msg, LOGGER_DATA);
@@ -1120,6 +1181,46 @@ function fb_queue_hook(&$a,&$b) {
        }
 }
 
+function fb_get_timeline($access_token, &$since) {
+
+       $entries->data = array();
+       $newest = 0;
+
+       $url = 'https://graph.facebook.com/me/home?access_token='.$access_token;
+
+       if ($since != 0)
+               $url .= "&since=".$since;
+
+       do {
+               $s = fetch_url($url);
+               $j = json_decode($s);
+               $oldestdate = time();
+               if (isset($j->data))
+                       foreach ($j->data as $entry) {
+                               $created = strtotime($entry->created_time);
+
+                               if ($newest < $created)
+                                       $newest = $created;
+
+                               if ($created >= $since)
+                                       $entries->data[] = $entry;
+
+                               if ($created <= $oldestdate)
+                                       $oldestdate = $created;
+                       }
+               else
+                       break;
+
+               $url = $j->paging->next;
+
+       } while (($oldestdate > $since) and ($since != 0) and ($url != ''));
+
+       if ($newest > $since)
+               $since = $newest;
+
+       return($entries);
+}
+
 function fb_consume_all($uid) {
 
        require_once('include/items.php');
@@ -1141,23 +1242,25 @@ function fb_consume_all($uid) {
                        }
                }
        }
-       $s = fetch_url('https://graph.facebook.com/me/home?access_token=' . $access_token);
-       if($s) {
-               $j = json_decode($s);
-               if (isset($j->data)) {
-                       logger('fb_consume_stream: feed: ' . print_r($j,true), LOGGER_DATA);
-                       fb_consume_stream($uid,$j,false);
-               } else {
-                       logger('fb_consume_stream: feed: got no data from Facebook: ' . print_r($j,true), LOGGER_NORMAL);
-               }
-       }
-
+       // Get the last date
+       $lastdate = get_pconfig($uid,'facebook','lastdate');
+       // fetch all items since the last date
+       $j = fb_get_timeline($access_token, &$lastdate);
+       if (isset($j->data)) {
+               logger('fb_consume_stream: feed: ' . print_r($j,true), LOGGER_DATA);
+               fb_consume_stream($uid,$j,false);
+
+               // Write back the last date
+               set_pconfig($uid,'facebook','lastdate', $lastdate);
+       } else
+               logger('fb_consume_stream: feed: got no data from Facebook: ' . print_r($j,true), LOGGER_NORMAL);
 }
 
 function fb_get_photo($uid,$link) {
        $access_token = get_pconfig($uid,'facebook','access_token');
        if(! $access_token || (! stristr($link,'facebook.com/photo.php')))
-               return "\n" . '[url=' . $link . ']' . t('link') . '[/url]';
+               return "";
+               //return "\n" . '[url=' . $link . ']' . t('link') . '[/url]';
        $ret = preg_match('/fbid=([0-9]*)/',$link,$match);
        if($ret)
                $photo_id = $match[1];
@@ -1165,8 +1268,8 @@ function fb_get_photo($uid,$link) {
        $j = json_decode($x);
        if($j->picture)
                return "\n\n" . '[url=' . $link . '][img]' . $j->picture . '[/img][/url]';
-       else
-               return "\n" . '[url=' . $link . ']' . t('link') . '[/url]';
+       //else
+       //      return "\n" . '[url=' . $link . ']' . t('link') . '[/url]';
 }
 
 function fb_consume_stream($uid,$j,$wall = false) {
@@ -1225,6 +1328,10 @@ function fb_consume_stream($uid,$j,$wall = false) {
                        if($from->id == $self_id)
                                $datarray['contact-id'] = $self[0]['id'];
                        else {
+                               // Looking if user is known - if not he is added
+                               $access_token = get_pconfig($uid, 'facebook', 'access_token');
+                               fb_get_friends_sync_new($uid, $access_token, $from);
+
                                $r = q("SELECT * FROM `contact` WHERE `notify` = '%s' AND `uid` = %d AND `blocked` = 0 AND `readonly` = 0 LIMIT 1",
                                        dbesc($from->id),
                                        intval($uid)
@@ -1234,9 +1341,8 @@ function fb_consume_stream($uid,$j,$wall = false) {
                        }
 
                        // don't store post if we don't have a contact
-
                        if(! x($datarray,'contact-id')) {
-                               logger('no contact: post ignored');
+                               logger('facebook: no contact '.$from->name.' '.$from->id.'. post ignored');
                                continue;
                        }
 
@@ -1271,24 +1377,103 @@ function fb_consume_stream($uid,$j,$wall = false) {
                        $datarray['author-avatar'] = 'https://graph.facebook.com/' . $from->id . '/picture';
                        $datarray['plink'] = $datarray['author-link'] . '&v=wall&story_fbid=' . substr($entry->id,strpos($entry->id,'_') + 1);
 
+                       logger('facebook: post '.$entry->id.' from '.$from->name);
+
                        $datarray['body'] = escape_tags($entry->message);
 
-                       if($entry->picture && $entry->link) {
-                               $datarray['body'] .= "\n\n" . '[url=' . $entry->link . '][img]' . $entry->picture . '[/img][/url]';
+                       if($entry->name and $entry->link)
+                               $datarray['body'] .= "\n\n[bookmark=".$entry->link."]".$entry->name."[/bookmark]";
+                       elseif ($entry->name)
+                               $datarray['body'] .= "\n\n[b]" . $entry->name."[/b]";
+
+                       if($entry->caption) {
+                               if(!$entry->name and $entry->link)
+                                       $datarray['body'] .= "\n\n[bookmark=".$entry->link."]".$entry->caption."[/bookmark]";
+                               else
+                                       $datarray['body'] .= "[i]" . $entry->caption."[/i]\n";
                        }
-                       else {
-                               if($entry->picture)
-                                       $datarray['body'] .= "\n\n" . '[img]' . $entry->picture . '[/img]';
-                               // if just a link, it may be a wall photo - check
-                               if($entry->link)
-                                       $datarray['body'] .= fb_get_photo($uid,$entry->link);
+
+                       if(!$entry->caption and !$entry->name) {
+                               if ($entry->link)
+                                       $datarray['body'] .= "\n[url]".$entry->link."[/url]\n";
+                               else
+                                       $datarray['body'] .= "\n";
                        }
-                       if($entry->name)
-                               $datarray['body'] .= "\n" . $entry->name;
-                       if($entry->caption)
-                               $datarray['body'] .= "\n" . $entry->caption;
+
+                       $quote = "";
                        if($entry->description)
-                               $datarray['body'] .= "\n" . $entry->description;
+                               $quote = $entry->description;
+
+                       if ($entry->properties)
+                               foreach ($entry->properties as $property)
+                                       $quote .= "\n".$property->name.": [url=".$property->href."]".$property->text."[/url]";
+
+                       if ($quote)
+                               $datarray['body'] .= "\n[quote]".$quote."[/quote]";
+
+                       // Only import the picture when the message is no video
+                       // oembed display a picture of the video as well 
+                       if ($entry->type != "video") {
+                               if($entry->picture && $entry->link) {
+                                       $datarray['body'] .= "\n" . '[url=' . $entry->link . '][img]'.$entry->picture.'[/img][/url]';   
+                               }
+                               else {
+                                       if($entry->picture)
+                                               $datarray['body'] .= "\n" . '[img]' . $entry->picture . '[/img]';
+                                       // if just a link, it may be a wall photo - check
+                                       if($entry->link)
+                                               $datarray['body'] .= fb_get_photo($uid,$entry->link);
+                               }
+                       }
+
+                       if (($datarray['app'] == "Events") and $entry->actions)
+                               foreach ($entry->actions as $action)
+                                       if ($action->name == "View")
+                                               $datarray['body'] .= " [url=".$action->link."]".$entry->story."[/url]";
+
+                       // Just as a test - to see if these are the missing entries
+                       //if(trim($datarray['body']) == '')
+                       //      $datarray['body'] = $entry->story;
+
+                       // Adding the "story" text to see if there are useful data in it (testing)
+                       //if (($datarray['app'] != "Events") and $entry->story)
+                       //      $datarray['body'] .= "\n".$entry->story;
+
+                       if(trim($datarray['body']) == '') {
+                               logger('facebook: empty body '.$entry->id.' '.print_r($entry, true));
+                               continue;
+                       }
+
+                       $datarray['body'] .= "\n";
+
+                       if ($entry->icon)
+                               $datarray['body'] .= "[img]".$entry->icon."[/img] &nbsp; ";
+
+                       if ($entry->actions)
+                               foreach ($entry->actions as $action)
+                                       if (($action->name != "Comment") and ($action->name != "Like"))
+                                               $datarray['body'] .= "[url=".$action->link."]".$action->name."[/url] &nbsp; ";
+
+                       $datarray['body'] = trim($datarray['body']);
+
+                       //if(($datarray['body'] != '') and ($uid == 1))
+                       //      $datarray['body'] .= "[noparse]".print_r($entry, true)."[/noparse]";
+
+                       if ($entry->place->name or $entry->place->location->street or 
+                               $entry->place->location->city or $entry->place->location->Denmark) {
+                               $datarray['coord'] = '';
+                               if ($entry->place->name)
+                                       $datarray['coord'] .= $entry->place->name;
+                               if ($entry->place->location->street)
+                                       $datarray['coord'] .= $entry->place->location->street;
+                               if ($entry->place->location->city)
+                                       $datarray['coord'] .= " ".$entry->place->location->city;
+                               if ($entry->place->location->country)
+                                       $datarray['coord'] .= " ".$entry->place->location->country;
+                       } else if ($entry->place->location->latitude and $entry->place->location->longitude)
+                               $datarray['coord'] = substr($entry->place->location->latitude, 0, 8)
+                                                       .' '.substr($entry->place->location->longitude, 0, 8);
+
                        $datarray['created'] = datetime_convert('UTC','UTC',$entry->created_time);
                        $datarray['edited'] = datetime_convert('UTC','UTC',$entry->updated_time);
 
@@ -1300,11 +1485,6 @@ function fb_consume_stream($uid,$j,$wall = false) {
                                $datarray['allow_cid'] = '<' . $self[0]['id'] . '>';
                        }
 
-                       if(trim($datarray['body']) == '') {
-                               logger('facebook: empty body');
-                               continue;
-                       }
-
                        $top_item = item_store($datarray);
                        $r = q("SELECT * FROM `item` WHERE `id` = %d AND `uid` = %d LIMIT 1",
                                intval($top_item),