From 9a26a253c938483df9486031546d0311fccbbfa3 Mon Sep 17 00:00:00 2001 From: Ben Liyanage Date: Thu, 25 Sep 2014 12:49:23 -0400 Subject: [PATCH 01/15] added some clarity for the logger --- fbsync/fbsync.php | 32 +++++++++++--------------------- 1 file changed, 11 insertions(+), 21 deletions(-) diff --git a/fbsync/fbsync.php b/fbsync/fbsync.php index 51d2747f..5024898b 100644 --- a/fbsync/fbsync.php +++ b/fbsync/fbsync.php @@ -158,7 +158,6 @@ function fbsync_settings_post(&$a,&$b) { function fbsync_cron($a,$b) { $last = get_config('fbsync','last_poll'); - $poll_interval = intval(get_config('fbsync','poll_interval')); if(! $poll_interval) $poll_interval = FBSYNC_DEFAULT_POLL_INTERVAL; @@ -166,13 +165,14 @@ function fbsync_cron($a,$b) { if($last) { $next = $last + ($poll_interval * 60); if($next > time()) { - logger('fbsync_cron: poll intervall not reached'); + logger('fbsync_cron: poll intervall not reached. poll interval: ' . $poll_interval * 60 . '; actual interval: ' . $poll_interval); return; } } logger('fbsync_cron: cron_start'); $r = q("SELECT * FROM `pconfig` WHERE `cat` = 'fbsync' AND `k` = 'sync' AND `v` = '1' ORDER BY RAND()"); + if(count($r)) { foreach($r as $rr) { fbsync_get_self($rr['uid']); @@ -442,17 +442,7 @@ function fbsync_createpost($a, $uid, $self, $contacts, $applications, $post, $cr $postarray['private'] = 1; $postarray['allow_cid'] = '<' . $self[0]['id'] . '>'; } - - /* - $postarray["location"] = $post->place->name; - postarray["coord"] = $post->geo->coordinates[0]." ".$post->geo->coordinates[1]; - */ - - //$types = array(46, 80, 237, 247, 308); - //if (!in_array($post->type, $types)) - // $postarray["body"] = "Type: ".$post->type."\n".$postarray["body"]; - //print_r($post); - //print_r($postarray); + $item = item_store($postarray); logger('fbsync_createpost: User '.$self[0]["nick"].' posted feed item '.$item, LOGGER_DEBUG); } @@ -1005,31 +995,31 @@ function fbsync_fetchfeed($a, $uid) { //if ($last_updated == "") $last_updated = 0; - logger("fbsync_fetchfeed: fetching content for user ".$self_id); - + logger("fbsync_fetchfeed: fetching content for user " . $self_id); + $fql = array( "posts" => "SELECT action_links, actor_id, app_data, app_id, attachment, attribution, comment_info, created_time, filter_key, like_info, message, message_tags, parent_post_id, permalink, place, post_id, privacy, share_count, share_info, source_id, subscribed, tagged_ids, type, updated_time, with_tags FROM stream where filter_key in (SELECT filter_key FROM stream_filter WHERE uid=me() AND type='newsfeed') AND updated_time > $last_updated ORDER BY updated_time DESC LIMIT 500", "comments" => "SELECT app_id, attachment, post_id, id, likes, fromid, time, text, text_tags, user_likes, likes FROM comment WHERE post_id IN (SELECT post_id FROM #posts) ORDER BY time DESC LIMIT 500", "profiles" => "SELECT id, name, username, url, pic_square FROM profile WHERE id IN (SELECT actor_id FROM #posts) OR id IN (SELECT fromid FROM #comments) OR id IN (SELECT source_id FROM #posts) LIMIT 500", "applications" => "SELECT app_id, display_name FROM application WHERE app_id IN (SELECT app_id FROM #posts) OR app_id IN (SELECT app_id FROM #comments) LIMIT 500", "avatars" => "SELECT id, real_size, size, url FROM square_profile_pic WHERE id IN (SELECT id FROM #profiles) AND size = 256 LIMIT 500"); - + if ($do_likes) { $fql["likes"] = "SELECT post_id, user_id FROM like WHERE post_id IN (SELECT post_id FROM #posts)"; $fql["profiles"] .= " OR id IN (SELECT user_id FROM #likes)"; } $url = "https://graph.facebook.com/fql?q=".urlencode(json_encode($fql))."&access_token=".$access_token; - - $feed = fetch_url($url); + + $feed = fetch_url($url); $data = json_decode($feed); - + if (!is_array($data->data)) { logger("fbsync_fetchfeed: Error fetching data for user ".$uid.": ".print_r($data, true)); return; } - - $posts = array(); + + $posts = array(); $comments = array(); $likes = array(); $profiles = array(); From 68383f2552e59d61b7111cddf211d054c8adef3f Mon Sep 17 00:00:00 2001 From: Ben Liyanage Date: Thu, 25 Sep 2014 12:59:46 -0400 Subject: [PATCH 02/15] removed a redundant foreachloop also moved some data validation into the function that uses the data. This change is geared towards making this code more unit testable. --- fbsync/fbsync.php | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/fbsync/fbsync.php b/fbsync/fbsync.php index 5024898b..a66bc5aa 100644 --- a/fbsync/fbsync.php +++ b/fbsync/fbsync.php @@ -213,6 +213,10 @@ function fbsync_expire($a,$b) { function fbsync_createpost($a, $uid, $self, $contacts, $applications, $post, $create_user) { + $post->actor_id = number_format($post->actor_id, 0, '', ''); + $post->source_id = number_format($post->source_id, 0, '', ''); + $post->app_id = number_format($post->app_id, 0, '', ''); + $access_token = get_pconfig($uid,'facebook','access_token'); require_once("include/oembed.php"); @@ -1078,23 +1082,16 @@ function fbsync_fetchfeed($a, $uid) { } unset($applications); - foreach ($posts AS $post) { - $post->actor_id = number_format($post->actor_id, 0, '', ''); - $post->source_id = number_format($post->source_id, 0, '', ''); - $post->app_id = number_format($post->app_id, 0, '', ''); - $post_data[$post->post_id] = $post; - } - unset($posts); - foreach($comments AS $comment) { $comment->fromid = number_format($comment->fromid, 0, '', ''); $comment_data[$comment->id] = $comment; } unset($comments); - foreach ($post_data AS $post) { + foreach ($posts AS $post) { if ($post->updated_time > $last_updated) $last_updated = $post->updated_time; + fbsync_createpost($a, $uid, $self, $contacts, $application_data, $post, $create_user); } From 249e330dc5842c002222bb5490e5674e76248cf9 Mon Sep 17 00:00:00 2001 From: Ben Liyanage Date: Thu, 25 Sep 2014 13:15:09 -0400 Subject: [PATCH 03/15] removed a couple more redundant loops --- fbsync/fbsync.php | 23 +++++++++-------------- 1 file changed, 9 insertions(+), 14 deletions(-) diff --git a/fbsync/fbsync.php b/fbsync/fbsync.php index a66bc5aa..1c4a5d8c 100644 --- a/fbsync/fbsync.php +++ b/fbsync/fbsync.php @@ -452,6 +452,8 @@ function fbsync_createpost($a, $uid, $self, $contacts, $applications, $post, $cr } function fbsync_createcomment($a, $uid, $self_id, $self, $user, $contacts, $applications, $comment) { + //Sanitize Data + $comment->fromid = number_format($comment->fromid, 0, '', ''); // check if it was already imported $r = q("SELECT `uri` FROM `item` WHERE `uid` = %d AND `uri` = '%s' LIMIT 1", @@ -1076,27 +1078,20 @@ function fbsync_fetchfeed($a, $uid) { unset($profiles); unset($square_avatars); - foreach ($applications AS $application) { + foreach ($applications AS $key = $application) { $application->app_id = number_format($application->app_id, 0, '', ''); - $application_data[$application->app_id] = $application; + $applications[$key] = $application; } - unset($applications); - - foreach($comments AS $comment) { - $comment->fromid = number_format($comment->fromid, 0, '', ''); - $comment_data[$comment->id] = $comment; - } - unset($comments); - + foreach ($posts AS $post) { if ($post->updated_time > $last_updated) $last_updated = $post->updated_time; - fbsync_createpost($a, $uid, $self, $contacts, $application_data, $post, $create_user); + fbsync_createpost($a, $uid, $self, $contacts, $applications, $post, $create_user); } - foreach ($comment_data AS $comment) { - fbsync_createcomment($a, $uid, $self_id, $self, $user, $contacts, $application_data, $comment); + foreach ($comments AS $comment) { + fbsync_createcomment($a, $uid, $self_id, $self, $user, $contacts, $applications, $comment); } foreach($likes AS $like) { @@ -1104,7 +1099,7 @@ function fbsync_fetchfeed($a, $uid) { fbsync_createlike($a, $uid, $self_id, $self, $contacts, $like); } - + set_pconfig($uid,'fbsync','last_updated', $last_updated); } ?> From 37c63e6a5ff76cdd513ab70f5973bd08ddf224f3 Mon Sep 17 00:00:00 2001 From: Ben Liyanage Date: Thu, 25 Sep 2014 13:29:34 -0400 Subject: [PATCH 04/15] moved feed processing into separate function this will let it be unit tested independent of data retrieval, which will help me update this to the facebook 2.1 api version. In addition I moved some additional data sanitation into the function that uses the data. --- fbsync/fbsync.php | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/fbsync/fbsync.php b/fbsync/fbsync.php index 1c4a5d8c..e78f46b4 100644 --- a/fbsync/fbsync.php +++ b/fbsync/fbsync.php @@ -178,7 +178,8 @@ function fbsync_cron($a,$b) { fbsync_get_self($rr['uid']); logger('fbsync_cron: importing timeline from user '.$rr['uid']); - fbsync_fetchfeed($a, $rr['uid']); + $data = fbsync_fetchfeed($a, $rr['uid']); + fbsync_processfeed($data); } } @@ -646,6 +647,8 @@ function fbsync_createcomment($a, $uid, $self_id, $self, $user, $contacts, $appl } function fbsync_createlike($a, $uid, $self_id, $self, $contacts, $like) { + //Sanitize data + $like->user_id = number_format($like->user_id, 0, '', ''); $r = q("SELECT * FROM `item` WHERE `uri` = '%s' AND `uid` = %d LIMIT 1", dbesc("fb::".$like->post_id), @@ -1025,6 +1028,10 @@ function fbsync_fetchfeed($a, $uid) { return; } + return $data; +} + +function fbsync_processfeed($data){ $posts = array(); $comments = array(); $likes = array(); @@ -1061,12 +1068,14 @@ function fbsync_fetchfeed($a, $uid) { $post_data = array(); $comment_data = array(); + //These Indexes are Used for lookups in the next loop foreach ($avatars AS $avatar) { $avatar->id = number_format($avatar->id, 0, '', ''); $square_avatars[$avatar->id] = $avatar; } unset($avatars); + //These Indexes are used for lookups elsewhere foreach ($profiles AS $profile) { $profile->id = number_format($profile->id, 0, '', ''); @@ -1078,10 +1087,12 @@ function fbsync_fetchfeed($a, $uid) { unset($profiles); unset($square_avatars); - foreach ($applications AS $key = $application) { + //These Indexes are Used for lookups elsewhere + foreach ($applications AS $application) { $application->app_id = number_format($application->app_id, 0, '', ''); - $applications[$key] = $application; + $application_data[$application->app_id] = $application; } + unset($applications); foreach ($posts AS $post) { if ($post->updated_time > $last_updated) @@ -1095,8 +1106,6 @@ function fbsync_fetchfeed($a, $uid) { } foreach($likes AS $like) { - $like->user_id = number_format($like->user_id, 0, '', ''); - fbsync_createlike($a, $uid, $self_id, $self, $contacts, $like); } From 07e2c0168994c0837216af7fbca59df821428940 Mon Sep 17 00:00:00 2001 From: Ben Liyanage Date: Thu, 25 Sep 2014 13:41:48 -0400 Subject: [PATCH 05/15] begining of unit test This is the begining of my unit test of the code, as well as some notes for how to do the graph 2.1 api calls. --- fbsync/tests/fbsync_test.php | 53 ++++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100644 fbsync/tests/fbsync_test.php diff --git a/fbsync/tests/fbsync_test.php b/fbsync/tests/fbsync_test.php new file mode 100644 index 00000000..676b74fd --- /dev/null +++ b/fbsync/tests/fbsync_test.php @@ -0,0 +1,53 @@ + GET, + "relative_url" =>"me/home?limit=$limit&fields=actions,link,id,created_time,application,attachments,updated_time,object_id,with_tags,comments{can_comment,comment_count},likes,message,message_tags,description,parent_id,place,privacy,shares&since=$last_updated" + ), + array(method=>GET, + "relative_url" => "me") + ); + + + static $GETRequest = '{"method":"GET","relative_url":%s}'; + var_dump($graph); + $graphURL = 'https://graph.facebook.com/v2.1/?batch=' . urlencode(json_encode($graph)) + .'&access_token=' . $access_token . '&method=post' + ; + + //Facebook API v2.1 + $graphData = json_decode(file_get_contents($graphURL)); + + //Facebook v2.1 Data + $posts = json_decode($graphData[0]->body); + + +*/ +?> \ No newline at end of file From 0996ab115a7d4cc0619f405c04343f96c9f87e6a Mon Sep 17 00:00:00 2001 From: Ben Liyanage Date: Wed, 8 Oct 2014 13:46:54 -0400 Subject: [PATCH 06/15] initial dev added some mach data for unit testing. Also added some base classes for structuring post creation using different versions of the api --- fbsync/fbsync.php | 2 +- fbsync/object/Facebook.php | 10 ++++ fbsync/object/Facebook_Graph21.php | 41 +++++++++++++ fbsync/tests/fbsync_test.php | 19 +++++- fbsync/tests/fql.txt | 64 ++++++++++++++++++++ fbsync/tests/graph2.1-no-filter.txt | 90 +++++++++++++++++++++++++++++ fbsync/tests/graph2.1.txt | 53 +++++++++++++++++ 7 files changed, 276 insertions(+), 3 deletions(-) create mode 100644 fbsync/object/Facebook.php create mode 100644 fbsync/object/Facebook_Graph21.php create mode 100644 fbsync/tests/fql.txt create mode 100644 fbsync/tests/graph2.1-no-filter.txt create mode 100644 fbsync/tests/graph2.1.txt diff --git a/fbsync/fbsync.php b/fbsync/fbsync.php index e78f46b4..8e87cfc5 100644 --- a/fbsync/fbsync.php +++ b/fbsync/fbsync.php @@ -213,7 +213,7 @@ function fbsync_expire($a,$b) { } function fbsync_createpost($a, $uid, $self, $contacts, $applications, $post, $create_user) { - + //Sanitize Inputs $post->actor_id = number_format($post->actor_id, 0, '', ''); $post->source_id = number_format($post->source_id, 0, '', ''); $post->app_id = number_format($post->app_id, 0, '', ''); diff --git a/fbsync/object/Facebook.php b/fbsync/object/Facebook.php new file mode 100644 index 00000000..8e7598b3 --- /dev/null +++ b/fbsync/object/Facebook.php @@ -0,0 +1,10 @@ + \ No newline at end of file diff --git a/fbsync/object/Facebook_Graph21.php b/fbsync/object/Facebook_Graph21.php new file mode 100644 index 00000000..0c459f4f --- /dev/null +++ b/fbsync/object/Facebook_Graph21.php @@ -0,0 +1,41 @@ +post_id) + ); + if(count($r)) + return; + + $postarray = array(); + $postarray['gravity'] = 0; + $postarray['uid'] = $uid; + $postarray['wall'] = 0; + + $postarray['verb'] = ACTIVITY_POST; + $postarray['object-type'] = ACTIVITY_OBJ_NOTE; // default value - is maybe changed later when media is attached + $postarray['network'] = dbesc(NETWORK_FACEBOOK); + + $postarray['uri'] = "fb::".$post->post_id; + $postarray['thr-parent'] = $postarray['uri']; + $postarray['parent-uri'] = $postarray['uri']; + $postarray['plink'] = $post->permalink; + } +} +?> \ No newline at end of file diff --git a/fbsync/tests/fbsync_test.php b/fbsync/tests/fbsync_test.php index 676b74fd..3ae2596e 100644 --- a/fbsync/tests/fbsync_test.php +++ b/fbsync/tests/fbsync_test.php @@ -9,9 +9,24 @@ $d = datetime_convert(); global $db; $db = new dba($db_host, $db_user, $db_pass, $db_data, $install); -$data = fbsync_fetchfeed($a, 1); -var_dump($data); +//Test Data Retrieval +//$data = fbsync_fetchfeed($a, 1); +//var_dump($data); + +//Test Data Processing + +// Test Base Class +require_once("./addon/fbsync/object/Facebook.php"); +$myFBSync = new Facebook(); + +// Test graph 2.1 class +require_once("./addon/fbsync/object/Facebook_Graph21.php"); +$myFBSync = new Facebook_Graph21(); +$uid = 1; +$post = json_decode(readfile("./addon/fbsync/tests/graph2.1.txt")); +$myFBSync->CreatePost($a,$uid,0,0,0,$post,0); + /* https://developers.facebook.com/tools/explorer diff --git a/fbsync/tests/fql.txt b/fbsync/tests/fql.txt new file mode 100644 index 00000000..c3f9b9d1 --- /dev/null +++ b/fbsync/tests/fql.txt @@ -0,0 +1,64 @@ +{ + "data": [ + { + "action_links": null, + "actor_id": "109524391244", + "app_data": [ + ], + "app_id": "2309869772", + "attachment": { + "media": [ + { + "href": "http://www.theverge.com/2014/10/8/6946033/google-put-street-view-camera-on-camels-back-to-tour-desert", + "alt": "", + "type": "link", + "src": "https://fbexternal-a.akamaihd.net/safe_image.php?d=AQC6sIH1Zb6kwIlg&w=158&h=158&url=http%3A%2F%2Fcdn1.vox-cdn.com%2Fuploads%2Fchorus_image%2Fimage%2F41261020%2FScreen_Shot_2014-10-08_at_10.44.15_AM.0.0_cinema_1200.0.png" + } + ], + "name": "Google put its Street View camera on a camel's back to tour the Arabian desert", + "href": "http://www.theverge.com/2014/10/8/6946033/google-put-street-view-camera-on-camels-back-to-tour-desert", + "caption": "www.theverge.com", + "description": "Google's Street View cameras have been carried around on cars, boats, people, and now camels. The company recently set out to capture 360-degree imagery of the Arabian desert, and to \"minimize\"...", + "properties": [ + ], + "icon": "https://fbstatic-a.akamaihd.net/rsrc.php/v2/yD/r/aS8ecmYRys0.gif" + }, + "attribution": null, + "comment_info": { + "can_comment": true, + "comment_count": 0, + "comment_order": "chronological" + }, + "created_time": 1412784080, + "filter_key": "nf", + "like_info": { + "can_like": true, + "like_count": 0, + "user_likes": false + }, + "message": "", + "message_tags": [ + ], + "parent_post_id": null, + "permalink": "https://www.facebook.com/baltimorenode/posts/10152483187826245", + "place": null, + "post_id": "109524391244_10152483187826245", + "privacy": { + "value": "" + }, + "share_count": 0, + "share_info": { + "can_share": true, + "share_count": 0 + }, + "source_id": "109524391244", + "subscribed": false, + "tagged_ids": [ + ], + "type": 80, + "updated_time": 1412784080, + "with_tags": [ + ] + } + ] +} \ No newline at end of file diff --git a/fbsync/tests/graph2.1-no-filter.txt b/fbsync/tests/graph2.1-no-filter.txt new file mode 100644 index 00000000..96a463d9 --- /dev/null +++ b/fbsync/tests/graph2.1-no-filter.txt @@ -0,0 +1,90 @@ +{ + "data": [ + { + "id": "109524391244_10152483187826245", + "from": { + "category": "Non-profit organization", + "category_list": [ + { + "id": "133436743388217", + "name": "Arts & Entertainment" + }, + { + "id": "139823692748565", + "name": "Computers & Electronics" + }, + { + "id": "292231357479999", + "name": "Robotics" + } + ], + "name": "Baltimore Node", + "id": "109524391244" + }, + "story": "Baltimore Node shared a link.", + "picture": "https://fbexternal-a.akamaihd.net/safe_image.php?d=AQC6sIH1Zb6kwIlg&w=158&h=158&url=http%3A%2F%2Fcdn1.vox-cdn.com%2Fuploads%2Fchorus_image%2Fimage%2F41261020%2FScreen_Shot_2014-10-08_at_10.44.15_AM.0.0_cinema_1200.0.png", + "link": "http://www.theverge.com/2014/10/8/6946033/google-put-street-view-camera-on-camels-back-to-tour-desert", + "name": "Google put its Street View camera on a camel's back to tour the Arabian desert", + "caption": "www.theverge.com", + "description": "Google's Street View cameras have been carried around on cars, boats, people, and now camels. The company recently set out to capture 360-degree imagery of the Arabian desert, and to \"minimize\"...", + "icon": "https://fbstatic-a.akamaihd.net/rsrc.php/v2/yD/r/aS8ecmYRys0.gif", + "actions": [ + { + "name": "Comment", + "link": "https://www.facebook.com/109524391244/posts/10152483187826245" + }, + { + "name": "Like", + "link": "https://www.facebook.com/109524391244/posts/10152483187826245" + } + ], + "privacy": { + "value": "" + }, + "type": "link", + "status_type": "shared_story", + "application": { + "name": "Links", + "id": "2309869772" + }, + "created_time": "2014-10-08T16:01:20+0000", + "updated_time": "2014-10-08T16:01:20+0000" + }, + { + "id": "146218052067513_801079643248014", + "from": { + "category": "Local business", + "category_list": [ + { + "id": "2500", + "name": "Local Business" + } + ], + "name": "The Loading Dock, Inc.", + "id": "146218052067513" + }, + "message": "Blow In Insulation\n\n$2/ bag\n\nEach bag covers about 10 sf (at 6\" thickness)\n\nInsulation is used but very, very clean.\n\nRoughly 860 sf is available.", + "actions": [ + { + "name": "Comment", + "link": "https://www.facebook.com/146218052067513/posts/801079643248014" + }, + { + "name": "Like", + "link": "https://www.facebook.com/146218052067513/posts/801079643248014" + } + ], + "privacy": { + "value": "" + }, + "type": "status", + "status_type": "mobile_status_update", + "created_time": "2014-10-08T15:56:47+0000", + "updated_time": "2014-10-08T15:56:47+0000" + } + ], + "paging": { + "previous": "https://graph.facebook.com/v2.1/10152271780185899/home?limit=10&since=1412784449", + "next": "https://graph.facebook.com/v2.1/10152271780185899/home?limit=10&until=1412780437" + } +} \ No newline at end of file diff --git a/fbsync/tests/graph2.1.txt b/fbsync/tests/graph2.1.txt new file mode 100644 index 00000000..a8263d59 --- /dev/null +++ b/fbsync/tests/graph2.1.txt @@ -0,0 +1,53 @@ +{ + "data": [ + { + "actions": [ + { + "name": "Comment", + "link": "https://www.facebook.com/109524391244/posts/10152483187826245" + }, + { + "name": "Like", + "link": "https://www.facebook.com/109524391244/posts/10152483187826245" + } + ], + "link": "http://www.theverge.com/2014/10/8/6946033/google-put-street-view-camera-on-camels-back-to-tour-desert", + "id": "109524391244_10152483187826245", + "created_time": "2014-10-08T16:01:20+0000", + "application": { + "name": "Links", + "id": "2309869772" + }, + "updated_time": "2014-10-08T16:01:20+0000", + "description": "Google's Street View cameras have been carried around on cars, boats, people, and now camels. The company recently set out to capture 360-degree imagery of the Arabian desert, and to \"minimize\"...", + "privacy": { + "value": "" + }, + "attachments": { + "data": [ + { + "description": "Google's Street View cameras have been carried around on cars, boats, people, and now camels. The company recently set out to capture 360-degree imagery of the Arabian desert, and to \"minimize\"...", + "media": { + "image": { + "height": 674, + "src": "https://fbexternal-a.akamaihd.net/safe_image.php?d=AQBgDPhjhIZYFbxy&w=720&h=720&url=http%3A%2F%2Fcdn1.vox-cdn.com%2Fuploads%2Fchorus_image%2Fimage%2F41261020%2FScreen_Shot_2014-10-08_at_10.44.15_AM.0.0_cinema_1200.0.png&cfs=1", + "width": 674 + } + }, + "target": { + "id": "10152483187826245", + "url": "http://www.facebook.com/l.php?u=http%3A%2F%2Fwww.theverge.com%2F2014%2F10%2F8%2F6946033%2Fgoogle-put-street-view-camera-on-camels-back-to-tour-desert&h=XAQGWkIO2&s=1&enc=AZNOhgg2O7yFa63a0PeP8UE1EdJLbSArpD1HntdBft53llpu9kK38pKnp5svQCc6B355x1mgDXK3fD6dZfqIm29e" + }, + "title": "Google put its Street View camera on a camel's back to tour the Arabian desert", + "type": "share", + "url": "http://www.facebook.com/l.php?u=http%3A%2F%2Fwww.theverge.com%2F2014%2F10%2F8%2F6946033%2Fgoogle-put-street-view-camera-on-camels-back-to-tour-desert&h=XAQGWkIO2&s=1&enc=AZNOhgg2O7yFa63a0PeP8UE1EdJLbSArpD1HntdBft53llpu9kK38pKnp5svQCc6B355x1mgDXK3fD6dZfqIm29e" + } + ] + } + } + ], + "paging": { + "previous": "https://graph.facebook.com/v2.1/10152271780185899/home?fields=actions,link,id,created_time,application,attachments,updated_time,object_id,with_tags,comments{can_comment,comment_count},likes,message,message_tags,description,parent_id,place,privacy,shares&limit=1&since=1412784080", + "next": "https://graph.facebook.com/v2.1/10152271780185899/home?fields=actions,link,id,created_time,application,attachments,updated_time,object_id,with_tags,comments{can_comment,comment_count},likes,message,message_tags,description,parent_id,place,privacy,shares&limit=1&until=1412784079" + } +} \ No newline at end of file From b3d813b7aa558dce3769c75d12a911a432082d82 Mon Sep 17 00:00:00 2001 From: Ben Liyanage Date: Wed, 8 Oct 2014 14:50:38 -0400 Subject: [PATCH 07/15] got some initial fields set --- fbsync/object/Facebook_Graph21.php | 34 +++++++++++++++++++---------- fbsync/tests/fbsync_test.php | 22 +++++++++++++++---- fbsync/tests/graph2.1-no-filter.txt | 32 --------------------------- 3 files changed, 41 insertions(+), 47 deletions(-) diff --git a/fbsync/object/Facebook_Graph21.php b/fbsync/object/Facebook_Graph21.php index 0c459f4f..2de68e8c 100644 --- a/fbsync/object/Facebook_Graph21.php +++ b/fbsync/object/Facebook_Graph21.php @@ -1,41 +1,53 @@ uid = $uid; + $this->access_token = get_pconfig($uid,'facebook','access_token'); } - function CreatePost($a, $uid, $self, $contacts, $applications, $post, $create_user) + function CreatePost($a, $self, $contacts, $applications, $post, $create_user) { //Sanitize Inputs //Check if post exists //This is legacy--shouldn't we check if the various parts of the post was updated? $r = q("SELECT * FROM `item` WHERE `uid` = %d AND `uri` = '%s' LIMIT 1", - intval($uid), - dbesc('fb::'.$post->post_id) + intval($this->uid), + dbesc('fb::'.$post->id) ); if(count($r)) return; $postarray = array(); $postarray['gravity'] = 0; - $postarray['uid'] = $uid; + $postarray['uid'] = $this->uid; $postarray['wall'] = 0; $postarray['verb'] = ACTIVITY_POST; $postarray['object-type'] = ACTIVITY_OBJ_NOTE; // default value - is maybe changed later when media is attached $postarray['network'] = dbesc(NETWORK_FACEBOOK); - $postarray['uri'] = "fb::".$post->post_id; + $postarray['uri'] = "fb::". $post->id; $postarray['thr-parent'] = $postarray['uri']; $postarray['parent-uri'] = $postarray['uri']; - $postarray['plink'] = $post->permalink; + + //No permalink in new api. Can use one of the action links, they seem to be all the same. + //Another option is spliting the id AAA_BBB where AAA is the id of the person, and BBB is the ID of the post. final url would be facebook.com/AAA/post/BBB + $ids = split("_", $post->id); + $postarray['plink'] = 'https://www.facebook.com/' . $ids[0] . '/posts/' . $ids[1]; + + return $postarray; + } + } + ?> \ No newline at end of file diff --git a/fbsync/tests/fbsync_test.php b/fbsync/tests/fbsync_test.php index 3ae2596e..e81c6372 100644 --- a/fbsync/tests/fbsync_test.php +++ b/fbsync/tests/fbsync_test.php @@ -15,6 +15,7 @@ $db = new dba($db_host, $db_user, $db_pass, $db_data, $install); //var_dump($data); //Test Data Processing +$uid = 1; // Test Base Class require_once("./addon/fbsync/object/Facebook.php"); @@ -22,10 +23,23 @@ $myFBSync = new Facebook(); // Test graph 2.1 class require_once("./addon/fbsync/object/Facebook_Graph21.php"); -$myFBSync = new Facebook_Graph21(); -$uid = 1; -$post = json_decode(readfile("./addon/fbsync/tests/graph2.1.txt")); -$myFBSync->CreatePost($a,$uid,0,0,0,$post,0); +$myFBSync = new Facebook_Graph21($uid); + +//verify class loaded correctly +if ($myFBSync->uid != 1) die("class did not load"); +if ($myFBSync->access_token == '') die("failed to load access_token"); + + +$posts = json_decode(file_get_contents("./addon/fbsync/tests/graph2.1.txt")); + +$post = $myFBSync->CreatePost($a,0,0,0,$posts->data[0],0); + +//verify data +if ($post['uri'] != "fb::109524391244_10152483187826245") die("uri does not match"); +if ($post['plink'] != "https://www.facebook.com/109524391244/posts/10152483187826245") die("plink does not match"); + +//var_dump($posts->data[0]); +//test creating the same post again /* diff --git a/fbsync/tests/graph2.1-no-filter.txt b/fbsync/tests/graph2.1-no-filter.txt index 96a463d9..d28c49c7 100644 --- a/fbsync/tests/graph2.1-no-filter.txt +++ b/fbsync/tests/graph2.1-no-filter.txt @@ -49,38 +49,6 @@ }, "created_time": "2014-10-08T16:01:20+0000", "updated_time": "2014-10-08T16:01:20+0000" - }, - { - "id": "146218052067513_801079643248014", - "from": { - "category": "Local business", - "category_list": [ - { - "id": "2500", - "name": "Local Business" - } - ], - "name": "The Loading Dock, Inc.", - "id": "146218052067513" - }, - "message": "Blow In Insulation\n\n$2/ bag\n\nEach bag covers about 10 sf (at 6\" thickness)\n\nInsulation is used but very, very clean.\n\nRoughly 860 sf is available.", - "actions": [ - { - "name": "Comment", - "link": "https://www.facebook.com/146218052067513/posts/801079643248014" - }, - { - "name": "Like", - "link": "https://www.facebook.com/146218052067513/posts/801079643248014" - } - ], - "privacy": { - "value": "" - }, - "type": "status", - "status_type": "mobile_status_update", - "created_time": "2014-10-08T15:56:47+0000", - "updated_time": "2014-10-08T15:56:47+0000" } ], "paging": { From 24a1cb695fb61ca20fc5ebd7f4c165eaa53e25c9 Mon Sep 17 00:00:00 2001 From: Ben Liyanage Date: Wed, 8 Oct 2014 16:08:56 -0400 Subject: [PATCH 08/15] cleanup -- not working right yet removed an uncessary variable from the function fbsync_createpost cleaned up some formatting please note, this and previous version of this file will not work because $self is not available in some spots where its needed. --- fbsync/fbsync.php | 39 +++++++++++++++++++++------------------ 1 file changed, 21 insertions(+), 18 deletions(-) diff --git a/fbsync/fbsync.php b/fbsync/fbsync.php index 8e87cfc5..2ae64676 100644 --- a/fbsync/fbsync.php +++ b/fbsync/fbsync.php @@ -212,7 +212,7 @@ function fbsync_expire($a,$b) { logger('fbsync_expire: expire_end'); } -function fbsync_createpost($a, $uid, $self, $contacts, $applications, $post, $create_user) { +function fbsync_createpost($a, $uid, $contacts, $applications, $post, $create_user) { //Sanitize Inputs $post->actor_id = number_format($post->actor_id, 0, '', ''); $post->source_id = number_format($post->source_id, 0, '', ''); @@ -325,20 +325,21 @@ function fbsync_createpost($a, $uid, $self, $contacts, $applications, $post, $cr // Change the object type when an attachment is present if (isset($post->attachment->fb_object_type)) logger('fb_object_type: '.$post->attachment->fb_object_type." ".print_r($post->attachment, true), LOGGER_DEBUG); - switch ($post->attachment->fb_object_type) { - case 'photo': - $postarray['object-type'] = ACTIVITY_OBJ_IMAGE; // photo is deprecated: http://activitystrea.ms/head/activity-schema.html#image - break; - case 'video': - $postarray['object-type'] = ACTIVITY_OBJ_VIDEO; - break; - case '': - //$postarray['object-type'] = ACTIVITY_OBJ_BOOKMARK; - break; - default: - logger('Unknown object type '.$post->attachment->fb_object_type, LOGGER_DEBUG); - break; - } + + switch ($post->attachment->fb_object_type) { + case 'photo': + $postarray['object-type'] = ACTIVITY_OBJ_IMAGE; // photo is deprecated: http://activitystrea.ms/head/activity-schema.html#image + break; + case 'video': + $postarray['object-type'] = ACTIVITY_OBJ_VIDEO; + break; + case '': + //$postarray['object-type'] = ACTIVITY_OBJ_BOOKMARK; + break; + default: + logger('Unknown object type '.$post->attachment->fb_object_type, LOGGER_DEBUG); + break; + } $content = ""; $type = ""; @@ -445,11 +446,11 @@ function fbsync_createpost($a, $uid, $self, $contacts, $applications, $post, $cr if(isset($post->privacy) && $post->privacy->value !== '') { $postarray['private'] = 1; - $postarray['allow_cid'] = '<' . $self[0]['id'] . '>'; + $postarray['allow_cid'] = '<' . $uid . '>'; } $item = item_store($postarray); - logger('fbsync_createpost: User '.$self[0]["nick"].' posted feed item '.$item, LOGGER_DEBUG); + logger('fbsync_createpost: User ' . $uid . ' posted feed item '.$item, LOGGER_DEBUG); } function fbsync_createcomment($a, $uid, $self_id, $self, $user, $contacts, $applications, $comment) { @@ -1094,11 +1095,13 @@ function fbsync_processfeed($data){ } unset($applications); + + //FIXME: Need $self, which is in the fetch_data function foreach ($posts AS $post) { if ($post->updated_time > $last_updated) $last_updated = $post->updated_time; - fbsync_createpost($a, $uid, $self, $contacts, $applications, $post, $create_user); + fbsync_createpost($a, $uid, $contacts, $applications, $post, $create_user); } foreach ($comments AS $comment) { From dfffacb9c803d3b55d7f13e7afaa1716c5d71666 Mon Sep 17 00:00:00 2001 From: Ben Liyanage Date: Wed, 8 Oct 2014 16:24:48 -0400 Subject: [PATCH 09/15] first post went in --- fbsync/object/Facebook.php | 3 ++- fbsync/object/Facebook_Graph21.php | 41 +++++++++++++++++++++++++++--- fbsync/tests/fbsync_test.php | 6 ++++- 3 files changed, 44 insertions(+), 6 deletions(-) diff --git a/fbsync/object/Facebook.php b/fbsync/object/Facebook.php index 8e7598b3..10eef0d2 100644 --- a/fbsync/object/Facebook.php +++ b/fbsync/object/Facebook.php @@ -1,6 +1,7 @@ created_time)); + $postarray['edited'] = datetime_convert('UTC','UTC',date("c", $post->updated_time)); + $postarray['uri'] = "fb::". $post->id; $postarray['thr-parent'] = $postarray['uri']; $postarray['parent-uri'] = $postarray['uri']; //No permalink in new api. Can use one of the action links, they seem to be all the same. //Another option is spliting the id AAA_BBB where AAA is the id of the person, and BBB is the ID of the post. final url would be facebook.com/AAA/post/BBB + //TODO: Remove actions if not in use $ids = split("_", $post->id); $postarray['plink'] = 'https://www.facebook.com/' . $ids[0] . '/posts/' . $ids[1]; + $postarray['author-name'] = $post->from->name; // $contacts[$post->actor_id]->name; + $postarray['author-link'] = 'https://www.facebook.com/' . $post->from->id; //$contacts[$post->actor_id]->url; + + //TODO: Pic not included in graph + //$postarray['author-avatar'] = $contacts[$post->actor_id]->pic_square; + + //TODO: Source not in in graph api. What was this before? Seemed like it was the same as the author with FQL + //$postarray['owner-name'] = $contacts[$post->source_id]->name; + //$postarray['owner-link'] = $contacts[$post->source_id]->url; + //$postarray['owner-avatar'] = $contacts[$post->source_id]->pic_square; + + //TODO: Parent Post Code + + //TODO: Set $postarray['contact-id'] = $contact_id; Should either be the actor_id or the source_id (not in graph?) + + //TODO: Body does not seem to be used in graph or fql any more. What is this value supposed to be? + $postarray["body"] = ""; + + //TODO: Deal with attachments + //Kind of a big deal. + + $postarray['app'] = ($post->application->name == "" ? "Facebook" : $post->application->name); + + if(isset($post->privacy) && $post->privacy->value !== '') { + $postarray['private'] = 1; + $postarray['allow_cid'] = '<' . $uid . '>'; + } + + $item = item_store($postarray); + logger('fbsync_createpost: User ' . $uid . ' posted feed item '.$item, LOGGER_DEBUG); + return $postarray; - } - } ?> \ No newline at end of file diff --git a/fbsync/tests/fbsync_test.php b/fbsync/tests/fbsync_test.php index e81c6372..7c9fdc1b 100644 --- a/fbsync/tests/fbsync_test.php +++ b/fbsync/tests/fbsync_test.php @@ -29,7 +29,9 @@ $myFBSync = new Facebook_Graph21($uid); if ($myFBSync->uid != 1) die("class did not load"); if ($myFBSync->access_token == '') die("failed to load access_token"); +//Test FetchContact +//Test CreatePost $posts = json_decode(file_get_contents("./addon/fbsync/tests/graph2.1.txt")); $post = $myFBSync->CreatePost($a,0,0,0,$posts->data[0],0); @@ -42,11 +44,13 @@ if ($post['plink'] != "https://www.facebook.com/109524391244/posts/1015248318782 //test creating the same post again +echo "All done\n"; + /* https://developers.facebook.com/tools/explorer SELECT action_links, actor_id, app_data, app_id, attachment, attribution, comment_info, created_time, filter_key, like_info, message, message_tags, parent_post_id, permalink, place, post_id, privacy, share_count, share_info, source_id, subscribed, tagged_ids, type, updated_time, with_tags FROM stream where filter_key ='nf' ORDER BY updated_time DESC LIMIT 5 - +//Todo:Actions can probably be removed me/home?fields=actions&since=992438&updated_time=0&filter=nf&limit=1 me/home?fields=actions,link,id,created_time,application,attachments,updated_time,object_id,with_tags,comments{can_comment,comment_count},likes,message,message_tags,description,parent_id,place,privacy,shares&limit=1 https://developers.facebook.com/docs/graph-api/reference/v2.1/test-user From 6d82fcd55b9eedbc14dff763cb312341a1945ee9 Mon Sep 17 00:00:00 2001 From: Ben Liyanage Date: Thu, 9 Oct 2014 15:53:45 -0400 Subject: [PATCH 10/15] added a bunch of code for the post body --- fbsync/object/Facebook_Graph21.php | 140 +++++++++++++++++++++++++++-- fbsync/tests/fbsync_test.php | 6 +- 2 files changed, 139 insertions(+), 7 deletions(-) diff --git a/fbsync/object/Facebook_Graph21.php b/fbsync/object/Facebook_Graph21.php index cdd66550..e670f56b 100644 --- a/fbsync/object/Facebook_Graph21.php +++ b/fbsync/object/Facebook_Graph21.php @@ -32,7 +32,6 @@ Class Facebook_Graph21 extends Facebook $postarray['wall'] = 0; $postarray['verb'] = ACTIVITY_POST; - $postarray['object-type'] = ACTIVITY_OBJ_NOTE; // default value - is maybe changed later when media is attached $postarray['network'] = dbesc(NETWORK_FACEBOOK); $postarray['created'] = datetime_convert('UTC','UTC',date("c", $post->created_time)); @@ -62,12 +61,30 @@ Class Facebook_Graph21 extends Facebook //TODO: Parent Post Code //TODO: Set $postarray['contact-id'] = $contact_id; Should either be the actor_id or the source_id (not in graph?) + $postarray['contact-id'] = 1; - //TODO: Body does not seem to be used in graph or fql any more. What is this value supposed to be? - $postarray["body"] = ""; + //Set Object Type + if (!isset($post->attachment[0]->type)) + { + //Default Object Type + $postarray['object-type'] = ACTIVITY_OBJ_NOTE; // default value - is maybe changed later when media is attached + } else { + // Change the object type when an attachment is present + $postarray['object-type'] = $post->attachment[0]->type; // default value - is maybe changed later when media is attached + } + /* More type code. I think this is not necessary. + require_once("include/oembed.php"); + $oembed_data = oembed_fetch_url($post->attachment->href); + $type = $oembed_data->type; + if ($type == "rich") + $type = "link"; + */ - //TODO: Deal with attachments - //Kind of a big deal. + //TODO: Body needs more testing, and has some more frindge cases. + $postarray["body"] = $this->AssembleBody($post->name, $post->link, $post->description, $post->picture); //"This is the body. [quote]This is the quote.[/quote]"; + + //TODO: Do tags + $postarray["tag"] = "This is the tag"; $postarray['app'] = ($post->application->name == "" ? "Facebook" : $post->application->name); @@ -81,6 +98,119 @@ Class Facebook_Graph21 extends Facebook return $postarray; } + + function AssembleBody($Title, $Href, $Body, $Picture) + { + //TODO: Need to do prebody code still. + //TODO: Need to add class (aka type) code + $postarray["body"] = (isset($post->message) ? escape_tags($post->message) : ''); + + $msgdata = fbsync_convertmsg($a, $postarray["body"]); + + $postarray["body"] = $msgdata["body"]; + $postarray["tag"] = $msgdata["tags"]; + + $content = ""; + + if ($Picture != "") + { + $pictureStr = '[img]' . $Picture . '[/img]'; + if ($Href != "") + { + $pictureStr = '[url=' . $Href . ']' . $pictureStr . '[/url]'; + } + + $content .= "\n" . $pictureStr; + } + + if ($Title != "" and $Href != "") { + + $content .= "[bookmark=".$Href."]".$Title."[/bookmark]"; + + // If a link is not only attached but also added in the body, look if it can be removed in the body. + /* + $removedlink = trim(str_replace($post->attachment->href, "", $postarray["body"])); + + if (($removedlink == "") OR strstr($postarray["body"], $removedlink)) + $postarray["body"] = $removedlink; + */ + } elseif ($Title != "") { + $content .= "[b]" . $post->attachment->name."[/b]"; + } + + $content .= "\n[quote]".trim($Body)."[/quote]"; + + + /* + + if (isset($post->attachment->media) AND (($type == "") OR ($type == "link"))) { + foreach ($post->attachment->media AS $media) { + + if (isset($media->type)) + $type = $media->type; + + if (isset($media->src)) + $preview = $media->src; + + if (isset($media->photo)) { + if (isset($media->photo->images) AND (count($media->photo->images) > 1)) + $preview = $media->photo->images[1]->src; + + if (isset($media->photo->fbid)) { + logger('fbsync_createpost: fetching fbid '.$media->photo->fbid, LOGGER_DEBUG); + $url = "https://graph.facebook.com/".$media->photo->fbid."?access_token=".$access_token; + $feed = fetch_url($url); + $data = json_decode($feed); + if (isset($data->images)) { + $preview = $data->images[0]->source; + logger('fbsync_createpost: got fbid '.$media->photo->fbid.' image '.$preview, LOGGER_DEBUG); + } else + logger('fbsync_createpost: error fetching fbid '.$media->photo->fbid.' '.print_r($data, true), LOGGER_DEBUG); + } + } + + if (isset($media->href) AND ($preview != "") AND ($media->href != "")) + $content .= "\n".'[url='.$media->href.'][img]'.$preview.'[/img][/url]'; + else { + if ($preview != "") + $content .= "\n".'[img]'.$preview.'[/img]'; + + // if just a link, it may be a wall photo - check + if (isset($post->link)) + $content .= fbpost_get_photo($media->href); + } + } + } + + if ($type == "link") + $postarray["object-type"] = ACTIVITY_OBJ_BOOKMARK; + + if ($content) + $postarray["body"] .= "\n"; + + if ($type) + $postarray["body"] .= "[class=type-".$type."]"; + + if ($content) + $postarray["body"] .= trim($content); + + if ($quote) + $postarray["body"] .= "\n[quote]".trim($quote)."[/quote]"; + + if ($type) + $postarray["body"] .= "[/class]"; + + $postarray["body"] = trim($postarray["body"]); + + if (trim($postarray["body"]) == "") + return; + + if ($prebody != "") + $postarray["body"] = $prebody.$postarray["body"]."[/share]"; + */ + + return $content; + } } ?> \ No newline at end of file diff --git a/fbsync/tests/fbsync_test.php b/fbsync/tests/fbsync_test.php index 7c9fdc1b..b4bbbe89 100644 --- a/fbsync/tests/fbsync_test.php +++ b/fbsync/tests/fbsync_test.php @@ -32,7 +32,9 @@ if ($myFBSync->access_token == '') die("failed to load access_token"); //Test FetchContact //Test CreatePost -$posts = json_decode(file_get_contents("./addon/fbsync/tests/graph2.1.txt")); +$posts = json_decode(file_get_contents("./addon/fbsync/tests/graph2.1-no-filter.txt")); + +var_dump($posts); $post = $myFBSync->CreatePost($a,0,0,0,$posts->data[0],0); @@ -52,7 +54,7 @@ SELECT action_links, actor_id, app_data, app_id, attachment, attribution, commen //Todo:Actions can probably be removed me/home?fields=actions&since=992438&updated_time=0&filter=nf&limit=1 -me/home?fields=actions,link,id,created_time,application,attachments,updated_time,object_id,with_tags,comments{can_comment,comment_count},likes,message,message_tags,description,parent_id,place,privacy,shares&limit=1 +me/home?fields=actions,link,id,created_time,application,attachments,updated_time,object_id,with_tags,comments{can_comment,comment_count},likes,message,message_tags,description,parent_id,place,privacy,shares,from&limit=1 https://developers.facebook.com/docs/graph-api/reference/v2.1/test-user From 86846d9ff4688a40e66c7ee18ba71a9808e20db0 Mon Sep 17 00:00:00 2001 From: Ben Liyanage Date: Thu, 9 Oct 2014 16:39:25 -0400 Subject: [PATCH 11/15] cleaned up some other missing variables. --- fbsync/fbsync.php | 43 +++++++++++++----------------- fbsync/object/Facebook_Graph21.php | 2 +- 2 files changed, 20 insertions(+), 25 deletions(-) diff --git a/fbsync/fbsync.php b/fbsync/fbsync.php index 2ae64676..f8f8dc68 100644 --- a/fbsync/fbsync.php +++ b/fbsync/fbsync.php @@ -175,11 +175,19 @@ function fbsync_cron($a,$b) { if(count($r)) { foreach($r as $rr) { - fbsync_get_self($rr['uid']); - - logger('fbsync_cron: importing timeline from user '.$rr['uid']); - $data = fbsync_fetchfeed($a, $rr['uid']); - fbsync_processfeed($data); + logger('fbsync_cron: importing timeline from user '.$rr['uid']); + + $uid = fbsync_get_self($rr['uid']); + $self_id = get_pconfig($uid,'fbsync','self_id'); + $last_updated = get_pconfig($uid,'fbsync','last_updated'); + + $self = q("SELECT * FROM `contact` WHERE `self` = 1 AND `uid` = %d LIMIT 1", intval($uid)); + $user = q("SELECT * FROM `user` WHERE `uid` = %d AND `account_expired` = 0 LIMIT 1", intval($uid)); + if(! count($user)) + return; + + $data = fbsync_fetchfeed($a, $uid, $self_id, $last_updated); + fbsync_processfeed($data, $self, $a, $uid, $self_id, $user, $last_updated); } } @@ -982,23 +990,9 @@ function fbsync_fetchuser($a, $uid, $id) { return($user); } -function fbsync_fetchfeed($a, $uid) { +function fbsync_fetchfeed($a, $uid, $self_id, $last_updated) { $access_token = get_pconfig($uid,'facebook','access_token'); - $last_updated = get_pconfig($uid,'fbsync','last_updated'); - $self_id = get_pconfig($uid,'fbsync','self_id'); - - $create_user = get_pconfig($uid, 'fbsync', 'create_user'); - $do_likes = get_config('fbsync', 'do_likes'); - - $self = q("SELECT * FROM `contact` WHERE `self` = 1 AND `uid` = %d LIMIT 1", - intval($uid) - ); - - $user = q("SELECT * FROM `user` WHERE `uid` = %d AND `account_expired` = 0 LIMIT 1", - intval($uid) - ); - if(! count($user)) - return; + $do_likes = get_config('fbsync', 'do_likes'); require_once('include/items.php'); @@ -1032,7 +1026,10 @@ function fbsync_fetchfeed($a, $uid) { return $data; } -function fbsync_processfeed($data){ +function fbsync_processfeed($data, $self, $a, $uid, $self_id, $user, $last_updated){ + + $create_user = get_pconfig($uid, 'fbsync', 'create_user'); + $posts = array(); $comments = array(); $likes = array(); @@ -1095,8 +1092,6 @@ function fbsync_processfeed($data){ } unset($applications); - - //FIXME: Need $self, which is in the fetch_data function foreach ($posts AS $post) { if ($post->updated_time > $last_updated) $last_updated = $post->updated_time; diff --git a/fbsync/object/Facebook_Graph21.php b/fbsync/object/Facebook_Graph21.php index e670f56b..4de7c3cc 100644 --- a/fbsync/object/Facebook_Graph21.php +++ b/fbsync/object/Facebook_Graph21.php @@ -80,7 +80,7 @@ Class Facebook_Graph21 extends Facebook $type = "link"; */ - //TODO: Body needs more testing, and has some more frindge cases. + //TODO: Body needs more testing, and has some more fringe cases. $postarray["body"] = $this->AssembleBody($post->name, $post->link, $post->description, $post->picture); //"This is the body. [quote]This is the quote.[/quote]"; //TODO: Do tags From d17c71611f52621d02172e31b3438ed39965601b Mon Sep 17 00:00:00 2001 From: Ben Liyanage Date: Mon, 13 Oct 2014 16:07:20 -0400 Subject: [PATCH 12/15] more tests, some cleanup Added tests for the FQL code. Cleaned up some of the graph stuff. Added some things that don't work. Object type is definitely broken--there needs to be a test for it. --- fbsync/fbsync.php | 28 ++++---- fbsync/object/Facebook_FQL.php | 9 +++ fbsync/object/Facebook_Graph21.php | 65 +++++++++---------- fbsync/tests/fbsync_test.php | 25 +++++-- fbsync/tests/fql-full.txt | 101 +++++++++++++++++++++++++++++ 5 files changed, 176 insertions(+), 52 deletions(-) create mode 100644 fbsync/object/Facebook_FQL.php create mode 100644 fbsync/tests/fql-full.txt diff --git a/fbsync/fbsync.php b/fbsync/fbsync.php index f8f8dc68..470a2a12 100644 --- a/fbsync/fbsync.php +++ b/fbsync/fbsync.php @@ -18,6 +18,7 @@ FBPost: */ require_once("addon/fbpost/fbpost.php"); +require_once("include/items.php"); define('FBSYNC_DEFAULT_POLL_INTERVAL', 5); // given in minutes @@ -205,8 +206,7 @@ function fbsync_expire($a,$b) { $r = q("DELETE FROM `item` WHERE `deleted` AND `network` = '%s'", dbesc(NETWORK_FACEBOOK)); - require_once("include/items.php"); - + logger('fbsync_expire: expire_start'); $r = q("SELECT * FROM `pconfig` WHERE `cat` = 'fbsync' AND `k` = 'sync' AND `v` = '1' ORDER BY RAND()"); @@ -236,7 +236,7 @@ function fbsync_createpost($a, $uid, $contacts, $applications, $post, $create_us dbesc('fb::'.$post->post_id) ); if(count($r)) - return; + return 1; $postarray = array(); $postarray['gravity'] = 0; @@ -310,10 +310,10 @@ function fbsync_createpost($a, $uid, $contacts, $applications, $post, $create_us if ($contact_id == -1) { logger('fbsync_createpost: Contact is blocked. Post not imported '.print_r($post, true), LOGGER_DEBUG); - return; + return 2; } elseif (($contact_id <= 0) AND !$create_user) { logger('fbsync_createpost: No matching contact found. Post not imported '.print_r($post, true), LOGGER_DEBUG); - return; + return 3; } elseif ($contact_id == 0) { // This case should never happen logger('fbsync_createpost: No matching contact found. Using own id. (Should never happen) '.print_r($post, true), LOGGER_DEBUG); @@ -377,7 +377,7 @@ function fbsync_createpost($a, $uid, $contacts, $applications, $post, $create_us $quote = $post->attachment->caption; if ($quote.$post->attachment->href.$content.$postarray["body"] == "") - return; + return 3; if (isset($post->attachment->media) AND (($type == "") OR ($type == "link"))) { foreach ($post->attachment->media AS $media) { @@ -439,7 +439,7 @@ function fbsync_createpost($a, $uid, $contacts, $applications, $post, $create_us $postarray["body"] = trim($postarray["body"]); if (trim($postarray["body"]) == "") - return; + return 4; if ($prebody != "") $postarray["body"] = $prebody.$postarray["body"]."[/share]"; @@ -459,6 +459,7 @@ function fbsync_createpost($a, $uid, $contacts, $applications, $post, $create_us $item = item_store($postarray); logger('fbsync_createpost: User ' . $uid . ' posted feed item '.$item, LOGGER_DEBUG); + return 0; } function fbsync_createcomment($a, $uid, $self_id, $self, $user, $contacts, $applications, $comment) { @@ -994,8 +995,6 @@ function fbsync_fetchfeed($a, $uid, $self_id, $last_updated) { $access_token = get_pconfig($uid,'facebook','access_token'); $do_likes = get_config('fbsync', 'do_likes'); - require_once('include/items.php'); - //if ($last_updated == "") $last_updated = 0; @@ -1012,9 +1011,9 @@ function fbsync_fetchfeed($a, $uid, $self_id, $last_updated) { $fql["likes"] = "SELECT post_id, user_id FROM like WHERE post_id IN (SELECT post_id FROM #posts)"; $fql["profiles"] .= " OR id IN (SELECT user_id FROM #likes)"; } - - $url = "https://graph.facebook.com/fql?q=".urlencode(json_encode($fql))."&access_token=".$access_token; + $url = "https://graph.facebook.com/fql?q=".urlencode(json_encode($fql))."&access_token=".$access_token; + echo $url; $feed = fetch_url($url); $data = json_decode($feed); @@ -1092,11 +1091,14 @@ function fbsync_processfeed($data, $self, $a, $uid, $self_id, $user, $last_updat } unset($applications); + foreach ($posts AS $post) { if ($post->updated_time > $last_updated) $last_updated = $post->updated_time; - - fbsync_createpost($a, $uid, $contacts, $applications, $post, $create_user); + + $result = fbsync_createpost($a, $uid, $contacts, $applications, $post, $create_user); + + echo $result; } foreach ($comments AS $comment) { diff --git a/fbsync/object/Facebook_FQL.php b/fbsync/object/Facebook_FQL.php new file mode 100644 index 00000000..7183ebcf --- /dev/null +++ b/fbsync/object/Facebook_FQL.php @@ -0,0 +1,9 @@ + \ No newline at end of file diff --git a/fbsync/object/Facebook_Graph21.php b/fbsync/object/Facebook_Graph21.php index 4de7c3cc..bfd37c90 100644 --- a/fbsync/object/Facebook_Graph21.php +++ b/fbsync/object/Facebook_Graph21.php @@ -24,7 +24,10 @@ Class Facebook_Graph21 extends Facebook dbesc('fb::'.$post->id) ); if(count($r)) + { + logger('fbsync_createpost: skipping post $post->id--already exists', LOGGER_DEBUG); return; + } $postarray = array(); $postarray['gravity'] = 0; @@ -64,7 +67,8 @@ Class Facebook_Graph21 extends Facebook $postarray['contact-id'] = 1; //Set Object Type - if (!isset($post->attachment[0]->type)) + //TODO: This code is broken. + if (!isset($post->attachment[0]->type)) //This is never set since its from the FQL dataset. { //Default Object Type $postarray['object-type'] = ACTIVITY_OBJ_NOTE; // default value - is maybe changed later when media is attached @@ -79,14 +83,19 @@ Class Facebook_Graph21 extends Facebook if ($type == "rich") $type = "link"; */ - + /* + echo "type: " . $postarray['object-type']; + die(); + */ //TODO: Body needs more testing, and has some more fringe cases. - $postarray["body"] = $this->AssembleBody($post->name, $post->link, $post->description, $post->picture); //"This is the body. [quote]This is the quote.[/quote]"; + $postarray["body"] = $this->AssembleBody($post->name, $post->link, $post->description, $post->picture, $postarray['object-type']); + + //TODO: Do tags $postarray["tag"] = "This is the tag"; - $postarray['app'] = ($post->application->name == "" ? "Facebook" : $post->application->name); + $postarray['app'] = ($post->application->name == "Links" ? "Facebook" : $post->application->name); if(isset($post->privacy) && $post->privacy->value !== '') { $postarray['private'] = 1; @@ -99,17 +108,16 @@ Class Facebook_Graph21 extends Facebook return $postarray; } - function AssembleBody($Title, $Href, $Body, $Picture) + function AssembleBody($Title, $Href, $Body, $Picture, $ObjectType) { - //TODO: Need to do prebody code still. - //TODO: Need to add class (aka type) code + /* $postarray["body"] = (isset($post->message) ? escape_tags($post->message) : ''); $msgdata = fbsync_convertmsg($a, $postarray["body"]); $postarray["body"] = $msgdata["body"]; $postarray["tag"] = $msgdata["tags"]; - + */ $content = ""; if ($Picture != "") @@ -181,32 +189,21 @@ Class Facebook_Graph21 extends Facebook } } } - - if ($type == "link") - $postarray["object-type"] = ACTIVITY_OBJ_BOOKMARK; - - if ($content) - $postarray["body"] .= "\n"; - - if ($type) - $postarray["body"] .= "[class=type-".$type."]"; - - if ($content) - $postarray["body"] .= trim($content); - - if ($quote) - $postarray["body"] .= "\n[quote]".trim($quote)."[/quote]"; - - if ($type) - $postarray["body"] .= "[/class]"; - - $postarray["body"] = trim($postarray["body"]); - - if (trim($postarray["body"]) == "") - return; - - if ($prebody != "") - $postarray["body"] = $prebody.$postarray["body"]."[/share]"; + */ + + $content = '[class="type-'. $ObjectType . '"]' . $content . '[/class]'; + + /* + TODO: + * What is the wall-to-wall system setting supposed to do? What is the "Share" syntax used for? + This code does not seem to match what happens with the previous posts. I stripped out some stuff comparing author and source below. + + if (!intval(get_config('system','wall-to-wall_share'))) { + $ShareAuthor = "Test Share Author"; + $ShareAuthorLink = "http://test.com"; + + $content = '[share author="' . $ShareAuthor . '" profile="' . $ShareAuthorLink . '" avatar="' . $ShareAuthorAvatar . '"]' . $content . '[/share]'; + } */ return $content; diff --git a/fbsync/tests/fbsync_test.php b/fbsync/tests/fbsync_test.php index b4bbbe89..da30e552 100644 --- a/fbsync/tests/fbsync_test.php +++ b/fbsync/tests/fbsync_test.php @@ -14,8 +14,23 @@ $db = new dba($db_host, $db_user, $db_pass, $db_data, $install); //$data = fbsync_fetchfeed($a, 1); //var_dump($data); -//Test Data Processing +//Test Data Prcoessing -- Constants-- used in both tests $uid = 1; +$self_id = get_pconfig($uid,'fbsync','self_id'); +$last_updated = get_pconfig($uid,'fbsync','last_updated'); +$self = q("SELECT * FROM `contact` WHERE `self` = 1 AND `uid` = %d LIMIT 1", intval($uid)); +$user = q("SELECT * FROM `user` WHERE `uid` = %d AND `account_expired` = 0 LIMIT 1", intval($uid)); +$create_user = get_pconfig($uid, 'fbsync', 'create_user'); + +//Test Data Processing fql +$data = json_decode(file_get_contents("./addon/fbsync/tests/fql-full.txt")); +$result = fbsync_processfeed($data, $self, $a, $uid, $self_id, $user, $last_updated); + +if ($result != 0) die("FQL Processing broken.\n"); + +echo "Done with fql_data processing.\n"; + +//Test data processing -- graph` // Test Base Class require_once("./addon/fbsync/object/Facebook.php"); @@ -30,12 +45,11 @@ if ($myFBSync->uid != 1) die("class did not load"); if ($myFBSync->access_token == '') die("failed to load access_token"); //Test FetchContact +//TODO: build tests for facebook api requests using API test user functions //Test CreatePost $posts = json_decode(file_get_contents("./addon/fbsync/tests/graph2.1-no-filter.txt")); -var_dump($posts); - $post = $myFBSync->CreatePost($a,0,0,0,$posts->data[0],0); //verify data @@ -43,7 +57,8 @@ if ($post['uri'] != "fb::109524391244_10152483187826245") die("uri does not matc if ($post['plink'] != "https://www.facebook.com/109524391244/posts/10152483187826245") die("plink does not match"); //var_dump($posts->data[0]); -//test creating the same post again + +//TODO: test creating the same post again echo "All done\n"; @@ -85,4 +100,4 @@ https://developers.facebook.com/docs/graph-api/reference/v2.1/test-user */ -?> \ No newline at end of file +?> \ No newline at end of file diff --git a/fbsync/tests/fql-full.txt b/fbsync/tests/fql-full.txt new file mode 100644 index 00000000..07d1b3c3 --- /dev/null +++ b/fbsync/tests/fql-full.txt @@ -0,0 +1,101 @@ +{ + "data": [ + { + "name": "posts", + "fql_result_set": [ + { + "action_links": null, + "actor_id": 568851657, + "app_data": [ + ], + "app_id": null, + "attachment": { + "description": "" + }, + "attribution": null, + "comment_info": { + "can_comment": true, + "comment_count": 3, + "comment_order": "chronological" + }, + "created_time": 1413220907, + "filter_key": "nf", + "like_info": { + "can_like": true, + "like_count": 1, + "user_likes": false + }, + "message": "Max Gladstone on modern magic:\n\n\"[C]onsider the smartphone I have in my pocket. No single human being knows how to make this phone. I acquired the phone, and I use it. People who know more about the phone can tell it to do more things than I can, but they're still bound by the limits of the hardware. A few communities are dedicated to modding and hacking phones like mine, yes, but for most people most of the time a smartphone is a portable magic mirror. We make mystic passes before the glass, address the indwelling spirit with suitably respectful tones, and LEARN THE FUTURE. (\"Siri, what will the weather be like tomorrow?\") The same thought experiment works for many modern technologies.\"", + "message_tags": [ + ], + "parent_post_id": null, + "permalink": "https://www.facebook.com/stephen.carr.547/posts/10152403039101658", + "place": null, + "post_id": "568851657_10152403039101658", + "privacy": { + "value": "" + }, + "share_count": 0, + "share_info": { + "can_share": true, + "share_count": 0 + }, + "source_id": 568851657, + "subscribed": false, + "tagged_ids": [ + ], + "type": 46, + "updated_time": 1413222111, + "with_tags": [ + ] + } + ] + }, + { + "name": "comments", + "fql_result_set": [ + { + "app_id": 0, + "attachment": null, + "post_id": "568851657_10152403039101658", + "id": "10152403039101658_10152403084216658", + "likes": 0, + "fromid": 568851657, + "time": 1413222111, + "text": "And Siri said unto them, \"I'm sorry, I did not understand that.\" And the pharisees were wroth, and sought to harden the heart of Palmius Pilot against her.", + "text_tags": [ + ], + "user_likes": false + } + ] + }, + { + "name": "applications", + "fql_result_set": [ + ] + }, + { + "name": "profiles", + "fql_result_set": [ + { + "id": 568851657, + "name": "Stephen Carr", + "username": "stephen.carr.547", + "url": "https://www.facebook.com/stephen.carr.547", + "pic_square": "https://scontent-a.xx.fbcdn.net/hprofile-xpa1/v/t1.0-1/c0.0.50.50/p50x50/1229928_10152376737046658_8387683222153583301_n.jpg?oh=4c9cf110c2953f26e0c83bc644449730&oe=54B95BF9" + } + ] + }, + { + "name": "avatars", + "fql_result_set": [ + { + "id": 568851657, + "real_size": 320, + "size": 256, + "url": "https://scontent-a.xx.fbcdn.net/hprofile-xpa1/v/t1.0-1/c0.0.320.320/p320x320/1229928_10152376737046658_8387683222153583301_n.jpg?oh=9627591ac52d10005212abbae4c1f451&oe=54AD7B88" + } + ] + } + ] +} \ No newline at end of file From 7736439ab43da28c868e4bd2f64c8e3c8179c062 Mon Sep 17 00:00:00 2001 From: Ben Liyanage Date: Sat, 25 Oct 2014 15:53:10 -0700 Subject: [PATCH 13/15] did the fetch_contact function Did a little debug cleanup and some formating. Non of this has been tested yet. This function needs to be tested thoroughly. --- fbsync/fbsync.php | 28 ++++-- fbsync/object/Facebook_Graph21.php | 146 ++++++++++++++++++++++++++++- fbsync/tests/fbsync_test.php | 8 +- 3 files changed, 172 insertions(+), 10 deletions(-) diff --git a/fbsync/fbsync.php b/fbsync/fbsync.php index 470a2a12..1dda1c01 100644 --- a/fbsync/fbsync.php +++ b/fbsync/fbsync.php @@ -783,10 +783,26 @@ function fbsync_fetch_contact($uid, $contact, $create_user) { if(!count($r)) { // create contact record - q("INSERT INTO `contact` (`uid`, `created`, `url`, `nurl`, `addr`, `alias`, `notify`, `poll`, - `name`, `nick`, `photo`, `network`, `rel`, `priority`, - `writable`, `blocked`, `readonly`, `pending`) - VALUES (%d, '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', %d, %d, %d, 0, 0, 0)", + q("INSERT INTO `contact` ( + `uid`, + `created`, + `url`, + `nurl`, + `addr`, + `alias`, + `notify`, + `poll`, + `name`, + `nick`, + `photo`, + `network`, + `rel`, + `priority`, + `writable`, + `blocked`, + `readonly`, + `pending` + ) VALUES (%d, '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', %d, %d, %d, 0, 0, 0)", intval($uid), dbesc(datetime_convert()), dbesc($contact->url), @@ -1013,7 +1029,7 @@ function fbsync_fetchfeed($a, $uid, $self_id, $last_updated) { } $url = "https://graph.facebook.com/fql?q=".urlencode(json_encode($fql))."&access_token=".$access_token; - echo $url; + logger("fbsync_fetchfeed: query: $url",LOGGER_DEBUG); $feed = fetch_url($url); $data = json_decode($feed); @@ -1098,7 +1114,7 @@ function fbsync_processfeed($data, $self, $a, $uid, $self_id, $user, $last_updat $result = fbsync_createpost($a, $uid, $contacts, $applications, $post, $create_user); - echo $result; + //echo $result; } foreach ($comments AS $comment) { diff --git a/fbsync/object/Facebook_Graph21.php b/fbsync/object/Facebook_Graph21.php index bfd37c90..9a8cc043 100644 --- a/fbsync/object/Facebook_Graph21.php +++ b/fbsync/object/Facebook_Graph21.php @@ -6,6 +6,8 @@ Class Facebook_Graph21 extends Facebook { public $access_token;// = "test"; public $uid; + private $cachedContacts = array(); + public $graphBase = "https://graph.facebook.com/v2.1/"; function __construct($uid) { @@ -13,6 +15,142 @@ Class Facebook_Graph21 extends Facebook $this->access_token = get_pconfig($uid,'facebook','access_token'); } + function PictureURL($facebookID) + { + //Picture is always here. This url redirects to CDN. CDN images should not be used as they can move around. + //TODO: the Proxy URL that is being used to serve images is screwing up this URL + //TODO: Add this to make image sized correctly '&type=square&width=80&height=80' + return $this->graphBase . $post->from->id . '/picture'; + } + + //Every User Request must be processed individually. + //Facebook no longer allows you to request all of a users contacts. + function FetchContact($facebookID, $uid, $create_user) + { + /* + $facebookID - The facebook user to fetch + $uid - The user to associate the fetched facebook contact with. + $create_user - If the fetched user doesn't exist, create him as a contact. + */ + + $url = $graphBase . $facebookID . '/&access_token=' . $access_token; + $contact = fetch_url($url); + $contact = json_decode($contact); + $url = normalise_link($contact->link); + + // Check if the unique contact is existing + $r = q("SELECT id FROM unique_contacts WHERE url='%s' LIMIT 1", + dbesc($url)); + + if (count($r) == 0) + q("INSERT INTO unique_contacts (url, name, nick, avatar) VALUES ('%s', '%s', '%s', '%s')", + dbesc($url), + dbesc($contact->name), + dbesc($contact->username), + dbesc($this->PictureURL($contact->id))); + else + q("UPDATE unique_contacts SET name = '%s', nick = '%s', avatar = '%s' WHERE url = '%s'", + dbesc($contact->name), + dbesc($contact->username), + dbesc($this->PictureURL($contact-id)), + dbesc($url)); + + //TODO: uid is undefined + $r = q("SELECT * FROM `contact` WHERE `uid` = %d AND `alias` = '%s' LIMIT 1", + intval($uid), dbesc("facebook::".$contact->id)); + + if(!count($r) AND !$create_user) + return(0); + + if (count($r) AND ($r[0]["readonly"] OR $r[0]["blocked"])) { + logger("fbsync_fetch_contact: Contact '".$r[0]["nick"]."' is blocked or readonly.", LOGGER_DEBUG); + return(-1); + } + //This should probably happen always if the unique_contacts record is created. + if(!count($r)) + { + // create contact record if it doesn't exist + q(" INSERT INTO `contact` ( + `uid`, + `created`, + `alias`, + `poll`, + `network`, + `rel`, + `priority`, + `writable`, + `blocked`, + `readonly`, + `pending` + ) VALUES ( + %d, + '%s', + '%s' + 1, + 1, + 0, + 0, + 0 + )", + intval($uid), //uid + dbesc(datetime_convert()), //created + dbesc("facebook::".$contact->id), //alias + dbesc("facebook::".$contact->id), //poll + dbesc(NETWORK_FACEBOOK), //network + intval(CONTACT_IS_FRIEND) //rel + ); + + $r = q("SELECT * FROM `contact` WHERE `alias` = '%s' AND `uid` = %d LIMIT 1", + dbesc("facebook::".$contact->id), + intval($uid) + ); + } + + // update profile photos once every 12 hours as we have no notification of when they change. + //TODO: Probably need to test if avatar-date is null + $update_photo = ($r[0]['avatar-date'] < datetime_convert('','','now -12 hours')); + + // check that we have all the photos, this has been known to fail on occasion + if((! $r[0]['photo']) || (! $r[0]['thumb']) || (! $r[0]['micro']) || ($update_photo)) { + + logger("fbsync_fetch_contact: Updating contact ".$contact->username, LOGGER_DEBUG); + + require_once("Photo.php"); + + $photos = import_profile_photo($this->PictureURL($facebookID), $uid, $r[0]['id']); + + q("UPDATE `contact` SET `photo` = '%s', + `thumb` = '%s', + `micro` = '%s', + `name-date` = '%s', + `uri-date` = '%s', + `avatar-date` = '%s', + `url` = '%s', + `nurl` = '%s', + `addr` = '%s', + `name` = '%s', + `nick` = '%s', + `notify` = '%s' + WHERE `id` = %d", + dbesc($photos[0]), + dbesc($photos[1]), + dbesc($photos[2]), + dbesc(datetime_convert()), + dbesc(datetime_convert()), + dbesc(datetime_convert()), + dbesc($contact->url), + dbesc(normalise_link($contact->url)), + dbesc($contact->username."@facebook.com"), + dbesc($contact->name), + dbesc($contact->username), + dbesc($contact->id), + intval($r[0]['id']) + ); + } + + return($r[0]["id"]); + } + function CreatePost($a, $self, $contacts, $applications, $post, $create_user) { //Sanitize Inputs @@ -53,8 +191,8 @@ Class Facebook_Graph21 extends Facebook $postarray['author-name'] = $post->from->name; // $contacts[$post->actor_id]->name; $postarray['author-link'] = 'https://www.facebook.com/' . $post->from->id; //$contacts[$post->actor_id]->url; - //TODO: Pic not included in graph - //$postarray['author-avatar'] = $contacts[$post->actor_id]->pic_square; + + $postarray['author-avatar'] = $this->PictureURL($post->from->id); //TODO: Source not in in graph api. What was this before? Seemed like it was the same as the author with FQL //$postarray['owner-name'] = $contacts[$post->source_id]->name; @@ -64,7 +202,9 @@ Class Facebook_Graph21 extends Facebook //TODO: Parent Post Code //TODO: Set $postarray['contact-id'] = $contact_id; Should either be the actor_id or the source_id (not in graph?) - $postarray['contact-id'] = 1; + echo $post->from->id; + //TODO: From Needs to be added in order to be set for item? + $postarray['contact-id'] = 1; //$post->from->id; //Set Object Type //TODO: This code is broken. diff --git a/fbsync/tests/fbsync_test.php b/fbsync/tests/fbsync_test.php index da30e552..d2a5081e 100644 --- a/fbsync/tests/fbsync_test.php +++ b/fbsync/tests/fbsync_test.php @@ -29,7 +29,7 @@ $result = fbsync_processfeed($data, $self, $a, $uid, $self_id, $user, $last_upda if ($result != 0) die("FQL Processing broken.\n"); echo "Done with fql_data processing.\n"; - +//die(); //Test data processing -- graph` // Test Base Class @@ -64,6 +64,12 @@ if ($post['plink'] != "https://www.facebook.com/109524391244/posts/1015248318782 echo "All done\n"; /* + +Outstanding Questions: + + + + https://developers.facebook.com/tools/explorer SELECT action_links, actor_id, app_data, app_id, attachment, attribution, comment_info, created_time, filter_key, like_info, message, message_tags, parent_post_id, permalink, place, post_id, privacy, share_count, share_info, source_id, subscribed, tagged_ids, type, updated_time, with_tags FROM stream where filter_key ='nf' ORDER BY updated_time DESC LIMIT 5 From ff34f81a179500d7df8370075a73ac8febe939d8 Mon Sep 17 00:00:00 2001 From: Ben Liyanage Date: Mon, 27 Oct 2014 20:33:08 -0700 Subject: [PATCH 14/15] some formating and cleanup --- fbsync/fbsync.php | 7 +++++-- fbsync/object/Facebook_Graph21.php | 18 +++++++----------- 2 files changed, 12 insertions(+), 13 deletions(-) diff --git a/fbsync/fbsync.php b/fbsync/fbsync.php index 1dda1c01..979d211e 100644 --- a/fbsync/fbsync.php +++ b/fbsync/fbsync.php @@ -802,7 +802,7 @@ function fbsync_fetch_contact($uid, $contact, $create_user) { `blocked`, `readonly`, `pending` - ) VALUES (%d, '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', %d, %d, %d, 0, 0, 0)", + ) VALUES (%d, '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', %d, %d, %d, %d, %d, %d)", intval($uid), dbesc(datetime_convert()), dbesc($contact->url), @@ -817,7 +817,10 @@ function fbsync_fetch_contact($uid, $contact, $create_user) { dbesc(NETWORK_FACEBOOK), intval(CONTACT_IS_FRIEND), intval(1), - intval(1) + intval(1), + intval(0), + intval(0), + intval(0) ); $r = q("SELECT * FROM `contact` WHERE `alias` = '%s' AND `uid` = %d LIMIT 1", diff --git a/fbsync/object/Facebook_Graph21.php b/fbsync/object/Facebook_Graph21.php index 9a8cc043..759f532c 100644 --- a/fbsync/object/Facebook_Graph21.php +++ b/fbsync/object/Facebook_Graph21.php @@ -82,22 +82,18 @@ Class Facebook_Graph21 extends Facebook `blocked`, `readonly`, `pending` - ) VALUES ( - %d, - '%s', - '%s' - 1, - 1, - 0, - 0, - 0 - )", + ) VALUES ( %d, '%s', '%s', '%s', '%s', %d, %d, %d, %d, %d, %d)", intval($uid), //uid dbesc(datetime_convert()), //created dbesc("facebook::".$contact->id), //alias dbesc("facebook::".$contact->id), //poll dbesc(NETWORK_FACEBOOK), //network - intval(CONTACT_IS_FRIEND) //rel + intval(CONTACT_IS_FRIEND), //rel + intval(1), //priority + intval(1), //writable + intval(0), //blocked + intval(0), //readonly + intval(0) //pending ); $r = q("SELECT * FROM `contact` WHERE `alias` = '%s' AND `uid` = %d LIMIT 1", From ff022c813fa366759cacf32d4130a92b0d438409 Mon Sep 17 00:00:00 2001 From: Ben Liyanage Date: Tue, 28 Oct 2014 11:53:30 -0700 Subject: [PATCH 15/15] fixed uid, and contact lookup Contact picture caching is currently broken. Not sure why. Seems to not work for the existing fql code as well, so some troubleshooting may be needed with the vagrant setup of the machine. --- fbsync/object/Facebook_Graph21.php | 22 +++++++++++----------- fbsync/tests/fbsync_test.php | 8 +++++++- 2 files changed, 18 insertions(+), 12 deletions(-) diff --git a/fbsync/object/Facebook_Graph21.php b/fbsync/object/Facebook_Graph21.php index 759f532c..106012cc 100644 --- a/fbsync/object/Facebook_Graph21.php +++ b/fbsync/object/Facebook_Graph21.php @@ -25,15 +25,15 @@ Class Facebook_Graph21 extends Facebook //Every User Request must be processed individually. //Facebook no longer allows you to request all of a users contacts. - function FetchContact($facebookID, $uid, $create_user) + function FetchContact($facebookID, $create_user) { /* $facebookID - The facebook user to fetch - $uid - The user to associate the fetched facebook contact with. $create_user - If the fetched user doesn't exist, create him as a contact. */ - $url = $graphBase . $facebookID . '/&access_token=' . $access_token; + //TODO: check if the contact has been updated recently before making this hit. Not sure if this is possible. + $url = $this->graphBase . $facebookID . '?access_token=' . $this->access_token; $contact = fetch_url($url); $contact = json_decode($contact); $url = normalise_link($contact->link); @@ -55,9 +55,8 @@ Class Facebook_Graph21 extends Facebook dbesc($this->PictureURL($contact-id)), dbesc($url)); - //TODO: uid is undefined $r = q("SELECT * FROM `contact` WHERE `uid` = %d AND `alias` = '%s' LIMIT 1", - intval($uid), dbesc("facebook::".$contact->id)); + intval($this->uid), dbesc("facebook::".$contact->id)); if(!count($r) AND !$create_user) return(0); @@ -83,7 +82,7 @@ Class Facebook_Graph21 extends Facebook `readonly`, `pending` ) VALUES ( %d, '%s', '%s', '%s', '%s', %d, %d, %d, %d, %d, %d)", - intval($uid), //uid + intval($this->uid), //uid dbesc(datetime_convert()), //created dbesc("facebook::".$contact->id), //alias dbesc("facebook::".$contact->id), //poll @@ -98,7 +97,7 @@ Class Facebook_Graph21 extends Facebook $r = q("SELECT * FROM `contact` WHERE `alias` = '%s' AND `uid` = %d LIMIT 1", dbesc("facebook::".$contact->id), - intval($uid) + intval($this->uid) ); } @@ -113,9 +112,10 @@ Class Facebook_Graph21 extends Facebook require_once("Photo.php"); - $photos = import_profile_photo($this->PictureURL($facebookID), $uid, $r[0]['id']); + $photos = import_profile_photo($this->PictureURL($facebookID), $this->uid, $r[0]['id']); - q("UPDATE `contact` SET `photo` = '%s', + q("UPDATE `contact` SET + `photo` = '%s', `thumb` = '%s', `micro` = '%s', `name-date` = '%s', @@ -198,9 +198,9 @@ Class Facebook_Graph21 extends Facebook //TODO: Parent Post Code //TODO: Set $postarray['contact-id'] = $contact_id; Should either be the actor_id or the source_id (not in graph?) - echo $post->from->id; + //echo $post->from->id; //TODO: From Needs to be added in order to be set for item? - $postarray['contact-id'] = 1; //$post->from->id; + $postarray['contact-id'] = $this->FetchContact($post->from->id, $create_user); //Set Object Type //TODO: This code is broken. diff --git a/fbsync/tests/fbsync_test.php b/fbsync/tests/fbsync_test.php index d2a5081e..637c6543 100644 --- a/fbsync/tests/fbsync_test.php +++ b/fbsync/tests/fbsync_test.php @@ -46,8 +46,14 @@ if ($myFBSync->access_token == '') die("failed to load access_token"); //Test FetchContact //TODO: build tests for facebook api requests using API test user functions +$create_user = 1; +$facebookID = 109524391244; //BaltimoreNode +$id1 = $myFBSync->FetchContact($facebookID, $uid, $create_user); +//Re fetch the user, and make sure the id mataches +$id2 = $myFBSync->FetchContact($facebookID, $uid, $create_user); +if ($id1 != $id2) die("fetch contact did not work consistently"); -//Test CreatePost +//Test CreatePost in friendica $posts = json_decode(file_get_contents("./addon/fbsync/tests/graph2.1-no-filter.txt")); $post = $myFBSync->CreatePost($a,0,0,0,$posts->data[0],0);