]> git.mxchange.org Git - friendica.git/blob - mod/poco.php
We can now return a list of known servers
[friendica.git] / mod / poco.php
1 <?php
2 // See here for a documentation for portable contacts:
3 // https://web.archive.org/web/20160405005550/http://portablecontacts.net/draft-spec.html
4
5 function poco_init(App $a) {
6         require_once("include/bbcode.php");
7
8         $system_mode = false;
9
10         if(intval(get_config('system','block_public')) || (get_config('system','block_local_dir')))
11                 http_status_exit(401);
12
13
14         if($a->argc > 1) {
15                 $user = notags(trim($a->argv[1]));
16         }
17         if(! x($user)) {
18                 $c = q("SELECT * FROM `pconfig` WHERE `cat` = 'system' AND `k` = 'suggestme' AND `v` = 1");
19                 if (! dbm::is_result($c)) {
20                         http_status_exit(401);
21                 }
22                 $system_mode = true;
23         }
24
25         $format = (($_GET['format']) ? $_GET['format'] : 'json');
26
27         $justme = false;
28         $global = false;
29
30         if($a->argc > 1 && $a->argv[1] === '@server') {
31                 $ret = poco_serverlist();
32                 header('Content-type: application/json');
33                 echo json_encode($ret);
34                 killme();
35         }
36         if($a->argc > 1 && $a->argv[1] === '@global') {
37                 $global = true;
38                 $update_limit = date("Y-m-d H:i:s", time() - 30 * 86400);
39         }
40         if($a->argc > 2 && $a->argv[2] === '@me')
41                 $justme = true;
42         if($a->argc > 3 && $a->argv[3] === '@all')
43                 $justme = false;
44         if($a->argc > 3 && $a->argv[3] === '@self')
45                 $justme = true;
46         if($a->argc > 4 && intval($a->argv[4]) && $justme == false)
47                 $cid = intval($a->argv[4]);
48
49
50         if(!$system_mode AND !$global) {
51                 $r = q("SELECT `user`.*,`profile`.`hide-friends` from user left join profile on `user`.`uid` = `profile`.`uid`
52                         where `user`.`nickname` = '%s' and `profile`.`is-default` = 1 limit 1",
53                         dbesc($user)
54                 );
55                 if(! dbm::is_result($r) || $r[0]['hidewall'] || $r[0]['hide-friends'])
56                         http_status_exit(404);
57
58                 $user = $r[0];
59         }
60
61         if($justme)
62                 $sql_extra = " AND `contact`.`self` = 1 ";
63 //      else
64 //              $sql_extra = " AND `contact`.`self` = 0 ";
65
66         if($cid)
67                 $sql_extra = sprintf(" AND `contact`.`id` = %d ",intval($cid));
68
69         if(x($_GET,'updatedSince'))
70                 $update_limit =  date("Y-m-d H:i:s",strtotime($_GET['updatedSince']));
71
72         if ($global) {
73                 $r = q("SELECT count(*) AS `total` FROM `gcontact` WHERE `updated` >= '%s' AND `updated` >= `last_failure` AND NOT `hide` AND `network` IN ('%s', '%s', '%s')",
74                         dbesc($update_limit),
75                         dbesc(NETWORK_DFRN),
76                         dbesc(NETWORK_DIASPORA),
77                         dbesc(NETWORK_OSTATUS)
78                 );
79         } elseif($system_mode) {
80                 $r = q("SELECT count(*) AS `total` FROM `contact` WHERE `self` = 1
81                         AND `uid` IN (SELECT `uid` FROM `pconfig` WHERE `cat` = 'system' AND `k` = 'suggestme' AND `v` = 1) ");
82         } else {
83                 $r = q("SELECT count(*) AS `total` FROM `contact` WHERE `uid` = %d AND `blocked` = 0 AND `pending` = 0 AND `hidden` = 0 AND `archive` = 0
84                         AND (`success_update` >= `failure_update` OR `last-item` >= `failure_update`)
85                         AND `network` IN ('%s', '%s', '%s', '%s') $sql_extra",
86                         intval($user['uid']),
87                         dbesc(NETWORK_DFRN),
88                         dbesc(NETWORK_DIASPORA),
89                         dbesc(NETWORK_OSTATUS),
90                         dbesc(NETWORK_STATUSNET)
91                 );
92         }
93         if (dbm::is_result($r))
94                 $totalResults = intval($r[0]['total']);
95         else
96                 $totalResults = 0;
97
98         $startIndex = intval($_GET['startIndex']);
99         if(! $startIndex)
100                 $startIndex = 0;
101         $itemsPerPage = ((x($_GET,'count') && intval($_GET['count'])) ? intval($_GET['count']) : $totalResults);
102
103         if ($global) {
104                 logger("Start global query", LOGGER_DEBUG);
105                 $r = q("SELECT * FROM `gcontact` WHERE `updated` > '%s' AND NOT `hide` AND `network` IN ('%s', '%s', '%s') AND `updated` > `last_failure`
106                         ORDER BY `updated` DESC LIMIT %d, %d",
107                         dbesc($update_limit),
108                         dbesc(NETWORK_DFRN),
109                         dbesc(NETWORK_DIASPORA),
110                         dbesc(NETWORK_OSTATUS),
111                         intval($startIndex),
112                         intval($itemsPerPage)
113                 );
114         } elseif($system_mode) {
115                 logger("Start system mode query", LOGGER_DEBUG);
116                 $r = q("SELECT `contact`.*, `profile`.`about` AS `pabout`, `profile`.`locality` AS `plocation`, `profile`.`pub_keywords`,
117                                 `profile`.`gender` AS `pgender`, `profile`.`address` AS `paddress`, `profile`.`region` AS `pregion`,
118                                 `profile`.`postal-code` AS `ppostalcode`, `profile`.`country-name` AS `pcountry`, `user`.`account-type`
119                         FROM `contact` INNER JOIN `profile` ON `profile`.`uid` = `contact`.`uid`
120                                 INNER JOIN `user` ON `user`.`uid` = `contact`.`uid`
121                         WHERE `self` = 1 AND `profile`.`is-default`
122                         AND `contact`.`uid` IN (SELECT `uid` FROM `pconfig` WHERE `cat` = 'system' AND `k` = 'suggestme' AND `v` = 1) LIMIT %d, %d",
123                         intval($startIndex),
124                         intval($itemsPerPage)
125                 );
126         } else {
127                 logger("Start query for user ".$user['nickname'], LOGGER_DEBUG);
128                 $r = q("SELECT * FROM `contact` WHERE `uid` = %d AND `blocked` = 0 AND `pending` = 0 AND `hidden` = 0 AND `archive` = 0
129                         AND (`success_update` >= `failure_update` OR `last-item` >= `failure_update`)
130                         AND `network` IN ('%s', '%s', '%s', '%s') $sql_extra LIMIT %d, %d",
131                         intval($user['uid']),
132                         dbesc(NETWORK_DFRN),
133                         dbesc(NETWORK_DIASPORA),
134                         dbesc(NETWORK_OSTATUS),
135                         dbesc(NETWORK_STATUSNET),
136                         intval($startIndex),
137                         intval($itemsPerPage)
138                 );
139         }
140         logger("Query done", LOGGER_DEBUG);
141
142         $ret = array();
143         if(x($_GET,'sorted'))
144                 $ret['sorted'] = false;
145         if(x($_GET,'filtered'))
146                 $ret['filtered'] = false;
147         if(x($_GET,'updatedSince') AND !$global)
148                 $ret['updatedSince'] = false;
149
150         $ret['startIndex']   = (int) $startIndex;
151         $ret['itemsPerPage'] = (int) $itemsPerPage;
152         $ret['totalResults'] = (int) $totalResults;
153         $ret['entry']        = array();
154
155
156         $fields_ret = array(
157                 'id' => false,
158                 'displayName' => false,
159                 'urls' => false,
160                 'updated' => false,
161                 'preferredUsername' => false,
162                 'photos' => false,
163                 'aboutMe' => false,
164                 'currentLocation' => false,
165                 'network' => false,
166                 'gender' => false,
167                 'tags' => false,
168                 'address' => false,
169                 'contactType' => false,
170                 'generation' => false
171         );
172
173         if((! x($_GET,'fields')) || ($_GET['fields'] === '@all'))
174                 foreach($fields_ret as $k => $v)
175                         $fields_ret[$k] = true;
176         else {
177                 $fields_req = explode(',',$_GET['fields']);
178                 foreach($fields_req as $f)
179                         $fields_ret[trim($f)] = true;
180         }
181
182         if(is_array($r)) {
183                 if (dbm::is_result($r)) {
184                         foreach ($r as $rr) {
185                                 if (!isset($rr['generation'])) {
186                                         if ($global)
187                                                 $rr['generation'] = 3;
188                                         elseif ($system_mode)
189                                                 $rr['generation'] = 1;
190                                         else
191                                                 $rr['generation'] = 2;
192                                 }
193
194                                 if (($rr['about'] == "") AND isset($rr['pabout']))
195                                         $rr['about'] = $rr['pabout'];
196
197                                 if ($rr['location'] == "") {
198                                         if (isset($rr['plocation']))
199                                                 $rr['location'] = $rr['plocation'];
200
201                                         if (isset($rr['pregion']) AND ($rr['pregion'] != "")) {
202                                                 if ($rr['location'] != "")
203                                                         $rr['location'] .= ", ";
204
205                                                 $rr['location'] .= $rr['pregion'];
206                                         }
207
208                                         if (isset($rr['pcountry']) AND ($rr['pcountry'] != "")) {
209                                                 if ($rr['location'] != "")
210                                                         $rr['location'] .= ", ";
211
212                                                 $rr['location'] .= $rr['pcountry'];
213                                         }
214                                 }
215
216                                 if (($rr['gender'] == "") AND isset($rr['pgender']))
217                                         $rr['gender'] = $rr['pgender'];
218
219                                 if (($rr['keywords'] == "") AND isset($rr['pub_keywords']))
220                                         $rr['keywords'] = $rr['pub_keywords'];
221
222                                 if (isset($rr['account-type']))
223                                         $rr['contact-type'] = $rr['account-type'];
224
225                                 $about = Cache::get("about:".$rr['updated'].":".$rr['nurl']);
226                                 if (is_null($about)) {
227                                         $about = bbcode($rr['about'], false, false);
228                                         Cache::set("about:".$rr['updated'].":".$rr['nurl'],$about);
229                                 }
230
231                                 // Non connected persons can only see the keywords of a Diaspora account
232                                 if ($rr['network'] == NETWORK_DIASPORA) {
233                                         $rr['location'] = "";
234                                         $about = "";
235                                         $rr['gender'] = "";
236                                 }
237
238                                 $entry = array();
239                                 if($fields_ret['id'])
240                                         $entry['id'] = (int)$rr['id'];
241                                 if($fields_ret['displayName'])
242                                         $entry['displayName'] = $rr['name'];
243                                 if($fields_ret['aboutMe'])
244                                         $entry['aboutMe'] = $about;
245                                 if($fields_ret['currentLocation'])
246                                         $entry['currentLocation'] = $rr['location'];
247                                 if($fields_ret['gender'])
248                                         $entry['gender'] = $rr['gender'];
249                                 if($fields_ret['generation'])
250                                         $entry['generation'] = (int)$rr['generation'];
251                                 if($fields_ret['urls']) {
252                                         $entry['urls'] = array(array('value' => $rr['url'], 'type' => 'profile'));
253                                         if($rr['addr'] && ($rr['network'] !== NETWORK_MAIL))
254                                                 $entry['urls'][] = array('value' => 'acct:' . $rr['addr'], 'type' => 'webfinger');
255                                 }
256                                 if($fields_ret['preferredUsername'])
257                                         $entry['preferredUsername'] = $rr['nick'];
258                                 if($fields_ret['updated']) {
259                                         if (!$global) {
260                                                 $entry['updated'] = $rr['success_update'];
261
262                                                 if ($rr['name-date'] > $entry['updated'])
263                                                         $entry['updated'] = $rr['name-date'];
264
265                                                 if ($rr['uri-date'] > $entry['updated'])
266                                                         $entry['updated'] = $rr['uri-date'];
267
268                                                 if ($rr['avatar-date'] > $entry['updated'])
269                                                         $entry['updated'] = $rr['avatar-date'];
270                                         } else
271                                                 $entry['updated'] = $rr['updated'];
272
273                                         $entry['updated'] = date("c", strtotime($entry['updated']));
274                                 }
275                                 if($fields_ret['photos'])
276                                         $entry['photos'] = array(array('value' => $rr['photo'], 'type' => 'profile'));
277                                 if($fields_ret['network']) {
278                                         $entry['network'] = $rr['network'];
279                                         if ($entry['network'] == NETWORK_STATUSNET)
280                                                 $entry['network'] = NETWORK_OSTATUS;
281                                         if (($entry['network'] == "") AND ($rr['self']))
282                                                 $entry['network'] = NETWORK_DFRN;
283                                 }
284                                 if($fields_ret['tags']) {
285                                         $tags = str_replace(","," ",$rr['keywords']);
286                                         $tags = explode(" ", $tags);
287
288                                         $cleaned = array();
289                                         foreach ($tags as $tag) {
290                                                 $tag = trim(strtolower($tag));
291                                                 if ($tag != "")
292                                                         $cleaned[] = $tag;
293                                         }
294
295                                         $entry['tags'] = array($cleaned);
296                                 }
297                                 if($fields_ret['address']) {
298                                         $entry['address'] = array();
299
300                                         // Deactivated. It just reveals too much data. (Although its from the default profile)
301                                         //if (isset($rr['paddress']))
302                                         //       $entry['address']['streetAddress'] = $rr['paddress'];
303
304                                         if (isset($rr['plocation']))
305                                                  $entry['address']['locality'] = $rr['plocation'];
306
307                                         if (isset($rr['pregion']))
308                                                  $entry['address']['region'] = $rr['pregion'];
309
310                                         // See above
311                                         //if (isset($rr['ppostalcode']))
312                                         //       $entry['address']['postalCode'] = $rr['ppostalcode'];
313
314                                         if (isset($rr['pcountry']))
315                                                  $entry['address']['country'] = $rr['pcountry'];
316                                 }
317
318                                 if($fields_ret['contactType'])
319                                         $entry['contactType'] = intval($rr['contact-type']);
320
321                                 $ret['entry'][] = $entry;
322                         }
323                 } else
324                         $ret['entry'][] = array();
325         } else
326                 http_status_exit(500);
327
328         logger("End of poco", LOGGER_DEBUG);
329
330         if($format === 'xml') {
331                 header('Content-type: text/xml');
332                 echo replace_macros(get_markup_template('poco_xml.tpl'),array_xmlify(array('$response' => $ret)));
333                 killme();
334         }
335         if($format === 'json') {
336                 header('Content-type: application/json');
337                 echo json_encode($ret);
338                 killme();
339         } else
340                 http_status_exit(500);
341
342
343 }