]> git.mxchange.org Git - friendica.git/blob - boot.php
relationship direction was too confusing to work with. instead of "in,out,both" it...
[friendica.git] / boot.php
1 <?php
2
3 set_time_limit(0);
4
5 define ( 'BUILD_ID' , 1003 );
6
7 define ( 'EOL', "<br />\r\n");
8 define ( 'ATOM_TIME',  'Y-m-d\TH:i:s\Z' );
9
10 define ( 'REGISTER_CLOSED',  0);
11 define ( 'REGISTER_APPROVE', 1);
12 define ( 'REGISTER_OPEN',    2);
13
14 // relationship types
15
16 define ( 'REL_VIP',        1);
17 define ( 'REL_FAN',        2);
18 define ( 'REL_BUD',        3);
19
20 define ( 'NOTIFY_INTRO',   0x0001 );
21 define ( 'NOTIFY_CONFIRM', 0x0002 );
22 define ( 'NOTIFY_WALL',    0x0004 );
23 define ( 'NOTIFY_COMMENT', 0x0008 );
24 define ( 'NOTIFY_MAIL',    0x0010 );
25
26 define ( 'NAMESPACE_DFRN' ,           'http://purl.org/macgirvin/dfrn/1.0' ); 
27 define ( 'NAMESPACE_THREAD' ,         'http://purl.org/syndication/thread/1.0' );
28 define ( 'NAMESPACE_TOMB' ,           'http://purl.org/atompub/tombstones/1.0' );
29 define ( 'NAMESPACE_ACTIVITY',        'http://activitystrea.ms/spec/1.0/' );
30 define ( 'NAMESPACE_ACTIVITY_SCHEMA', 'http://activitystrea.ms/schema/1.0/');
31
32 define ( 'ACTIVITY_LIKE',        NAMESPACE_ACTIVITY_SCHEMA . 'like' );
33 define ( 'ACTIVITY_DISLIKE',     NAMESPACE_DFRN            . '/dislike' );
34 define ( 'ACTIVITY_OBJ_HEART',   NAMESPACE_DFRN            . '/heart' );
35
36 define ( 'ACTIVITY_FRIEND',      NAMESPACE_ACTIVITY_SCHEMA . 'make-friend' );
37 define ( 'ACTIVITY_POST',        NAMESPACE_ACTIVITY_SCHEMA . 'post' );
38 define ( 'ACTIVITY_UPDATE',      NAMESPACE_ACTIVITY_SCHEMA . 'update' );
39
40 define ( 'ACTIVITY_OBJ_COMMENT', NAMESPACE_ACTIVITY_SCHEMA . 'comment' );
41 define ( 'ACTIVITY_OBJ_NOTE',    NAMESPACE_ACTIVITY_SCHEMA . 'note' );
42 define ( 'ACTIVITY_OBJ_PERSON',  NAMESPACE_ACTIVITY_SCHEMA . 'person' );
43 define ( 'ACTIVITY_OBJ_PHOTO',   NAMESPACE_ACTIVITY_SCHEMA . 'photo' );
44 define ( 'ACTIVITY_OBJ_P_PHOTO', NAMESPACE_ACTIVITY_SCHEMA . 'profile-photo' );
45 define ( 'ACTIVITY_OBJ_ALBUM',   NAMESPACE_ACTIVITY_SCHEMA . 'photo-album' );
46
47 define ( 'GRAVITY_PARENT',       0);
48 define ( 'GRAVITY_LIKE',         3);
49 define ( 'GRAVITY_COMMENT',      6);
50
51
52 if(! class_exists('App')) {
53 class App {
54
55         public  $module_loaded = false;
56         public  $config;
57         public  $page;
58         public  $profile;
59         public  $user;
60         public  $cid;
61         public  $contact;
62         public  $content;
63         public  $data;
64         public  $error = false;
65         public  $cmd;
66         public  $argv;
67         public  $argc;
68         public  $module;
69         public  $pager;
70         public  $strings;   
71         public  $path;
72
73         private $scheme;
74         private $hostname;
75         private $baseurl;
76         private $db;
77
78         function __construct() {
79
80                 $this->config = array();
81                 $this->page = array();
82                 $this->pager= array();
83
84                 $this->scheme = ((isset($_SERVER['HTTPS']) 
85                                 && ($_SERVER['HTTPS'])) ?  'https' : 'http' );
86                 $this->hostname = str_replace('www.','',
87                                 $_SERVER['SERVER_NAME']);
88                 set_include_path("include/$this->hostname" 
89                                 . PATH_SEPARATOR . 'include' 
90                                 . PATH_SEPARATOR . '.' );
91
92                 if(substr($_SERVER['QUERY_STRING'],0,2) == "q=")
93                         $_SERVER['QUERY_STRING'] = substr($_SERVER['QUERY_STRING'],2);
94                 $this->cmd = trim($_GET['q'],'/');
95
96
97                 $this->argv = explode('/',$this->cmd);
98                 $this->argc = count($this->argv);
99                 if((array_key_exists('0',$this->argv)) && strlen($this->argv[0])) {
100                         $this->module = $this->argv[0];
101                 }
102                 else {
103                         $this->module = 'home';
104                 }
105
106                 if($this->cmd == '.well-known/host-meta')
107                         require_once('include/hostxrd.php');
108
109                 $this->pager['page'] = ((x($_GET,'page')) ? $_GET['page'] : 1);
110                 $this->pager['itemspage'] = 50;
111                 $this->pager['start'] = ($this->pager['page'] * $this->pager['itemspage']) - $this->pager['itemspage'];
112                 $this->pager['total'] = 0;
113         }
114
115         function get_baseurl($ssl = false) {
116                 if(strlen($this->baseurl))
117                         return $this->baseurl;
118
119                 $this->baseurl = (($ssl) ? 'https' : $this->scheme) . "://" . $this->hostname
120                         . ((isset($this->path) && strlen($this->path)) 
121                         ? '/' . $this->path : '' );
122                 return $this->baseurl;
123         }
124
125         function set_baseurl($url) {
126                 $this->baseurl = $url;
127                 $this->hostname = basename($url);
128         }
129
130         function get_hostname() {
131                 return $this->hostname;
132         }
133
134         function set_hostname($h) {
135                 $this->hostname = $h;
136         }
137
138         function set_path($p) {
139                 $this->path = ltrim(trim($p),'/');
140         } 
141
142         function get_path() {
143                 return $this->path;
144         }
145
146         function set_pager_total($n) {
147                 $this->pager['total'] = intval($n);
148         }
149
150         function set_pager_itemspage($n) {
151                 $this->pager['itemspage'] = intval($n);
152                 $this->pager['start'] = ($this->pager['page'] * $this->pager['itemspage']) - $this->pager['itemspage'];
153
154         } 
155
156         function init_pagehead() {
157                 if(file_exists("view/head.tpl"))
158                         $s = file_get_contents("view/head.tpl");
159                 $this->page['htmlhead'] = replace_macros($s,array(
160                         '$baseurl' => $this->get_baseurl()
161                 ));
162         }
163
164 }}
165
166
167 if(! function_exists('x')) {
168 function x($s,$k = NULL) {
169         if($k != NULL) {
170                 if((is_array($s)) && (array_key_exists($k,$s))) {
171                         if($s[$k])
172                                 return (int) 1;
173                         return (int) 0;
174                 }
175                 return false;
176         }
177         else {          
178                 if(isset($s)) {
179                         if($s) {
180                                 return (int) 1;
181                         }
182                         return (int) 0;
183                 }
184                 return false;
185         }
186 }}
187
188 if(! function_exists('system_unavailable')) {
189 function system_unavailable() {
190         include('system_unavailable.php');
191         killme();
192 }}
193
194
195 if(! function_exists('check_config')) {
196 function check_config(&$a) {
197
198         load_config('system');
199
200         $build = get_config('system','build');
201         if(! x($build))
202                 $build = set_config('system','build',BUILD_ID);
203
204         $url = get_config('system','url');
205         if(! x($url))
206                 $url = set_config('system','url',$a->get_baseurl());
207
208         if($build != BUILD_ID) {
209                 $stored = intval($build);
210                 $current = intval(BUILD_ID);
211                 if(($stored < $current) && file_exists('update.php')) {
212
213                         // We're reporting a different version than what is currently installed.
214                         // Run any existing update scripts to bring the database up to current.
215
216                         require_once('update.php');
217                         for($x = $stored; $x < $current; $x ++) {
218                                 if(function_exists('update_' . $x)) {
219                                         $func = 'update_' . $x;
220                                         $func($a);
221                                 }
222                         }
223                         set_config('system','build', BUILD_ID);
224                 }
225         }
226         return;
227 }}
228
229
230
231 if(! function_exists('replace_macros')) {  
232 function replace_macros($s,$r) {
233
234         $search = array();
235         $replace = array();
236
237         if(is_array($r) && count($r)) {
238                 foreach ($r as $k => $v ) {
239                         $search[] =  $k;
240                         $replace[] = $v;
241                 }
242         }
243         return str_replace($search,$replace,$s);
244 }}
245
246
247 if(! function_exists('load_translation_table')) {
248 function load_translation_table($lang) {
249         global $a;
250
251 }}
252
253 if(! function_exists('t')) {
254 function t($s) {
255         global $a;
256
257         if($a->strings[$s])
258                 return $a->strings[$s];
259         return $s;
260 }}
261
262 if(! function_exists('fetch_url')) {
263 function fetch_url($url,$binary = false) {
264         $ch = curl_init($url);
265         if(! $ch) return false;
266
267         curl_setopt($ch, CURLOPT_HEADER, 0);
268         curl_setopt($ch, CURLOPT_FOLLOWLOCATION,true);
269         curl_setopt($ch, CURLOPT_MAXREDIRS,8);
270         curl_setopt($ch, CURLOPT_RETURNTRANSFER,true);
271         $prx = get_config('system','proxy');
272         if(strlen($prx)) {
273                 curl_setopt($ch, CURLOPT_HTTPPROXYTUNNEL, 1);
274                 curl_setopt($ch, CURLOPT_PROXY, $prx);
275                 $prxusr = get_config('system','proxyuser');
276                 if(strlen($prxusr))
277                         curl_setopt($ch, CURLOPT_PROXYUSERPWD, $prxusr);
278         }
279         if($binary)
280                 curl_setopt($ch, CURLOPT_BINARYTRANSFER,1);
281
282         $s = curl_exec($ch);
283         curl_close($ch);
284         return($s);
285 }}
286
287
288 if(! function_exists('post_url')) {
289 function post_url($url,$params) {
290         $ch = curl_init($url);
291         if(! $ch) return false;
292
293         curl_setopt($ch, CURLOPT_HEADER, 0);
294         curl_setopt($ch, CURLOPT_FOLLOWLOCATION,true);
295         curl_setopt($ch, CURLOPT_MAXREDIRS,8);
296         curl_setopt($ch, CURLOPT_RETURNTRANSFER,true);
297         curl_setopt($ch, CURLOPT_POST,1);
298         curl_setopt($ch, CURLOPT_POSTFIELDS,$params);
299         $prx = get_config('system','proxy');
300         if(strlen($prx)) {
301                 curl_setopt($ch, CURLOPT_HTTPPROXYTUNNEL, 1);
302                 curl_setopt($ch, CURLOPT_PROXY, $prx);
303                 $prxusr = get_config('system','proxyuser');
304                 if(strlen($prxusr))
305                         curl_setopt($ch, CURLOPT_PROXYUSERPWD, $prxusr);
306         }
307
308         $s = curl_exec($ch);
309         curl_close($ch);
310         return($s);
311 }}
312
313
314 if(! function_exists('random_string')) {
315 function random_string() {
316         return(hash('sha256',uniqid(rand(),true)));
317 }}
318
319 if(! function_exists('notags')) {
320 function notags($string) {
321         // protect against :<> with high-bit set
322         return(str_replace(array("<",">","\xBA","\xBC","\xBE"), array('[',']','','',''), $string));
323 }}
324
325 if(! function_exists('escape_tags')) {
326 function escape_tags($string) {
327
328         return(htmlspecialchars($string));
329 }}
330
331 if(! function_exists('login')) {
332 function login($register = false) {
333         $o = "";
334         $register_html = (($register) ? file_get_contents("view/register-link.tpl") : "");
335
336
337         if(x($_SESSION,'authenticated')) {
338                 $o = file_get_contents("view/logout.tpl");
339         }
340         else {
341                 $o = file_get_contents("view/login.tpl");
342
343                 $o = replace_macros($o,array('$register_html' => $register_html ));
344         }
345         return $o;
346 }}
347
348
349 if(! function_exists('autoname')) {
350 function autoname($len) {
351
352         $vowels = array('a','a','ai','au','e','e','e','ee','ea','i','ie','o','ou','u'); 
353         if(mt_rand(0,5) == 4)
354                 $vowels[] = 'y';
355
356         $cons = array(
357                         'b','bl','br',
358                         'c','ch','cl','cr',
359                         'd','dr',
360                         'f','fl','fr',
361                         'g','gh','gl','gr',
362                         'h',
363                         'j',
364                         'k','kh','kl','kr',
365                         'l',
366                         'm',
367                         'n',
368                         'p','ph','pl','pr',
369                         'qu',
370                         'r','rh',
371                         's','sc','sh','sm','sp','st',
372                         't','th','tr',
373                         'v',
374                         'w','wh',
375                         'x',
376                         'z','zh'
377                         );
378
379         $midcons = array('ck','ct','gn','ld','lf','lm','lt','mb','mm', 'mn','mp',
380                                 'nd','ng','nk','nt','rn','rp','rt');
381
382         $noend = array('bl', 'br', 'cl','cr','dr','fl','fr','gl','gr',
383                                 'kh', 'kl','kr','mn','pl','pr','rh','tr','qu','wh');
384
385         $start = mt_rand(0,2);
386         if($start == 0)
387                 $table = $vowels;
388         else
389                 $table = $cons;
390
391         $word = '';
392
393         for ($x = 0; $x < $len; $x ++) {
394                 $r = mt_rand(0,count($table) - 1);
395                 $word .= $table[$r];
396   
397                 if($table == $vowels)
398                         $table = array_merge($cons,$midcons);
399                 else
400                         $table = $vowels;
401
402         }
403
404         $word = substr($word,0,$len);
405
406         foreach($noend as $noe) {
407                 if((strlen($word) > 2) && (substr($word,-2) == $noe)) {
408                         $word = substr($word,0,-1);
409                         break;
410                 }
411         }
412         if(substr($word,-1) == 'q')
413                 $word = substr($word,0,-1);    
414         return $word;
415 }}
416
417 if(! function_exists('killme')) {
418 function killme() {
419         session_write_close();
420         exit;
421 }}
422
423 if(! function_exists('goaway')) {
424 function goaway($s) {
425         header("Location: $s");
426         killme();
427 }}
428
429
430 if(! function_exists('xml_status')) {
431 function xml_status($st) {
432         header( "Content-type: text/xml" );
433         echo '<?xml version="1.0" encoding="UTF-8"?>'."\r\n";
434         echo "<result><status>$st</status></result>\r\n";
435         killme();
436 }}
437
438 if(! function_exists('local_user')) {
439 function local_user() {
440         if((x($_SESSION,'authenticated')) && (x($_SESSION,'uid')))
441                 return $_SESSION['uid'];
442         return false;
443 }}
444
445 if(! function_exists('remote_user')) {
446 function remote_user() {
447         if((x($_SESSION,'authenticated')) && (x($_SESSION,'visitor_id')))
448                 return $_SESSION['visitor_id'];
449         return false;
450 }}
451
452 if(! function_exists('notice')) {
453 function notice($s) {
454
455         $_SESSION['sysmsg'] .= $s;
456
457 }}
458
459 if(! function_exists('get_max_import_size')) {
460 function get_max_import_size() {
461         global $a;
462         return ((x($a->config,'max_import_size')) ? $a->config['max_import_size'] : 0 );
463 }}
464
465 if(! function_exists('xmlify')) {
466 function xmlify($str) {
467         $buffer = '';
468         
469         for($x = 0; $x < strlen($str); $x ++) {
470                 $char = $str[$x];
471         
472                 switch( $char ) {
473
474                         case "\r" :
475                                 break;
476                         case "&" :
477                                 $buffer .= '&amp;';
478                                 break;
479                         case "'" :
480                                 $buffer .= '&apos;';
481                                 break;
482
483                         case "\"" :
484                                 $buffer .= '&quot;';
485                                 break;
486                         case '<' :
487                                 $buffer .= '&lt;';
488                                 break;
489                         case '>' :
490                                 $buffer .= '&gt;';
491                                 break;
492                         case "\n" :
493                                 $buffer .= ' ';
494                                 break;
495                         default :
496                                 $buffer .= $char;
497                                 break;
498                 }       
499         }
500         $buffer = trim($buffer);
501         return($buffer);
502 }}
503
504 if(! function_exists('unxmlify')) {
505 function unxmlify($s) {
506         $ret = str_replace('&amp;','&', $s);
507         $ret = str_replace(array('&lt;','&gt;','&quot;','&apos;'),array('<','>','"',"'"),$ret);
508         return $ret;    
509 }}
510
511 if(! function_exists('hex2bin')) {
512 function hex2bin($s) {
513         return(pack("H*",$s));
514 }}
515
516
517 if(! function_exists('paginate')) {
518 function paginate(&$a) {
519         $o = '';
520         $stripped = ereg_replace("(&page=[0-9]*)","",$_SERVER['QUERY_STRING']);
521         $stripped = str_replace('q=','',$stripped);
522         $stripped = trim($stripped,'/');
523         $url = $a->get_baseurl() . '/' . $stripped;
524
525
526           if($a->pager['total'] > $a->pager['itemspage']) {
527                 $o .= '<div class="pager">';
528                 if($a->pager['page'] != 1)
529                         $o .= '<span class="pager_prev">'."<a href=\"$url".'&page='.($a->pager['page'] - 1).'">' . t('prev') . '</a></span> ';
530
531                 $o .=  "<span class=\"pager_first\"><a href=\"$url"."&page=1\">" . t('first') . "</a></span> ";
532
533                 $numpages = $a->pager['total'] / $a->pager['itemspage'];
534
535                 $numstart = 1;
536                 $numstop = $numpages;
537
538                 if($numpages > 14) {
539                         $numstart = (($pagenum > 7) ? ($pagenum - 7) : 1);
540                         $numstop = (($pagenum > ($numpages - 7)) ? $numpages : ($numstart + 14));
541                 }
542    
543                 for($i = $numstart; $i <= $numstop; $i++){
544                         if($i == $a->pager['page'])
545                                 $o .= '<span class="pager_current">'.(($i < 10) ? '&nbsp;'.$i : $i);
546                         else
547                                 $o .= "<span class=\"pager_n\"><a href=\"$url"."&page=$i\">".(($i < 10) ? '&nbsp;'.$i : $i)."</a>";
548                         $o .= '</span> ';
549                 }
550
551                 if(($a->pager['total'] % $a->pager['itemspage']) != 0) {
552                         if($i == $a->pager['page'])
553                                 $o .= '<span class="pager_current">'.(($i < 10) ? '&nbsp;'.$i : $i);
554                         else
555                                 $o .= "<span class=\"pager_n\"><a href=\"$url"."&page=$i\">".(($i < 10) ? '&nbsp;'.$i : $i)."</a>";
556                         $o .= '</span> ';
557                 }
558
559                 $lastpage = (($numpages > intval($numpages)) ? intval($numpages)+1 : $numpages);
560                 $o .= "<span class=\"pager_last\"><a href=\"$url"."&page=$lastpage\">" . t('last') . "</a></span> ";
561
562                 if(($a->pager['total'] - ($a->pager['itemspage'] * $a->pager['page'])) > 0)
563                         $o .= '<span class="pager_next">'."<a href=\"$url"."&page=".($a->pager['page'] + 1).'">' . t('next') . '</a></span>';
564                 $o .= '</div>'."\r\n";
565         }
566         return $o;
567 }}
568
569 if(! function_exists('expand_acl')) {
570 function expand_acl($s) {
571
572         if(strlen($s)) {
573                 $a = explode('<',$s);
574                 for($x = 0; $x < count($a); $x ++) {
575                         $a[$x] = intval(str_replace(array('<','>'),array('',''),$a[$x]));
576                 }
577                 return $a;
578         }
579         return array();
580 }}              
581
582 if(! function_exists('sanitise_acl')) {
583 function sanitise_acl(&$item) {
584         if(intval($item))
585                 $item = '<' . intval(notags(trim($item))) . '>';
586         else
587                 unset($item);
588 }}
589
590 if(! function_exists('load_config')) {
591 function load_config($family) {
592         global $a;
593         $r = q("SELECT * FROM `config` WHERE `cat` = '%s'",
594                 dbesc($family)
595         );
596         if(count($r)) {
597                 foreach($r as $rr) {
598                         $k = $rr['k'];
599                         $a->config[$family][$k] = $rr['v'];
600                 }
601         }
602 }}
603
604
605 if(! function_exists('get_config')) {
606 function get_config($family, $key, $instore = false) {
607
608         global $a;
609         if(! $instore) {
610                 if(isset($a->config[$family][$key])) {
611                         if($a->config[$family][$key] == '!<unset>!')
612                                 return false;
613                         return $a->config[$family][$key];
614                 }
615         }
616         $ret = q("SELECT `v` FROM `config` WHERE `cat` = '%s' AND `k` = '%s' LIMIT 1",
617                 dbesc($family),
618                 dbesc($key)
619         );
620         if(count($ret)) {
621                 $a->config[$family][$key] = $ret[0]['v'];
622                 return $ret[0]['v'];
623         }
624         else {
625                 $a->config[$family][$key] = '!<unset>!';
626         }
627         return false;
628 }}
629
630 if(! function_exists('set_config')) {
631 function set_config($family,$key,$value) {
632
633         global $a;
634         $a->config[$family][$key] = $value;
635
636         if(get_config($family,$key,true) === false) {
637                 $ret = q("INSERT INTO `config` ( `cat`, `k`, `v` ) VALUES ( '%s', '%s', '%s' ) ",
638                         dbesc($family),
639                         dbesc($key),
640                         dbesc($value)
641                 );
642                 if($ret) 
643                         return $value;
644                 return $ret;
645         }
646         $ret = q("UPDATE `config` SET `v` = '%s' WHERE `cat` = '%s' AND `k` = '%s' LIMIT 1",
647                 dbesc($value),
648                 dbesc($family),
649                 dbesc($key)
650         );
651         if($ret)
652                 return $value;
653         return $ret;
654 }}
655
656 if(! function_exists('convert_xml_element_to_array')) {
657 function convert_xml_element_to_array($xml_element, &$recursion_depth=0) {
658
659         // If we're getting too deep, bail out
660         if ($recursion_depth > 512) {
661                 return(null);
662         }
663
664         if (!is_string($xml_element) &&
665         !is_array($xml_element) &&
666         (get_class($xml_element) == 'SimpleXMLElement')) {
667                 $xml_element_copy = $xml_element;
668                 $xml_element = get_object_vars($xml_element);
669         }
670
671         if (is_array($xml_element)) {
672                 $result_array = array();
673                 if (count($xml_element) <= 0) {
674                         return (trim(strval($xml_element_copy)));
675                 }
676
677                 foreach($xml_element as $key=>$value) {
678
679                         $recursion_depth++;
680                         $result_array[strtolower($key)] =
681                 convert_xml_element_to_array($value, $recursion_depth);
682                         $recursion_depth--;
683                 }
684                 if ($recursion_depth == 0) {
685                         $temp_array = $result_array;
686                         $result_array = array(
687                                 strtolower($xml_element_copy->getName()) => $temp_array,
688                         );
689                 }
690
691                 return ($result_array);
692
693         } else {
694                 return (trim(strval($xml_element)));
695         }
696 }}
697
698
699 if(! function_exists('webfinger')) {
700 function webfinger($s) {
701         if(! strstr($s,'@')) {
702                 return $s;
703         }
704         $host = substr($s,strpos($s,'@') + 1);
705         $url = 'http://' . $host . '/.well-known/host-meta' ;
706         $xml = fetch_url($url);
707         if (! $xml)
708                 return '';
709         $h = simplexml_load_string($xml);
710         $arr = convert_xml_element_to_array($h);
711
712         if(! isset($arr['xrd']['link']))
713                 return '';
714
715         $link = $arr['xrd']['link'];
716         if(! isset($link[0]))
717                 $links = array($link);
718         else
719                 $links = $link;
720
721         foreach($links as $link)
722                 if($link['@attributes']['rel'] && $link['@attributes']['rel'] == 'lrdd')
723                         $tpl = $link['@attributes']['template'];
724         if((empty($tpl)) || (! strpos($tpl, '{uri}')))
725                 return '';
726
727         $pxrd = str_replace('{uri}', urlencode('acct://'.$s), $tpl);
728
729         $xml = fetch_url($pxrd);
730         if (! $xml)
731                 return '';
732         $h = simplexml_load_string($xml);
733         $arr = convert_xml_element_to_array($h);
734
735         if(! isset($arr['xrd']['link']))
736                 return '';
737
738         $link = $arr['xrd']['link'];
739         if(! isset($link[0]))
740                 $links = array($link);
741         else
742                 $links = $link;
743
744         foreach($links as $link)
745                 if($link['@attributes']['rel'] == NAMESPACE_DFRN)
746                         return $link['@attributes']['href'];
747         return '';
748 }}
749
750 if(! function_exists('perms2str')) {
751 function perms2str($p) {
752         $ret = '';
753         $tmp = $p;
754         if(is_array($tmp)) {
755                 array_walk($tmp,'sanitise_acl');
756                 $ret = implode('',$tmp);
757         }
758         return $ret;
759 }}
760
761 if(! function_exists('item_new_uri')) {
762 function item_new_uri($hostname,$uid) {
763
764         do {
765                 $dups = false;
766                 $hash = random_string();
767
768                 $uri = "urn:X-dfrn:" . $hostname . ':' . $uid . ':' . $hash;
769
770                 $r = q("SELECT `id` FROM `item` WHERE `uri` = '%s' LIMIT 1",
771                         dbesc($uri));
772                 if(count($r))
773                         $dups = true;
774         } while($dups == true);
775         return $uri;
776 }}
777
778 if(! function_exists('photo_new_resource')) {
779 function photo_new_resource() {
780
781         do {
782                 $found = false;
783                 $resource = hash('md5',uniqid(mt_rand(),true));
784                 $r = q("SELECT `id` FROM `photo` WHERE `resource-id` = '%s' LIMIT 1",
785                         dbesc($resource)
786                 );
787                 if(count($r))
788                         $found = true;
789         } while($found == true);
790         return $resource;
791 }}
792
793
794
795 if(! function_exists('get_uid')) {
796 function get_uid() {
797         return ((x($_SESSION,'uid')) ? intval($_SESSION['uid']) : 0) ;
798 }}
799
800 if(! function_exists('validate_url')) {
801 function validate_url(&$url) {
802         if(substr($url,0,4) != 'http')
803                 $url = 'http://' . $url;
804         $h = parse_url($url);
805
806         if(! $h) {
807                 return false;
808         }
809         if(! checkdnsrr($h['host'], 'ANY')) {
810                 return false;
811         }
812         return true;
813 }}
814
815 if(! function_exists('allowed_url')) {
816 function allowed_url($url) {
817
818         $h = parse_url($url);
819
820         if(! $h) {
821                 return false;
822         }
823
824         $str_allowed = get_config('system','allowed_sites');
825         if(! $str_allowed)
826                 return true;
827
828         $found = false;
829
830         $host = strtolower($h['host']);
831
832         // always allow our own site
833
834         if($host == strtolower($_SERVER['SERVER_NAME']))
835                 return true;
836
837         $fnmatch = function_exists('fnmatch');
838         $allowed = explode(',',$str_allowed);
839
840         if(count($allowed)) {
841                 foreach($allowed as $a) {
842                         $pat = strtolower(trim($a));
843                         if(($fnmatch && fnmatch($pat,$host)) || ($pat == $host)) {
844                                 $found = true; 
845                                 break;
846                         }
847                 }
848         }
849         return $found;
850 }}
851
852 if(! function_exists('format_like')) {
853 function format_like($cnt,$arr,$type,$id) {
854         if($cnt == 1)
855                 $o .= $arr[0] . (($type == 'like') ? t(' likes this.') : t(' doesn\'t like this.')) . EOL ;
856         else {
857                 $o .= '<span class="fakelink" onclick="openClose(\'' . $type . 'list-' . $id . '\');" >' 
858                         . $cnt . ' ' . t('people') . '</span> ' . (($type == 'like') ? t('like this.') : t('don\'t like this.')) . EOL ;
859                 $total = count($arr);
860                 if($total >= 75)
861                         $arr = array_slice($arr,0,74);
862                 if($total < 75)
863                         $arr[count($arr)-1] = t('and') . ' ' . $arr[count($arr)-1];
864                 $str = implode(', ', $arr);
865                 if($total >= 75)
866                         $str .= t(', and ') . $total - 75 . t(' other people');
867                 $str .= (($type == 'like') ? t(' like this.') : t(' don\'t like this.'));
868                 $o .= '<div id="' . $type . 'list-' . $id . '" style="display: none;" >' . $str . '</div>';
869         }
870         return $o;
871 }}
872