]> git.mxchange.org Git - friendica.git/blobdiff - addon/facebook/facebook.php
item source
[friendica.git] / addon / facebook / facebook.php
index 440f0e349a59a29c373e3eff27b705a3f1452915..5d86c66c2ce96435167e54bd304026030f826674 100644 (file)
@@ -1,4 +1,9 @@
 <?php
+/**
+ * Name: Facebook Connector
+ * Version: 1.0
+ * Author: Mike Macgirvin <http://macgirvin.com/profile/mike>
+ */
 
 /**
  * Installing the Friendika/Facebook connector
@@ -112,6 +117,11 @@ function fb_get_self($uid) {
 function fb_get_friends($uid) {
 
        $access_token = get_pconfig($uid,'facebook','access_token');
+
+       $no_linking = get_pconfig($uid,'facebook','no_linking');
+       if($no_linking)
+               return;
+
        if(! $access_token)
                return;
        $s = fetch_url('https://graph.facebook.com/me/friends?access_token=' . $access_token);
@@ -229,10 +239,40 @@ function fb_get_friends($uid) {
 
 function facebook_post(&$a) {
 
-       if(local_user()){
+       $uid = local_user();
+       if($uid){
+
                $value = ((x($_POST,'post_by_default')) ? intval($_POST['post_by_default']) : 0);
-               set_pconfig(local_user(),'facebook','post_by_default', $value);
+               set_pconfig($uid,'facebook','post_by_default', $value);
+
+               $no_linking = get_pconfig($uid,'facebook','no_linking');
+
+               $linkvalue = ((x($_POST,'facebook_linking')) ? intval($_POST['facebook_linking']) : 0);
+               set_pconfig($uid,'facebook','no_linking', (($linkvalue) ? 0 : 1));
+
+               // FB linkage was allowed but has just been turned off - remove all FB contacts and posts
+
+               if((! intval($no_linking)) && (! intval($linkvalue))) {
+                       $r = q("SELECT `id` FROM `contact` WHERE `uid` = %d AND `network` = '%s' ",
+                               intval($uid),
+                               dbesc(NETWORK_FACEBOOK)
+                       );
+                       if(count($r)) {
+                               require_once('include/Contact.php');
+                               foreach($r as $rr)
+                                       contact_remove($rr['id']);
+                       }
+               }
+               elseif(intval($no_linking) && intval($linkvalue)) {
+                       // FB linkage is now allowed - import stuff.
+                       fb_get_self($uid);
+                       fb_get_friends($uid);
+                       fb_consume_all($uid);
+               }
+
+               info( t('Settings updated.') . EOL);
        } 
+
        return;         
 }
 
@@ -245,12 +285,12 @@ function facebook_content(&$a) {
 
        if($a->argc > 1 && $a->argv[1] === 'remove') {
                del_pconfig(local_user(),'facebook','post');
-               notice( t('Facebook disabled') . EOL);
+               info( t('Facebook disabled') . EOL);
        }
 
        if($a->argc > 1 && $a->argv[1] === 'friends') {
                fb_get_friends(local_user());
-               notice( t('Updating contacts') . EOL);
+               info( t('Updating contacts') . EOL);
        }
 
 
@@ -286,6 +326,13 @@ function facebook_content(&$a) {
                $post_by_default = get_pconfig(local_user(),'facebook','post_by_default');
                $checked = (($post_by_default) ? ' checked="checked" ' : '');
                $o .= '<input type="checkbox" name="post_by_default" value="1"' . $checked . '/>' . ' ' . t('Post to Facebook by default') . '<br />';
+
+               $no_linking = get_pconfig(local_user(),'facebook','no_linking');
+               $checked = (($no_linking) ? '' : ' checked="checked" ');
+               $o .= '<input type="checkbox" name="facebook_linking" value="1"' . $checked . '/>' . ' ' . t('Link all your Facebook friends and conversations') . '<br />';
+
+
+
                $o .= '<input type="submit" name="submit" value="' . t('Submit') . '" /></form></div>';
        }
 
@@ -293,18 +340,20 @@ function facebook_content(&$a) {
 }
 
 function facebook_install() {
-       register_hook('post_local_end',  'addon/facebook/facebook.php', 'facebook_post_hook');
-       register_hook('jot_networks',    'addon/facebook/facebook.php', 'facebook_jot_nets');
-       register_hook('plugin_settings', 'addon/facebook/facebook.php', 'facebook_plugin_settings');
-       register_hook('cron',            'addon/facebook/facebook.php', 'facebook_cron');
+       register_hook('post_local_end',   'addon/facebook/facebook.php', 'facebook_post_hook');
+       register_hook('jot_networks',     'addon/facebook/facebook.php', 'facebook_jot_nets');
+       register_hook('plugin_settings',  'addon/facebook/facebook.php', 'facebook_plugin_settings');
+       register_hook('cron',             'addon/facebook/facebook.php', 'facebook_cron');
+       register_hook('queue_predeliver', 'addon/facebook/facebook.php', 'fb_queue_hook');
 }
 
 
 function facebook_uninstall() {
-       unregister_hook('post_local_end',  'addon/facebook/facebook.php', 'facebook_post_hook');
-       unregister_hook('jot_networks',    'addon/facebook/facebook.php', 'facebook_jot_nets');
-       unregister_hook('plugin_settings', 'addon/facebook/facebook.php', 'facebook_plugin_settings');
-       unregister_hook('cron',            'addon/facebook/facebook.php', 'facebook_cron');
+       unregister_hook('post_local_end',   'addon/facebook/facebook.php', 'facebook_post_hook');
+       unregister_hook('jot_networks',     'addon/facebook/facebook.php', 'facebook_jot_nets');
+       unregister_hook('plugin_settings',  'addon/facebook/facebook.php', 'facebook_plugin_settings');
+       unregister_hook('cron',             'addon/facebook/facebook.php', 'facebook_cron');
+       unregister_hook('queue_predeliver', 'addon/facebook/facebook.php', 'fb_queue_hook');
 }
 
 
@@ -396,7 +445,7 @@ function facebook_post_hook(&$a,&$b) {
                        logger('facebook reply id=' . $reply);
                }
 
-               if($b['private'] && $reply == false) {
+               if($b['private'] && $reply === false) {
                        $allow_people = expand_acl($b['allow_cid']);
                        $allow_groups = expand_groups(expand_acl($b['allow_gid']));
                        $deny_people  = expand_acl($b['deny_cid']);
@@ -474,25 +523,52 @@ function facebook_post_hook(&$a,&$b) {
 
                                // make links readable before we strip the code
 
-                               if(preg_match("/\[url=(.+?)\](.+?)\[\/url\]/is",$msg,$matches)) {
+                               // unless it's a dislike - just send the text as a comment
+
+                               if($b['verb'] == ACTIVITY_DISLIKE)
+                                       $msg = trim(strip_tags(bbcode($msg)));
+
+                               $search_str = $a->get_baseurl() . '/search';
 
-                                       $link = $matches[1];
-                                       if(substr($matches[2],0,5) != '[img]' )
-                                               $linkname = $matches[2];
+                               if(preg_match("/\[url=(.*?)\](.*?)\[\/url\]/is",$msg,$matches)) {
+
+                                       // don't use hashtags for message link
+
+                                       if(strpos($matches[2],$search_str) === false) {
+                                               $link = $matches[1];
+                                               if(substr($matches[2],0,5) != '[img]')
+                                                       $linkname = $matches[2];
+                                       }
                                }
 
-                               $msg = preg_replace("/\[url=(.+?)\](.+?)\[\/url\]/is",'$2 $1',$msg);
+                               $msg = preg_replace("/\[url=(.*?)\](.*?)\[\/url\]/is",'$2 $1',$msg);
 
-                               if(preg_match("/\[img\](.+?)\[\/img\]/is",$msg,$matches))
+                               if(preg_match("/\[img\](.*?)\[\/img\]/is",$msg,$matches))
                                        $image = $matches[1];
 
-                               $msg = preg_replace("/\[img\](.+?)\[\/img\]/is", t('Image: ') . '$1', $msg);
-
+                               $msg = preg_replace("/\[img\](.*?)\[\/img\]/is", t('Image: ') . '$1', $msg);
 
+                               if((strpos($link,$a->get_baseurl()) !== false) && (! $image))
+                                       $image = $a->get_baseurl() . '/images/friendika-64.jpg';
 
                                $msg = trim(strip_tags(bbcode($msg)));
                                $msg = html_entity_decode($msg,ENT_QUOTES,'UTF-8');
 
+                               // add any attachments as text urls
+
+                           $arr = explode(',',$b['attach']);
+
+                           if(count($arr)) {
+                                       $msg .= "\n";
+                               foreach($arr as $r) {
+                               $matches = false;
+                                               $cnt = preg_match('|\[attach\]href=\"(.*?)\" size=\"(.*?)\" type=\"(.*?)\" title=\"(.*?)\"\[\/attach\]|',$r,$matches);
+                                               if($cnt) {
+                                                       $msg .= $matches[1];
+                                               }
+                                       }
+                               }
+
                                if (strlen($msg) > FACEBOOK_MAXPOSTLEN) {
                                        $shortlink = "";
                                        require_once('library/slinky.php');
@@ -555,25 +631,98 @@ function facebook_post_hook(&$a,&$b) {
                                // "test_mode" prevents anything from actually being posted.
                                // Otherwise, let's do it. 
 
-                               if(! get_config('facebook','test_mode'))
+                               if(! get_config('facebook','test_mode')) {
                                        $x = post_url($url, $postvars);
 
-                               $retj = json_decode($x);
+                                       $retj = json_decode($x);
+                                       if($retj->id) {
+                                               q("UPDATE `item` SET `extid` = '%s' WHERE `id` = %d LIMIT 1",
+                                                       dbesc('fb::' . $retj->id),
+                                                       intval($b['id'])
+                                               );
+                                       }
+                                       else {
+                                               if(! $likes) {
+                                                       $s = serialize(array('url' => $url, 'item' => $b['id'], 'post' => $postvars));
+                                                       q("INSERT INTO `queue` ( `network`, `cid`, `created`, `last`, `content`)
+                                                               VALUES ( '%s', %d, '%s', '%s', '%s') ",
+                                                               dbesc(NETWORK_FACEBOOK),
+                                                               intval($a->contact),
+                                                               dbesc(datetime_convert()),
+                                                               dbesc(datetime_convert()),
+                                                               dbesc($s)
+                                                       );                                                              
+
+                                                       notice( t('Facebook post failed. Queued for retry.') . EOL);
+                                               }
+                                       }
+                                       
+                                       logger('Facebook post returns: ' . $x, LOGGER_DEBUG);
+                               }
+                       }
+               }
+       }
+}
+
+
+function fb_queue_hook(&$a,&$b) {
+
+       $qi = q("SELECT * FROM `queue` WHERE `network` = '%s'",
+               dbesc(NETWORK_FACEBOOK)
+       );
+       if(! count($qi))
+               return;
+
+       require_once('include/queue_fn.php');
+
+       foreach($qi as $x) {
+               if($x['network'] !== NETWORK_FACEBOOK)
+                       continue;
+
+               logger('facebook_queue: run');
+
+               $r = q("SELECT `user`.* FROM `user` LEFT JOIN `contact` on `contact`.`uid` = `user`.`uid` 
+                       WHERE `contact`.`self` = 1 AND `contact`.`id` = %d LIMIT 1",
+                       intval($x['cid'])
+               );
+               if(! count($r))
+                       continue;
+
+               $user = $r[0];
+
+               $appid  = get_config('facebook', 'appid'  );
+               $secret = get_config('facebook', 'appsecret' );
+
+               if($appid && $secret) {
+                       $fb_post   = intval(get_pconfig($user['uid'],'facebook','post'));
+                       $fb_token  = get_pconfig($user['uid'],'facebook','access_token');
+
+                       if($fb_post && $fb_token) {
+                               logger('facebook_queue: able to post');
+                               require_once('library/facebook.php');
+
+                               $z = unserialize($x['content']);
+                               $item = $z['item'];
+                               $j = post_url($z['url'],$z['post']);
+
+                               $retj = json_decode($j);
                                if($retj->id) {
                                        q("UPDATE `item` SET `extid` = '%s' WHERE `id` = %d LIMIT 1",
                                                dbesc('fb::' . $retj->id),
-                                               intval($b['id'])
+                                               intval($item)
                                        );
+                                       logger('facebook_queue: success: ' . $j); 
+                                       remove_queue_item($x['id']);
+                               }
+                               else {
+                                       logger('facebook_queue: failed: ' . $j);
+                                       update_queue_time($x['id']);
                                }
-                               
-                               logger('Facebook post returns: ' . $x, LOGGER_DEBUG);
-
                        }
                }
        }
 }
 
-
 function fb_consume_all($uid) {
 
        require_once('include/items.php');
@@ -599,6 +748,10 @@ function fb_consume_all($uid) {
 function fb_consume_stream($uid,$j,$wall = false) {
        $a = get_app();
 
+       $no_linking = get_pconfig($uid,'facebook','no_linking');
+       if($no_linking)
+               return;
+
        $self = q("SELECT * FROM `contact` WHERE `self` = 1 AND `uid` = %d LIMIT 1",
                intval($uid)
        );
@@ -617,10 +770,6 @@ function fb_consume_stream($uid,$j,$wall = false) {
        foreach($j->data as $entry) {
                logger('fb_consume: entry: ' . print_r($entry,true), LOGGER_DATA);
                $datarray = array();
-               $we_posted = false;
-               $app = $entry->application;
-               if($app->id == get_config('facebook','appid') && $wall)
-                       $we_posted = true;
 
                $r = q("SELECT * FROM `item` WHERE ( `uri` = '%s' OR `extid` = '%s') AND `uid` = %d LIMIT 1",
                                dbesc('fb::' . $entry->id),
@@ -656,8 +805,10 @@ function fb_consume_stream($uid,$j,$wall = false) {
 
                        // don't store post if we don't have a contact
 
-                       if(! x($datarray,'contact-id'))
+                       if(! x($datarray,'contact-id')) {
+                               logger('no contact: post ignored');
                                continue; 
+                       }
 
                        $datarray['verb'] = ACTIVITY_POST;                                              
                        if($wall) {
@@ -690,12 +841,21 @@ function fb_consume_stream($uid,$j,$wall = false) {
                                intval($top_item),
                                intval($uid)
                        );                      
-                       if(count($r))
+                       if(count($r)) {
                                $orig_post = $r[0];
-
+                               logger('fb: new top level item posted');
+                       }
                }
-               $likers = $entry->likes->data;
-               $comments = $entry->comments->data;
+
+               if(isset($entry->likes) && isset($entry->likes->data))
+                       $likers = $entry->likes->data;
+               else
+                       $likers = null;
+
+               if(isset($entry->comments) && isset($entry->comments->data))
+                       $comments = $entry->comments->data;
+               else
+                       $comments = null;
 
                if(is_array($likers)) {
                        foreach($likers as $likes) {
@@ -703,11 +863,17 @@ function fb_consume_stream($uid,$j,$wall = false) {
                                if(! $orig_post)
                                        continue;
 
-                               $r = q("SELECT * FROM `item` WHERE `parent-uri` = '%s' AND `uid` = %d AND `verb` = '%s' AND `author-link` = '%s' LIMIT 1",
+                               // If we posted the like locally, it will be found with our url, not the FB url.
+
+                               $second_url = (($likes->id == $self_id) ? $self[0]['url'] : 'http://facebook.com/profile.php?id=' . $likes->id); 
+
+                               $r = q("SELECT * FROM `item` WHERE `parent-uri` = '%s' AND `uid` = %d AND `verb` = '%s' 
+                                       AND ( `author-link` = '%s' OR `author-link` = '%s' ) LIMIT 1",
                                        dbesc($orig_post['uri']),
                                        intval($uid),
                                        dbesc(ACTIVITY_LIKE),
-                                       dbesc('http://facebook.com/profile.php?id=' . $likes->id)
+                                       dbesc('http://facebook.com/profile.php?id=' . $likes->id),
+                                       dbesc($second_url)
                                );
 
                                if(count($r))
@@ -747,7 +913,7 @@ function fb_consume_stream($uid,$j,$wall = false) {
 
                                $likedata['body'] = sprintf( t('%1$s likes %2$s\'s %3$s'), $author, $objauthor, $plink);
                                $likedata['object'] = '<object><type>' . ACTIVITY_OBJ_NOTE . '</type><local>1</local>' . 
-                                       '<id>' . $orig_post['uri'] . '</id><link>' . xmlify('<link rel="alternate" type="text/html" href="' . $orig_post['plink'] . '">') . '</link><title>' . $orig_post['title'] . '</title><content>' . $orig_post['body'] . '</content></object>';  
+                                       '<id>' . $orig_post['uri'] . '</id><link>' . xmlify('<link rel="alternate" type="text/html" href="' . xmlify($orig_post['plink']) . '" />') . '</link><title>' . $orig_post['title'] . '</title><content>' . $orig_post['body'] . '</content></object>';  
 
                                $item = item_store($likedata);                  
                        }
@@ -778,17 +944,19 @@ function fb_consume_stream($uid,$j,$wall = false) {
                                        $cmntdata['contact-id'] = $self[0]['id'];
                                }
                                else {
-                                       $r = q("SELECT * FROM `contact` WHERE `notify` = '%s' AND `uid` = %d AND `blocked` = 0 AND `readonly` = 0 LIMIT 1",
+                                       $r = q("SELECT * FROM `contact` WHERE `notify` = '%s' AND `uid` = %d LIMIT 1",
                                                dbesc($cmnt->from->id),
                                                intval($uid)
                                        );
-                                       if(count($r))
+                                       if(count($r)) {
                                                $cmntdata['contact-id'] = $r[0]['id'];
+                                               if($r[0]['blocked'] || $r[0]['readonly'])
+                                                       continue;
+                                       }
                                }
-                               if(! x($cmntdata,'contact-id')) {
-                                       logger('fb_consume: comment: no contact-id available');
-                                       return;
-                               }
+                               if(! x($cmntdata,'contact-id'))
+                                       $cmntdata['contact-id'] = $orig_post['contact-id'];
+
                                $cmntdata['created'] = datetime_convert('UTC','UTC',$cmnt->created_time);
                                $cmntdata['edited']  = datetime_convert('UTC','UTC',$cmnt->created_time);
                                $cmntdata['verb'] = ACTIVITY_POST;