+}}
+
+/**
+ *
+ * Wrap calls to proc_close(proc_open()) and call hook
+ * so plugins can take part in process :)
+ *
+ * args:
+ * $cmd program to run
+ * next args are passed as $cmd command line
+ *
+ * e.g.: proc_run("ls","-la","/tmp");
+ *
+ * $cmd and string args are surrounded with ""
+ */
+
+if(! function_exists('proc_run')) {
+function proc_run($cmd){
+
+ $a = get_app();
+
+ $args = func_get_args();
+ call_hooks("proc_run", $args);
+
+ if(count($args) && $args[0] === 'php')
+ $args[0] = ((x($a->config,'php_path')) && (strlen($a->config['php_path'])) ? $a->config['php_path'] : 'php');
+
+ foreach ($args as $arg){
+ $arg = escapeshellarg($arg);
+ }
+ $cmdline = implode($args," ");
+ proc_close(proc_open($cmdline." &",array(),$foo));
+}}
+
+/*
+ * Return full URL to theme which is currently in effect.
+ * Provide a sane default if nothing is chosen or the specified theme does not exist.
+ */
+
+if(! function_exists('current_theme_url')) {
+function current_theme_url() {
+
+ $app_base_themes = array('duepuntozero', 'loozah');
+
+ $a = get_app();
+
+ $system_theme = ((isset($a->config['system']['theme'])) ? $a->config['system']['theme'] : '');
+ $theme_name = ((x($_SESSION,'theme')) ? $_SESSION['theme'] : $system_theme);
+
+ if($theme_name && file_exists('view/theme/' . $theme_name . '/style.css'))
+ return($a->get_baseurl() . '/view/theme/' . $theme_name . '/style.css');
+
+ foreach($app_base_themes as $t) {
+ if(file_exists('view/theme/' . $t . '/style.css'))
+ return($a->get_baseurl() . '/view/theme/' . $t . '/style.css');
+ }
+
+ $fallback = glob('view/theme/*/style.css');
+ if(count($fallback))
+ return($a->get_baseurl() . $fallback[0]);
+
+
+}}
+
+if(! function_exists('feed_birthday')) {
+function feed_birthday($uid,$tz) {
+
+ /**
+ *
+ * Determine the next birthday, but only if the birthday is published
+ * in the default profile. We _could_ also look for a private profile that the
+ * recipient can see, but somebody could get mad at us if they start getting
+ * public birthday greetings when they haven't made this info public.
+ *
+ * Assuming we are able to publish this info, we are then going to convert
+ * the start time from the owner's timezone to UTC.
+ *
+ * This will potentially solve the problem found with some social networks
+ * where birthdays are converted to the viewer's timezone and salutations from
+ * elsewhere in the world show up on the wrong day. We will convert it to the
+ * viewer's timezone also, but first we are going to convert it from the birthday
+ * person's timezone to GMT - so the viewer may find the birthday starting at
+ * 6:00PM the day before, but that will correspond to midnight to the birthday person.
+ *
+ */
+
+ $birthday = '';
+
+ $p = q("SELECT `dob` FROM `profile` WHERE `is-default` = 1 AND `uid` = %d LIMIT 1",
+ intval($uid)
+ );
+
+ if($p && count($p)) {
+ $tmp_dob = substr($p[0]['dob'],5);
+ if(intval($tmp_dob)) {
+ $y = datetime_convert($tz,$tz,'now','Y');
+ $bd = $y . '-' . $tmp_dob . ' 00:00';
+ $t_dob = strtotime($bd);
+ $now = strtotime(datetime_convert($tz,$tz,'now'));
+ if($t_dob < $now)
+ $bd = $y + 1 . '-' . $tmp_dob . ' 00:00';
+ $birthday = datetime_convert($tz,'UTC',$bd,ATOM_TIME);
+ }
+ }
+
+ return $birthday;
+}}
+
+/**
+ * return atom link elements for all of our hubs
+ */