2010-12-28 08:28:34 +01:00
< ? php
2010-12-28 08:36:19 +01:00
/**
2011-05-12 13:51:54 +02:00
* Installing the Friendika / Facebook connector
2010-12-28 08:36:19 +01:00
*
2011-02-24 01:39:21 +01:00
* 1. register an API key for your site from developer . facebook . com
2011-02-11 08:10:50 +01:00
* a . We ' d be very happy if you include " Friendika " in the application name
2011-02-24 01:39:21 +01:00
* to increase name recognition . The Friendika icons are also present
* in the images directory and may be uploaded as a Facebook app icon .
2011-05-12 13:51:54 +02:00
* Use images / friendika - 16. jpg for the Icon and images / friendika - 128. jpg for the Logo .
2011-02-24 01:39:21 +01:00
* b . The url should be your site URL with a trailing slash .
* You may use http :// portal . friendika . com / privacy as the privacy policy
* URL unless your site has different requirements , and
* http :// portal . friendika . com as the Terms of Service URL unless
* you have different requirements . ( Friendika is a software application
* and does not require Terms of Service , though your installation of it might ) .
2011-02-11 08:10:50 +01:00
* c . Set the following values in your . htconfig . php file
* $a -> config [ 'facebook' ][ 'appid' ] = 'xxxxxxxxxxx' ;
* $a -> config [ 'facebook' ][ 'appsecret' ] = 'xxxxxxxxxxxxxxx' ;
* Replace with the settings Facebook gives you .
* 2. Enable the facebook plugin by including it in . htconfig . php - e . g .
* $a -> config [ 'system' ][ 'addon' ] = 'plugin1,plugin2,facebook' ;
2011-05-12 13:51:54 +02:00
* 3. Visit the Facebook Settings section of the " Settings->Plugin Settings " page .
2011-04-27 13:24:00 +02:00
* and click 'Install Facebook Connector' .
2011-02-11 08:10:50 +01:00
* 4. This will ask you to login to Facebook and grant permission to the
* plugin to do its stuff . Allow it to do so .
2011-05-12 13:51:54 +02:00
* 5. You ' re done . To turn it off visit the Plugin Settings page again and
2011-02-11 08:10:50 +01:00
* 'Remove Facebook posting' .
*
* Vidoes and embeds will not be posted if there is no other content . Links
2011-05-12 13:51:54 +02:00
* and images will be converted to a format suitable for the Facebook API and
* long posts truncated - with a link to view the full post .
2010-12-28 08:36:19 +01:00
*
2011-05-12 13:51:54 +02:00
* Facebook contacts will not be able to view private photos , as they are not able to
* authenticate to your site to establish identity . We will address this
* in a future release .
2010-12-28 08:36:19 +01:00
*/
2011-02-11 03:01:38 +01:00
define ( 'FACEBOOK_MAXPOSTLEN' , 420 );
/* declare the facebook_module function so that /facebook url requests will land here */
function facebook_module () {}
2011-02-11 06:25:24 +01:00
/* If a->argv[1] is a nickname, this is a callback from Facebook oauth requests. */
2011-02-11 03:01:38 +01:00
function facebook_init ( & $a ) {
if ( $a -> argc != 2 )
return ;
$nick = $a -> argv [ 1 ];
if ( strlen ( $nick ))
$r = q ( " SELECT `uid` FROM `user` WHERE `nickname` = '%s' LIMIT 1 " ,
dbesc ( $nick )
);
if ( ! count ( $r ))
return ;
$uid = $r [ 0 ][ 'uid' ];
$auth_code = (( $_GET [ 'code' ]) ? $_GET [ 'code' ] : '' );
$error = (( $_GET [ 'error_description' ]) ? $_GET [ 'error_description' ] : '' );
2011-02-11 06:25:24 +01:00
if ( $error )
logger ( 'facebook_init: Error: ' . $error );
2011-02-11 03:01:38 +01:00
if ( $auth_code && $uid ) {
$appid = get_config ( 'facebook' , 'appid' );
$appsecret = get_config ( 'facebook' , 'appsecret' );
$x = fetch_url ( 'https://graph.facebook.com/oauth/access_token?client_id='
. $appid . '&client_secret=' . $appsecret . '&redirect_uri='
. urlencode ( $a -> get_baseurl () . '/facebook/' . $nick )
. '&code=' . $auth_code );
2011-02-11 06:25:24 +01:00
logger ( 'facebook_init: returned access token: ' . $x , LOGGER_DATA );
2011-02-11 03:01:38 +01:00
if ( strpos ( $x , 'access_token=' ) !== false ) {
$token = str_replace ( 'access_token=' , '' , $x );
if ( strpos ( $token , '&' ) !== false )
2011-02-11 06:25:24 +01:00
$token = substr ( $token , 0 , strpos ( $token , '&' ));
2011-02-11 03:01:38 +01:00
set_pconfig ( $uid , 'facebook' , 'access_token' , $token );
2011-02-11 11:35:19 +01:00
set_pconfig ( $uid , 'facebook' , 'post' , '1' );
2011-04-25 15:22:45 +02:00
fb_get_self ( $uid );
fb_get_friends ( $uid );
fb_consume_all ( $uid );
2011-02-11 03:01:38 +01:00
}
// todo: is this a browser session or a server session? where do we go?
}
}
2011-04-25 15:22:45 +02:00
function fb_get_self ( $uid ) {
$access_token = get_pconfig ( $uid , 'facebook' , 'access_token' );
if ( ! $access_token )
return ;
$s = fetch_url ( 'https://graph.facebook.com/me/?access_token=' . $access_token );
if ( $s ) {
$j = json_decode ( $s );
set_pconfig ( $uid , 'facebook' , 'self_id' ,( string ) $j -> id );
}
}
function fb_get_friends ( $uid ) {
$access_token = get_pconfig ( $uid , 'facebook' , 'access_token' );
2011-05-30 05:36:45 +02:00
$no_linking = get_pconfig ( $uid , 'facebook' , 'no_linking' );
if ( $no_linking )
return ;
2011-04-25 15:22:45 +02:00
if ( ! $access_token )
return ;
$s = fetch_url ( 'https://graph.facebook.com/me/friends?access_token=' . $access_token );
if ( $s ) {
2011-05-10 01:51:25 +02:00
logger ( 'facebook: fb_get_friends: ' . $s , LOGGER_DATA );
2011-04-25 15:22:45 +02:00
$j = json_decode ( $s );
2011-04-26 14:57:53 +02:00
logger ( 'facebook: fb_get_friends: json: ' . print_r ( $j , true ), LOGGER_DATA );
2011-04-25 15:22:45 +02:00
foreach ( $j -> data as $person ) {
$s = fetch_url ( 'https://graph.facebook.com/' . $person -> id . '?access_token=' . $access_token );
if ( $s ) {
$jp = json_decode ( $s );
2011-04-26 14:57:53 +02:00
logger ( 'fb_get_friends: info: ' . print_r ( $jp , true ), LOGGER_DATA );
2011-04-26 13:39:27 +02:00
// always use numeric link for consistency
$jp -> link = 'http://facebook.com/profile.php?id=' . $person -> id ;
2011-04-25 15:22:45 +02:00
// check if we already have a contact
$r = q ( " SELECT * FROM `contact` WHERE `uid` = %d AND `url` = '%s' LIMIT 1 " ,
intval ( $uid ),
dbesc ( $jp -> link )
);
if ( count ( $r )) {
2011-05-10 07:44:14 +02:00
// 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' ])) {
require_once ( " Photo.php " );
$photos = import_profile_photo ( 'https://graph.facebook.com/' . $jp -> id . '/picture' , $uid , $r [ 0 ][ 'id' ]);
$r = q ( " UPDATE `contact` SET `photo` = '%s',
`thumb` = '%s' ,
`micro` = '%s' ,
`name-date` = '%s' ,
`uri-date` = '%s' ,
`avatar-date` = '%s'
WHERE `id` = % d LIMIT 1
" ,
dbesc ( $photos [ 0 ]),
dbesc ( $photos [ 1 ]),
dbesc ( $photos [ 2 ]),
dbesc ( datetime_convert ()),
dbesc ( datetime_convert ()),
dbesc ( datetime_convert ()),
intval ( $r [ 0 ][ 'id' ])
);
}
2011-04-25 15:22:45 +02:00
continue ;
}
else {
// create contact record
$r = q ( " INSERT INTO `contact` ( `uid`, `created`, `url`, `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' , % d , % d , % d , 0 , 0 , 0 ) " ,
intval ( $uid ),
dbesc ( datetime_convert ()),
dbesc ( $jp -> link ),
dbesc ( '' ),
dbesc ( '' ),
dbesc ( $jp -> id ),
dbesc ( 'facebook ' . $jp -> id ),
dbesc ( $jp -> name ),
dbesc (( $jp -> nickname ) ? $jp -> nickname : strtolower ( $jp -> first_name )),
dbesc ( 'https://graph.facebook.com/' . $jp -> id . '/picture' ),
dbesc ( NETWORK_FACEBOOK ),
intval ( REL_BUD ),
intval ( 1 ),
intval ( 1 )
);
}
$r = q ( " SELECT * FROM `contact` WHERE `url` = '%s' AND `uid` = %d LIMIT 1 " ,
dbesc ( $jp -> link ),
intval ( $uid )
);
if ( ! count ( $r )) {
continue ;
}
$contact = $r [ 0 ];
$contact_id = $r [ 0 ][ 'id' ];
require_once ( " Photo.php " );
$photos = import_profile_photo ( $r [ 0 ][ 'photo' ], $uid , $contact_id );
$r = q ( " UPDATE `contact` SET `photo` = '%s',
`thumb` = '%s' ,
`micro` = '%s' ,
`name-date` = '%s' ,
`uri-date` = '%s' ,
`avatar-date` = '%s'
WHERE `id` = % d LIMIT 1
" ,
dbesc ( $photos [ 0 ]),
dbesc ( $photos [ 1 ]),
dbesc ( $photos [ 2 ]),
dbesc ( datetime_convert ()),
dbesc ( datetime_convert ()),
dbesc ( datetime_convert ()),
intval ( $contact_id )
);
}
}
}
}
2011-03-09 23:39:18 +01:00
function facebook_post ( & $a ) {
2011-05-30 05:36:45 +02:00
$uid = local_user ();
if ( $uid ){
2011-03-09 23:39:18 +01:00
$value = (( x ( $_POST , 'post_by_default' )) ? intval ( $_POST [ 'post_by_default' ]) : 0 );
2011-05-30 05:36:45 +02:00
set_pconfig ( $uid , 'facebook' , 'post_by_default' , $value );
$no_linking = get_pconfig ( $uid , 'facebook' , 'no_linking' );
$linkvalue = (( x ( $_POST , 'facebook_linking' )) ? intval ( $_POST [ 'facebook_linking' ]) : 0 );
set_pconfig ( $uid , 'facebook' , 'no_linking' , (( $linkvalue ) ? 0 : 1 ));
// FB linkage was allowed but has just been turned off - remove all FB contacts and posts
if (( ! intval ( $no_linking )) && ( ! intval ( $linkvalue ))) {
$r = q ( " SELECT `id` FROM `contact` WHERE `uid` = %d AND `network` = '%s' " ,
intval ( $uid ),
dbesc ( NETWORK_FACEBOOK )
);
if ( count ( $r )) {
require_once ( 'include/Contact.php' );
foreach ( $r as $rr )
contact_remove ( $rr [ 'id' ]);
}
}
elseif ( intval ( $no_linking ) && intval ( $linkvalue )) {
// FB linkage is now allowed - import stuff.
fb_get_self ( $uid );
fb_get_friends ( $uid );
fb_consume_all ( $uid );
}
info ( t ( 'Settings updated.' ) . EOL );
2011-03-09 23:39:18 +01:00
}
2011-05-30 05:36:45 +02:00
2011-03-09 23:39:18 +01:00
return ;
}
2011-02-11 03:01:38 +01:00
function facebook_content ( & $a ) {
2011-02-11 06:25:24 +01:00
if ( ! local_user ()) {
notice ( t ( 'Permission denied.' ) . EOL );
return '' ;
}
if ( $a -> argc > 1 && $a -> argv [ 1 ] === 'remove' ) {
del_pconfig ( local_user (), 'facebook' , 'post' );
2011-05-23 11:39:57 +02:00
info ( t ( 'Facebook disabled' ) . EOL );
2011-02-11 06:25:24 +01:00
}
2011-04-28 02:06:42 +02:00
if ( $a -> argc > 1 && $a -> argv [ 1 ] === 'friends' ) {
fb_get_friends ( local_user ());
2011-05-23 11:39:57 +02:00
info ( t ( 'Updating contacts' ) . EOL );
2011-04-28 02:06:42 +02:00
}
2011-03-09 23:39:18 +01:00
$fb_installed = get_pconfig ( local_user (), 'facebook' , 'post' );
2011-02-11 06:25:24 +01:00
$appid = get_config ( 'facebook' , 'appid' );
if ( ! $appid ) {
2011-02-27 10:36:52 +01:00
notice ( t ( 'Facebook API key is missing.' ) . EOL );
2011-02-11 06:25:24 +01:00
return '' ;
}
2011-02-24 03:24:29 +01:00
$a -> page [ 'htmlhead' ] .= '<link rel="stylesheet" type="text/css" href="'
. $a -> get_baseurl () . '/addon/facebook/facebook.css' . '" media="all" />' . " \r \n " ;
2011-02-11 06:25:24 +01:00
$o .= '<h3>' . t ( 'Facebook Connect' ) . '</h3>' ;
2011-03-09 23:39:18 +01:00
if ( ! $fb_installed ) {
$o .= '<div id="facebook-enable-wrapper">' ;
2011-02-11 06:25:24 +01:00
2011-03-09 23:39:18 +01:00
$o .= '<a href="https://www.facebook.com/dialog/oauth?client_id=' . $appid . '&redirect_uri='
2011-04-27 13:24:00 +02:00
. $a -> get_baseurl () . '/facebook/' . $a -> user [ 'nickname' ] . '&scope=publish_stream,read_stream,offline_access">' . t ( 'Install Facebook connector for this account.' ) . '</a>' ;
2011-03-09 23:39:18 +01:00
$o .= '</div>' ;
}
2011-02-11 06:25:24 +01:00
2011-03-09 23:39:18 +01:00
if ( $fb_installed ) {
$o .= '<div id="facebook-disable-wrapper">' ;
2011-04-27 13:24:00 +02:00
$o .= '<a href="' . $a -> get_baseurl () . '/facebook/remove' . '">' . t ( 'Remove Facebook connector' ) . '</a></div>' ;
2011-03-09 23:39:18 +01:00
$o .= '<div id="facebook-post-default-form">' ;
$o .= '<form action="facebook" method="post" >' ;
$post_by_default = get_pconfig ( local_user (), 'facebook' , 'post_by_default' );
$checked = (( $post_by_default ) ? ' checked="checked" ' : '' );
$o .= '<input type="checkbox" name="post_by_default" value="1"' . $checked . '/>' . ' ' . t ( 'Post to Facebook by default' ) . '<br />' ;
2011-05-30 05:36:45 +02:00
$no_linking = get_pconfig ( local_user (), 'facebook' , 'no_linking' );
$checked = (( $no_linking ) ? '' : ' checked="checked" ' );
$o .= '<input type="checkbox" name="facebook_linking" value="1"' . $checked . '/>' . ' ' . t ( 'Link all your Facebook friends and conversations' ) . '<br />' ;
2011-03-09 23:39:18 +01:00
$o .= '<input type="submit" name="submit" value="' . t ( 'Submit' ) . '" /></form></div>' ;
}
2011-02-11 06:25:24 +01:00
2011-02-11 03:01:38 +01:00
return $o ;
}
2010-12-28 08:28:34 +01:00
function facebook_install () {
2011-02-11 11:35:19 +01:00
register_hook ( 'post_local_end' , 'addon/facebook/facebook.php' , 'facebook_post_hook' );
register_hook ( 'jot_networks' , 'addon/facebook/facebook.php' , 'facebook_jot_nets' );
2011-02-20 12:32:57 +01:00
register_hook ( 'plugin_settings' , 'addon/facebook/facebook.php' , 'facebook_plugin_settings' );
2011-04-26 13:39:27 +02:00
register_hook ( 'cron' , 'addon/facebook/facebook.php' , 'facebook_cron' );
2010-12-28 08:28:34 +01:00
}
function facebook_uninstall () {
2011-02-11 11:35:19 +01:00
unregister_hook ( 'post_local_end' , 'addon/facebook/facebook.php' , 'facebook_post_hook' );
unregister_hook ( 'jot_networks' , 'addon/facebook/facebook.php' , 'facebook_jot_nets' );
2011-02-20 12:32:57 +01:00
unregister_hook ( 'plugin_settings' , 'addon/facebook/facebook.php' , 'facebook_plugin_settings' );
2011-04-26 13:39:27 +02:00
unregister_hook ( 'cron' , 'addon/facebook/facebook.php' , 'facebook_cron' );
}
function facebook_cron ( $a , $b ) {
$last = get_config ( 'facebook' , 'last_poll' );
2011-05-03 14:27:19 +02:00
$poll_interval = intval ( get_config ( 'facebook' , 'poll_interval' ));
2011-05-03 05:14:37 +02:00
if ( ! $poll_interval )
$poll_interval = 3600 ;
2011-04-26 13:39:27 +02:00
if ( $last ) {
2011-05-03 05:14:37 +02:00
$next = $last + $poll_interval ;
2011-04-26 13:39:27 +02:00
if ( $next > time ())
return ;
}
logger ( 'facebook_cron' );
set_config ( 'facebook' , 'last_poll' , time ());
$r = q ( " SELECT * FROM `pconfig` WHERE `cat` = 'facebook' AND `k` = 'post' AND `v` = '1' " );
if ( count ( $r )) {
foreach ( $r as $rr ) {
// check for new friends once a day
2011-04-28 00:59:18 +02:00
$last_friend_check = get_pconfig ( $rr [ 'uid' ], 'facebook' , 'friend_check' );
2011-04-26 13:39:27 +02:00
if ( $last_friend_check )
$next_friend_check = $last_friend_check + 86400 ;
if ( $next_friend_check <= time ()) {
2011-04-28 00:59:18 +02:00
fb_get_friends ( $rr [ 'uid' ]);
set_pconfig ( $rr [ 'uid' ], 'facebook' , 'friend_check' , time ());
2011-04-26 13:39:27 +02:00
}
fb_consume_all ( $rr [ 'uid' ]);
}
}
2011-02-11 11:35:19 +01:00
}
2011-04-26 13:39:27 +02:00
2011-02-20 12:32:57 +01:00
function facebook_plugin_settings ( & $a , & $b ) {
2011-02-24 03:24:29 +01:00
$b .= '<div class="settings-block">' ;
2011-02-20 12:32:57 +01:00
$b .= '<h3>' . t ( 'Facebook' ) . '</h3>' ;
$b .= '<a href="facebook">' . t ( 'Facebook Connector Settings' ) . '</a><br />' ;
2011-02-24 03:24:29 +01:00
$b .= '</div>' ;
2011-02-20 12:32:57 +01:00
}
2011-02-11 11:35:19 +01:00
function facebook_jot_nets ( & $a , & $b ) {
if ( ! local_user ())
return ;
$fb_post = get_pconfig ( local_user (), 'facebook' , 'post' );
if ( intval ( $fb_post ) == 1 ) {
$fb_defpost = get_pconfig ( local_user (), 'facebook' , 'post_by_default' );
2011-03-09 23:39:18 +01:00
$selected = (( intval ( $fb_defpost ) == 1 ) ? ' checked="checked" ' : '' );
2011-02-11 13:32:38 +01:00
$b .= '<div class="profile-jot-net"><input type="checkbox" name="facebook_enable"' . $selected . 'value="1" /> '
2011-02-11 11:35:19 +01:00
. t ( 'Post to Facebook' ) . '</div>' ;
}
}
2010-12-28 08:28:34 +01:00
function facebook_post_hook ( & $a , & $b ) {
/**
* Post to Facebook stream
*/
2011-04-26 13:39:27 +02:00
require_once ( 'include/group.php' );
2011-02-11 06:25:24 +01:00
logger ( 'Facebook post' );
2011-04-26 13:39:27 +02:00
$reply = false ;
$likes = false ;
if (( local_user ()) && ( local_user () == $b [ 'uid' ])) {
if ( $b [ 'parent' ]) {
$r = q ( " SELECT * FROM `item` WHERE `id` = %d AND `uid` = %d LIMIT 1 " ,
intval ( $b [ 'parent' ]),
intval ( local_user ())
);
if ( count ( $r ) && substr ( $r [ 0 ][ 'uri' ], 0 , 4 ) === 'fb::' )
$reply = substr ( $r [ 0 ][ 'uri' ], 4 );
2011-05-14 05:40:28 +02:00
elseif ( count ( $r ) && substr ( $r [ 0 ][ 'extid' ], 0 , 4 ) === 'fb::' )
$reply = substr ( $r [ 0 ][ 'extid' ], 4 );
2011-04-26 13:39:27 +02:00
else
return ;
logger ( 'facebook reply id=' . $reply );
}
if ( $b [ 'private' ] && $reply == false ) {
$allow_people = expand_acl ( $b [ 'allow_cid' ]);
$allow_groups = expand_groups ( expand_acl ( $b [ 'allow_gid' ]));
$deny_people = expand_acl ( $b [ 'deny_cid' ]);
$deny_groups = expand_groups ( expand_acl ( $b [ 'deny_gid' ]));
$recipients = array_unique ( array_merge ( $allow_people , $allow_groups ));
$deny = array_unique ( array_merge ( $deny_people , $deny_groups ));
$allow_str = dbesc ( implode ( ', ' , $recipients ));
2011-05-01 02:28:57 +02:00
if ( $allow_str ) {
$r = q ( " SELECT `notify` FROM `contact` WHERE `id` IN ( $allow_str ) AND `network` = 'face' " );
$allow_arr = array ();
if ( count ( $r ))
foreach ( $r as $rr )
$allow_arr [] = $rr [ 'notify' ];
}
2011-04-26 13:39:27 +02:00
$deny_str = dbesc ( implode ( ', ' , $deny ));
2011-05-01 02:28:57 +02:00
if ( $deny_str ) {
$r = q ( " SELECT `notify` FROM `contact` WHERE `id` IN ( $deny_str ) AND `network` = 'face' " );
$deny_arr = array ();
if ( count ( $r ))
foreach ( $r as $rr )
$deny_arr [] = $rr [ 'notify' ];
}
2011-04-27 05:11:15 +02:00
if ( count ( $deny_arr ) && ( ! count ( $allow_arr ))) {
// One or more FB folks were denied access but nobody on FB was specifically allowed access.
// This might cause the post to be open to public on Facebook, but only to selected members
// on another network. Since this could potentially leak a post to somebody who was denied,
// we will skip posting it to Facebook with a slightly vague but relevant message that will
// hopefully lead somebody to this code comment for a better explanation of what went wrong.
notice ( t ( 'Post to Facebook cancelled because of multi-network access permission conflict.' ) . EOL );
return ;
}
// if it's a private message but no Facebook members are allowed or denied, skip Facebook post
2011-04-26 13:39:27 +02:00
if (( ! count ( $allow_arr )) && ( ! count ( $deny_arr )))
return ;
}
if ( $b [ 'verb' ] == ACTIVITY_LIKE )
$likes = true ;
2010-12-28 08:28:34 +01:00
2011-02-11 06:25:24 +01:00
2011-02-11 03:01:38 +01:00
$appid = get_config ( 'facebook' , 'appid' );
$secret = get_config ( 'facebook' , 'appsecret' );
2010-12-28 08:28:34 +01:00
if ( $appid && $secret ) {
2011-02-12 14:07:24 +01:00
logger ( 'facebook: have appid+secret' );
2011-02-11 11:35:19 +01:00
$fb_post = intval ( get_pconfig ( local_user (), 'facebook' , 'post' ));
2011-02-13 04:24:19 +01:00
$fb_enable = (( $fb_post && x ( $_POST , 'facebook_enable' )) ? intval ( $_POST [ 'facebook_enable' ]) : 0 );
2011-02-11 11:35:19 +01:00
$fb_token = get_pconfig ( local_user (), 'facebook' , 'access_token' );
2010-12-28 08:28:34 +01:00
2011-02-13 04:24:19 +01:00
logger ( 'facebook: $fb_post: ' . $fb_post . ' $fb_enable: ' . $fb_enable . ' $fb_token: ' . $fb_token , LOGGER_DEBUG );
2011-04-27 02:17:34 +02:00
// post to facebook if it's a public post and we've ticked the 'post to Facebook' box,
// or it's a private message with facebook participants
// or it's a reply or likes action to an existing facebook post
if ( $fb_post && $fb_token && ( $fb_enable || $b [ 'private' ] || $reply )) {
2011-02-12 14:07:24 +01:00
logger ( 'facebook: able to post' );
2010-12-28 08:28:34 +01:00
require_once ( 'library/facebook.php' );
require_once ( 'include/bbcode.php' );
2011-02-11 06:25:24 +01:00
$msg = $b [ 'body' ];
2011-02-12 14:07:24 +01:00
logger ( 'Facebook post: original msg=' . $msg , LOGGER_DATA );
2011-02-11 03:01:38 +01:00
// make links readable before we strip the code
2011-05-17 13:53:05 +02:00
// unless it's a dislike - just send the text as a comment
if ( $b [ 'verb' ] == ACTIVITY_DISLIKE )
$msg = trim ( strip_tags ( bbcode ( $msg )));
2011-05-20 10:48:59 +02:00
$search_str = $a -> get_baseurl () . '/search' ;
2011-04-29 04:19:36 +02:00
if ( preg_match ( " / \ [url=(.+?) \ ](.+?) \ [ \ /url \ ]/is " , $msg , $matches )) {
2011-05-20 10:48:59 +02:00
// don't use hashtags for message link
if ( strpos ( $matches [ 2 ], $search_str ) === false ) {
$link = $matches [ 1 ];
if ( substr ( $matches [ 2 ], 0 , 5 ) != '[img]' )
$linkname = $matches [ 2 ];
}
2011-04-29 04:19:36 +02:00
}
2011-03-16 01:47:49 +01:00
$msg = preg_replace ( " / \ [url=(.+?) \ ](.+?) \ [ \ /url \ ]/is " , '$2 $1' , $msg );
2011-02-11 03:01:38 +01:00
2011-04-29 04:19:36 +02:00
if ( preg_match ( " / \ [img \ ](.+?) \ [ \ /img \ ]/is " , $msg , $matches ))
$image = $matches [ 1 ];
2011-04-28 13:44:17 +02:00
$msg = preg_replace ( " / \ [img \ ](.+?) \ [ \ /img \ ]/is " , t ( 'Image: ' ) . '$1' , $msg );
2011-02-11 06:25:24 +01:00
2011-05-23 06:20:28 +02:00
if (( strpos ( $link , $a -> get_baseurl ()) !== false ) && ( ! $image ))
$image = $a -> get_baseurl () . '/images/friendika-64.jpg' ;
2011-04-29 04:19:36 +02:00
2011-02-11 06:25:24 +01:00
$msg = trim ( strip_tags ( bbcode ( $msg )));
2011-02-21 04:51:00 +01:00
$msg = html_entity_decode ( $msg , ENT_QUOTES , 'UTF-8' );
2011-02-11 03:01:38 +01:00
2011-05-26 15:46:55 +02:00
// add any attachments as text urls
$arr = explode ( ',' , $b [ 'attach' ]);
if ( count ( $arr )) {
$msg .= " \n " ;
foreach ( $arr as $r ) {
$matches = false ;
$cnt = preg_match ( '|\[attach\]href=\"(.+?)\" size=\"(.+?)\" type=\"(.+?)\" title=\"(.+?)\"\[\/attach\]|' , $r , $matches );
if ( $cnt ) {
$msg .= $matches [ 1 ];
}
}
}
2011-02-11 03:01:38 +01:00
if ( strlen ( $msg ) > FACEBOOK_MAXPOSTLEN ) {
$shortlink = " " ;
2011-02-22 05:19:33 +01:00
require_once ( 'library/slinky.php' );
2011-02-11 03:01:38 +01:00
$display_url = $a -> get_baseurl () . '/display/' . $a -> user [ 'nickname' ] . '/' . $b [ 'id' ];
2011-03-17 23:31:46 +01:00
$slinky = new Slinky ( $display_url );
2011-02-11 03:01:38 +01:00
// setup a cascade of shortening services
// try to get a short link from these services
// in the order ur1.ca, trim, id.gd, tinyurl
$slinky -> set_cascade ( array ( new Slinky_UR1ca (), new Slinky_Trim (), new Slinky_IsGd (), new Slinky_TinyURL () ) );
$shortlink = $slinky -> short ();
// the new message will be shortened such that "... $shortlink"
// will fit into the character limit
$msg = substr ( $msg , 0 , FACEBOOK_MAXPOSTLEN - strlen ( $shortlink ) - 4 );
$msg .= '... ' . $shortlink ;
}
if ( ! strlen ( $msg ))
return ;
2011-02-11 06:25:24 +01:00
logger ( 'Facebook post: msg=' . $msg , LOGGER_DATA );
2011-02-11 03:01:38 +01:00
2011-04-27 02:17:34 +02:00
if ( $likes ) {
$postvars = array ( 'access_token' => $fb_token );
}
else {
$postvars = array (
'access_token' => $fb_token ,
'message' => $msg
);
2011-04-29 04:19:36 +02:00
if ( isset ( $image ))
$postvars [ 'picture' ] = $image ;
if ( isset ( $link ))
$postvars [ 'link' ] = $link ;
if ( isset ( $linkname ))
$postvars [ 'name' ] = $linkname ;
2011-04-27 02:17:34 +02:00
}
2011-02-11 03:01:38 +01:00
2011-04-26 13:39:27 +02:00
if (( $b [ 'private' ]) && ( ! $b [ 'parent' ])) {
$postvars [ 'privacy' ] = '{"value": "CUSTOM", "friends": "SOME_FRIENDS"' ;
if ( count ( $allow_arr ))
$postvars [ 'privacy' ] .= ',"allow": "' . implode ( ',' , $allow_arr ) . '"' ;
if ( count ( $deny_arr ))
$postvars [ 'privacy' ] .= ',"deny": "' . implode ( ',' , $deny_arr ) . '"' ;
$postvars [ 'privacy' ] .= '}' ;
}
if ( $reply ) {
$url = 'https://graph.facebook.com/' . $reply . '/' . (( $likes ) ? 'likes' : 'comments' );
}
else {
$url = 'https://graph.facebook.com/me/feed' ;
2011-04-29 04:19:36 +02:00
if ( $b [ 'plink' ])
$postvars [ 'actions' ] = '{"name": "' . t ( 'View on Friendika' ) . '", "link": "' . $b [ 'plink' ] . '"}' ;
2011-04-26 13:39:27 +02:00
}
2011-04-29 04:19:36 +02:00
2011-04-26 13:39:27 +02:00
logger ( 'facebook: post to ' . $url );
logger ( 'facebook: postvars: ' . print_r ( $postvars , true ));
2011-04-28 13:44:17 +02:00
// "test_mode" prevents anything from actually being posted.
// Otherwise, let's do it.
if ( ! get_config ( 'facebook' , 'test_mode' ))
$x = post_url ( $url , $postvars );
2011-04-27 13:24:00 +02:00
$retj = json_decode ( $x );
if ( $retj -> id ) {
q ( " UPDATE `item` SET `extid` = '%s' WHERE `id` = %d LIMIT 1 " ,
2011-04-28 03:23:39 +02:00
dbesc ( 'fb::' . $retj -> id ),
2011-04-27 13:24:00 +02:00
intval ( $b [ 'id' ])
);
}
2011-02-11 06:25:24 +01:00
logger ( 'Facebook post returns: ' . $x , LOGGER_DEBUG );
2011-02-11 03:01:38 +01:00
2010-12-28 08:28:34 +01:00
}
}
}
2010-12-31 08:28:33 +01:00
}
2010-12-28 08:28:34 +01:00
2011-04-25 15:22:45 +02:00
function fb_consume_all ( $uid ) {
require_once ( 'include/items.php' );
$access_token = get_pconfig ( $uid , 'facebook' , 'access_token' );
if ( ! $access_token )
return ;
$s = fetch_url ( 'https://graph.facebook.com/me/feed?access_token=' . $access_token );
if ( $s ) {
$j = json_decode ( $s );
2011-04-26 13:39:27 +02:00
logger ( 'fb_consume_stream: wall: ' . print_r ( $j , true ), LOGGER_DATA );
2011-04-25 15:22:45 +02:00
fb_consume_stream ( $uid , $j , true );
}
$s = fetch_url ( 'https://graph.facebook.com/me/home?access_token=' . $access_token );
if ( $s ) {
$j = json_decode ( $s );
2011-04-26 13:39:27 +02:00
logger ( 'fb_consume_stream: feed: ' . print_r ( $j , true ), LOGGER_DATA );
2011-04-25 15:22:45 +02:00
fb_consume_stream ( $uid , $j , false );
}
}
function fb_consume_stream ( $uid , $j , $wall = false ) {
$a = get_app ();
2011-05-30 05:36:45 +02:00
$no_linking = get_pconfig ( $uid , 'facebook' , 'no_linking' );
if ( $no_linking )
return ;
2011-04-25 15:22:45 +02:00
$self = q ( " SELECT * FROM `contact` WHERE `self` = 1 AND `uid` = %d LIMIT 1 " ,
intval ( $uid )
);
2011-04-26 13:39:27 +02:00
$user = q ( " SELECT `nickname` FROM `user` WHERE `uid` = %d LIMIT 1 " ,
intval ( $uid )
);
if ( count ( $user ))
$my_local_url = $a -> get_baseurl () . '/profile/' . $user [ 0 ][ 'nickname' ];
2011-04-25 15:22:45 +02:00
$self_id = get_pconfig ( $uid , 'facebook' , 'self_id' );
if ( ! count ( $j -> data ) || ( ! strlen ( $self_id )))
return ;
foreach ( $j -> data as $entry ) {
2011-04-26 13:39:27 +02:00
logger ( 'fb_consume: entry: ' . print_r ( $entry , true ), LOGGER_DATA );
2011-04-25 15:22:45 +02:00
$datarray = array ();
2011-04-27 13:24:00 +02:00
$r = q ( " SELECT * FROM `item` WHERE ( `uri` = '%s' OR `extid` = '%s') AND `uid` = %d LIMIT 1 " ,
dbesc ( 'fb::' . $entry -> id ),
2011-04-25 15:22:45 +02:00
dbesc ( 'fb::' . $entry -> id ),
intval ( $uid )
2011-04-27 13:24:00 +02:00
);
2011-04-25 15:22:45 +02:00
if ( count ( $r )) {
$post_exists = true ;
$orig_post = $r [ 0 ];
$top_item = $r [ 0 ][ 'id' ];
}
else {
$post_exists = false ;
$orig_post = null ;
}
2011-04-26 13:39:27 +02:00
2011-04-25 15:22:45 +02:00
if ( ! $orig_post ) {
$datarray [ 'gravity' ] = 0 ;
$datarray [ 'uid' ] = $uid ;
$datarray [ 'wall' ] = (( $wall ) ? 1 : 0 );
$datarray [ 'uri' ] = $datarray [ 'parent-uri' ] = 'fb::' . $entry -> id ;
$from = $entry -> from ;
if ( $from -> id == $self_id )
$datarray [ 'contact-id' ] = $self [ 0 ][ 'id' ];
else {
2011-04-28 12:14:30 +02:00
$r = q ( " SELECT * FROM `contact` WHERE `notify` = '%s' AND `uid` = %d AND `blocked` = 0 AND `readonly` = 0 LIMIT 1 " ,
2011-04-25 15:22:45 +02:00
dbesc ( $from -> id ),
intval ( $uid )
);
if ( count ( $r ))
$datarray [ 'contact-id' ] = $r [ 0 ][ 'id' ];
}
2011-04-28 02:06:42 +02:00
// don't store post if we don't have a contact
if ( ! x ( $datarray , 'contact-id' ))
continue ;
2011-04-25 15:22:45 +02:00
$datarray [ 'verb' ] = ACTIVITY_POST ;
2011-04-26 13:39:27 +02:00
if ( $wall ) {
$datarray [ 'owner-name' ] = $self [ 0 ][ 'name' ];
2011-04-27 05:32:18 +02:00
$datarray [ 'owner-link' ] = $self [ 0 ][ 'url' ];
$datarray [ 'owner-avatar' ] = $self [ 0 ][ 'thumb' ];
2011-04-26 13:39:27 +02:00
}
2011-04-25 15:22:45 +02:00
$datarray [ 'author-name' ] = $from -> name ;
$datarray [ 'author-link' ] = 'http://facebook.com/profile.php?id=' . $from -> id ;
$datarray [ 'author-avatar' ] = 'https://graph.facebook.com/' . $from -> id . '/picture' ;
2011-04-27 04:01:10 +02:00
$datarray [ 'plink' ] = $datarray [ 'author-link' ] . '&v=wall&story_fbid=' . substr ( $entry -> id , strpos ( $entry -> id , '_' ) + 1 );
2011-04-25 15:22:45 +02:00
$datarray [ 'body' ] = $entry -> message ;
if ( $entry -> picture )
$datarray [ 'body' ] .= " \n \n " . '[img]' . $entry -> picture . '[/img]' ;
if ( $entry -> link )
$datarray [ 'body' ] .= " \n " . linkify ( $entry -> link );
if ( $entry -> name )
$datarray [ 'body' ] .= " \n " . $entry -> name ;
if ( $entry -> caption )
$datarray [ 'body' ] .= " \n " . $entry -> caption ;
if ( $entry -> description )
$datarray [ 'body' ] .= " \n " . $entry -> description ;
$datarray [ 'created' ] = datetime_convert ( 'UTC' , 'UTC' , $entry -> created_time );
$datarray [ 'edited' ] = datetime_convert ( 'UTC' , 'UTC' , $entry -> updated_time );
2011-04-26 13:39:27 +02:00
if ( $entry -> privacy && $entry -> privacy -> value !== 'EVERYONE' )
$datarray [ 'private' ] = 1 ;
2011-04-25 15:22:45 +02:00
$top_item = item_store ( $datarray );
2011-04-26 13:39:27 +02:00
$r = q ( " SELECT * FROM `item` WHERE `id` = %d AND `uid` = %d LIMIT 1 " ,
2011-04-25 15:22:45 +02:00
intval ( $top_item ),
intval ( $uid )
);
if ( count ( $r ))
$orig_post = $r [ 0 ];
}
2011-05-23 04:20:33 +02:00
if ( isset ( $entry -> likes ) && isset ( $entry -> likes -> data ))
$likers = $entry -> likes -> data ;
2011-05-23 06:47:22 +02:00
else
$likers = null ;
2011-05-23 04:20:33 +02:00
if ( isset ( $entry -> comments ) && isset ( $entry -> comments -> data ))
$comments = $entry -> comments -> data ;
2011-05-23 06:47:22 +02:00
else
$comments = null ;
2011-04-25 15:22:45 +02:00
if ( is_array ( $likers )) {
foreach ( $likers as $likes ) {
2011-05-14 09:47:00 +02:00
if ( ! $orig_post )
continue ;
2011-05-28 00:33:01 +02:00
// If we posted the like locally, it will be found with our url, not the FB url.
$second_url = (( $likes -> id == $self_id ) ? $self [ 0 ][ 'url' ] : 'http://facebook.com/profile.php?id=' . $likes -> id );
$r = q ( " SELECT * FROM `item` WHERE `parent-uri` = '%s' AND `uid` = %d AND `verb` = '%s'
AND ( `author-link` = '%s' OR `author-link` = '%s' ) LIMIT 1 " ,
2011-05-14 09:47:00 +02:00
dbesc ( $orig_post [ 'uri' ]),
2011-04-25 15:22:45 +02:00
intval ( $uid ),
dbesc ( ACTIVITY_LIKE ),
2011-05-28 00:33:01 +02:00
dbesc ( 'http://facebook.com/profile.php?id=' . $likes -> id ),
dbesc ( $second_url )
2011-04-25 15:22:45 +02:00
);
2011-05-14 09:47:00 +02:00
2011-04-25 15:22:45 +02:00
if ( count ( $r ))
continue ;
$likedata = array ();
$likedata [ 'parent' ] = $top_item ;
$likedata [ 'verb' ] = ACTIVITY_LIKE ;
$likedata [ 'gravity' ] = 3 ;
$likedata [ 'uid' ] = $uid ;
$likedata [ 'wall' ] = (( $wall ) ? 1 : 0 );
$likedata [ 'uri' ] = item_new_uri ( $a -> get_baseurl (), $uid );
2011-05-14 09:47:00 +02:00
$likedata [ 'parent-uri' ] = $orig_post [ 'uri' ];
2011-04-25 15:22:45 +02:00
if ( $likes -> id == $self_id )
$likedata [ 'contact-id' ] = $self [ 0 ][ 'id' ];
else {
2011-04-28 12:14:30 +02:00
$r = q ( " SELECT * FROM `contact` WHERE `notify` = '%s' AND `uid` = %d AND `blocked` = 0 AND `readonly` = 0 LIMIT 1 " ,
2011-04-25 15:22:45 +02:00
dbesc ( $likes -> id ),
intval ( $uid )
);
if ( count ( $r ))
$likedata [ 'contact-id' ] = $r [ 0 ][ 'id' ];
}
if ( ! x ( $likedata , 'contact-id' ))
$likedata [ 'contact-id' ] = $orig_post [ 'contact-id' ];
$likedata [ 'verb' ] = ACTIVITY_LIKE ;
$likedata [ 'author-name' ] = $likes -> name ;
$likedata [ 'author-link' ] = 'http://facebook.com/profile.php?id=' . $likes -> id ;
$likedata [ 'author-avatar' ] = 'https://graph.facebook.com/' . $likes -> id . '/picture' ;
2011-04-27 01:37:26 +02:00
$author = '[url=' . $likedata [ 'author-link' ] . ']' . $likedata [ 'author-name' ] . '[/url]' ;
$objauthor = '[url=' . $orig_post [ 'author-link' ] . ']' . $orig_post [ 'author-name' ] . '[/url]' ;
$post_type = t ( 'status' );
$plink = '[url=' . $orig_post [ 'plink' ] . ']' . $post_type . '[/url]' ;
$likedata [ 'object-type' ] = ACTIVITY_OBJ_NOTE ;
$likedata [ 'body' ] = sprintf ( t ( '%1$s likes %2$s\'s %3$s' ), $author , $objauthor , $plink );
$likedata [ 'object' ] = '<object><type>' . ACTIVITY_OBJ_NOTE . '</type><local>1</local>' .
'<id>' . $orig_post [ 'uri' ] . '</id><link>' . xmlify ( '<link rel="alternate" type="text/html" href="' . $orig_post [ 'plink' ] . '">' ) . '</link><title>' . $orig_post [ 'title' ] . '</title><content>' . $orig_post [ 'body' ] . '</content></object>' ;
2011-04-25 15:22:45 +02:00
$item = item_store ( $likedata );
}
}
if ( is_array ( $comments )) {
foreach ( $comments as $cmnt ) {
2011-05-14 09:47:00 +02:00
if ( ! $orig_post )
continue ;
2011-04-27 13:24:00 +02:00
$r = q ( " SELECT * FROM `item` WHERE `uid` = %d AND ( `uri` = '%s' OR `extid` = '%s' ) LIMIT 1 " ,
2011-04-25 15:22:45 +02:00
intval ( $uid ),
2011-04-27 13:24:00 +02:00
dbesc ( 'fb::' . $cmnt -> id ),
2011-04-25 15:22:45 +02:00
dbesc ( 'fb::' . $cmnt -> id )
);
if ( count ( $r ))
continue ;
$cmntdata = array ();
$cmntdata [ 'parent' ] = $top_item ;
$cmntdata [ 'verb' ] = ACTIVITY_POST ;
$cmntdata [ 'gravity' ] = 6 ;
$cmntdata [ 'uid' ] = $uid ;
$cmntdata [ 'wall' ] = (( $wall ) ? 1 : 0 );
$cmntdata [ 'uri' ] = 'fb::' . $cmnt -> id ;
2011-05-14 09:47:00 +02:00
$cmntdata [ 'parent-uri' ] = $orig_post [ 'uri' ];
2011-04-26 13:39:27 +02:00
if ( $cmnt -> from -> id == $self_id ) {
2011-04-25 15:22:45 +02:00
$cmntdata [ 'contact-id' ] = $self [ 0 ][ 'id' ];
2011-04-26 13:39:27 +02:00
}
2011-04-25 15:22:45 +02:00
else {
2011-05-16 02:04:02 +02:00
$r = q ( " SELECT * FROM `contact` WHERE `notify` = '%s' AND `uid` = %d LIMIT 1 " ,
2011-04-25 15:22:45 +02:00
dbesc ( $cmnt -> from -> id ),
intval ( $uid )
);
2011-05-16 02:04:02 +02:00
if ( count ( $r )) {
2011-04-25 15:22:45 +02:00
$cmntdata [ 'contact-id' ] = $r [ 0 ][ 'id' ];
2011-05-16 02:04:02 +02:00
if ( $r [ 0 ][ 'blocked' ] || $r [ 0 ][ 'readonly' ])
continue ;
}
2011-04-25 15:22:45 +02:00
}
2011-05-14 11:25:26 +02:00
if ( ! x ( $cmntdata , 'contact-id' ))
$cmntdata [ 'contact-id' ] = $orig_post [ 'contact-id' ];
2011-04-27 03:14:38 +02:00
$cmntdata [ 'created' ] = datetime_convert ( 'UTC' , 'UTC' , $cmnt -> created_time );
$cmntdata [ 'edited' ] = datetime_convert ( 'UTC' , 'UTC' , $cmnt -> created_time );
2011-04-25 15:22:45 +02:00
$cmntdata [ 'verb' ] = ACTIVITY_POST ;
$cmntdata [ 'author-name' ] = $cmnt -> from -> name ;
$cmntdata [ 'author-link' ] = 'http://facebook.com/profile.php?id=' . $cmnt -> from -> id ;
$cmntdata [ 'author-avatar' ] = 'https://graph.facebook.com/' . $cmnt -> from -> id . '/picture' ;
$cmntdata [ 'body' ] = $cmnt -> message ;
$item = item_store ( $cmntdata );
}
}
}
2011-04-27 13:24:00 +02:00
}
2011-04-25 15:22:45 +02:00