2011-11-01 03:39:04 +00:00
< ? php
2011-11-01 03:54:24 +00:00
require_once ( 'include/datetime.php' );
2015-07-17 21:05:50 +00:00
require_once ( " include/Scrape.php " );
2015-07-18 20:26:06 +00:00
require_once ( " include/html2bbcode.php " );
2015-07-17 06:38:20 +00:00
2015-07-22 09:51:37 +00:00
/*
To - Do :
- Move GNU Social URL schemata ( http :// server . tld / user / number ) to http :// server . tld / username
*/
2011-11-01 03:39:04 +00:00
/*
* poco_load
*
* Given a contact - id ( minimum ), load the PortableContacts friend list for that contact ,
* and add the entries to the gcontact ( Global Contact ) table , or update existing entries
* if anything ( name or photo ) has changed .
* We use normalised urls for comparison which ignore http vs https and www . domain vs domain
*
* Once the global contact is stored add ( if necessary ) the contact linkage which associates
* the given uid , cid to the global contact entry . There can be many uid / cid combinations
2015-01-08 06:59:20 +00:00
* pointing to the same global contact id .
2011-11-01 03:39:04 +00:00
*
*/
2015-01-08 06:59:20 +00:00
2011-11-01 03:39:04 +00:00
2012-05-01 08:16:47 +00:00
function poco_load ( $cid , $uid = 0 , $zcid = 0 , $url = null ) {
2015-02-04 18:49:43 +00:00
2011-11-01 03:39:04 +00:00
$a = get_app ();
2011-11-29 03:28:33 +00:00
if ( $cid ) {
if (( ! $url ) || ( ! $uid )) {
$r = q ( " select `poco`, `uid` from `contact` where `id` = %d limit 1 " ,
intval ( $cid )
);
if ( count ( $r )) {
$url = $r [ 0 ][ 'poco' ];
$uid = $r [ 0 ][ 'uid' ];
}
2011-11-01 03:39:04 +00:00
}
2011-11-29 03:28:33 +00:00
if ( ! $uid )
return ;
2011-11-01 03:39:04 +00:00
}
2011-11-29 03:28:33 +00:00
if ( ! $url )
2011-11-01 03:39:04 +00:00
return ;
2011-11-29 03:28:33 +00:00
2015-02-15 09:52:45 +00:00
$url = $url . (( $uid ) ? '/@me/@all?fields=displayName,urls,photos,updated,network,aboutMe,currentLocation,tags,gender,generation' : '?fields=displayName,urls,photos,updated,network,aboutMe,currentLocation,tags,gender,generation' ) ;
2011-11-29 03:28:33 +00:00
2011-12-19 08:40:00 +00:00
logger ( 'poco_load: ' . $url , LOGGER_DEBUG );
2011-12-15 21:52:52 +00:00
2011-12-19 08:40:00 +00:00
$s = fetch_url ( $url );
logger ( 'poco_load: returns ' . $s , LOGGER_DATA );
logger ( 'poco_load: return code: ' . $a -> get_curl_code (), LOGGER_DEBUG );
2011-11-01 03:39:04 +00:00
if (( $a -> get_curl_code () > 299 ) || ( ! $s ))
return ;
2011-12-19 08:40:00 +00:00
2011-11-01 03:39:04 +00:00
$j = json_decode ( $s );
2011-12-19 08:40:00 +00:00
logger ( 'poco_load: json: ' . print_r ( $j , true ), LOGGER_DATA );
2011-12-20 00:51:57 +00:00
if ( ! isset ( $j -> entry ))
return ;
2011-12-19 08:40:00 +00:00
$total = 0 ;
2011-11-01 03:39:04 +00:00
foreach ( $j -> entry as $entry ) {
2011-12-19 08:40:00 +00:00
$total ++ ;
2011-11-01 03:39:04 +00:00
$profile_url = '' ;
$profile_photo = '' ;
2011-12-18 08:50:17 +00:00
$connect_url = '' ;
2011-11-01 03:39:04 +00:00
$name = '' ;
2015-01-08 06:59:20 +00:00
$network = '' ;
2015-01-04 18:19:47 +00:00
$updated = '0000-00-00 00:00:00' ;
2015-01-25 01:29:46 +00:00
$location = '' ;
$about = '' ;
2015-01-25 12:19:37 +00:00
$keywords = '' ;
$gender = '' ;
2015-02-15 09:52:45 +00:00
$generation = 0 ;
2011-11-01 03:39:04 +00:00
$name = $entry -> displayName ;
2012-05-23 04:20:31 +00:00
if ( isset ( $entry -> urls )) {
foreach ( $entry -> urls as $url ) {
if ( $url -> type == 'profile' ) {
$profile_url = $url -> value ;
continue ;
}
if ( $url -> type == 'webfinger' ) {
$connect_url = str_replace ( 'acct:' , '' , $url -> value );
continue ;
}
2011-11-01 03:39:04 +00:00
}
2012-05-23 04:20:31 +00:00
}
2015-01-04 18:19:47 +00:00
if ( isset ( $entry -> photos )) {
2012-05-23 04:20:31 +00:00
foreach ( $entry -> photos as $photo ) {
if ( $photo -> type == 'profile' ) {
$profile_photo = $photo -> value ;
continue ;
}
2011-11-01 03:39:04 +00:00
}
}
2015-01-04 18:19:47 +00:00
if ( isset ( $entry -> updated ))
$updated = date ( " Y-m-d H:i:s " , strtotime ( $entry -> updated ));
2015-01-08 06:59:20 +00:00
if ( isset ( $entry -> network ))
$network = $entry -> network ;
2015-01-25 01:29:46 +00:00
if ( isset ( $entry -> currentLocation ))
$location = $entry -> currentLocation ;
if ( isset ( $entry -> aboutMe ))
2015-02-04 18:49:43 +00:00
$about = html2bbcode ( $entry -> aboutMe );
2015-01-25 01:29:46 +00:00
2015-01-25 12:19:37 +00:00
if ( isset ( $entry -> gender ))
$gender = $entry -> gender ;
2015-01-25 01:29:46 +00:00
2015-02-15 09:52:45 +00:00
if ( isset ( $entry -> generation ) AND ( $entry -> generation > 0 ))
$generation = ++ $entry -> generation ;
2015-01-25 12:19:37 +00:00
if ( isset ( $entry -> tags ))
2015-01-25 15:40:20 +00:00
foreach ( $entry -> tags as $tag )
$keywords = implode ( " , " , $tag );
2015-02-16 21:11:51 +00:00
// If you query a Friendica server for its profiles, the network has to be Friendica
2015-07-16 08:09:59 +00:00
// To-Do: It could also be a Redmatrix server
//if ($uid == 0)
// $network = NETWORK_DFRN;
2015-02-16 21:11:51 +00:00
2015-02-15 09:52:45 +00:00
poco_check ( $profile_url , $name , $network , $profile_photo , $about , $location , $gender , $keywords , $connect_url , $updated , $generation , $cid , $uid , $zcid );
2015-01-26 00:07:15 +00:00
// Update the Friendica contacts. Diaspora is doing it via a message. (See include/diaspora.php)
if (( $location != " " ) OR ( $about != " " ) OR ( $keywords != " " ) OR ( $gender != " " ))
q ( " UPDATE `contact` SET `location` = '%s', `about` = '%s', `keywords` = '%s', `gender` = '%s'
WHERE `nurl` = '%s' AND NOT `self` AND `network` = '%s' " ,
dbesc ( $location ),
dbesc ( $about ),
dbesc ( $keywords ),
dbesc ( $gender ),
dbesc ( normalise_link ( $profile_url )),
dbesc ( NETWORK_DFRN ));
2011-11-01 03:39:04 +00:00
}
2011-12-19 08:40:00 +00:00
logger ( " poco_load: loaded $total entries " , LOGGER_DEBUG );
2011-11-01 03:39:04 +00:00
2015-01-05 07:03:29 +00:00
q ( " DELETE FROM `glink` WHERE `cid` = %d AND `uid` = %d AND `zcid` = %d AND `updated` < UTC_TIMESTAMP - INTERVAL 2 DAY " ,
2012-05-01 08:34:47 +00:00
intval ( $cid ),
intval ( $uid ),
intval ( $zcid )
);
2011-11-01 03:39:04 +00:00
2011-11-02 02:16:33 +00:00
}
2015-02-15 09:52:45 +00:00
function poco_check ( $profile_url , $name , $network , $profile_photo , $about , $location , $gender , $keywords , $connect_url , $updated , $generation , $cid = 0 , $uid = 0 , $zcid = 0 ) {
2015-02-16 21:11:51 +00:00
$a = get_app ();
2015-02-15 09:52:45 +00:00
// Generation:
// 0: No definition
// 1: Profiles on this server
// 2: Contacts of profiles on this server
// 3: Contacts of contacts of profiles on this server
// 4: ...
2015-01-06 06:23:11 +00:00
$gcid = " " ;
2015-01-24 23:19:59 +00:00
if ( $profile_url == " " )
return $gcid ;
2015-07-22 09:51:37 +00:00
$urlparts = parse_url ( $profile_url );
if ( ! isset ( $urlparts [ " scheme " ]))
return $gcid ;
if ( in_array ( $urlparts [ " host " ], array ( " facebook.com " , " twitter.com " , " www.twitter-rss.com " ,
" identi.ca " , " alpha.app.net " )))
return $gcid ;
2015-07-17 06:58:42 +00:00
$orig_updated = $updated ;
2015-02-16 21:11:51 +00:00
// Don't store the statusnet connector as network
// We can't simply set this to NETWORK_OSTATUS since the connector could have fetched posts from friendica as well
if ( $network == NETWORK_STATUSNET )
$network = " " ;
// The global contacts should contain the original picture, not the cached one
if (( $generation != 1 ) AND stristr ( normalise_link ( $profile_photo ), normalise_link ( $a -> get_baseurl () . " /photo/ " )))
$profile_photo = " " ;
$r = q ( " SELECT `network` FROM `contact` WHERE `nurl` = '%s' AND `network` != '' AND `network` != '%s' LIMIT 1 " ,
dbesc ( normalise_link ( $profile_url )), dbesc ( NETWORK_STATUSNET )
2015-02-15 09:52:45 +00:00
);
if ( count ( $r ))
$network = $r [ 0 ][ " network " ];
2015-02-16 21:11:51 +00:00
if (( $network == " " ) OR ( $network == NETWORK_OSTATUS )) {
$r = q ( " SELECT `network`, `url` FROM `contact` WHERE `alias` IN ('%s', '%s') AND `network` != '' AND `network` != '%s' LIMIT 1 " ,
dbesc ( $profile_url ), dbesc ( normalise_link ( $profile_url )), dbesc ( NETWORK_STATUSNET )
2015-02-15 09:52:45 +00:00
);
if ( count ( $r )) {
$network = $r [ 0 ][ " network " ];
$profile_url = $r [ 0 ][ " url " ];
}
}
2015-01-26 00:07:15 +00:00
$x = q ( " SELECT * FROM `gcontact` WHERE `nurl` = '%s' LIMIT 1 " ,
dbesc ( normalise_link ( $profile_url ))
);
2015-07-16 23:08:28 +00:00
if ( count ( $x )) {
if (( $network == " " ) AND ( $x [ 0 ][ " network " ] != NETWORK_STATUSNET ))
$network = $x [ 0 ][ " network " ];
2015-07-17 06:58:42 +00:00
if ( $updated == " 0000-00-00 00:00:00 " )
2015-07-16 23:08:28 +00:00
$updated = $x [ 0 ][ " updated " ];
2015-07-20 22:05:44 +00:00
$created = $x [ 0 ][ " created " ];
2015-07-16 23:08:28 +00:00
$last_contact = $x [ 0 ][ " last_contact " ];
$last_failure = $x [ 0 ][ " last_failure " ];
2015-07-18 18:15:21 +00:00
$server_url = $x [ 0 ][ " server_url " ];
2015-07-20 22:05:44 +00:00
$nick = $x [ 0 ][ " nick " ];
2015-07-16 23:08:28 +00:00
} else {
2015-07-20 22:05:44 +00:00
$created = " 0000-00-00 00:00:00 " ;
2015-07-16 23:08:28 +00:00
$last_contact = " 0000-00-00 00:00:00 " ;
$last_failure = " 0000-00-00 00:00:00 " ;
2015-07-18 18:15:21 +00:00
$server_url = " " ;
2015-07-20 22:05:44 +00:00
$urlparts = parse_url ( $profile_url );
$nick = end ( explode ( " / " , $urlparts [ " path " ]));
2015-07-16 23:08:28 +00:00
}
2015-01-26 00:07:15 +00:00
2015-07-22 09:51:37 +00:00
if ((( $network == " " ) OR ( $name == " " ) OR ( $profile_photo == " " ) OR ( $server_url == " " ))
AND poco_reachable ( $profile_url , $server_url , $network )) {
2015-02-16 21:11:51 +00:00
$data = probe_url ( $profile_url );
2015-01-24 23:19:59 +00:00
$network = $data [ " network " ];
$name = $data [ " name " ];
2015-07-20 22:05:44 +00:00
$nick = $data [ " nick " ];
2015-02-16 21:11:51 +00:00
$profile_url = $data [ " url " ];
2015-01-24 23:19:59 +00:00
$profile_photo = $data [ " photo " ];
2015-07-18 18:15:21 +00:00
$server_url = $data [ " baseurl " ];
2015-01-24 23:19:59 +00:00
}
2015-01-26 00:07:15 +00:00
if ( count ( $x ) AND ( $x [ 0 ][ " network " ] == " " ) AND ( $network != " " )) {
q ( " UPDATE `gcontact` SET `network` = '%s' WHERE `nurl` = '%s' " ,
dbesc ( $network ),
dbesc ( normalise_link ( $profile_url ))
);
}
2015-01-24 23:19:59 +00:00
if (( $name == " " ) OR ( $profile_photo == " " ))
2015-01-06 06:23:11 +00:00
return $gcid ;
2015-02-16 21:11:51 +00:00
if ( ! in_array ( $network , array ( NETWORK_DFRN , NETWORK_OSTATUS , NETWORK_DIASPORA )))
2015-01-26 00:07:15 +00:00
return $gcid ;
2015-01-06 06:23:11 +00:00
2015-02-15 09:52:45 +00:00
logger ( " profile-check generation: " . $generation . " Network: " . $network . " URL: " . $profile_url . " name: " . $name . " avatar: " . $profile_photo , LOGGER_DEBUG );
2015-01-06 06:23:11 +00:00
2015-07-19 19:29:24 +00:00
poco_check_server ( $server_url , $network );
2015-07-17 22:48:42 +00:00
// Only fetch last update manually if it wasn't provided and enabled in the system
2015-07-22 09:51:37 +00:00
if ( get_config ( 'system' , 'poco_completion' ) AND ( $orig_updated == " 0000-00-00 00:00:00 " )
AND poco_do_update ( $created , $updated , $last_failure , $last_contact )
AND poco_reachable ( $profile_url , $server_url , $network )) {
2015-07-16 23:08:28 +00:00
$last_updated = poco_last_updated ( $profile_url );
if ( $last_updated ) {
$updated = $last_updated ;
$last_contact = datetime_convert ();
logger ( " Last updated for profile " . $profile_url . " : " . $updated , LOGGER_DEBUG );
2015-07-19 19:29:24 +00:00
} else
2015-07-16 23:08:28 +00:00
$last_failure = datetime_convert ();
}
2015-01-06 06:23:11 +00:00
if ( count ( $x )) {
$gcid = $x [ 0 ][ 'id' ];
2015-01-25 01:29:46 +00:00
if (( $location == " " ) AND ( $x [ 0 ][ 'location' ] != " " ))
$location = $x [ 0 ][ 'location' ];
if (( $about == " " ) AND ( $x [ 0 ][ 'about' ] != " " ))
$about = $x [ 0 ][ 'about' ];
2015-01-25 12:19:37 +00:00
if (( $gender == " " ) AND ( $x [ 0 ][ 'gender' ] != " " ))
$gender = $x [ 0 ][ 'gender' ];
if (( $keywords == " " ) AND ( $x [ 0 ][ 'keywords' ] != " " ))
$keywords = $x [ 0 ][ 'keywords' ];
2015-02-15 09:52:45 +00:00
if (( $generation == 0 ) AND ( $x [ 0 ][ 'generation' ] > 0 ))
$generation = $x [ 0 ][ 'generation' ];
2015-01-06 06:23:11 +00:00
if ( $x [ 0 ][ 'name' ] != $name || $x [ 0 ][ 'photo' ] != $profile_photo || $x [ 0 ][ 'updated' ] < $updated ) {
2015-07-18 18:15:21 +00:00
q ( " UPDATE `gcontact` SET `name` = '%s', `network` = '%s', `photo` = '%s', `connect` = '%s', `url` = '%s', `server_url` = '%s',
2015-02-15 09:52:45 +00:00
`updated` = '%s' , `location` = '%s' , `about` = '%s' , `keywords` = '%s' , `gender` = '%s' , `generation` = % d
WHERE ( `generation` >= % d OR `generation` = 0 ) AND `nurl` = '%s' " ,
2015-01-06 06:23:11 +00:00
dbesc ( $name ),
2015-01-08 06:59:20 +00:00
dbesc ( $network ),
2015-01-06 06:23:11 +00:00
dbesc ( $profile_photo ),
dbesc ( $connect_url ),
dbesc ( $profile_url ),
2015-07-18 18:15:21 +00:00
dbesc ( $server_url ),
2015-01-06 06:23:11 +00:00
dbesc ( $updated ),
2015-01-25 01:29:46 +00:00
dbesc ( $location ),
dbesc ( $about ),
2015-01-25 12:19:37 +00:00
dbesc ( $keywords ),
dbesc ( $gender ),
2015-02-15 09:52:45 +00:00
intval ( $generation ),
intval ( $generation ),
2015-01-06 06:23:11 +00:00
dbesc ( normalise_link ( $profile_url ))
);
}
} else {
2015-07-20 22:05:44 +00:00
q ( " INSERT INTO `gcontact` (`name`, `nick`, `network`, `url`, `nurl`, `photo`, `connect`, `server_url`, `created`, `updated`, `last_contact`, `last_failure`, `location`, `about`, `keywords`, `gender`, `generation`)
VALUES ( '%s' , '%s' , '%s' , '%s' , '%s' , '%s' , '%s' , '%s' , '%s' , '%s' , '%s' , '%s' , '%s' , '%s' , '%s' , '%s' , % d ) " ,
2015-01-06 06:23:11 +00:00
dbesc ( $name ),
2015-07-20 22:05:44 +00:00
dbesc ( $nick ),
2015-01-08 06:59:20 +00:00
dbesc ( $network ),
2015-01-06 06:23:11 +00:00
dbesc ( $profile_url ),
dbesc ( normalise_link ( $profile_url )),
dbesc ( $profile_photo ),
dbesc ( $connect_url ),
2015-07-18 18:15:21 +00:00
dbesc ( $server_url ),
2015-07-20 22:05:44 +00:00
dbesc ( datetime_convert ()),
2015-01-25 01:29:46 +00:00
dbesc ( $updated ),
2015-07-16 23:08:28 +00:00
dbesc ( $last_contact ),
dbesc ( $last_failure ),
2015-01-25 01:29:46 +00:00
dbesc ( $location ),
2015-01-25 12:19:37 +00:00
dbesc ( $about ),
dbesc ( $keywords ),
2015-02-15 09:52:45 +00:00
dbesc ( $gender ),
intval ( $generation )
2015-01-06 06:23:11 +00:00
);
$x = q ( " SELECT * FROM `gcontact` WHERE `nurl` = '%s' LIMIT 1 " ,
dbesc ( normalise_link ( $profile_url ))
);
if ( count ( $x ))
$gcid = $x [ 0 ][ 'id' ];
}
2015-01-06 07:16:15 +00:00
if ( ! $gcid )
return $gcid ;
$r = q ( " SELECT * FROM `glink` WHERE `cid` = %d AND `uid` = %d AND `gcid` = %d AND `zcid` = %d LIMIT 1 " ,
intval ( $cid ),
intval ( $uid ),
intval ( $gcid ),
intval ( $zcid )
);
if ( ! count ( $r )) {
q ( " INSERT INTO `glink` (`cid`,`uid`,`gcid`,`zcid`, `updated`) VALUES (%d,%d,%d,%d, '%s') " ,
intval ( $cid ),
intval ( $uid ),
intval ( $gcid ),
intval ( $zcid ),
dbesc ( datetime_convert ())
);
} else {
q ( " UPDATE `glink` SET `updated` = '%s' WHERE `cid` = %d AND `uid` = %d AND `gcid` = %d AND `zcid` = %d " ,
dbesc ( datetime_convert ()),
intval ( $cid ),
intval ( $uid ),
intval ( $gcid ),
intval ( $zcid )
);
}
// For unknown reasons there are sometimes duplicates
q ( " DELETE FROM `gcontact` WHERE `nurl` = '%s' AND `id` != %d AND
NOT EXISTS ( SELECT `gcid` FROM `glink` WHERE `gcid` = `gcontact` . `id` ) " ,
dbesc ( normalise_link ( $profile_url )),
intval ( $gcid )
);
2015-01-06 06:23:11 +00:00
return $gcid ;
}
2011-11-02 02:16:33 +00:00
2015-07-22 09:51:37 +00:00
function poco_reachable ( $profile , $server = " " , $network = " " ) {
if ( $server == " " )
$server = poco_detect_server ( $profile );
if ( $server == " " )
return true ;
return poco_check_server ( $server , $network );
}
function poco_detect_server ( $profile ) {
// Try to detect the server path based upon some known standard paths
$server_url = " " ;
if ( $server_url == " " ) {
$friendica = preg_replace ( " =(https?://)(.*)/profile/(.*)=ism " , " $ 1 $ 2 " , $profile );
if ( $friendica != $profile ) {
$server_url = $friendica ;
$network = NETWORK_DFRN ;
}
}
if ( $server_url == " " ) {
$diaspora = preg_replace ( " =(https?://)(.*)/u/(.*)=ism " , " $ 1 $ 2 " , $profile );
if ( $diaspora != $profile ) {
$server_url = $diaspora ;
$network = NETWORK_DIASPORA ;
}
}
if ( $server_url == " " ) {
$red = preg_replace ( " =(https?://)(.*)/channel/(.*)=ism " , " $ 1 $ 2 " , $profile );
if ( $red != $profile ) {
$server_url = $red ;
$network = NETWORK_DIASPORA ;
}
}
return $server_url ;
}
2015-07-16 23:08:28 +00:00
function poco_last_updated ( $profile ) {
2015-07-19 19:29:24 +00:00
$gcontacts = q ( " SELECT * FROM `gcontact` WHERE `nurl` = '%s' " ,
dbesc ( normalise_link ( $profile )));
2015-07-20 22:05:44 +00:00
if ( $gcontacts [ 0 ][ " created " ] == " 0000-00-00 00:00:00 " )
q ( " UPDATE `gcontact` SET `created` = '%s' WHERE `nurl` = '%s' " ,
dbesc ( datetime_convert ()), dbesc ( normalise_link ( $profile )));
2015-07-19 19:29:24 +00:00
2015-07-20 22:05:44 +00:00
if (( $gcontacts [ 0 ][ " server_url " ] != " " ) AND ( $gcontacts [ 0 ][ " network " ] != " " ))
if ( ! poco_check_server ( $gcontacts [ 0 ][ " server_url " ], $gcontacts [ 0 ][ " network " ]))
2015-07-19 19:29:24 +00:00
return false ;
2015-07-20 22:05:44 +00:00
// noscrape is really fast so we don't cache the call.
if (( $gcontacts [ 0 ][ " server_url " ] != " " ) AND ( $gcontacts [ 0 ][ " nick " ] != " " )) {
// Use noscrape if possible
$server = q ( " SELECT `noscrape` FROM `gserver` WHERE `nurl` = '%s' AND `noscrape` != '' " , dbesc ( normalise_link ( $gcontacts [ 0 ][ " server_url " ])));
if ( $server ) {
$noscraperet = z_fetch_url ( $server [ 0 ][ " noscrape " ] . " / " . $gcontacts [ 0 ][ " nick " ]);
if ( $noscraperet [ " success " ]) {
$noscrape = json_decode ( $noscraperet [ " body " ], true );
if (( $noscrape [ " name " ] != " " ) AND ( $noscrape [ " name " ] != $gcontacts [ 0 ][ " name " ]))
q ( " UPDATE `gcontact` SET `name` = '%s' WHERE `nurl` = '%s' " ,
dbesc ( $noscrape [ " name " ]), dbesc ( normalise_link ( $profile )));
if (( $noscrape [ " photo " ] != " " ) AND ( $noscrape [ " photo " ] != $gcontacts [ 0 ][ " photo " ]))
q ( " UPDATE `gcontact` SET `photo` = '%s' WHERE `nurl` = '%s' " ,
dbesc ( $noscrape [ " photo " ]), dbesc ( normalise_link ( $profile )));
if (( $noscrape [ " updated " ] != " " ) AND ( $noscrape [ " updated " ] != $gcontacts [ 0 ][ " updated " ]))
q ( " UPDATE `gcontact` SET `updated` = '%s' WHERE `nurl` = '%s' " ,
dbesc ( $noscrape [ " updated " ]), dbesc ( normalise_link ( $profile )));
if (( $noscrape [ " gender " ] != " " ) AND ( $noscrape [ " gender " ] != $gcontacts [ 0 ][ " gender " ]))
q ( " UPDATE `gcontact` SET `gender` = '%s' WHERE `nurl` = '%s' " ,
dbesc ( $noscrape [ " gender " ]), dbesc ( normalise_link ( $profile )));
if (( $noscrape [ " about " ] != " " ) AND ( $noscrape [ " about " ] != $gcontacts [ 0 ][ " name " ]))
q ( " UPDATE `gcontact` SET `about` = '%s' WHERE `nurl` = '%s' " ,
dbesc ( $noscrape [ " about " ]), dbesc ( normalise_link ( $profile )));
2015-07-22 22:32:41 +00:00
if ( isset ( $noscrape [ " tags " ]))
$keywords = implode ( " " , $noscrape [ " tags " ]);
else
$keywords = " " ;
2015-07-20 22:05:44 +00:00
if (( $keywords != " " ) AND ( $keywords != $gcontacts [ 0 ][ " keywords " ]))
q ( " UPDATE `gcontact` SET `keywords` = '%s' WHERE `nurl` = '%s' " ,
dbesc ( $keywords ), dbesc ( normalise_link ( $profile )));
$location = $noscrape [ " locality " ];
if ( $noscrape [ " region " ] != " " ) {
if ( $location != " " )
$location .= " , " ;
$location .= $noscrape [ " region " ];
}
if ( $noscrape [ " country-name " ] != " " ) {
if ( $location != " " )
$location .= " , " ;
$location .= $noscrape [ " country-name " ];
}
if (( $location != " " ) AND ( $location != $gcontacts [ 0 ][ " location " ]))
q ( " UPDATE `gcontact` SET `location` = '%s' WHERE `nurl` = '%s' " ,
dbesc ( $location ), dbesc ( normalise_link ( $profile )));
return $noscrape [ " updated " ];
}
}
2015-07-19 19:29:24 +00:00
}
2015-07-20 22:05:44 +00:00
// If we only can poll the feed, then we only do this once a while
if ( ! poco_do_update ( $gcontacts [ 0 ][ " created " ], $gcontacts [ 0 ][ " updated " ], $gcontacts [ 0 ][ " last_failure " ], $gcontacts [ 0 ][ " last_contact " ]))
2015-07-22 09:51:37 +00:00
return $gcontacts [ 0 ][ " updated " ];
2015-07-20 22:05:44 +00:00
2015-07-16 23:08:28 +00:00
$data = probe_url ( $profile );
2015-07-19 19:29:24 +00:00
if (( $data [ " poll " ] == " " ) OR ( $data [ " network " ] == NETWORK_FEED )) {
q ( " UPDATE `gcontact` SET `last_failure` = '%s' WHERE `nurl` = '%s' " ,
dbesc ( datetime_convert ()), dbesc ( normalise_link ( $profile )));
2015-07-16 23:08:28 +00:00
return false ;
2015-07-19 19:29:24 +00:00
}
if (( $data [ " name " ] != " " ) AND ( $data [ " name " ] != $gcontacts [ 0 ][ " name " ]))
q ( " UPDATE `gcontact` SET `name` = '%s' WHERE `nurl` = '%s' " ,
dbesc ( $data [ " name " ]), dbesc ( normalise_link ( $profile )));
2015-07-20 22:05:44 +00:00
if (( $data [ " nick " ] != " " ) AND ( $data [ " nick " ] != $gcontacts [ 0 ][ " nick " ]))
q ( " UPDATE `gcontact` SET `nick` = '%s' WHERE `nurl` = '%s' " ,
dbesc ( $data [ " nick " ]), dbesc ( normalise_link ( $profile )));
2015-07-19 19:29:24 +00:00
if (( $data [ " addr " ] != " " ) AND ( $data [ " addr " ] != $gcontacts [ 0 ][ " connect " ]))
q ( " UPDATE `gcontact` SET `connect` = '%s' WHERE `nurl` = '%s' " ,
dbesc ( $data [ " addr " ]), dbesc ( normalise_link ( $profile )));
if (( $data [ " photo " ] != " " ) AND ( $data [ " photo " ] != $gcontacts [ 0 ][ " photo " ]))
q ( " UPDATE `gcontact` SET `photo` = '%s' WHERE `nurl` = '%s' " ,
dbesc ( $data [ " photo " ]), dbesc ( normalise_link ( $profile )));
if (( $data [ " baseurl " ] != " " ) AND ( $data [ " baseurl " ] != $gcontacts [ 0 ][ " server_url " ]))
q ( " UPDATE `gcontact` SET `server_url` = '%s' WHERE `nurl` = '%s' " ,
dbesc ( $data [ " baseurl " ]), dbesc ( normalise_link ( $profile )));
2015-07-16 23:08:28 +00:00
$feedret = z_fetch_url ( $data [ " poll " ]);
2015-07-19 19:29:24 +00:00
if ( ! $feedret [ " success " ]) {
q ( " UPDATE `gcontact` SET `last_failure` = '%s' WHERE `nurl` = '%s' " ,
dbesc ( datetime_convert ()), dbesc ( normalise_link ( $profile )));
2015-07-16 23:08:28 +00:00
return false ;
2015-07-19 19:29:24 +00:00
}
2015-07-16 23:08:28 +00:00
$doc = new DOMDocument ();
@ $doc -> loadXML ( $feedret [ " body " ]);
$xpath = new DomXPath ( $doc );
$xpath -> registerNamespace ( 'atom' , " http://www.w3.org/2005/Atom " );
$entries = $xpath -> query ( '/atom:feed/atom:entry' );
$last_updated = " " ;
foreach ( $entries AS $entry ) {
$published = $xpath -> query ( 'atom:published/text()' , $entry ) -> item ( 0 ) -> nodeValue ;
$updated = $xpath -> query ( 'atom:updated/text()' , $entry ) -> item ( 0 ) -> nodeValue ;
if ( $last_updated < $published )
$last_updated = $published ;
if ( $last_updated < $updated )
$last_updated = $updated ;
}
// Maybe there aren't any entries. Then check if it is a valid feed
if ( $last_updated == " " )
if ( $xpath -> query ( '/atom:feed' ) -> length > 0 )
$last_updated = " 0000-00-00 00:00:00 " ;
2015-07-19 19:29:24 +00:00
q ( " UPDATE `gcontact` SET `updated` = '%s', `last_contact` = '%s' WHERE `nurl` = '%s' " ,
dbesc ( $last_updated ), dbesc ( datetime_convert ()), dbesc ( normalise_link ( $profile )));
2015-07-19 22:14:14 +00:00
if (( $gcontacts [ 0 ][ " generation " ] == 0 ))
q ( " UPDATE `gcontact` SET `generation` = 9 WHERE `nurl` = '%s' " ,
dbesc ( normalise_link ( $profile )));
2015-07-16 23:08:28 +00:00
return ( $last_updated );
}
2015-07-20 22:05:44 +00:00
function poco_do_update ( $created , $updated , $last_failure , $last_contact ) {
2015-07-16 23:08:28 +00:00
$now = strtotime ( datetime_convert ());
if ( $updated > $last_contact )
$contact_time = strtotime ( $updated );
else
$contact_time = strtotime ( $last_contact );
$failure_time = strtotime ( $last_failure );
2015-07-20 22:05:44 +00:00
$created_time = strtotime ( $created );
// If there is no "created" time then use the current time
if ( $created_time <= 0 )
$created_time = $now ;
2015-07-16 23:08:28 +00:00
// If the last contact was less than 24 hours then don't update
if (( $now - $contact_time ) < ( 60 * 60 * 24 ))
return false ;
// If the last failure was less than 24 hours then don't update
if (( $now - $failure_time ) < ( 60 * 60 * 24 ))
return false ;
// If the last contact was less than a week ago and the last failure is older than a week then don't update
if ((( $now - $contact_time ) < ( 60 * 60 * 24 * 7 )) AND ( $contact_time > $failure_time ))
return false ;
2015-07-20 22:05:44 +00:00
// If the last contact time was more than a week ago and the contact was created more than a week ago, then only try once a week
if ((( $now - $contact_time ) > ( 60 * 60 * 24 * 7 )) AND (( $now - $created_time ) > ( 60 * 60 * 24 * 7 )) AND (( $now - $failure_time ) < ( 60 * 60 * 24 * 7 )))
2015-07-16 23:08:28 +00:00
return false ;
2015-07-20 22:05:44 +00:00
// If the last contact time was more than a month ago and the contact was created more than a month ago, then only try once a month
if ((( $now - $contact_time ) > ( 60 * 60 * 24 * 30 )) AND (( $now - $created_time ) > ( 60 * 60 * 24 * 30 )) AND (( $now - $failure_time ) < ( 60 * 60 * 24 * 30 )))
2015-07-16 23:08:28 +00:00
return false ;
return true ;
}
2015-07-18 18:15:21 +00:00
function poco_to_boolean ( $val ) {
2015-07-18 20:26:06 +00:00
if (( $val == " true " ) OR ( $val == 1 ))
return ( true );
if (( $val == " false " ) OR ( $val == 0 ))
return ( false );
2015-07-18 18:15:21 +00:00
2015-07-18 20:26:06 +00:00
return ( $val );
2015-07-18 18:15:21 +00:00
}
2015-07-22 09:51:37 +00:00
function poco_check_server ( $server_url , $network = " " , $force = false ) {
2015-07-18 18:15:21 +00:00
if ( $server_url == " " )
2015-07-19 19:29:24 +00:00
return false ;
2015-07-18 18:15:21 +00:00
$servers = q ( " SELECT * FROM `gserver` WHERE `nurl` = '%s' " , dbesc ( normalise_link ( $server_url )));
if ( $servers ) {
2015-07-20 22:05:44 +00:00
if ( $servers [ 0 ][ " created " ] == " 0000-00-00 00:00:00 " )
q ( " UPDATE `gserver` SET `created` = '%s' WHERE `nurl` = '%s' " ,
dbesc ( datetime_convert ()), dbesc ( normalise_link ( $server_url )));
2015-07-18 18:15:21 +00:00
$poco = $servers [ 0 ][ " poco " ];
$noscrape = $servers [ 0 ][ " noscrape " ];
if ( $network == " " )
$network = $servers [ 0 ][ " network " ];
$last_contact = $servers [ 0 ][ " last_contact " ];
$last_failure = $servers [ 0 ][ " last_failure " ];
$version = $servers [ 0 ][ " version " ];
$platform = $servers [ 0 ][ " platform " ];
$site_name = $servers [ 0 ][ " site_name " ];
$info = $servers [ 0 ][ " info " ];
$register_policy = $servers [ 0 ][ " register_policy " ];
2015-07-22 09:51:37 +00:00
if ( ! $force AND ! poco_do_update ( $servers [ 0 ][ " created " ], " " , $last_failure , $last_contact )) {
logger ( " Use cached data for server " . $server_url , LOGGER_DEBUG );
2015-07-19 19:29:24 +00:00
return ( $last_contact >= $last_failure );
2015-07-22 09:51:37 +00:00
}
2015-07-18 18:15:21 +00:00
} else {
$poco = " " ;
$noscrape = " " ;
$version = " " ;
$platform = " " ;
$site_name = " " ;
$info = " " ;
$register_policy = - 1 ;
$last_contact = " 0000-00-00 00:00:00 " ;
$last_failure = " 0000-00-00 00:00:00 " ;
}
2015-07-22 09:51:37 +00:00
logger ( " Server " . $server_url . " is unknown. Start discovery. " , LOGGER_DEBUG );
2015-07-18 18:15:21 +00:00
$failure = false ;
$orig_last_failure = $last_failure ;
// Check if the page is accessible via SSL.
$server_url = str_replace ( " http:// " , " https:// " , $server_url );
$serverret = z_fetch_url ( $server_url . " /.well-known/host-meta " );
// Maybe the page is unencrypted only?
$xmlobj = @ simplexml_load_string ( $serverret [ " body " ], 'SimpleXMLElement' , 0 , " http://docs.oasis-open.org/ns/xri/xrd-1.0 " );
if ( ! $serverret [ " success " ] OR ( $serverret [ " body " ] == " " ) OR ( @ sizeof ( $xmlobj ) == 0 ) OR ! is_object ( $xmlobj )) {
$server_url = str_replace ( " https:// " , " http:// " , $server_url );
$serverret = z_fetch_url ( $server_url . " /.well-known/host-meta " );
$xmlobj = @ simplexml_load_string ( $serverret [ " body " ], 'SimpleXMLElement' , 0 , " http://docs.oasis-open.org/ns/xri/xrd-1.0 " );
}
if ( ! $serverret [ " success " ] OR ( $serverret [ " body " ] == " " ) OR ( sizeof ( $xmlobj ) == 0 ) OR ! is_object ( $xmlobj )) {
$last_failure = datetime_convert ();
$failure = true ;
} elseif ( $network == NETWORK_DIASPORA )
$last_contact = datetime_convert ();
2015-07-22 22:32:41 +00:00
if ( ! $failure ) {
// Test for Diaspora
$serverret = z_fetch_url ( $server_url );
$lines = explode ( " \n " , $serverret [ " header " ]);
if ( count ( $lines ))
foreach ( $lines as $line ) {
$line = trim ( $line );
if ( stristr ( $line , 'X-Diaspora-Version:' )) {
$platform = " Diaspora " ;
$version = trim ( str_replace ( " X-Diaspora-Version: " , " " , $line ));
$version = trim ( str_replace ( " x-diaspora-version: " , " " , $version ));
$network = NETWORK_DIASPORA ;
}
}
}
2015-07-18 18:15:21 +00:00
if ( ! $failure ) {
// Test for Statusnet
// Will also return data for Friendica and GNU Social - but it will be overwritten later
// The "not implemented" is a special treatment for really, really old Friendica versions
$serverret = z_fetch_url ( $server_url . " /api/statusnet/version.json " );
if ( $serverret [ " success " ] AND ( $serverret [ " body " ] != '{"error":"not implemented"}' ) AND ( $serverret [ " body " ] != '' ) AND ( strlen ( $serverret [ " body " ]) < 250 )) {
$platform = " StatusNet " ;
$version = trim ( $serverret [ " body " ], '"' );
$network = NETWORK_OSTATUS ;
}
// Test for GNU Social
$serverret = z_fetch_url ( $server_url . " /api/gnusocial/version.json " );
if ( $serverret [ " success " ] AND ( $serverret [ " body " ] != '{"error":"not implemented"}' ) AND ( $serverret [ " body " ] != '' ) AND ( strlen ( $serverret [ " body " ]) < 250 )) {
$platform = " GNU Social " ;
$version = trim ( $serverret [ " body " ], '"' );
$network = NETWORK_OSTATUS ;
}
$serverret = z_fetch_url ( $server_url . " /api/statusnet/config.json " );
if ( $serverret [ " success " ]) {
$data = json_decode ( $serverret [ " body " ]);
if ( isset ( $data -> site -> server )) {
$last_contact = datetime_convert ();
2015-07-19 22:14:14 +00:00
if ( isset ( $data -> site -> hubzilla )) {
$platform = $data -> site -> hubzilla -> PLATFORM_NAME ;
$version = $data -> site -> hubzilla -> RED_VERSION ;
2015-07-20 22:05:44 +00:00
$network = NETWORK_DIASPORA ;
2015-07-19 22:14:14 +00:00
}
2015-07-18 18:15:21 +00:00
if ( isset ( $data -> site -> redmatrix )) {
if ( isset ( $data -> site -> redmatrix -> PLATFORM_NAME ))
$platform = $data -> site -> redmatrix -> PLATFORM_NAME ;
elseif ( isset ( $data -> site -> redmatrix -> RED_PLATFORM ))
$platform = $data -> site -> redmatrix -> RED_PLATFORM ;
$version = $data -> site -> redmatrix -> RED_VERSION ;
$network = NETWORK_DIASPORA ;
}
if ( isset ( $data -> site -> friendica )) {
$platform = $data -> site -> friendica -> FRIENDICA_PLATFORM ;
$version = $data -> site -> friendica -> FRIENDICA_VERSION ;
$network = NETWORK_DFRN ;
}
$site_name = $data -> site -> name ;
$data -> site -> closed = poco_to_boolean ( $data -> site -> closed );
$data -> site -> private = poco_to_boolean ( $data -> site -> private );
$data -> site -> inviteonly = poco_to_boolean ( $data -> site -> inviteonly );
if ( ! $data -> site -> closed AND ! $data -> site -> private and $data -> site -> inviteonly )
$register_policy = REGISTER_APPROVE ;
elseif ( ! $data -> site -> closed AND ! $data -> site -> private )
$register_policy = REGISTER_OPEN ;
else
$register_policy = REGISTER_CLOSED ;
}
}
}
// Query statistics.json. Optional package for Diaspora, Friendica and Redmatrix
if ( ! $failure ) {
$serverret = z_fetch_url ( $server_url . " /statistics.json " );
if ( $serverret [ " success " ]) {
$data = json_decode ( $serverret [ " body " ]);
if ( $version == " " )
$version = $data -> version ;
$site_name = $data -> name ;
if ( isset ( $data -> network ) AND ( $platform == " " ))
$platform = $data -> network ;
2015-07-22 22:32:41 +00:00
if ( $platform == " Diaspora " )
$network = NETWORK_DIASPORA ;
2015-07-18 18:15:21 +00:00
if ( $data -> registrations_open )
$register_policy = REGISTER_OPEN ;
else
$register_policy = REGISTER_CLOSED ;
if ( isset ( $data -> version ))
$last_contact = datetime_convert ();
}
}
// Check for noscrape
// Friendica servers could be detected as OStatus servers
if ( ! $failure AND in_array ( $network , array ( NETWORK_DFRN , NETWORK_OSTATUS ))) {
$serverret = z_fetch_url ( $server_url . " /friendica/json " );
2015-07-22 22:32:41 +00:00
if ( ! $serverret [ " success " ])
$serverret = z_fetch_url ( $server_url . " /friendika/json " );
2015-07-18 18:15:21 +00:00
if ( $serverret [ " success " ]) {
$data = json_decode ( $serverret [ " body " ]);
if ( isset ( $data -> version )) {
$last_contact = datetime_convert ();
$network = NETWORK_DFRN ;
$noscrape = $data -> no_scrape_url ;
$version = $data -> version ;
$site_name = $data -> site_name ;
$info = $data -> info ;
$register_policy_str = $data -> register_policy ;
$platform = $data -> platform ;
switch ( $register_policy_str ) {
case " REGISTER_CLOSED " :
$register_policy = REGISTER_CLOSED ;
break ;
case " REGISTER_APPROVE " :
$register_policy = REGISTER_APPROVE ;
break ;
case " REGISTER_OPEN " :
$register_policy = REGISTER_OPEN ;
break ;
}
}
}
}
// Look for poco
if ( ! $failure ) {
$serverret = z_fetch_url ( $server_url . " /poco " );
if ( $serverret [ " success " ]) {
$data = json_decode ( $serverret [ " body " ]);
if ( isset ( $data -> totalResults )) {
$poco = $server_url . " /poco " ;
$last_contact = datetime_convert ();
}
}
}
2015-07-22 09:51:37 +00:00
// Check again if the server exists
$servers = q ( " SELECT `nurl` FROM `gserver` WHERE `nurl` = '%s' " , dbesc ( normalise_link ( $server_url )));
2015-07-18 18:15:21 +00:00
if ( $servers )
q ( " UPDATE `gserver` SET `url` = '%s', `version` = '%s', `site_name` = '%s', `info` = '%s', `register_policy` = %d, `poco` = '%s', `noscrape` = '%s',
`network` = '%s' , `platform` = '%s' , `last_contact` = '%s' , `last_failure` = '%s' WHERE `nurl` = '%s' " ,
dbesc ( $server_url ),
dbesc ( $version ),
dbesc ( $site_name ),
dbesc ( $info ),
intval ( $register_policy ),
dbesc ( $poco ),
dbesc ( $noscrape ),
dbesc ( $network ),
dbesc ( $platform ),
dbesc ( $last_contact ),
dbesc ( $last_failure ),
dbesc ( normalise_link ( $server_url ))
);
else
2015-07-20 22:05:44 +00:00
q ( " INSERT INTO `gserver` (`url`, `nurl`, `version`, `site_name`, `info`, `register_policy`, `poco`, `noscrape`, `network`, `platform`, `created`, `last_contact`, `last_failure`)
2015-07-22 09:51:37 +00:00
VALUES ( '%s' , '%s' , '%s' , '%s' , '%s' , % d , '%s' , '%s' , '%s' , '%s' , '%s' , '%s' , '%s' ) " ,
2015-07-18 18:15:21 +00:00
dbesc ( $server_url ),
dbesc ( normalise_link ( $server_url )),
dbesc ( $version ),
dbesc ( $site_name ),
dbesc ( $info ),
intval ( $register_policy ),
dbesc ( $poco ),
dbesc ( $noscrape ),
dbesc ( $network ),
dbesc ( $platform ),
2015-07-20 22:05:44 +00:00
dbesc ( datetime_convert ()),
2015-07-19 22:14:14 +00:00
dbesc ( $last_contact ),
dbesc ( $last_failure ),
2015-07-18 18:15:21 +00:00
dbesc ( datetime_convert ())
);
2015-07-22 09:51:37 +00:00
logger ( " End discovery for server " . $server_url , LOGGER_DEBUG );
2015-07-19 22:14:14 +00:00
return ! $failure ;
2015-07-18 18:15:21 +00:00
}
2015-01-24 23:19:59 +00:00
function poco_contact_from_body ( $body , $created , $cid , $uid ) {
preg_replace_callback ( " / \ [share(.*?) \ ].*? \ [ \ /share \ ]/ism " ,
function ( $match ) use ( $created , $cid , $uid ){
return ( sub_poco_from_share ( $match , $created , $cid , $uid ));
}, $body );
}
function sub_poco_from_share ( $share , $created , $cid , $uid ) {
2015-07-16 23:08:28 +00:00
$profile = " " ;
preg_match ( " /profile='(.*?)'/ism " , $share [ 1 ], $matches );
if ( $matches [ 1 ] != " " )
$profile = $matches [ 1 ];
2015-01-24 23:19:59 +00:00
2015-07-16 23:08:28 +00:00
preg_match ( '/profile="(.*?)"/ism' , $share [ 1 ], $matches );
if ( $matches [ 1 ] != " " )
$profile = $matches [ 1 ];
2015-01-24 23:19:59 +00:00
if ( $profile == " " )
return ;
logger ( " prepare poco_check for profile " . $profile , LOGGER_DEBUG );
2015-07-16 23:08:28 +00:00
poco_check ( $profile , " " , " " , " " , " " , " " , " " , " " , " " , $created , 3 , $cid , $uid );
2015-02-15 09:52:45 +00:00
}
function poco_store ( $item ) {
// Isn't it public?
2015-02-16 21:11:51 +00:00
if ( $item [ 'private' ])
2015-02-15 09:52:45 +00:00
return ;
// Or is it from a network where we don't store the global contacts?
2015-02-16 21:11:51 +00:00
if ( ! in_array ( $item [ " network " ], array ( NETWORK_DFRN , NETWORK_DIASPORA , NETWORK_OSTATUS , NETWORK_STATUSNET , " " )))
2015-02-15 09:52:45 +00:00
return ;
// Is it a global copy?
$store_gcontact = ( $item [ " uid " ] == 0 );
// Is it a comment on a global copy?
if ( ! $store_gcontact AND ( $item [ " uri " ] != $item [ " parent-uri " ])) {
$q = q ( " SELECT `id` FROM `item` WHERE `uri`='%s' AND `uid` = 0 " , $item [ " parent-uri " ]);
$store_gcontact = count ( $q );
}
if ( ! $store_gcontact )
return ;
// "3" means: We don't know this contact directly (Maybe a reshared item)
$generation = 3 ;
$network = " " ;
2015-02-16 21:11:51 +00:00
$profile_url = $item [ " author-link " ];
2015-02-15 09:52:45 +00:00
// Is it a user from our server?
$q = q ( " SELECT `id` FROM `contact` WHERE `self` AND `nurl` = '%s' LIMIT 1 " ,
dbesc ( normalise_link ( $item [ " author-link " ])));
if ( count ( $q )) {
2015-02-16 21:11:51 +00:00
logger ( " Our user (generation 1): " . $item [ " author-link " ], LOGGER_DEBUG );
2015-02-15 09:52:45 +00:00
$generation = 1 ;
$network = NETWORK_DFRN ;
} else { // Is it a contact from a user on our server?
2015-02-16 21:11:51 +00:00
$q = q ( " SELECT `network`, `url` FROM `contact` WHERE `uid` != 0 AND `network` != ''
AND ( `nurl` = '%s' OR `alias` IN ( '%s' , '%s' )) AND `network` != '%s' LIMIT 1 " ,
2015-02-15 09:52:45 +00:00
dbesc ( normalise_link ( $item [ " author-link " ])),
dbesc ( normalise_link ( $item [ " author-link " ])),
2015-02-16 21:11:51 +00:00
dbesc ( $item [ " author-link " ]),
dbesc ( NETWORK_STATUSNET ));
2015-02-15 09:52:45 +00:00
if ( count ( $q )) {
$generation = 2 ;
$network = $q [ 0 ][ " network " ];
2015-02-16 21:11:51 +00:00
$profile_url = $q [ 0 ][ " url " ];
logger ( " Known contact (generation 2): " . $profile_url , LOGGER_DEBUG );
2015-02-15 09:52:45 +00:00
}
}
2015-02-16 21:11:51 +00:00
if ( $generation == 3 )
logger ( " Unknown contact (generation 3): " . $item [ " author-link " ], LOGGER_DEBUG );
poco_check ( $profile_url , $item [ " author-name " ], $network , $item [ " author-avatar " ], " " , " " , " " , " " , " " , $item [ " received " ], $generation , $item [ " contact-id " ], $item [ " uid " ]);
2015-02-15 09:52:45 +00:00
// Maybe its a body with a shared item? Then extract a global contact from it.
poco_contact_from_body ( $item [ " body " ], $item [ " received " ], $item [ " contact-id " ], $item [ " uid " ]);
2015-01-24 23:19:59 +00:00
}
2011-11-02 02:16:33 +00:00
function count_common_friends ( $uid , $cid ) {
$r = q ( " SELECT count(*) as `total`
2014-03-09 08:19:14 +00:00
FROM `glink` INNER JOIN `gcontact` on `glink` . `gcid` = `gcontact` . `id`
2011-11-02 02:16:33 +00:00
where `glink` . `cid` = % d and `glink` . `uid` = % d
2012-05-02 23:15:59 +00:00
and `gcontact` . `nurl` in ( select nurl from contact where uid = % d and self = 0 and blocked = 0 and hidden = 0 and id != % d ) " ,
2011-11-02 02:16:33 +00:00
intval ( $cid ),
intval ( $uid ),
intval ( $uid ),
intval ( $cid )
);
2012-05-04 03:47:04 +00:00
// logger("count_common_friends: $uid $cid {$r[0]['total']}");
2011-11-02 02:16:33 +00:00
if ( count ( $r ))
return $r [ 0 ][ 'total' ];
return 0 ;
}
2012-05-04 08:46:36 +00:00
function common_friends ( $uid , $cid , $start = 0 , $limit = 9999 , $shuffle = false ) {
2012-05-02 07:44:37 +00:00
if ( $shuffle )
$sql_extra = " order by rand() " ;
else
2015-01-08 06:59:20 +00:00
$sql_extra = " order by `gcontact`.`name` asc " ;
2011-11-02 02:16:33 +00:00
2015-01-08 06:59:20 +00:00
$r = q ( " SELECT `gcontact`.*
2014-03-09 08:19:14 +00:00
FROM `glink` INNER JOIN `gcontact` on `glink` . `gcid` = `gcontact` . `id`
2011-11-02 02:16:33 +00:00
where `glink` . `cid` = % d and `glink` . `uid` = % d
2012-05-02 23:15:59 +00:00
and `gcontact` . `nurl` in ( select nurl from contact where uid = % d and self = 0 and blocked = 0 and hidden = 0 and id != % d )
2012-05-04 08:46:36 +00:00
$sql_extra limit % d , % d " ,
2011-11-02 02:16:33 +00:00
intval ( $cid ),
intval ( $uid ),
intval ( $uid ),
2012-05-02 04:22:27 +00:00
intval ( $cid ),
2012-05-04 08:46:36 +00:00
intval ( $start ),
2012-05-02 04:22:27 +00:00
intval ( $limit )
2011-11-02 02:16:33 +00:00
);
return $r ;
2011-11-02 03:29:55 +00:00
}
2012-05-02 02:16:18 +00:00
2012-05-02 03:33:19 +00:00
function count_common_friends_zcid ( $uid , $zcid ) {
2012-05-02 02:16:18 +00:00
2015-01-08 06:59:20 +00:00
$r = q ( " SELECT count(*) as `total`
2014-03-09 08:19:14 +00:00
FROM `glink` INNER JOIN `gcontact` on `glink` . `gcid` = `gcontact` . `id`
2012-05-02 03:33:19 +00:00
where `glink` . `zcid` = % d
2012-05-02 23:15:59 +00:00
and `gcontact` . `nurl` in ( select nurl from contact where uid = % d and self = 0 and blocked = 0 and hidden = 0 ) " ,
2012-05-02 03:33:19 +00:00
intval ( $zcid ),
2012-05-02 03:36:35 +00:00
intval ( $uid )
2012-05-02 02:16:18 +00:00
);
if ( count ( $r ))
return $r [ 0 ][ 'total' ];
return 0 ;
}
2012-07-16 00:07:53 +00:00
function common_friends_zcid ( $uid , $zcid , $start = 0 , $limit = 9999 , $shuffle = false ) {
2012-05-02 07:44:37 +00:00
if ( $shuffle )
$sql_extra = " order by rand() " ;
else
2015-01-08 06:59:20 +00:00
$sql_extra = " order by `gcontact`.`name` asc " ;
2012-05-02 02:16:18 +00:00
2015-01-08 06:59:20 +00:00
$r = q ( " SELECT `gcontact`.*
2014-03-09 08:19:14 +00:00
FROM `glink` INNER JOIN `gcontact` on `glink` . `gcid` = `gcontact` . `id`
2012-05-02 03:33:19 +00:00
where `glink` . `zcid` = % d
2012-05-02 23:15:59 +00:00
and `gcontact` . `nurl` in ( select nurl from contact where uid = % d and self = 0 and blocked = 0 and hidden = 0 )
2012-05-04 08:46:36 +00:00
$sql_extra limit % d , % d " ,
2012-05-02 03:33:19 +00:00
intval ( $zcid ),
2012-05-02 02:16:18 +00:00
intval ( $uid ),
2012-05-04 08:46:36 +00:00
intval ( $start ),
2012-05-02 02:16:18 +00:00
intval ( $limit )
);
return $r ;
}
2011-11-09 02:30:20 +00:00
function count_all_friends ( $uid , $cid ) {
$r = q ( " SELECT count(*) as `total`
2014-03-09 08:19:14 +00:00
FROM `glink` INNER JOIN `gcontact` on `glink` . `gcid` = `gcontact` . `id`
2011-11-09 02:30:20 +00:00
where `glink` . `cid` = % d and `glink` . `uid` = % d " ,
intval ( $cid ),
intval ( $uid )
);
if ( count ( $r ))
return $r [ 0 ][ 'total' ];
return 0 ;
}
function all_friends ( $uid , $cid , $start = 0 , $limit = 80 ) {
2015-01-08 06:59:20 +00:00
$r = q ( " SELECT `gcontact`.*
2014-03-09 08:19:14 +00:00
FROM `glink` INNER JOIN `gcontact` on `glink` . `gcid` = `gcontact` . `id`
2015-01-08 06:59:20 +00:00
where `glink` . `cid` = % d and `glink` . `uid` = % d
2011-11-10 03:30:14 +00:00
order by `gcontact` . `name` asc LIMIT % d , % d " ,
2011-11-09 02:30:20 +00:00
intval ( $cid ),
intval ( $uid ),
intval ( $start ),
intval ( $limit )
);
return $r ;
}
2011-11-02 03:29:55 +00:00
2012-03-21 02:06:26 +00:00
function suggestion_query ( $uid , $start = 0 , $limit = 80 ) {
2011-11-02 03:29:55 +00:00
2011-11-02 04:27:11 +00:00
if ( ! $uid )
return array ();
2015-01-08 10:01:55 +00:00
$network = array ( NETWORK_DFRN );
2015-01-08 06:59:20 +00:00
if ( get_config ( 'system' , 'diaspora_enabled' ))
$network [] = NETWORK_DIASPORA ;
if ( ! get_config ( 'system' , 'ostatus_disabled' ))
$network [] = NETWORK_OSTATUS ;
$sql_network = implode ( " ', ' " , $network );
2015-01-08 10:01:55 +00:00
//$sql_network = "'".$sql_network."', ''";
$sql_network = " ' " . $sql_network . " ' " ;
2015-01-08 06:59:20 +00:00
2015-01-05 07:03:29 +00:00
$r = q ( " SELECT count(glink.gcid) as `total`, gcontact.* from gcontact
INNER JOIN glink on glink . gcid = gcontact . id
2012-03-26 04:43:17 +00:00
where uid = % d and not gcontact . nurl in ( select nurl from contact where uid = % d )
and not gcontact . name in ( select name from contact where uid = % d )
2011-11-03 23:00:52 +00:00
and not gcontact . id in ( select gcid from gcign where uid = % d )
2015-01-05 07:03:29 +00:00
AND `gcontact` . `updated` != '0000-00-00 00:00:00'
2015-07-17 06:38:20 +00:00
AND `gcontact` . `last_contact` >= `gcontact` . `last_failure`
2015-01-08 06:59:20 +00:00
AND `gcontact` . `network` IN ( % s )
2015-01-05 07:03:29 +00:00
group by glink . gcid order by gcontact . updated desc , total desc limit % d , % d " ,
2011-11-02 03:29:55 +00:00
intval ( $uid ),
intval ( $uid ),
2011-11-03 23:00:52 +00:00
intval ( $uid ),
2012-03-26 04:43:17 +00:00
intval ( $uid ),
2015-01-08 06:59:20 +00:00
$sql_network ,
2011-11-02 03:29:55 +00:00
intval ( $start ),
intval ( $limit )
);
2011-12-18 21:03:20 +00:00
if ( count ( $r ) && count ( $r ) >= ( $limit - 1 ))
2011-11-29 03:28:33 +00:00
return $r ;
2015-01-05 07:03:29 +00:00
$r2 = q ( " SELECT gcontact.* from gcontact
INNER JOIN glink on glink . gcid = gcontact . id
2012-05-01 08:16:47 +00:00
where glink . uid = 0 and glink . cid = 0 and glink . zcid = 0 and not gcontact . nurl in ( select nurl from contact where uid = % d )
2012-03-26 04:43:17 +00:00
and not gcontact . name in ( select name from contact where uid = % d )
2011-11-29 03:28:33 +00:00
and not gcontact . id in ( select gcid from gcign where uid = % d )
2015-01-05 07:03:29 +00:00
AND `gcontact` . `updated` != '0000-00-00 00:00:00'
2015-01-08 06:59:20 +00:00
AND `gcontact` . `network` IN ( % s )
2011-12-18 21:03:20 +00:00
order by rand () limit % d , % d " ,
intval ( $uid ),
2011-11-29 03:28:33 +00:00
intval ( $uid ),
2012-03-26 04:43:17 +00:00
intval ( $uid ),
2015-01-08 06:59:20 +00:00
$sql_network ,
2011-11-29 03:28:33 +00:00
intval ( $start ),
intval ( $limit )
);
2015-01-05 07:03:29 +00:00
$list = array ();
foreach ( $r2 AS $suggestion )
$list [ $suggestion [ " nurl " ]] = $suggestion ;
2011-12-18 21:03:20 +00:00
2015-01-05 07:03:29 +00:00
foreach ( $r AS $suggestion )
$list [ $suggestion [ " nurl " ]] = $suggestion ;
2011-11-02 03:29:55 +00:00
2015-01-05 07:03:29 +00:00
return $list ;
2011-11-02 03:29:55 +00:00
}
2011-11-29 03:28:33 +00:00
function update_suggestions () {
$a = get_app ();
$done = array ();
2015-07-19 08:40:33 +00:00
// To-Do: Check if it is really neccessary to poll the own server
2012-05-01 08:16:47 +00:00
poco_load ( 0 , 0 , 0 , $a -> get_baseurl () . '/poco' );
2011-11-29 03:28:33 +00:00
$done [] = $a -> get_baseurl () . '/poco' ;
if ( strlen ( get_config ( 'system' , 'directory_submit_url' ))) {
$x = fetch_url ( 'http://dir.friendica.com/pubsites' );
if ( $x ) {
$j = json_decode ( $x );
if ( $j -> entries ) {
foreach ( $j -> entries as $entry ) {
2015-07-19 08:40:33 +00:00
poco_check_server ( $entry -> url );
2011-11-29 03:28:33 +00:00
$url = $entry -> url . '/poco' ;
if ( ! in_array ( $url , $done ))
2012-05-01 08:16:47 +00:00
poco_load ( 0 , 0 , 0 , $entry -> url . '/poco' );
2011-11-29 03:28:33 +00:00
}
}
}
}
2015-07-19 08:40:33 +00:00
// Query your contacts from Friendica and Redmatrix/Hubzilla for their contacts
$r = q ( " SELECT DISTINCT(`poco`) AS `poco` FROM `contact` WHERE `network` IN ('%s', '%s') " ,
dbesc ( NETWORK_DFRN ), dbesc ( NETWORK_DIASPORA )
2011-11-29 03:28:33 +00:00
);
if ( count ( $r )) {
foreach ( $r as $rr ) {
$base = substr ( $rr [ 'poco' ], 0 , strrpos ( $rr [ 'poco' ], '/' ));
if ( ! in_array ( $base , $done ))
2012-05-01 08:16:47 +00:00
poco_load ( 0 , 0 , 0 , $base );
2011-11-29 03:28:33 +00:00
}
}
}
2015-07-18 20:26:06 +00:00
2015-07-19 07:41:36 +00:00
function poco_discover ( $complete = false ) {
2015-07-18 20:26:06 +00:00
2015-07-22 09:51:37 +00:00
$no_of_queries = 5 ;
$last_update = date ( " c " , time () - ( 60 * 60 * 6 )); // 24
2015-07-18 20:26:06 +00:00
2015-07-22 09:51:37 +00:00
$r = q ( " SELECT `poco`, `nurl`, `url`, `network` FROM `gserver` WHERE `last_contact` > `last_failure` AND `poco` != '' AND `last_poco_query` < '%s' ORDER BY RAND() " , dbesc ( $last_update ));
2015-07-18 20:26:06 +00:00
if ( $r )
foreach ( $r AS $server ) {
2015-07-22 09:51:37 +00:00
if ( ! poco_check_server ( $server [ " url " ], $server [ " network " ]))
continue ;
2015-07-18 21:33:54 +00:00
// Fetch all users from the other server
$url = $server [ " poco " ] . " /?fields=displayName,urls,photos,updated,network,aboutMe,currentLocation,tags,gender,generation " ;
2015-07-18 20:26:06 +00:00
2015-07-19 07:41:36 +00:00
logger ( " Fetch all users from the server " . $server [ " nurl " ], LOGGER_DEBUG );
2015-07-18 20:26:06 +00:00
$retdata = z_fetch_url ( $url );
if ( $retdata [ " success " ]) {
2015-07-19 07:41:36 +00:00
$data = json_decode ( $retdata [ " body " ]);
2015-07-22 09:51:37 +00:00
2015-07-19 07:41:36 +00:00
poco_discover_server ( $data , 2 );
if ( get_config ( 'system' , 'poco_discovery' ) > 1 ) {
2015-07-20 22:05:44 +00:00
$timeframe = get_config ( 'system' , 'poco_discovery_since' );
if ( $timeframe == 0 )
$timeframe = 30 ;
$updatedSince = date ( " Y-m-d H:i:s " , time () - $timeframe * 86400 );
2015-07-19 07:41:36 +00:00
// Fetch all global contacts from the other server (Not working with Redmatrix and Friendica versions before 3.3)
2015-07-20 22:05:44 +00:00
$url = $server [ " poco " ] . " /@global?updatedSince= " . $updatedSince . " &fields=displayName,urls,photos,updated,network,aboutMe,currentLocation,tags,gender,generation " ;
2015-07-19 07:41:36 +00:00
2015-07-22 09:51:37 +00:00
$success = false ;
2015-07-19 07:41:36 +00:00
$retdata = z_fetch_url ( $url );
if ( $retdata [ " success " ]) {
logger ( " Fetch all global contacts from the server " . $server [ " nurl " ], LOGGER_DEBUG );
2015-07-22 09:51:37 +00:00
$success = poco_discover_server ( json_decode ( $retdata [ " body " ]));
}
if ( ! $success AND ( get_config ( 'system' , 'poco_discovery' ) > 2 )) {
2015-07-19 07:41:36 +00:00
logger ( " Fetch contacts from users of the server " . $server [ " nurl " ], LOGGER_DEBUG );
2015-07-22 09:51:37 +00:00
poco_discover_server_users ( $data , $server );
2015-07-19 07:41:36 +00:00
}
}
2015-07-18 21:33:54 +00:00
2015-07-18 20:26:06 +00:00
q ( " UPDATE `gserver` SET `last_poco_query` = '%s' WHERE `nurl` = '%s' " , dbesc ( datetime_convert ()), dbesc ( $server [ " nurl " ]));
2015-07-22 09:51:37 +00:00
if ( ! $complete AND ( -- $no_of_queries == 0 ))
2015-07-19 07:41:36 +00:00
break ;
2015-07-22 09:51:37 +00:00
} else // If the server hadn't replied correctly, then force a sanity check
poco_check_server ( $server [ " url " ], $server [ " network " ], true );
2015-07-18 20:26:06 +00:00
}
}
2015-07-22 09:51:37 +00:00
function poco_discover_server_users ( $data , $server ) {
2015-07-22 22:32:41 +00:00
if ( ! isset ( $data -> entry ))
return ;
2015-07-19 07:41:36 +00:00
foreach ( $data -> entry AS $entry ) {
$username = " " ;
if ( isset ( $entry -> urls )) {
foreach ( $entry -> urls as $url )
if ( $url -> type == 'profile' ) {
$profile_url = $url -> value ;
$urlparts = parse_url ( $profile_url );
$username = end ( explode ( " / " , $urlparts [ " path " ]));
}
}
if ( $username != " " ) {
logger ( " Fetch contacts for the user " . $username . " from the server " . $server [ " nurl " ], LOGGER_DEBUG );
// Fetch all contacts from a given user from the other server
$url = $server [ " poco " ] . " / " . $username . " /?fields=displayName,urls,photos,updated,network,aboutMe,currentLocation,tags,gender,generation " ;
$retdata = z_fetch_url ( $url );
if ( $retdata [ " success " ])
poco_discover_server ( json_decode ( $retdata [ " body " ]), 3 );
}
}
}
2015-07-18 21:33:54 +00:00
function poco_discover_server ( $data , $default_generation = 0 ) {
2015-07-18 20:26:06 +00:00
2015-07-19 07:41:36 +00:00
if ( ! isset ( $data -> entry ) OR ! count ( $data -> entry ))
2015-07-22 09:51:37 +00:00
return false ;
$success = false ;
2015-07-19 07:41:36 +00:00
2015-07-18 20:26:06 +00:00
foreach ( $data -> entry AS $entry ) {
$profile_url = '' ;
$profile_photo = '' ;
$connect_url = '' ;
$name = '' ;
$network = '' ;
$updated = '0000-00-00 00:00:00' ;
$location = '' ;
$about = '' ;
$keywords = '' ;
$gender = '' ;
2015-07-18 21:33:54 +00:00
$generation = $default_generation ;
2015-07-18 20:26:06 +00:00
$name = $entry -> displayName ;
if ( isset ( $entry -> urls )) {
foreach ( $entry -> urls as $url ) {
if ( $url -> type == 'profile' ) {
$profile_url = $url -> value ;
continue ;
}
if ( $url -> type == 'webfinger' ) {
$connect_url = str_replace ( 'acct:' , '' , $url -> value );
continue ;
}
}
}
2015-07-22 09:51:37 +00:00
2015-07-18 20:26:06 +00:00
if ( isset ( $entry -> photos )) {
foreach ( $entry -> photos as $photo ) {
if ( $photo -> type == 'profile' ) {
$profile_photo = $photo -> value ;
continue ;
}
}
}
if ( isset ( $entry -> updated ))
$updated = date ( " Y-m-d H:i:s " , strtotime ( $entry -> updated ));
if ( isset ( $entry -> network ))
$network = $entry -> network ;
if ( isset ( $entry -> currentLocation ))
$location = $entry -> currentLocation ;
if ( isset ( $entry -> aboutMe ))
$about = html2bbcode ( $entry -> aboutMe );
if ( isset ( $entry -> gender ))
$gender = $entry -> gender ;
if ( isset ( $entry -> generation ) AND ( $entry -> generation > 0 ))
$generation = ++ $entry -> generation ;
if ( isset ( $entry -> tags ))
foreach ( $entry -> tags as $tag )
$keywords = implode ( " , " , $tag );
2015-07-19 07:41:36 +00:00
if ( $generation > 0 ) {
2015-07-22 09:51:37 +00:00
$success = true ;
2015-07-19 07:41:36 +00:00
logger ( " Store profile " . $profile_url , LOGGER_DEBUG );
2015-07-22 09:51:37 +00:00
poco_check ( $profile_url , $name , $network , $profile_photo , $about , $location , $gender , $keywords , $connect_url , $updated , $generation , 0 , 0 , 0 );
2015-07-19 07:41:36 +00:00
logger ( " Done for profile " . $profile_url , LOGGER_DEBUG );
}
2015-07-18 20:26:06 +00:00
}
2015-07-22 09:51:37 +00:00
return $success ;
2015-07-18 20:26:06 +00:00
}
?>