X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=include%2Fsocgraph.php;h=186326f42d961a11ca39c9e002f7b8b16ec07692;hb=9619829b4ab693bdbe2e24071e3d39d840d855b0;hp=c5aa08d086637faaece17f143bb95491f0f51fa2;hpb=2e81d0a2b3cd2b76495472c8ee2ef04524c2447a;p=friendica.git diff --git a/include/socgraph.php b/include/socgraph.php index c5aa08d086..186326f42d 100644 --- a/include/socgraph.php +++ b/include/socgraph.php @@ -1,15 +1,17 @@ 0)) - $generation = $x[0]['generation']; - - if($x[0]['name'] != $name || $x[0]['photo'] != $profile_photo || $x[0]['updated'] < $updated) { - q("UPDATE `gcontact` SET `name` = '%s', `addr` = '%s', `network` = '%s', `photo` = '%s', `connect` = '%s', `url` = '%s', `server_url` = '%s', - `updated` = '%s', `location` = '%s', `about` = '%s', `keywords` = '%s', `gender` = '%s', `generation` = %d - WHERE (`generation` >= %d OR `generation` = 0) AND `nurl` = '%s'", - dbesc($name), - dbesc($addr), - dbesc($network), - dbesc($profile_photo), - dbesc($connect_url), - dbesc($profile_url), - dbesc($server_url), - dbesc($updated), - dbesc($location), - dbesc($about), - dbesc($keywords), - dbesc($gender), - intval($generation), - intval($generation), - dbesc(normalise_link($profile_url)) - ); - } - } else { - q("INSERT INTO `gcontact` (`name`, `nick`, `addr`, `network`, `url`, `nurl`, `photo`, `connect`, `server_url`, `created`, `updated`, `location`, `about`, `keywords`, `gender`, `generation`) - VALUES ('%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', %d)", - dbesc($name), - dbesc($nick), - dbesc($addr), - dbesc($network), - dbesc($profile_url), - dbesc(normalise_link($profile_url)), - dbesc($profile_photo), - dbesc($connect_url), - dbesc($server_url), - dbesc(datetime_convert()), - dbesc($updated), - dbesc($location), - dbesc($about), - dbesc($keywords), - dbesc($gender), - intval($generation) - ); - $x = q("SELECT * FROM `gcontact` WHERE `nurl` = '%s' LIMIT 1", - dbesc(normalise_link($profile_url)) - ); - if(count($x)) - $gcid = $x[0]['id']; - } - - if(! $gcid) + $gcontact = array("url" => $profile_url, + "addr" => $addr, + "alias" => $alias, + "name" => $name, + "network" => $network, + "photo" => $profile_photo, + "about" => $about, + "location" => $location, + "gender" => $gender, + "keywords" => $keywords, + "server_url" => $server_url, + "connect" => $connect_url, + "notify" => $notify, + "updated" => $updated, + "generation" => $generation); + + $gcid = update_gcontact($gcontact); + + if(!$gcid) return $gcid; $r = q("SELECT * FROM `glink` WHERE `cid` = %d AND `uid` = %d AND `gcid` = %d AND `zcid` = %d LIMIT 1", @@ -378,13 +336,6 @@ function poco_check($profile_url, $name, $network, $profile_photo, $about, $loca ); } - // 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) - ); - return $gcid; } @@ -478,7 +429,7 @@ function poco_last_updated($profile, $force = false) { 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"]))); + $server = q("SELECT `noscrape`, `network` 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"]); @@ -487,69 +438,47 @@ function poco_last_updated($profile, $force = false) { $noscrape = json_decode($noscraperet["body"], true); - if (($noscrape["fn"] != "") AND ($noscrape["fn"] != $gcontacts[0]["name"])) - q("UPDATE `gcontact` SET `name` = '%s' WHERE `nurl` = '%s'", - dbesc($noscrape["fn"]), 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 (is_array($noscrape)) { + $contact = array("url" => $profile, + "network" => $server[0]["network"], + "generation" => $gcontacts[0]["generation"]); - if (($noscrape["pdesc"] != "") AND ($noscrape["pdesc"] != $gcontacts[0]["about"])) - q("UPDATE `gcontact` SET `about` = '%s' WHERE `nurl` = '%s'", - dbesc($noscrape["pdesc"]), dbesc(normalise_link($profile))); + $contact["name"] = $noscrape["fn"]; + $contact["community"] = $noscrape["comm"]; - if (($noscrape["about"] != "") AND ($noscrape["about"] != $gcontacts[0]["about"])) - q("UPDATE `gcontact` SET `about` = '%s' WHERE `nurl` = '%s'", - dbesc($noscrape["about"]), dbesc(normalise_link($profile))); - - if (isset($noscrape["comm"]) AND ($noscrape["comm"] != $gcontacts[0]["community"])) - q("UPDATE `gcontact` SET `community` = %d WHERE `nurl` = '%s'", - intval($noscrape["comm"]), dbesc(normalise_link($profile))); - - if (isset($noscrape["tags"])) - $keywords = implode(" ", $noscrape["tags"]); - else - $keywords = ""; + if (isset($noscrape["tags"])) { + $keywords = implode(" ", $noscrape["tags"]); + if ($keywords != "") + $contact["keywords"] = $keywords; + } - if (($keywords != "") AND ($keywords != $gcontacts[0]["keywords"])) - q("UPDATE `gcontact` SET `keywords` = '%s' WHERE `nurl` = '%s'", - dbesc($keywords), dbesc(normalise_link($profile))); + $location = formatted_location($noscrape); + if ($location) + $contact["location"] = $location; - $location = $noscrape["locality"]; + $contact["notify"] = $noscrape["dfrn-notify"]; - if ($noscrape["region"] != "") { - if ($location != "") - $location .= ", "; + // Remove all fields that are not present in the gcontact table + unset($noscrape["fn"]); + unset($noscrape["key"]); + unset($noscrape["homepage"]); + unset($noscrape["comm"]); + unset($noscrape["tags"]); + unset($noscrape["locality"]); + unset($noscrape["region"]); + unset($noscrape["country-name"]); + unset($noscrape["contacts"]); + unset($noscrape["dfrn-request"]); + unset($noscrape["dfrn-confirm"]); + unset($noscrape["dfrn-notify"]); + unset($noscrape["dfrn-poll"]); - $location .= $noscrape["region"]; - } + $contact = array_merge($contact, $noscrape); - if ($noscrape["country-name"] != "") { - if ($location != "") - $location .= ", "; + update_gcontact($contact); - $location .= $noscrape["country-name"]; + return $noscrape["updated"]; } - - if (($location != "") AND ($location != $gcontacts[0]["location"])) - q("UPDATE `gcontact` SET `location` = '%s' WHERE `nurl` = '%s'", - dbesc($location), dbesc(normalise_link($profile))); - - // If we got data from noscrape then mark the contact as reachable - if (is_array($noscrape) AND count($noscrape)) - q("UPDATE `gcontact` SET `last_contact` = '%s' WHERE `nurl` = '%s'", - dbesc(datetime_convert()), dbesc(normalise_link($profile))); - - return $noscrape["updated"]; } } } @@ -584,25 +513,22 @@ function poco_last_updated($profile, $force = false) { return false; } - 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))); + $contact = array("generation" => $gcontacts[0]["generation"]); - 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))); + $contact = array_merge($contact, $data); - 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))); + $contact["server_url"] = $data["baseurl"]; - 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))); + unset($contact["batch"]); + unset($contact["poll"]); + unset($contact["request"]); + unset($contact["confirm"]); + unset($contact["poco"]); + unset($contact["priority"]); + unset($contact["pubkey"]); + unset($contact["baseurl"]); - 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))); + update_gcontact($contact); $feedret = z_fetch_url($data["poll"]); @@ -697,6 +623,10 @@ function poco_to_boolean($val) { function poco_check_server($server_url, $network = "", $force = false) { + // Unify the server address + $server_url = trim($server_url, "/"); + $server_url = str_replace("/index.php", "", $server_url); + if ($server_url == "") return false; @@ -768,17 +698,23 @@ function poco_check_server($server_url, $network = "", $force = false) { // 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; + if (!$serverret["success"] OR ($serverret["body"] == "")) + $failure = true; + else { + $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; + $versionparts = explode("-", $version); + $version = $versionparts[0]; + } } - } + } } if (!$failure) { @@ -961,94 +897,13 @@ function poco_check_server($server_url, $network = "", $force = false) { return !$failure; } -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) { - $profile = ""; - preg_match("/profile='(.*?)'/ism", $share[1], $matches); - if ($matches[1] != "") - $profile = $matches[1]; - - preg_match('/profile="(.*?)"/ism', $share[1], $matches); - if ($matches[1] != "") - $profile = $matches[1]; - - if ($profile == "") - return; - - logger("prepare poco_check for profile ".$profile, LOGGER_DEBUG); - poco_check($profile, "", "", "", "", "", "", "", "", $created, 3, $cid, $uid); -} - -function poco_store($item) { - - // Isn't it public? - if ($item['private']) - return; - - // Or is it from a network where we don't store the global contacts? - if (!in_array($item["network"], array(NETWORK_DFRN, NETWORK_DIASPORA, NETWORK_OSTATUS, NETWORK_STATUSNET, ""))) - 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 = ""; - $profile_url = $item["author-link"]; - - // 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)) { - logger("Our user (generation 1): ".$item["author-link"], LOGGER_DEBUG); - $generation = 1; - $network = NETWORK_DFRN; - } else { // Is it a contact from a user on our server? - $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", - dbesc(normalise_link($item["author-link"])), - dbesc(normalise_link($item["author-link"])), - dbesc($item["author-link"]), - dbesc(NETWORK_STATUSNET)); - if (count($q)) { - $generation = 2; - $network = $q[0]["network"]; - $profile_url = $q[0]["url"]; - logger("Known contact (generation 2): ".$profile_url, LOGGER_DEBUG); - } - } - - 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"]); - - // 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"]); -} - function count_common_friends($uid,$cid) { $r = q("SELECT count(*) as `total` FROM `glink` INNER JOIN `gcontact` on `glink`.`gcid` = `gcontact`.`id` - where `glink`.`cid` = %d and `glink`.`uid` = %d - and `gcontact`.`nurl` in (select nurl from contact where uid = %d and self = 0 and blocked = 0 and hidden = 0 and id != %d ) ", + WHERE `glink`.`cid` = %d AND `glink`.`uid` = %d AND + ((`gcontact`.`last_contact` >= `gcontact`.`last_failure`) OR (`gcontact`.`updated` >= `gcontact`.`last_failure`)) + AND `gcontact`.`nurl` IN (select nurl from contact where uid = %d and self = 0 and blocked = 0 and hidden = 0 and id != %d ) ", intval($cid), intval($uid), intval($uid), @@ -1077,6 +932,7 @@ function common_friends($uid,$cid,$start = 0,$limit=9999,$shuffle = false) { WHERE `glink`.`cid` = %d and `glink`.`uid` = %d AND `contact`.`uid` = %d AND `contact`.`self` = 0 AND `contact`.`blocked` = 0 AND `contact`.`hidden` = 0 AND `contact`.`id` != %d + AND ((`gcontact`.`last_contact` >= `gcontact`.`last_failure`) OR (`gcontact`.`updated` >= `gcontact`.`last_failure`)) $sql_extra LIMIT %d, %d", intval($cid), intval($uid), @@ -1134,7 +990,8 @@ function count_all_friends($uid,$cid) { $r = q("SELECT count(*) as `total` FROM `glink` INNER JOIN `gcontact` on `glink`.`gcid` = `gcontact`.`id` - where `glink`.`cid` = %d and `glink`.`uid` = %d ", + where `glink`.`cid` = %d and `glink`.`uid` = %d AND + ((`gcontact`.`last_contact` >= `gcontact`.`last_failure`) OR (`gcontact`.`updated` >= `gcontact`.`last_failure`))", intval($cid), intval($uid) ); @@ -1152,7 +1009,8 @@ function all_friends($uid,$cid,$start = 0, $limit = 80) { FROM `glink` INNER JOIN `gcontact` on `glink`.`gcid` = `gcontact`.`id` LEFT JOIN `contact` ON `contact`.`nurl` = `gcontact`.`nurl` AND `contact`.`uid` = %d - WHERE `glink`.`cid` = %d AND `glink`.`uid` = %d + WHERE `glink`.`cid` = %d AND `glink`.`uid` = %d AND + ((`gcontact`.`last_contact` >= `gcontact`.`last_failure`) OR (`gcontact`.`updated` >= `gcontact`.`last_failure`)) ORDER BY `gcontact`.`name` ASC LIMIT %d, %d ", intval($uid), intval($cid), @@ -1184,14 +1042,14 @@ function suggestion_query($uid, $start = 0, $limit = 80) { $sql_network = "'".$sql_network."'"; $r = q("SELECT count(glink.gcid) as `total`, gcontact.* from gcontact - INNER JOIN glink on glink.gcid = gcontact.id + INNER JOIN `glink` ON `glink`.`gcid` = `gcontact`.`id` 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 ) - and not gcontact.id in ( select gcid from gcign where uid = %d ) + AND NOT `gcontact`.`name` IN (SELECT `name` FROM `contact` WHERE `uid` = %d) + AND NOT `gcontact`.`id` IN (SELECT `gcid` FROM `gcign` WHERE `uid` = %d) AND `gcontact`.`updated` != '0000-00-00 00:00:00' AND `gcontact`.`last_contact` >= `gcontact`.`last_failure` AND `gcontact`.`network` IN (%s) - group by glink.gcid order by gcontact.updated desc,total desc limit %d, %d ", + GROUP BY `glink`.`gcid` ORDER BY `gcontact`.`updated` DESC,`total` DESC LIMIT %d, %d", intval($uid), intval($uid), intval($uid), @@ -1204,14 +1062,15 @@ function suggestion_query($uid, $start = 0, $limit = 80) { if(count($r) && count($r) >= ($limit -1)) return $r; - $r2 = q("SELECT gcontact.* from gcontact - INNER JOIN glink on glink.gcid = gcontact.id - where glink.uid = 0 and glink.cid = 0 and glink.zcid = 0 and not gcontact.nurl in ( select nurl from contact where uid = %d ) - and not gcontact.name in ( select name from contact where uid = %d ) - and not gcontact.id in ( select gcid from gcign where uid = %d ) + $r2 = q("SELECT gcontact.* FROM gcontact + INNER JOIN `glink` ON `glink`.`gcid` = `gcontact`.`id` + WHERE `glink`.`uid` = 0 AND `glink`.`cid` = 0 AND `glink`.`zcid` = 0 AND NOT `gcontact`.`nurl` IN (SELECT `nurl` FROM `contact` WHERE `uid` = %d) + AND NOT `gcontact`.`name` IN (SELECT `name` FROM `contact` WHERE `uid` = %d) + AND NOT `gcontact`.`id` IN (SELECT `gcid` FROM `gcign` WHERE `uid` = %d) AND `gcontact`.`updated` != '0000-00-00 00:00:00' + AND `gcontact`.`last_contact` >= `gcontact`.`last_failure` AND `gcontact`.`network` IN (%s) - order by rand() limit %d, %d ", + ORDER BY rand() LIMIT %d, %d", intval($uid), intval($uid), intval($uid), @@ -1227,6 +1086,9 @@ function suggestion_query($uid, $start = 0, $limit = 80) { foreach ($r AS $suggestion) $list[$suggestion["nurl"]] = $suggestion; + while (sizeof($list) > ($limit)) + array_pop($list); + return $list; } @@ -1236,7 +1098,7 @@ function update_suggestions() { $done = array(); - // To-Do: Check if it is really neccessary to poll the own server + /// TODO Check if it is really neccessary to poll the own server poco_load(0,0,0,$a->get_baseurl() . '/poco'); $done[] = $a->get_baseurl() . '/poco'; @@ -1281,18 +1143,30 @@ function poco_discover_federation() { return; } + // Discover Friendica, Hubzilla and Diaspora servers $serverdata = fetch_url("http://the-federation.info/pods.json"); - if (!$serverdata) - return; + if ($serverdata) { + $servers = json_decode($serverdata); - $servers = json_decode($serverdata); + foreach($servers->pods AS $server) + poco_check_server("https://".$server->host); + } - foreach($servers->pods AS $server) - poco_check_server("https://".$server->host); + // Discover GNU Social Servers + if (!get_config('system','ostatus_disabled')) { + $serverdata = "http://gstools.org/api/get_open_instances/"; - set_config('poco','last_federation_discovery', time()); + $result = z_fetch_url($serverdata); + if ($result["success"]) { + $servers = json_decode($result["body"]); + foreach($servers->data AS $server) + poco_check_server($server->instance_address); + } + } + + set_config('poco','last_federation_discovery', time()); } function poco_discover($complete = false) { @@ -1472,4 +1346,276 @@ function poco_discover_server($data, $default_generation = 0) { } return $success; } + +/** + * @brief Fetch the gcontact id, add an entry if not existed + * + * @param arr $contact contact array + * @return bool|int Returns false if not found, integer if contact was found + */ +function get_gcontact_id($contact) { + + $gcontact_id = 0; + + if ($contact["network"] == NETWORK_STATUSNET) + $contact["network"] = NETWORK_OSTATUS; + + $r = q("SELECT `id` FROM `gcontact` WHERE `nurl` = '%s' ORDER BY `id` LIMIT 2", + dbesc(normalise_link($contact["url"]))); + + if ($r) + $gcontact_id = $r[0]["id"]; + else { + q("INSERT INTO `gcontact` (`name`, `nick`, `addr` , `network`, `url`, `nurl`, `photo`, `created`, `updated`, `location`, `about`, `generation`) + VALUES ('%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', %d)", + dbesc($contact["name"]), + dbesc($contact["nick"]), + dbesc($contact["addr"]), + dbesc($contact["network"]), + dbesc($contact["url"]), + dbesc(normalise_link($contact["url"])), + dbesc($contact["photo"]), + dbesc(datetime_convert()), + dbesc(datetime_convert()), + dbesc($contact["location"]), + dbesc($contact["about"]), + intval($contact["generation"]) + ); + + $r = q("SELECT `id` FROM `gcontact` WHERE `nurl` = '%s' ORDER BY `id` LIMIT 2", + dbesc(normalise_link($contact["url"]))); + + if ($r) + $gcontact_id = $r[0]["id"]; + } + + if ((count($r) > 1) AND ($gcontact_id > 0) AND ($contact["url"] != "")) + q("DELETE FROM `gcontact` WHERE `nurl` = '%s' AND `id` != %d", + dbesc(normalise_link($contact["url"])), + intval($gcontact_id)); + + return $gcontact_id; +} + +/** + * @brief Updates the gcontact table from a given array + * + * @param arr $contact contact array + * @return bool|int Returns false if not found, integer if contact was found + */ +function update_gcontact($contact) { + + /// @todo update contact table as well + + $gcontact_id = get_gcontact_id($contact); + + if (!$gcontact_id) + return false; + + $r = q("SELECT `name`, `nick`, `photo`, `location`, `about`, `addr`, `generation`, `birthday`, `gender`, `keywords`, + `hide`, `nsfw`, `network`, `alias`, `notify`, `server_url`, `connect`, `updated`, `url` + FROM `gcontact` WHERE `id` = %d LIMIT 1", + intval($gcontact_id)); + + // Get all field names + $fields = array(); + foreach ($r[0] AS $field => $data) + $fields[$field] = $data; + + unset($fields["url"]); + unset($fields["updated"]); + + // Bugfix: We had an error in the storing of keywords which lead to the "0" + // This value is still transmitted via poco. + if ($contact["keywords"] == "0") + unset($contact["keywords"]); + + if ($r[0]["keywords"] == "0") + $r[0]["keywords"] = ""; + + // assign all unassigned fields from the database entry + foreach ($fields AS $field => $data) + if (!isset($contact[$field]) OR ($contact[$field] == "")) + $contact[$field] = $r[0][$field]; + + if ($contact["network"] == NETWORK_STATUSNET) + $contact["network"] = NETWORK_OSTATUS; + + if (!isset($contact["updated"])) + $contact["updated"] = datetime_convert(); + + if ($contact["server_url"] == "") { + $server_url = $contact["url"]; + + $server_url = matching_url($server_url, $contact["alias"]); + if ($server_url != "") + $contact["server_url"] = $server_url; + + $server_url = matching_url($server_url, $contact["photo"]); + if ($server_url != "") + $contact["server_url"] = $server_url; + + $server_url = matching_url($server_url, $contact["notify"]); + if ($server_url != "") + $contact["server_url"] = $server_url; + } else + $contact["server_url"] = normalise_link($contact["server_url"]); + + if (($contact["addr"] == "") AND ($contact["server_url"] != "") AND ($contact["nick"] != "")) { + $hostname = str_replace("http://", "", $contact["server_url"]); + $contact["addr"] = $contact["nick"]."@".$hostname; + } + + // Check if any field changed + $update = false; + unset($fields["generation"]); + + if ((($contact["generation"] > 0) AND ($contact["generation"] <= $r[0]["generation"])) OR ($r[0]["generation"] == 0)) { + foreach ($fields AS $field => $data) + if ($contact[$field] != $r[0][$field]) { + logger("Difference for contact ".$contact["url"]." in field '".$field."'. New value: '".$contact[$field]."', old value '".$r[0][$field]."'", LOGGER_DEBUG); + $update = true; + } + + if ($contact["generation"] < $r[0]["generation"]) { + logger("Difference for contact ".$contact["url"]." in field 'generation'. new value: '".$contact["generation"]."', old value '".$r[0]["generation"]."'", LOGGER_DEBUG); + $update = true; + } + } + + if ($update) { + logger("Update gcontact for ".$contact["url"]." Callstack: ".App::callstack(), LOGGER_DEBUG); + + q("UPDATE `gcontact` SET `photo` = '%s', `name` = '%s', `nick` = '%s', `addr` = '%s', `network` = '%s', + `birthday` = '%s', `gender` = '%s', `keywords` = '%s', `hide` = %d, `nsfw` = %d, + `alias` = '%s', `notify` = '%s', `url` = '%s', + `location` = '%s', `about` = '%s', `generation` = %d, `updated` = '%s', + `server_url` = '%s', `connect` = '%s' + WHERE `nurl` = '%s' AND (`generation` = 0 OR `generation` >= %d)", + dbesc($contact["photo"]), dbesc($contact["name"]), dbesc($contact["nick"]), + dbesc($contact["addr"]), dbesc($contact["network"]), dbesc($contact["birthday"]), + dbesc($contact["gender"]), dbesc($contact["keywords"]), intval($contact["hide"]), + intval($contact["nsfw"]), dbesc($contact["alias"]), dbesc($contact["notify"]), + dbesc($contact["url"]), dbesc($contact["location"]), dbesc($contact["about"]), + intval($contact["generation"]), dbesc($contact["updated"]), + dbesc($contact["server_url"]), dbesc($contact["connect"]), + dbesc(normalise_link($contact["url"])), intval($contact["generation"])); + + + // Now update the contact entry with the user id "0" as well. + // This is used for the shadow copies of public items. + $r = q("SELECT `id` FROM `contact` WHERE `nurl` = '%s' AND `uid` = 0 ORDER BY `id` LIMIT 1", + dbesc(normalise_link($contact["url"]))); + + if ($r) { + logger("Update shadow contact ".$r[0]["id"], LOGGER_DEBUG); + + update_contact_avatar($contact["photo"], 0, $r[0]["id"]); + + q("UPDATE `contact` SET `name` = '%s', `nick` = '%s', `addr` = '%s', + `network` = '%s', `bd` = '%s', `gender` = '%s', + `keywords` = '%s', `alias` = '%s', `url` = '%s', + `location` = '%s', `about` = '%s' + WHERE `id` = %d", + dbesc($contact["name"]), dbesc($contact["nick"]), dbesc($contact["addr"]), + dbesc($contact["network"]), dbesc($contact["birthday"]), dbesc($contact["gender"]), + dbesc($contact["keywords"]), dbesc($contact["alias"]), dbesc($contact["url"]), + dbesc($contact["location"]), dbesc($contact["about"]), intval($r[0]["id"])); + } + } + + return $gcontact_id; +} + +/** + * @brief Updates the gcontact entry from probe + * + * @param str $url profile link + */ +function update_gcontact_from_probe($url) { + $data = probe_url($url); + + if ($data["network"] == NETWORK_PHANTOM) + return; + + update_gcontact($data); +} + +/** + * @brief Fetches users of given GNU Social server + * + * If the "Statistics" plugin is enabled (See http://gstools.org/ for details) we query user data with this. + * + * @param str $server Server address + */ +function gs_fetch_users($server) { + + logger("Fetching users from GNU Social server ".$server, LOGGER_DEBUG); + + $a = get_app(); + + $url = $server."/main/statistics"; + + $result = z_fetch_url($url); + if (!$result["success"]) + return false; + + $statistics = json_decode($result["body"]); + + if (is_object($statistics->config)) { + if ($statistics->config->instance_with_ssl) + $server = "https://"; + else + $server = "http://"; + + $server .= $statistics->config->instance_address; + + $hostname = $statistics->config->instance_address; + } else { + if ($statistics->instance_with_ssl) + $server = "https://"; + else + $server = "http://"; + + $server .= $statistics->instance_address; + + $hostname = $statistics->instance_address; + } + + if (is_object($statistics->users)) + foreach ($statistics->users AS $nick => $user) { + $profile_url = $server."/".$user->nickname; + + $contact = array("url" => $profile_url, + "name" => $user->fullname, + "addr" => $user->nickname."@".$hostname, + "nick" => $user->nickname, + "about" => $user->bio, + "network" => NETWORK_OSTATUS, + "photo" => $a->get_baseurl()."/images/person-175.jpg"); + get_gcontact_id($contact); + } +} + +/** + * @brief Asking GNU Social server on a regular base for their user data + * + */ +function gs_discover() { + + $requery_days = intval(get_config("system", "poco_requery_days")); + + $last_update = date("c", time() - (60 * 60 * 24 * $requery_days)); + + $r = q("SELECT `nurl`, `url` FROM `gserver` WHERE `last_contact` >= `last_failure` AND `network` = '%s' AND `last_poco_query` < '%s' ORDER BY RAND() LIMIT 5", + dbesc(NETWORK_OSTATUS), dbesc($last_update)); + + if (!$r) + return; + + foreach ($r AS $server) { + gs_fetch_users($server["url"]); + q("UPDATE `gserver` SET `last_poco_query` = '%s' WHERE `nurl` = '%s'", dbesc(datetime_convert()), dbesc($server["nurl"])); + } +} ?>