Friendica Communications Platform (please note that this is a clone of the repository at github, issues are handled there) https://friendi.ca
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

466 lines
13 KiB

11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
10 years ago
10 years ago
  1. <?php
  2. // two-level sort for timezones.
  3. if(! function_exists('timezone_cmp')) {
  4. function timezone_cmp($a, $b) {
  5. if(strstr($a,'/') && strstr($b,'/')) {
  6. if ( t($a) == t($b)) return 0;
  7. return ( t($a) < t($b)) ? -1 : 1;
  8. }
  9. if(strstr($a,'/')) return -1;
  10. if(strstr($b,'/')) return 1;
  11. if ( t($a) == t($b)) return 0;
  12. return ( t($a) < t($b)) ? -1 : 1;
  13. }}
  14. // emit a timezone selector grouped (primarily) by continent
  15. if(! function_exists('select_timezone')) {
  16. function select_timezone($current = 'America/Los_Angeles') {
  17. $timezone_identifiers = DateTimeZone::listIdentifiers();
  18. $o ='<select id="timezone_select" name="timezone">';
  19. usort($timezone_identifiers, 'timezone_cmp');
  20. $continent = '';
  21. foreach($timezone_identifiers as $value) {
  22. $ex = explode("/", $value);
  23. if(count($ex) > 1) {
  24. if($ex[0] != $continent) {
  25. if($continent != '')
  26. $o .= '</optgroup>';
  27. $continent = $ex[0];
  28. $o .= '<optgroup label="' . t($continent) . '">';
  29. }
  30. if(count($ex) > 2)
  31. $city = substr($value,strpos($value,'/')+1);
  32. else
  33. $city = $ex[1];
  34. }
  35. else {
  36. $city = $ex[0];
  37. if($continent != t('Miscellaneous')) {
  38. $o .= '</optgroup>';
  39. $continent = t('Miscellaneous');
  40. $o .= '<optgroup label="' . t($continent) . '">';
  41. }
  42. }
  43. $city = str_replace('_', ' ', t($city));
  44. $selected = (($value == $current) ? " selected=\"selected\" " : "");
  45. $o .= "<option value=\"$value\" $selected >$city</option>";
  46. }
  47. $o .= '</optgroup></select>';
  48. return $o;
  49. }}
  50. // return a select using 'field_select_raw' template, with timezones
  51. // groupped (primarily) by continent
  52. // arguments follow convetion as other field_* template array:
  53. // 'name', 'label', $value, 'help'
  54. if (!function_exists('field_timezone')){
  55. function field_timezone($name='timezone', $label='', $current = 'America/Los_Angeles', $help){
  56. $options = select_timezone($current);
  57. $options = str_replace('<select id="timezone_select" name="timezone">','', $options);
  58. $options = str_replace('</select>','', $options);
  59. $tpl = get_markup_template('field_select_raw.tpl');
  60. return replace_macros($tpl, array(
  61. '$field' => array($name, $label, $current, $help, $options),
  62. ));
  63. }}
  64. // General purpose date parse/convert function.
  65. // $from = source timezone
  66. // $to = dest timezone
  67. // $s = some parseable date/time string
  68. // $fmt = output format
  69. if(! function_exists('datetime_convert')) {
  70. function datetime_convert($from = 'UTC', $to = 'UTC', $s = 'now', $fmt = "Y-m-d H:i:s") {
  71. // Slight hackish adjustment so that 'zero' datetime actually returns what is intended
  72. // otherwise we end up with -0001-11-30 ...
  73. // add 32 days so that we at least get year 00, and then hack around the fact that
  74. // months and days always start with 1.
  75. if(substr($s,0,10) == '0000-00-00') {
  76. $d = new DateTime($s . ' + 32 days', new DateTimeZone('UTC'));
  77. return str_replace('1','0',$d->format($fmt));
  78. }
  79. $d = new DateTime($s, new DateTimeZone($from));
  80. $d->setTimeZone(new DateTimeZone($to));
  81. return($d->format($fmt));
  82. }}
  83. // wrapper for date selector, tailored for use in birthday fields
  84. function dob($dob) {
  85. list($year,$month,$day) = sscanf($dob,'%4d-%2d-%2d');
  86. $y = datetime_convert('UTC',date_default_timezone_get(),'now','Y');
  87. $f = get_config('system','birthday_input_format');
  88. if(! $f)
  89. $f = 'ymd';
  90. $o = datesel($f,'',1920,$y,true,$year,$month,$day);
  91. return $o;
  92. }
  93. function datesel_format($f) {
  94. $o = '';
  95. if(strlen($f)) {
  96. for($x = 0; $x < strlen($f); $x ++) {
  97. switch($f[$x]) {
  98. case 'y':
  99. if(strlen($o))
  100. $o .= '-';
  101. $o .= t('year');
  102. break;
  103. case 'm':
  104. if(strlen($o))
  105. $o .= '-';
  106. $o .= t('month');
  107. break;
  108. case 'd':
  109. if(strlen($o))
  110. $o .= '-';
  111. $o .= t('day');
  112. break;
  113. default:
  114. break;
  115. }
  116. }
  117. }
  118. return $o;
  119. }
  120. // returns a date selector.
  121. // $f = format string, e.g. 'ymd' or 'mdy'
  122. // $pre = prefix (if needed) for HTML name and class fields
  123. // $ymin = first year shown in selector dropdown
  124. // $ymax = last year shown in selector dropdown
  125. // $allow_blank = allow an empty response on any field
  126. // $y = already selected year
  127. // $m = already selected month
  128. // $d = already selected day
  129. if(! function_exists('datesel')) {
  130. function datesel($f,$pre,$ymin,$ymax,$allow_blank,$y,$m,$d) {
  131. $o = '';
  132. if(strlen($f)) {
  133. for($z = 0; $z < strlen($f); $z ++) {
  134. if($f[$z] === 'y') {
  135. $o .= "<select name=\"{$pre}year\" class=\"{$pre}year\" size=\"1\">";
  136. if($allow_blank) {
  137. $sel = (($y == '0000') ? " selected=\"selected\" " : "");
  138. $o .= "<option value=\"0000\" $sel ></option>";
  139. }
  140. if($ymax > $ymin) {
  141. for($x = $ymax; $x >= $ymin; $x --) {
  142. $sel = (($x == $y) ? " selected=\"selected\" " : "");
  143. $o .= "<option value=\"$x\" $sel>$x</option>";
  144. }
  145. }
  146. else {
  147. for($x = $ymax; $x <= $ymin; $x ++) {
  148. $sel = (($x == $y) ? " selected=\"selected\" " : "");
  149. $o .= "<option value=\"$x\" $sel>$x</option>";
  150. }
  151. }
  152. }
  153. elseif($f[$z] == 'm') {
  154. $o .= "</select> <select name=\"{$pre}month\" class=\"{$pre}month\" size=\"1\">";
  155. for($x = (($allow_blank) ? 0 : 1); $x <= 12; $x ++) {
  156. $sel = (($x == $m) ? " selected=\"selected\" " : "");
  157. $y = (($x) ? $x : '');
  158. $o .= "<option value=\"$x\" $sel>$y</option>";
  159. }
  160. }
  161. elseif($f[$z] == 'd') {
  162. $o .= "</select> <select name=\"{$pre}day\" class=\"{$pre}day\" size=\"1\">";
  163. for($x = (($allow_blank) ? 0 : 1); $x <= 31; $x ++) {
  164. $sel = (($x == $d) ? " selected=\"selected\" " : "");
  165. $y = (($x) ? $x : '');
  166. $o .= "<option value=\"$x\" $sel>$y</option>";
  167. }
  168. }
  169. }
  170. }
  171. $o .= "</select>";
  172. return $o;
  173. }}
  174. if(! function_exists('timesel')) {
  175. function timesel($pre,$h,$m) {
  176. $o = '';
  177. $o .= "<select name=\"{$pre}hour\" class=\"{$pre}hour\" size=\"1\">";
  178. for($x = 0; $x < 24; $x ++) {
  179. $sel = (($x == $h) ? " selected=\"selected\" " : "");
  180. $o .= "<option value=\"$x\" $sel>$x</option>";
  181. }
  182. $o .= "</select> : <select name=\"{$pre}minute\" class=\"{$pre}minute\" size=\"1\">";
  183. for($x = 0; $x < 60; $x ++) {
  184. $sel = (($x == $m) ? " selected=\"selected\" " : "");
  185. $o .= "<option value=\"$x\" $sel>$x</option>";
  186. }
  187. $o .= "</select>";
  188. return $o;
  189. }}
  190. // implements "3 seconds ago" etc.
  191. // based on $posted_date, (UTC).
  192. // Results relative to current timezone
  193. // Limited to range of timestamps
  194. if(! function_exists('relative_date')) {
  195. function relative_date($posted_date) {
  196. $localtime = datetime_convert('UTC',date_default_timezone_get(),$posted_date);
  197. $abs = strtotime($localtime);
  198. if (is_null($posted_date) || $posted_date === '0000-00-00 00:00:00' || $abs === False) {
  199. return t('never');
  200. }
  201. $etime = time() - $abs;
  202. if ($etime < 1) {
  203. return t('less than a second ago');
  204. }
  205. $a = array( 12 * 30 * 24 * 60 * 60 => array( t('year'), t('years')),
  206. 30 * 24 * 60 * 60 => array( t('month'), t('months')),
  207. 7 * 24 * 60 * 60 => array( t('week'), t('weeks')),
  208. 24 * 60 * 60 => array( t('day'), t('days')),
  209. 60 * 60 => array( t('hour'), t('hours')),
  210. 60 => array( t('minute'), t('minutes')),
  211. 1 => array( t('second'), t('seconds'))
  212. );
  213. foreach ($a as $secs => $str) {
  214. $d = $etime / $secs;
  215. if ($d >= 1) {
  216. $r = round($d);
  217. // translators - e.g. 22 hours ago, 1 minute ago
  218. return sprintf( t('%1$d %2$s ago'),$r, (($r == 1) ? $str[0] : $str[1]));
  219. }
  220. }
  221. }}
  222. // Returns age in years, given a date of birth,
  223. // the timezone of the person whose date of birth is provided,
  224. // and the timezone of the person viewing the result.
  225. // Why? Bear with me. Let's say I live in Mittagong, Australia, and my
  226. // birthday is on New Year's. You live in San Bruno, California.
  227. // When exactly are you going to see my age increase?
  228. // A: 5:00 AM Dec 31 San Bruno time. That's precisely when I start
  229. // celebrating and become a year older. If you wish me happy birthday
  230. // on January 1 (San Bruno time), you'll be a day late.
  231. function age($dob,$owner_tz = '',$viewer_tz = '') {
  232. if(! intval($dob))
  233. return 0;
  234. if(! $owner_tz)
  235. $owner_tz = date_default_timezone_get();
  236. if(! $viewer_tz)
  237. $viewer_tz = date_default_timezone_get();
  238. $birthdate = datetime_convert('UTC',$owner_tz,$dob . ' 00:00:00+00:00','Y-m-d');
  239. list($year,$month,$day) = explode("-",$birthdate);
  240. $year_diff = datetime_convert('UTC',$viewer_tz,'now','Y') - $year;
  241. $curr_month = datetime_convert('UTC',$viewer_tz,'now','m');
  242. $curr_day = datetime_convert('UTC',$viewer_tz,'now','d');
  243. if(($curr_month < $month) || (($curr_month == $month) && ($curr_day < $day)))
  244. $year_diff--;
  245. return $year_diff;
  246. }
  247. // Get days in month
  248. // get_dim($year, $month);
  249. // returns number of days.
  250. // $month[1] = 'January';
  251. // to match human usage.
  252. if(! function_exists('get_dim')) {
  253. function get_dim($y,$m) {
  254. $dim = array( 0,
  255. 31, 28, 31, 30, 31, 30,
  256. 31, 31, 30, 31, 30, 31);
  257. if($m != 2)
  258. return $dim[$m];
  259. if(((($y % 4) == 0) && (($y % 100) != 0)) || (($y % 400) == 0))
  260. return 29;
  261. return $dim[2];
  262. }}
  263. // Returns the first day in month for a given month, year
  264. // get_first_dim($year,$month)
  265. // returns 0 = Sunday through 6 = Saturday
  266. // Months start at 1.
  267. if(! function_exists('get_first_dim')) {
  268. function get_first_dim($y,$m) {
  269. $d = sprintf('%04d-%02d-01 00:00', intval($y), intval($m));
  270. return datetime_convert('UTC','UTC',$d,'w');
  271. }}
  272. // output a calendar for the given month, year.
  273. // if $links are provided (array), e.g. $links[12] => 'http://mylink' ,
  274. // date 12 will be linked appropriately. Today's date is also noted by
  275. // altering td class.
  276. // Months count from 1.
  277. // TODO: provide (prev,next) links, define class variations for different size calendars
  278. if(! function_exists('cal')) {
  279. function cal($y = 0,$m = 0, $links = false, $class='') {
  280. // month table - start at 1 to match human usage.
  281. $mtab = array(' ',
  282. 'January','February','March',
  283. 'April','May','June',
  284. 'July','August','September',
  285. 'October','November','December'
  286. );
  287. $thisyear = datetime_convert('UTC',date_default_timezone_get(),'now','Y');
  288. $thismonth = datetime_convert('UTC',date_default_timezone_get(),'now','m');
  289. if(! $y)
  290. $y = $thisyear;
  291. if(! $m)
  292. $m = intval($thismonth);
  293. $dn = array('Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday');
  294. $f = get_first_dim($y,$m);
  295. $l = get_dim($y,$m);
  296. $d = 1;
  297. $dow = 0;
  298. $started = false;
  299. if(($y == $thisyear) && ($m == $thismonth))
  300. $tddate = intval(datetime_convert('UTC',date_default_timezone_get(),'now','j'));
  301. $str_month = day_translate($mtab[$m]);
  302. $o = '<table class="calendar' . $class . '">';
  303. $o .= "<caption>$str_month $y</caption><tr>";
  304. for($a = 0; $a < 7; $a ++)
  305. $o .= '<th>' . mb_substr(day_translate($dn[$a]),0,3,'UTF-8') . '</th>';
  306. $o .= '</tr><tr>';
  307. while($d <= $l) {
  308. if(($dow == $f) && (! $started))
  309. $started = true;
  310. $today = (((isset($tddate)) && ($tddate == $d)) ? "class=\"today\" " : '');
  311. $o .= "<td $today>";
  312. $day = str_replace(' ','&nbsp;',sprintf('%2.2d', $d));
  313. if($started) {
  314. if(is_array($links) && isset($links[$d]))
  315. $o .= "<a href=\"{$links[$d]}\">$day</a>";
  316. else
  317. $o .= $day;
  318. $d ++;
  319. }
  320. else
  321. $o .= '&nbsp;';
  322. $o .= '</td>';
  323. $dow ++;
  324. if(($dow == 7) && ($d <= $l)) {
  325. $dow = 0;
  326. $o .= '</tr><tr>';
  327. }
  328. }
  329. if($dow)
  330. for($a = $dow; $a < 7; $a ++)
  331. $o .= '<td>&nbsp;</td>';
  332. $o .= '</tr></table>'."\r\n";
  333. return $o;
  334. }}
  335. function update_contact_birthdays() {
  336. // This only handles foreign or alien networks where a birthday has been provided.
  337. // In-network birthdays are handled within local_delivery
  338. $r = q("SELECT * FROM contact WHERE `bd` != '' AND `bd` != '0000-00-00' AND SUBSTRING(`bd`,1,4) != `bdyear` ");
  339. if(count($r)) {
  340. foreach($r as $rr) {
  341. logger('update_contact_birthday: ' . $rr['bd']);
  342. $nextbd = datetime_convert('UTC','UTC','now','Y') . substr($rr['bd'],4);
  343. /**
  344. *
  345. * Add new birthday event for this person
  346. *
  347. * $bdtext is just a readable placeholder in case the event is shared
  348. * with others. We will replace it during presentation to our $importer
  349. * to contain a sparkle link and perhaps a photo.
  350. *
  351. */
  352. $bdtext = t('Birthday:') . ' [url=' . $rr['url'] . ']' . $rr['name'] . '[/url]' ;
  353. $r = q("INSERT INTO `event` (`uid`,`cid`,`created`,`edited`,`start`,`finish`,`desc`,`type`,`adjust`)
  354. VALUES ( %d, %d, '%s', '%s', '%s', '%s', '%s', '%s', '%d' ) ",
  355. intval($rr['uid']),
  356. intval($rr['id']),
  357. dbesc(datetime_convert()),
  358. dbesc(datetime_convert()),
  359. dbesc(datetime_convert('UTC','UTC', $nextbd)),
  360. dbesc(datetime_convert('UTC','UTC', $nextbd . ' + 1 day ')),
  361. dbesc($bdtext),
  362. dbesc('birthday'),
  363. intval(0)
  364. );
  365. // update bdyear
  366. q("UPDATE `contact` SET `bdyear` = '%s', `bd` = '%s' WHERE `uid` = %d AND `id` = %d LIMIT 1",
  367. dbesc(substr($nextbd,0,4)),
  368. dbesc($nextbd),
  369. intval($rr['uid']),
  370. intval($rr['id'])
  371. );
  372. }
  373. }
  374. }