Friendica Communications Platform (please note that this is a clone of the repository at github, issues are handled there) https://friendi.ca
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

748 lines
24 KiB

11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
  1. <?php
  2. /**
  3. * This module still needs a lot of work, but is functional today.
  4. * Please review this section if you upgrade because things will change.
  5. * If you have issues upgrading, remove facebook from the addon list,
  6. * view a page on your site, then add it back to the list. This will reset
  7. * all of the plugin 'hooks'.
  8. *
  9. * 1. register an API key for your site from developer.facebook.com
  10. * a. We'd be very happy if you include "Friendika" in the application name
  11. * to increase name recognition. The Friendika icons are also present
  12. * in the images directory and may be uploaded as a Facebook app icon.
  13. * Use images/ff-16.jpg for the Icon and images/ff-128.jpg for the Logo.
  14. * b. The url should be your site URL with a trailing slash.
  15. * You may use http://portal.friendika.com/privacy as the privacy policy
  16. * URL unless your site has different requirements, and
  17. * http://portal.friendika.com as the Terms of Service URL unless
  18. * you have different requirements. (Friendika is a software application
  19. * and does not require Terms of Service, though your installation of it might).
  20. * c. Set the following values in your .htconfig.php file
  21. * $a->config['facebook']['appid'] = 'xxxxxxxxxxx';
  22. * $a->config['facebook']['appsecret'] = 'xxxxxxxxxxxxxxx';
  23. * Replace with the settings Facebook gives you.
  24. * 2. Enable the facebook plugin by including it in .htconfig.php - e.g.
  25. * $a->config['system']['addon'] = 'plugin1,plugin2,facebook';
  26. * 3. Visit the Facebook Settings from "Settings->Plugin Settings" page.
  27. * and click 'Install Facebook Connector'.
  28. * 4. This will ask you to login to Facebook and grant permission to the
  29. * plugin to do its stuff. Allow it to do so.
  30. * 5. You're done. To turn it off visit your site's /facebook page again and
  31. * 'Remove Facebook posting'.
  32. *
  33. * Turn logging on (see the github Friendika wiki page 'Settings') and
  34. * repeat these steps if you have trouble.
  35. * Vidoes and embeds will not be posted if there is no other content. Links
  36. * and images will be converted to text and long posts truncated - with a link
  37. * to view the full post. Posts with permission settings and comments will
  38. * not be posted to Facebook.
  39. *
  40. */
  41. define('FACEBOOK_MAXPOSTLEN', 420);
  42. /* declare the facebook_module function so that /facebook url requests will land here */
  43. function facebook_module() {}
  44. /* If a->argv[1] is a nickname, this is a callback from Facebook oauth requests. */
  45. function facebook_init(&$a) {
  46. if($a->argc != 2)
  47. return;
  48. $nick = $a->argv[1];
  49. if(strlen($nick))
  50. $r = q("SELECT `uid` FROM `user` WHERE `nickname` = '%s' LIMIT 1",
  51. dbesc($nick)
  52. );
  53. if(! count($r))
  54. return;
  55. $uid = $r[0]['uid'];
  56. $auth_code = (($_GET['code']) ? $_GET['code'] : '');
  57. $error = (($_GET['error_description']) ? $_GET['error_description'] : '');
  58. if($error)
  59. logger('facebook_init: Error: ' . $error);
  60. if($auth_code && $uid) {
  61. $appid = get_config('facebook','appid');
  62. $appsecret = get_config('facebook', 'appsecret');
  63. $x = fetch_url('https://graph.facebook.com/oauth/access_token?client_id='
  64. . $appid . '&client_secret=' . $appsecret . '&redirect_uri='
  65. . urlencode($a->get_baseurl() . '/facebook/' . $nick)
  66. . '&code=' . $auth_code);
  67. logger('facebook_init: returned access token: ' . $x, LOGGER_DATA);
  68. if(strpos($x,'access_token=') !== false) {
  69. $token = str_replace('access_token=', '', $x);
  70. if(strpos($token,'&') !== false)
  71. $token = substr($token,0,strpos($token,'&'));
  72. set_pconfig($uid,'facebook','access_token',$token);
  73. set_pconfig($uid,'facebook','post','1');
  74. fb_get_self($uid);
  75. fb_get_friends($uid);
  76. fb_consume_all($uid);
  77. }
  78. // todo: is this a browser session or a server session? where do we go?
  79. }
  80. }
  81. function fb_get_self($uid) {
  82. $access_token = get_pconfig($uid,'facebook','access_token');
  83. if(! $access_token)
  84. return;
  85. $s = fetch_url('https://graph.facebook.com/me/?access_token=' . $access_token);
  86. if($s) {
  87. $j = json_decode($s);
  88. set_pconfig($uid,'facebook','self_id',(string) $j->id);
  89. }
  90. }
  91. function fb_get_friends($uid) {
  92. $access_token = get_pconfig($uid,'facebook','access_token');
  93. if(! $access_token)
  94. return;
  95. $s = fetch_url('https://graph.facebook.com/me/friends?access_token=' . $access_token);
  96. if($s) {
  97. logger('facebook: fb_get_friends: ' . $s);
  98. $j = json_decode($s);
  99. logger('facebook: fb_get_friends: json: ' . print_r($j,true), LOGGER_DATA);
  100. foreach($j->data as $person) {
  101. $s = fetch_url('https://graph.facebook.com/' . $person->id . '?access_token=' . $access_token);
  102. if($s) {
  103. $jp = json_decode($s);
  104. logger('fb_get_friends: info: ' . print_r($jp,true), LOGGER_DATA);
  105. // always use numeric link for consistency
  106. $jp->link = 'http://facebook.com/profile.php?id=' . $person->id;
  107. // check if we already have a contact
  108. $r = q("SELECT * FROM `contact` WHERE `uid` = %d AND `url` = '%s' LIMIT 1",
  109. intval($uid),
  110. dbesc($jp->link)
  111. );
  112. if(count($r)) {
  113. continue;
  114. }
  115. else {
  116. // create contact record
  117. $r = q("INSERT INTO `contact` ( `uid`, `created`, `url`, `addr`, `alias`, `notify`, `poll`,
  118. `name`, `nick`, `photo`, `network`, `rel`, `priority`,
  119. `writable`, `blocked`, `readonly`, `pending` )
  120. VALUES ( %d, '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', %d, %d, %d, 0, 0, 0 ) ",
  121. intval($uid),
  122. dbesc(datetime_convert()),
  123. dbesc($jp->link),
  124. dbesc(''),
  125. dbesc(''),
  126. dbesc($jp->id),
  127. dbesc('facebook ' . $jp->id),
  128. dbesc($jp->name),
  129. dbesc(($jp->nickname) ? $jp->nickname : strtolower($jp->first_name)),
  130. dbesc('https://graph.facebook.com/' . $jp->id . '/picture'),
  131. dbesc(NETWORK_FACEBOOK),
  132. intval(REL_BUD),
  133. intval(1),
  134. intval(1)
  135. );
  136. }
  137. $r = q("SELECT * FROM `contact` WHERE `url` = '%s' AND `uid` = %d LIMIT 1",
  138. dbesc($jp->link),
  139. intval($uid)
  140. );
  141. if(! count($r)) {
  142. continue;
  143. }
  144. $contact = $r[0];
  145. $contact_id = $r[0]['id'];
  146. require_once("Photo.php");
  147. $photos = import_profile_photo($r[0]['photo'],$uid,$contact_id);
  148. $r = q("UPDATE `contact` SET `photo` = '%s',
  149. `thumb` = '%s',
  150. `micro` = '%s',
  151. `name-date` = '%s',
  152. `uri-date` = '%s',
  153. `avatar-date` = '%s'
  154. WHERE `id` = %d LIMIT 1
  155. ",
  156. dbesc($photos[0]),
  157. dbesc($photos[1]),
  158. dbesc($photos[2]),
  159. dbesc(datetime_convert()),
  160. dbesc(datetime_convert()),
  161. dbesc(datetime_convert()),
  162. intval($contact_id)
  163. );
  164. }
  165. }
  166. }
  167. }
  168. function facebook_post(&$a) {
  169. if(local_user()){
  170. $value = ((x($_POST,'post_by_default')) ? intval($_POST['post_by_default']) : 0);
  171. set_pconfig(local_user(),'facebook','post_by_default', $value);
  172. }
  173. return;
  174. }
  175. function facebook_content(&$a) {
  176. if(! local_user()) {
  177. notice( t('Permission denied.') . EOL);
  178. return '';
  179. }
  180. if($a->argc > 1 && $a->argv[1] === 'remove') {
  181. del_pconfig(local_user(),'facebook','post');
  182. notice( t('Facebook disabled') . EOL);
  183. }
  184. if($a->argc > 1 && $a->argv[1] === 'friends') {
  185. fb_get_friends(local_user());
  186. notice( t('Updating contacts') . EOL);
  187. }
  188. $fb_installed = get_pconfig(local_user(),'facebook','post');
  189. $appid = get_config('facebook','appid');
  190. if(! $appid) {
  191. notice( t('Facebook API key is missing.') . EOL);
  192. return '';
  193. }
  194. $a->page['htmlhead'] .= '<link rel="stylesheet" type="text/css" href="'
  195. . $a->get_baseurl() . '/addon/facebook/facebook.css' . '" media="all" />' . "\r\n";
  196. $o .= '<h3>' . t('Facebook Connect') . '</h3>';
  197. if(! $fb_installed) {
  198. $o .= '<div id="facebook-enable-wrapper">';
  199. $o .= '<a href="https://www.facebook.com/dialog/oauth?client_id=' . $appid . '&redirect_uri='
  200. . $a->get_baseurl() . '/facebook/' . $a->user['nickname'] . '&scope=publish_stream,read_stream,offline_access">' . t('Install Facebook connector for this account.') . '</a>';
  201. $o .= '</div>';
  202. }
  203. if($fb_installed) {
  204. $o .= '<div id="facebook-disable-wrapper">';
  205. $o .= '<a href="' . $a->get_baseurl() . '/facebook/remove' . '">' . t('Remove Facebook connector') . '</a></div>';
  206. $o .= '<div id="facebook-post-default-form">';
  207. $o .= '<form action="facebook" method="post" >';
  208. $post_by_default = get_pconfig(local_user(),'facebook','post_by_default');
  209. $checked = (($post_by_default) ? ' checked="checked" ' : '');
  210. $o .= '<input type="checkbox" name="post_by_default" value="1"' . $checked . '/>' . ' ' . t('Post to Facebook by default') . '<br />';
  211. $o .= '<input type="submit" name="submit" value="' . t('Submit') . '" /></form></div>';
  212. }
  213. return $o;
  214. }
  215. function facebook_install() {
  216. register_hook('post_local_end', 'addon/facebook/facebook.php', 'facebook_post_hook');
  217. register_hook('jot_networks', 'addon/facebook/facebook.php', 'facebook_jot_nets');
  218. register_hook('plugin_settings', 'addon/facebook/facebook.php', 'facebook_plugin_settings');
  219. register_hook('cron', 'addon/facebook/facebook.php', 'facebook_cron');
  220. }
  221. function facebook_uninstall() {
  222. unregister_hook('post_local_end', 'addon/facebook/facebook.php', 'facebook_post_hook');
  223. unregister_hook('jot_networks', 'addon/facebook/facebook.php', 'facebook_jot_nets');
  224. unregister_hook('plugin_settings', 'addon/facebook/facebook.php', 'facebook_plugin_settings');
  225. unregister_hook('cron', 'addon/facebook/facebook.php', 'facebook_cron');
  226. }
  227. function facebook_cron($a,$b) {
  228. $last = get_config('facebook','last_poll');
  229. if($last) {
  230. $next = $last + 3600;
  231. if($next > time())
  232. return;
  233. }
  234. logger('facebook_cron');
  235. set_config('facebook','last_poll', time());
  236. $r = q("SELECT * FROM `pconfig` WHERE `cat` = 'facebook' AND `k` = 'post' AND `v` = '1' ");
  237. if(count($r)) {
  238. foreach($r as $rr) {
  239. // check for new friends once a day
  240. $last_friend_check = get_pconfig($rr['uid'],'facebook','friend_check');
  241. if($last_friend_check)
  242. $next_friend_check = $last_friend_check + 86400;
  243. if($next_friend_check <= time()) {
  244. fb_get_friends($rr['uid']);
  245. set_pconfig($rr['uid'],'facebook','friend_check',time());
  246. }
  247. fb_consume_all($rr['uid']);
  248. }
  249. }
  250. }
  251. function facebook_plugin_settings(&$a,&$b) {
  252. $b .= '<div class="settings-block">';
  253. $b .= '<h3>' . t('Facebook') . '</h3>';
  254. $b .= '<a href="facebook">' . t('Facebook Connector Settings') . '</a><br />';
  255. $b .= '</div>';
  256. }
  257. function facebook_jot_nets(&$a,&$b) {
  258. if(! local_user())
  259. return;
  260. $fb_post = get_pconfig(local_user(),'facebook','post');
  261. if(intval($fb_post) == 1) {
  262. $fb_defpost = get_pconfig(local_user(),'facebook','post_by_default');
  263. $selected = ((intval($fb_defpost) == 1) ? ' checked="checked" ' : '');
  264. $b .= '<div class="profile-jot-net"><input type="checkbox" name="facebook_enable"' . $selected . 'value="1" /> '
  265. . t('Post to Facebook') . '</div>';
  266. }
  267. }
  268. function facebook_post_hook(&$a,&$b) {
  269. /**
  270. * Post to Facebook stream
  271. */
  272. require_once('include/group.php');
  273. logger('Facebook post');
  274. $reply = false;
  275. $likes = false;
  276. if((local_user()) && (local_user() == $b['uid'])) {
  277. if($b['parent']) {
  278. $r = q("SELECT * FROM `item` WHERE `id` = %d AND `uid` = %d LIMIT 1",
  279. intval($b['parent']),
  280. intval(local_user())
  281. );
  282. if(count($r) && substr($r[0]['uri'],0,4) === 'fb::')
  283. $reply = substr($r[0]['uri'],4);
  284. else
  285. return;
  286. logger('facebook reply id=' . $reply);
  287. }
  288. if($b['private'] && $reply == false) {
  289. $allow_people = expand_acl($b['allow_cid']);
  290. $allow_groups = expand_groups(expand_acl($b['allow_gid']));
  291. $deny_people = expand_acl($b['deny_cid']);
  292. $deny_groups = expand_groups(expand_acl($b['deny_gid']));
  293. $recipients = array_unique(array_merge($allow_people,$allow_groups));
  294. $deny = array_unique(array_merge($deny_people,$deny_groups));
  295. $allow_str = dbesc(implode(', ',$recipients));
  296. $r = q("SELECT `notify` FROM `contact` WHERE `id` IN ( $allow_str ) AND `network` = 'face'");
  297. $allow_arr = array();
  298. if(count($r))
  299. foreach($r as $rr)
  300. $allow_arr[] = $rr['notify'];
  301. $deny_str = dbesc(implode(', ',$deny));
  302. $r = q("SELECT `notify` FROM `contact` WHERE `id` IN ( $deny_str ) AND `network` = 'face'");
  303. $deny_arr = array();
  304. if(count($r))
  305. foreach($r as $rr)
  306. $deny_arr[] = $rr['notify'];
  307. if(count($deny_arr) && (! count($allow_arr))) {
  308. // One or more FB folks were denied access but nobody on FB was specifically allowed access.
  309. // This might cause the post to be open to public on Facebook, but only to selected members
  310. // on another network. Since this could potentially leak a post to somebody who was denied,
  311. // we will skip posting it to Facebook with a slightly vague but relevant message that will
  312. // hopefully lead somebody to this code comment for a better explanation of what went wrong.
  313. notice( t('Post to Facebook cancelled because of multi-network access permission conflict.') . EOL);
  314. return;
  315. }
  316. // if it's a private message but no Facebook members are allowed or denied, skip Facebook post
  317. if((! count($allow_arr)) && (! count($deny_arr)))
  318. return;
  319. }
  320. if($b['verb'] == ACTIVITY_LIKE)
  321. $likes = true;
  322. $appid = get_config('facebook', 'appid' );
  323. $secret = get_config('facebook', 'appsecret' );
  324. if($appid && $secret) {
  325. logger('facebook: have appid+secret');
  326. $fb_post = intval(get_pconfig(local_user(),'facebook','post'));
  327. $fb_enable = (($fb_post && x($_POST,'facebook_enable')) ? intval($_POST['facebook_enable']) : 0);
  328. $fb_token = get_pconfig(local_user(),'facebook','access_token');
  329. logger('facebook: $fb_post: ' . $fb_post . ' $fb_enable: ' . $fb_enable . ' $fb_token: ' . $fb_token,LOGGER_DEBUG);
  330. // post to facebook if it's a public post and we've ticked the 'post to Facebook' box,
  331. // or it's a private message with facebook participants
  332. // or it's a reply or likes action to an existing facebook post
  333. if($fb_post && $fb_token && ($fb_enable || $b['private'] || $reply)) {
  334. logger('facebook: able to post');
  335. require_once('library/facebook.php');
  336. require_once('include/bbcode.php');
  337. $msg = $b['body'];
  338. logger('Facebook post: original msg=' . $msg, LOGGER_DATA);
  339. // make links readable before we strip the code
  340. $msg = preg_replace("/\[url=(.+?)\](.+?)\[\/url\]/is",'$2 $1',$msg);
  341. $msg = preg_replace("/\[img\](.+?)\[\/img\]/is", t('Image: ') . '$1',$msg);
  342. $msg = trim(strip_tags(bbcode($msg)));
  343. $msg = html_entity_decode($msg,ENT_QUOTES,'UTF-8');
  344. if (strlen($msg) > FACEBOOK_MAXPOSTLEN) {
  345. $shortlink = "";
  346. require_once('library/slinky.php');
  347. $display_url = $a->get_baseurl() . '/display/' . $a->user['nickname'] . '/' . $b['id'];
  348. $slinky = new Slinky( $display_url );
  349. // setup a cascade of shortening services
  350. // try to get a short link from these services
  351. // in the order ur1.ca, trim, id.gd, tinyurl
  352. $slinky->set_cascade( array( new Slinky_UR1ca(), new Slinky_Trim(), new Slinky_IsGd(), new Slinky_TinyURL() ) );
  353. $shortlink = $slinky->short();
  354. // the new message will be shortened such that "... $shortlink"
  355. // will fit into the character limit
  356. $msg = substr($msg, 0, FACEBOOK_MAXPOSTLEN - strlen($shortlink) - 4);
  357. $msg .= '... ' . $shortlink;
  358. }
  359. if(! strlen($msg))
  360. return;
  361. logger('Facebook post: msg=' . $msg, LOGGER_DATA);
  362. if($likes) {
  363. $postvars = array('access_token' => $fb_token);
  364. }
  365. else {
  366. $postvars = array(
  367. 'access_token' => $fb_token,
  368. 'message' => $msg
  369. );
  370. }
  371. if(($b['private']) && (! $b['parent'])) {
  372. $postvars['privacy'] = '{"value": "CUSTOM", "friends": "SOME_FRIENDS"';
  373. if(count($allow_arr))
  374. $postvars['privacy'] .= ',"allow": "' . implode(',',$allow_arr) . '"';
  375. if(count($deny_arr))
  376. $postvars['privacy'] .= ',"deny": "' . implode(',',$deny_arr) . '"';
  377. $postvars['privacy'] .= '}';
  378. }
  379. if(! $reply) {
  380. if($b['plink'])
  381. $postvars['actions'] = '{"name": "' . t('View on Friendika') . '", "link": "' . $b['plink'] . '"}';
  382. }
  383. if($reply) {
  384. $url = 'https://graph.facebook.com/' . $reply . '/' . (($likes) ? 'likes' : 'comments');
  385. }
  386. else {
  387. $url = 'https://graph.facebook.com/me/feed';
  388. }
  389. logger('facebook: post to ' . $url);
  390. logger('facebook: postvars: ' . print_r($postvars,true));
  391. $x = post_url($url, $postvars);
  392. $retj = json_decode($x);
  393. if($retj->id) {
  394. q("UPDATE `item` SET `extid` = '%s' WHERE `id` = %d LIMIT 1",
  395. dbesc('fb::' . $retj->id),
  396. intval($b['id'])
  397. );
  398. }
  399. logger('Facebook post returns: ' . $x, LOGGER_DEBUG);
  400. }
  401. }
  402. }
  403. }
  404. function fb_consume_all($uid) {
  405. require_once('include/items.php');
  406. $access_token = get_pconfig($uid,'facebook','access_token');
  407. if(! $access_token)
  408. return;
  409. $s = fetch_url('https://graph.facebook.com/me/feed?access_token=' . $access_token);
  410. if($s) {
  411. $j = json_decode($s);
  412. logger('fb_consume_stream: wall: ' . print_r($j,true), LOGGER_DATA);
  413. fb_consume_stream($uid,$j,true);
  414. }
  415. $s = fetch_url('https://graph.facebook.com/me/home?access_token=' . $access_token);
  416. if($s) {
  417. $j = json_decode($s);
  418. logger('fb_consume_stream: feed: ' . print_r($j,true), LOGGER_DATA);
  419. fb_consume_stream($uid,$j,false);
  420. }
  421. }
  422. function fb_consume_stream($uid,$j,$wall = false) {
  423. $a = get_app();
  424. $self = q("SELECT * FROM `contact` WHERE `self` = 1 AND `uid` = %d LIMIT 1",
  425. intval($uid)
  426. );
  427. $user = q("SELECT `nickname` FROM `user` WHERE `uid` = %d LIMIT 1",
  428. intval($uid)
  429. );
  430. if(count($user))
  431. $my_local_url = $a->get_baseurl() . '/profile/' . $user[0]['nickname'];
  432. $self_id = get_pconfig($uid,'facebook','self_id');
  433. if(! count($j->data) || (! strlen($self_id)))
  434. return;
  435. foreach($j->data as $entry) {
  436. logger('fb_consume: entry: ' . print_r($entry,true), LOGGER_DATA);
  437. $datarray = array();
  438. $we_posted = false;
  439. $app = $entry->application;
  440. if($app->id == get_config('facebook','appid') && $wall)
  441. $we_posted = true;
  442. $r = q("SELECT * FROM `item` WHERE ( `uri` = '%s' OR `extid` = '%s') AND `uid` = %d LIMIT 1",
  443. dbesc('fb::' . $entry->id),
  444. dbesc('fb::' . $entry->id),
  445. intval($uid)
  446. );
  447. if(count($r)) {
  448. $post_exists = true;
  449. $orig_post = $r[0];
  450. $top_item = $r[0]['id'];
  451. }
  452. else {
  453. $post_exists = false;
  454. $orig_post = null;
  455. }
  456. if(! $orig_post) {
  457. $datarray['gravity'] = 0;
  458. $datarray['uid'] = $uid;
  459. $datarray['wall'] = (($wall) ? 1 : 0);
  460. $datarray['uri'] = $datarray['parent-uri'] = 'fb::' . $entry->id;
  461. $from = $entry->from;
  462. if($from->id == $self_id)
  463. $datarray['contact-id'] = $self[0]['id'];
  464. else {
  465. $r = q("SELECT * FROM `contact` WHERE `notify` = '%s' AND `uid` = %d AND `blocked` = 0 AND `readonly` = 0 LIMIT 1",
  466. dbesc($from->id),
  467. intval($uid)
  468. );
  469. if(count($r))
  470. $datarray['contact-id'] = $r[0]['id'];
  471. }
  472. // don't store post if we don't have a contact
  473. if(! x($datarray,'contact-id'))
  474. continue;
  475. $datarray['verb'] = ACTIVITY_POST;
  476. if($wall) {
  477. $datarray['owner-name'] = $self[0]['name'];
  478. $datarray['owner-link'] = $self[0]['url'];
  479. $datarray['owner-avatar'] = $self[0]['thumb'];
  480. }
  481. $datarray['author-name'] = $from->name;
  482. $datarray['author-link'] = 'http://facebook.com/profile.php?id=' . $from->id;
  483. $datarray['author-avatar'] = 'https://graph.facebook.com/' . $from->id . '/picture';
  484. $datarray['plink'] = $datarray['author-link'] . '&v=wall&story_fbid=' . substr($entry->id,strpos($entry->id,'_') + 1);
  485. $datarray['body'] = $entry->message;
  486. if($entry->picture)
  487. $datarray['body'] .= "\n\n" . '[img]' . $entry->picture . '[/img]';
  488. if($entry->link)
  489. $datarray['body'] .= "\n" . linkify($entry->link);
  490. if($entry->name)
  491. $datarray['body'] .= "\n" . $entry->name;
  492. if($entry->caption)
  493. $datarray['body'] .= "\n" . $entry->caption;
  494. if($entry->description)
  495. $datarray['body'] .= "\n" . $entry->description;
  496. $datarray['created'] = datetime_convert('UTC','UTC',$entry->created_time);
  497. $datarray['edited'] = datetime_convert('UTC','UTC',$entry->updated_time);
  498. if($entry->privacy && $entry->privacy->value !== 'EVERYONE')
  499. $datarray['private'] = 1;
  500. $top_item = item_store($datarray);
  501. $r = q("SELECT * FROM `item` WHERE `id` = %d AND `uid` = %d LIMIT 1",
  502. intval($top_item),
  503. intval($uid)
  504. );
  505. if(count($r))
  506. $orig_post = $r[0];
  507. }
  508. $likers = $entry->likes->data;
  509. $comments = $entry->comments->data;
  510. if(is_array($likers)) {
  511. foreach($likers as $likes) {
  512. $r = q("SELECT * FROM `item` WHERE `parent-uri` = '%s' AND `uid` = %d AND `verb` = '%s' AND `author-link` = '%s'
  513. LIMIT 1",
  514. dbesc('fb::' . $entry->id),
  515. intval($uid),
  516. dbesc(ACTIVITY_LIKE),
  517. dbesc('http://facebook.com/profile.php?id=' . $likes->id)
  518. );
  519. if(count($r))
  520. continue;
  521. $likedata = array();
  522. $likedata['parent'] = $top_item;
  523. $likedata['verb'] = ACTIVITY_LIKE;
  524. $likedata['gravity'] = 3;
  525. $likedata['uid'] = $uid;
  526. $likedata['wall'] = (($wall) ? 1 : 0);
  527. $likedata['uri'] = item_new_uri($a->get_baseurl(), $uid);
  528. $likedata['parent-uri'] = 'fb::' . $entry->id;
  529. if($likes->id == $self_id)
  530. $likedata['contact-id'] = $self[0]['id'];
  531. else {
  532. $r = q("SELECT * FROM `contact` WHERE `notify` = '%s' AND `uid` = %d AND `blocked` = 0 AND `readonly` = 0 LIMIT 1",
  533. dbesc($likes->id),
  534. intval($uid)
  535. );
  536. if(count($r))
  537. $likedata['contact-id'] = $r[0]['id'];
  538. }
  539. if(! x($likedata,'contact-id'))
  540. $likedata['contact-id'] = $orig_post['contact-id'];
  541. $likedata['verb'] = ACTIVITY_LIKE;
  542. $likedata['author-name'] = $likes->name;
  543. $likedata['author-link'] = 'http://facebook.com/profile.php?id=' . $likes->id;
  544. $likedata['author-avatar'] = 'https://graph.facebook.com/' . $likes->id . '/picture';
  545. $author = '[url=' . $likedata['author-link'] . ']' . $likedata['author-name'] . '[/url]';
  546. $objauthor = '[url=' . $orig_post['author-link'] . ']' . $orig_post['author-name'] . '[/url]';
  547. $post_type = t('status');
  548. $plink = '[url=' . $orig_post['plink'] . ']' . $post_type . '[/url]';
  549. $likedata['object-type'] = ACTIVITY_OBJ_NOTE;
  550. $likedata['body'] = sprintf( t('%1$s likes %2$s\'s %3$s'), $author, $objauthor, $plink);
  551. $likedata['object'] = '<object><type>' . ACTIVITY_OBJ_NOTE . '</type><local>1</local>' .
  552. '<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>';
  553. $item = item_store($likedata);
  554. }
  555. }
  556. if(is_array($comments)) {
  557. foreach($comments as $cmnt) {
  558. $r = q("SELECT * FROM `item` WHERE `uid` = %d AND ( `uri` = '%s' OR `extid` = '%s' ) LIMIT 1",
  559. intval($uid),
  560. dbesc('fb::' . $cmnt->id),
  561. dbesc('fb::' . $cmnt->id)
  562. );
  563. if(count($r))
  564. continue;
  565. $cmntdata = array();
  566. $cmntdata['parent'] = $top_item;
  567. $cmntdata['verb'] = ACTIVITY_POST;
  568. $cmntdata['gravity'] = 6;
  569. $cmntdata['uid'] = $uid;
  570. $cmntdata['wall'] = (($wall) ? 1 : 0);
  571. $cmntdata['uri'] = 'fb::' . $cmnt->id;
  572. $cmntdata['parent-uri'] = 'fb::' . $entry->id;
  573. if($cmnt->from->id == $self_id) {
  574. $cmntdata['contact-id'] = $self[0]['id'];
  575. }
  576. elseif(is_array($orig_post) && (x($orig_post,'contact-id')))
  577. $cmntdata['contact-id'] = $orig_post['contact-id'];
  578. else {
  579. $r = q("SELECT * FROM `contact` WHERE `notify` = '%s' AND `uid` = %d AND `blocked` = 0 AND `readonly` = 0 LIMIT 1",
  580. dbesc($cmnt->from->id),
  581. intval($uid)
  582. );
  583. if(count($r))
  584. $cmntdata['contact-id'] = $r[0]['id'];
  585. }
  586. if(! x($cmntdata,'contact-id'))
  587. return;
  588. $cmntdata['created'] = datetime_convert('UTC','UTC',$cmnt->created_time);
  589. $cmntdata['edited'] = datetime_convert('UTC','UTC',$cmnt->created_time);
  590. $cmntdata['verb'] = ACTIVITY_POST;
  591. $cmntdata['author-name'] = $cmnt->from->name;
  592. $cmntdata['author-link'] = 'http://facebook.com/profile.php?id=' . $cmnt->from->id;
  593. $cmntdata['author-avatar'] = 'https://graph.facebook.com/' . $cmnt->from->id . '/picture';
  594. $cmntdata['body'] = $cmnt->message;
  595. $item = item_store($cmntdata);
  596. }
  597. }
  598. }
  599. }