2010-07-02 01:48:07 +02:00
< ? php
2010-09-27 09:38:26 +02:00
// two-level sort for timezones.
2010-07-02 01:48:07 +02:00
if ( ! function_exists ( 'timezone_cmp' )) {
function timezone_cmp ( $a , $b ) {
if ( strstr ( $a , '/' ) && strstr ( $b , '/' )) {
2010-09-30 03:11:23 +02:00
if ( t ( $a ) == t ( $b )) return 0 ;
return ( t ( $a ) < t ( $b )) ? - 1 : 1 ;
2010-07-02 01:48:07 +02:00
}
if ( strstr ( $a , '/' )) return - 1 ;
if ( strstr ( $b , '/' )) return 1 ;
2010-08-16 06:49:29 +02:00
if ( t ( $a ) == t ( $b )) return 0 ;
return ( t ( $a ) < t ( $b )) ? - 1 : 1 ;
2010-07-02 01:48:07 +02:00
}}
2010-09-27 09:38:26 +02:00
// emit a timezone selector grouped (primarily) by continent
2010-07-02 01:48:07 +02:00
if ( ! function_exists ( 'select_timezone' )) {
function select_timezone ( $current = 'America/Los_Angeles' ) {
$timezone_identifiers = DateTimeZone :: listIdentifiers ();
2014-03-11 23:52:32 +01:00
2010-07-02 01:48:07 +02:00
$o = '<select id="timezone_select" name="timezone">' ;
usort ( $timezone_identifiers , 'timezone_cmp' );
$continent = '' ;
foreach ( $timezone_identifiers as $value ) {
$ex = explode ( " / " , $value );
if ( count ( $ex ) > 1 ) {
if ( $ex [ 0 ] != $continent ) {
if ( $continent != '' )
$o .= '</optgroup>' ;
$continent = $ex [ 0 ];
2010-08-16 06:49:29 +02:00
$o .= '<optgroup label="' . t ( $continent ) . '">' ;
2010-07-02 01:48:07 +02:00
}
if ( count ( $ex ) > 2 )
$city = substr ( $value , strpos ( $value , '/' ) + 1 );
else
$city = $ex [ 1 ];
}
else {
$city = $ex [ 0 ];
2010-09-30 03:11:23 +02:00
if ( $continent != t ( 'Miscellaneous' )) {
2010-07-02 01:48:07 +02:00
$o .= '</optgroup>' ;
2010-09-30 03:11:23 +02:00
$continent = t ( 'Miscellaneous' );
2010-08-16 06:49:29 +02:00
$o .= '<optgroup label="' . t ( $continent ) . '">' ;
2010-07-02 01:48:07 +02:00
}
}
2010-08-16 06:49:29 +02:00
$city = str_replace ( '_' , ' ' , t ( $city ));
2010-07-02 01:48:07 +02:00
$selected = (( $value == $current ) ? " selected= \" selected \" " : " " );
$o .= " <option value= \" $value\ " $selected > $city </ option > " ;
}
$o .= '</optgroup></select>' ;
return $o ;
}}
2012-01-02 20:09:25 +01:00
// return a select using 'field_select_raw' template, with timezones
// groupped (primarily) by continent
// arguments follow convetion as other field_* template array:
// 'name', 'label', $value, 'help'
if ( ! function_exists ( 'field_timezone' )){
function field_timezone ( $name = 'timezone' , $label = '' , $current = 'America/Los_Angeles' , $help ){
$options = select_timezone ( $current );
$options = str_replace ( '<select id="timezone_select" name="timezone">' , '' , $options );
$options = str_replace ( '</select>' , '' , $options );
$tpl = get_markup_template ( 'field_select_raw.tpl' );
return replace_macros ( $tpl , array (
'$field' => array ( $name , $label , $current , $help , $options ),
));
}}
2010-09-27 09:38:26 +02:00
// General purpose date parse/convert function.
// $from = source timezone
// $to = dest timezone
// $s = some parseable date/time string
// $fmt = output format
2010-07-02 01:48:07 +02:00
if ( ! function_exists ( 'datetime_convert' )) {
function datetime_convert ( $from = 'UTC' , $to = 'UTC' , $s = 'now' , $fmt = " Y-m-d H:i:s " ) {
2010-09-09 05:14:17 +02:00
2012-04-09 03:09:21 +02:00
// Defaults to UTC if nothing is set, but throws an exception if set to empty string.
// Provide some sane defaults regardless.
2012-04-09 03:01:49 +02:00
2012-04-09 03:09:21 +02:00
if ( $from === '' )
2012-04-09 03:01:49 +02:00
$from = 'UTC' ;
2012-04-09 03:09:21 +02:00
if ( $to === '' )
2012-04-09 03:01:49 +02:00
$to = 'UTC' ;
2012-06-13 20:41:53 +02:00
if ( ( $s === '' ) || ( ! is_string ( $s )) )
2012-04-09 03:09:21 +02:00
$s = 'now' ;
2012-04-09 03:01:49 +02:00
2010-09-09 05:14:17 +02:00
// Slight hackish adjustment so that 'zero' datetime actually returns what is intended
2011-06-29 12:54:29 +02:00
// otherwise we end up with -0001-11-30 ...
2010-09-09 05:14:17 +02:00
// add 32 days so that we at least get year 00, and then hack around the fact that
2011-06-29 12:54:29 +02:00
// months and days always start with 1.
2010-09-09 05:14:17 +02:00
if ( substr ( $s , 0 , 10 ) == '0000-00-00' ) {
$d = new DateTime ( $s . ' + 32 days' , new DateTimeZone ( 'UTC' ));
return str_replace ( '1' , '0' , $d -> format ( $fmt ));
}
2012-07-16 06:00:11 +02:00
try {
$from_obj = new DateTimeZone ( $from );
}
catch ( Exception $e ) {
$from_obj = new DateTimeZone ( 'UTC' );
}
try {
$d = new DateTime ( $s , $from_obj );
}
catch ( Exception $e ) {
logger ( 'datetime_convert: exception: ' . $e -> getMessage ());
$d = new DateTime ( 'now' , $from_obj );
}
try {
$to_obj = new DateTimeZone ( $to );
}
catch ( Exception $e ) {
$to_obj = new DateTimeZone ( 'UTC' );
}
$d -> setTimeZone ( $to_obj );
2010-09-09 05:14:17 +02:00
return ( $d -> format ( $fmt ));
2010-07-02 01:48:07 +02:00
}}
2012-07-16 06:00:11 +02:00
2010-09-27 09:38:26 +02:00
// wrapper for date selector, tailored for use in birthday fields
2010-07-10 16:09:57 +02:00
function dob ( $dob ) {
list ( $year , $month , $day ) = sscanf ( $dob , '%4d-%2d-%2d' );
2011-07-26 05:59:25 +02:00
$f = get_config ( 'system' , 'birthday_input_format' );
if ( ! $f )
$f = 'ymd' ;
2015-05-22 18:53:18 +02:00
if ( $dob === '0000-00-00' )
$value = '' ;
else
$value = (( $year ) ? datetime_convert ( 'UTC' , 'UTC' , $dob , 'Y-m-d' ) : datetime_convert ( 'UTC' , 'UTC' , $dob , 'm-d' ));
$o = '<input type="text" name="dob" value="' . $value . '" placeholder="' . t ( 'YYYY-MM-DD or MM-DD' ) . '" />' ;
// if ($dob && $dob != '0000-00-00')
// $o = datesel($f,mktime(0,0,0,0,0,1900),mktime(),mktime(0,0,0,$month,$day,$year),'dob');
// else
// $o = datesel($f,mktime(0,0,0,0,0,1900),mktime(),false,'dob');
2011-07-26 05:59:25 +02:00
return $o ;
}
2015-05-22 18:53:18 +02:00
/**
* returns a date selector
* @ param $format
* format string , e . g . 'ymd' or 'mdy' . Not currently supported
* @ param $min
* unix timestamp of minimum date
* @ param $max
* unix timestap of maximum date
* @ param $default
* unix timestamp of default date
* @ param $id
* id and name of datetimepicker ( defaults to " datetimepicker " )
*/
2010-07-02 01:48:07 +02:00
if ( ! function_exists ( 'datesel' )) {
2015-05-22 18:53:18 +02:00
function datesel ( $format , $min , $max , $default , $id = 'datepicker' ) {
return datetimesel ( $format , $min , $max , $default , $id , true , false , '' , '' );
2010-07-02 01:48:07 +02:00
}}
2015-05-22 18:53:18 +02:00
/**
* returns a time selector
* @ param $format
* format string , e . g . 'ymd' or 'mdy' . Not currently supported
* @ param $h
* already selected hour
* @ param $m
* already selected minute
* @ param $id
* id and name of datetimepicker ( defaults to " timepicker " )
*/
2011-06-07 04:59:20 +02:00
if ( ! function_exists ( 'timesel' )) {
2015-05-22 18:53:18 +02:00
function timesel ( $format , $h , $m , $id = 'timepicker' ) {
return datetimesel ( $format , new DateTime (), new DateTime (), new DateTime ( " $h : $m " ), $id , false , true );
}}
2011-06-07 04:59:20 +02:00
2015-05-22 18:53:18 +02:00
/**
* @ brief Returns a datetime selector .
*
* @ param $format
* format string , e . g . 'ymd' or 'mdy' . Not currently supported
* @ param $min
* unix timestamp of minimum date
* @ param $max
* unix timestap of maximum date
* @ param $default
* unix timestamp of default date
* @ param string $id
* id and name of datetimepicker ( defaults to " datetimepicker " )
* @ param boolean $pickdate
* true to show date picker ( default )
* @ param boolean $picktime
* true to show time picker ( default )
* @ param $minfrom
* set minimum date from picker with id $minfrom ( none by default )
* @ param $maxfrom
* set maximum date from picker with id $maxfrom ( none by default )
* @ param boolean $required default false
* @ return string Parsed HTML output .
*
* @ todo Once browser support is better this could probably be replaced with
* native HTML5 date picker .
*/
if ( ! function_exists ( 'datetimesel' )) {
function datetimesel ( $format , $min , $max , $default , $id = 'datetimepicker' , $pickdate = true , $picktime = true , $minfrom = '' , $maxfrom = '' , $required = false ) {
2011-06-07 04:59:20 +02:00
2015-05-22 18:53:18 +02:00
$o = '' ;
$dateformat = '' ;
if ( $pickdate ) $dateformat .= 'Y-m-d' ;
if ( $pickdate && $picktime ) $dateformat .= ' ' ;
if ( $picktime ) $dateformat .= 'H:i' ;
$minjs = $min ? " ,minDate: new Date( { $min -> getTimestamp () } *1000), yearStart: " . $min -> format ( 'Y' ) : '' ;
$maxjs = $max ? " ,maxDate: new Date( { $max -> getTimestamp () } *1000), yearEnd: " . $max -> format ( 'Y' ) : '' ;
$input_text = $default ? 'value="' . date ( $dateformat , $default -> getTimestamp ()) . '"' : '' ;
$defaultdatejs = $default ? " ,defaultDate: new Date( { $default -> getTimestamp () } *1000) " : '' ;
$pickers = '' ;
if ( ! $pickdate ) $pickers .= ',datepicker: false' ;
if ( ! $picktime ) $pickers .= ',timepicker: false' ;
$extra_js = '' ;
if ( $minfrom != '' )
$extra_js .= " \$ ('# $minfrom ').data('xdsoft_datetimepicker').setOptions( { onChangeDateTime: function (currentDateTime) { \$ ('# $id ').data('xdsoft_datetimepicker').setOptions( { minDate: currentDateTime})}}) " ;
if ( $maxfrom != '' )
$extra_js .= " \$ ('# $maxfrom ').data('xdsoft_datetimepicker').setOptions( { onChangeDateTime: function (currentDateTime) { \$ ('# $id ').data('xdsoft_datetimepicker').setOptions( { maxDate: currentDateTime})}}) " ;
$readable_format = $dateformat ;
$readable_format = str_replace ( 'Y' , 'yyyy' , $readable_format );
$readable_format = str_replace ( 'm' , 'mm' , $readable_format );
$readable_format = str_replace ( 'd' , 'dd' , $readable_format );
$readable_format = str_replace ( 'H' , 'HH' , $readable_format );
$readable_format = str_replace ( 'i' , 'MM' , $readable_format );
$o .= " <div class='date'><input type='text' placeholder=' $readable_format ' name=' $id ' id=' $id ' $input_text /> " ;
$o .= '</div>' ;
$o .= " <script type='text/javascript'> \$ (function () { var picker = \$ ('# $id ').datetimepicker( { step:5,format:' $dateformat ' $minjs $maxjs $pickers $defaultdatejs }); $extra_js })</script> " ;
2011-06-07 04:59:20 +02:00
return $o ;
}}
2010-09-27 09:38:26 +02:00
// implements "3 seconds ago" etc.
// based on $posted_date, (UTC).
// Results relative to current timezone
// Limited to range of timestamps
2010-07-02 01:48:07 +02:00
2010-08-16 06:49:29 +02:00
if ( ! function_exists ( 'relative_date' )) {
2012-06-02 11:30:26 +02:00
function relative_date ( $posted_date , $format = null ) {
2010-07-02 01:48:07 +02:00
$localtime = datetime_convert ( 'UTC' , date_default_timezone_get (), $posted_date );
2010-08-16 06:49:29 +02:00
$abs = strtotime ( $localtime );
2011-06-29 16:06:32 +02:00
if ( is_null ( $posted_date ) || $posted_date === '0000-00-00 00:00:00' || $abs === False ) {
2011-06-29 12:05:09 +02:00
return t ( 'never' );
}
2011-06-29 12:54:29 +02:00
$etime = time () - $abs ;
2011-06-29 12:05:09 +02:00
2010-08-16 06:49:29 +02:00
if ( $etime < 1 ) {
return t ( 'less than a second ago' );
}
2014-10-25 16:44:24 +02:00
$time_append = '' ;
if ( $etime >= 86400 ) {
$time_append = ' (' . $localtime . ')' ;
}
2010-08-16 06:49:29 +02:00
$a = array ( 12 * 30 * 24 * 60 * 60 => array ( t ( 'year' ), t ( 'years' )),
2011-06-29 12:54:29 +02:00
30 * 24 * 60 * 60 => array ( t ( 'month' ), t ( 'months' )),
7 * 24 * 60 * 60 => array ( t ( 'week' ), t ( 'weeks' )),
24 * 60 * 60 => array ( t ( 'day' ), t ( 'days' )),
60 * 60 => array ( t ( 'hour' ), t ( 'hours' )),
60 => array ( t ( 'minute' ), t ( 'minutes' )),
1 => array ( t ( 'second' ), t ( 'seconds' ))
2010-08-16 06:49:29 +02:00
);
2010-07-02 01:48:07 +02:00
2010-08-16 06:49:29 +02:00
foreach ( $a as $secs => $str ) {
2012-02-13 02:15:09 +01:00
$d = $etime / $secs ;
if ( $d >= 1 ) {
$r = round ( $d );
// translators - e.g. 22 hours ago, 1 minute ago
2012-06-02 11:30:26 +02:00
if ( ! $format )
$format = t ( '%1$d %2$s ago' );
2014-10-25 16:44:24 +02:00
return sprintf ( $format , $r , (( $r == 1 ) ? $str [ 0 ] : $str [ 1 ])) . $time_append ;
2010-07-02 01:48:07 +02:00
}
}
2010-08-16 06:49:29 +02:00
}}
2010-07-10 07:47:32 +02:00
2010-09-27 09:38:26 +02:00
// Returns age in years, given a date of birth,
// the timezone of the person whose date of birth is provided,
// and the timezone of the person viewing the result.
2010-09-27 09:46:29 +02:00
// Why? Bear with me. Let's say I live in Mittagong, Australia, and my
// birthday is on New Year's. You live in San Bruno, California.
2010-09-27 09:38:26 +02:00
// When exactly are you going to see my age increase?
2010-09-27 09:46:29 +02:00
// A: 5:00 AM Dec 31 San Bruno time. That's precisely when I start
// celebrating and become a year older. If you wish me happy birthday
// on January 1 (San Bruno time), you'll be a day late.
2010-09-27 09:38:26 +02:00
2010-07-10 07:47:32 +02:00
function age ( $dob , $owner_tz = '' , $viewer_tz = '' ) {
2010-07-11 13:54:39 +02:00
if ( ! intval ( $dob ))
2010-07-10 07:47:32 +02:00
return 0 ;
if ( ! $owner_tz )
$owner_tz = date_default_timezone_get ();
if ( ! $viewer_tz )
$viewer_tz = date_default_timezone_get ();
$birthdate = datetime_convert ( 'UTC' , $owner_tz , $dob . ' 00:00:00+00:00' , 'Y-m-d' );
list ( $year , $month , $day ) = explode ( " - " , $birthdate );
$year_diff = datetime_convert ( 'UTC' , $viewer_tz , 'now' , 'Y' ) - $year ;
$curr_month = datetime_convert ( 'UTC' , $viewer_tz , 'now' , 'm' );
$curr_day = datetime_convert ( 'UTC' , $viewer_tz , 'now' , 'd' );
if (( $curr_month < $month ) || (( $curr_month == $month ) && ( $curr_day < $day )))
$year_diff -- ;
return $year_diff ;
}
2011-02-23 05:08:15 +01:00
// Get days in month
// get_dim($year, $month);
// returns number of days.
// $month[1] = 'January';
// to match human usage.
if ( ! function_exists ( 'get_dim' )) {
function get_dim ( $y , $m ) {
$dim = array ( 0 ,
31 , 28 , 31 , 30 , 31 , 30 ,
31 , 31 , 30 , 31 , 30 , 31 );
if ( $m != 2 )
return $dim [ $m ];
if (((( $y % 4 ) == 0 ) && (( $y % 100 ) != 0 )) || (( $y % 400 ) == 0 ))
return 29 ;
return $dim [ 2 ];
}}
// Returns the first day in month for a given month, year
// get_first_dim($year,$month)
// returns 0 = Sunday through 6 = Saturday
// Months start at 1.
if ( ! function_exists ( 'get_first_dim' )) {
function get_first_dim ( $y , $m ) {
$d = sprintf ( '%04d-%02d-01 00:00' , intval ( $y ), intval ( $m ));
return datetime_convert ( 'UTC' , 'UTC' , $d , 'w' );
}}
// output a calendar for the given month, year.
// if $links are provided (array), e.g. $links[12] => 'http://mylink' ,
// date 12 will be linked appropriately. Today's date is also noted by
// altering td class.
// Months count from 1.
// TODO: provide (prev,next) links, define class variations for different size calendars
if ( ! function_exists ( 'cal' )) {
2011-06-07 05:17:36 +02:00
function cal ( $y = 0 , $m = 0 , $links = false , $class = '' ) {
2011-02-23 05:08:15 +01:00
// month table - start at 1 to match human usage.
$mtab = array ( ' ' ,
'January' , 'February' , 'March' ,
'April' , 'May' , 'June' ,
'July' , 'August' , 'September' ,
'October' , 'November' , 'December'
);
$thisyear = datetime_convert ( 'UTC' , date_default_timezone_get (), 'now' , 'Y' );
$thismonth = datetime_convert ( 'UTC' , date_default_timezone_get (), 'now' , 'm' );
if ( ! $y )
$y = $thisyear ;
if ( ! $m )
$m = intval ( $thismonth );
$dn = array ( 'Sunday' , 'Monday' , 'Tuesday' , 'Wednesday' , 'Thursday' , 'Friday' , 'Saturday' );
$f = get_first_dim ( $y , $m );
$l = get_dim ( $y , $m );
$d = 1 ;
$dow = 0 ;
$started = false ;
if (( $y == $thisyear ) && ( $m == $thismonth ))
$tddate = intval ( datetime_convert ( 'UTC' , date_default_timezone_get (), 'now' , 'j' ));
$str_month = day_translate ( $mtab [ $m ]);
2011-06-07 05:17:36 +02:00
$o = '<table class="calendar' . $class . '">' ;
2011-02-23 05:08:15 +01:00
$o .= " <caption> $str_month $y </caption><tr> " ;
for ( $a = 0 ; $a < 7 ; $a ++ )
2011-02-23 10:37:15 +01:00
$o .= '<th>' . mb_substr ( day_translate ( $dn [ $a ]), 0 , 3 , 'UTF-8' ) . '</th>' ;
2011-02-23 05:08:15 +01:00
$o .= '</tr><tr>' ;
while ( $d <= $l ) {
if (( $dow == $f ) && ( ! $started ))
$started = true ;
$today = ((( isset ( $tddate )) && ( $tddate == $d )) ? " class= \" today \" " : '' );
$o .= " <td $today > " ;
$day = str_replace ( ' ' , ' ' , sprintf ( '%2.2d' , $d ));
if ( $started ) {
if ( is_array ( $links ) && isset ( $links [ $d ]))
$o .= " <a href= \" { $links [ $d ] } \" > $day </a> " ;
else
$o .= $day ;
$d ++ ;
}
else
$o .= ' ' ;
$o .= '</td>' ;
$dow ++ ;
if (( $dow == 7 ) && ( $d <= $l )) {
$dow = 0 ;
$o .= '</tr><tr>' ;
}
}
if ( $dow )
for ( $a = $dow ; $a < 7 ; $a ++ )
$o .= '<td> </td>' ;
$o .= '</tr></table>' . " \r \n " ;
return $o ;
}}
2011-10-14 09:20:37 +02:00
function update_contact_birthdays () {
// This only handles foreign or alien networks where a birthday has been provided.
// In-network birthdays are handled within local_delivery
$r = q ( " SELECT * FROM contact WHERE `bd` != '' AND `bd` != '0000-00-00' AND SUBSTRING(`bd`,1,4) != `bdyear` " );
if ( count ( $r )) {
foreach ( $r as $rr ) {
logger ( 'update_contact_birthday: ' . $rr [ 'bd' ]);
$nextbd = datetime_convert ( 'UTC' , 'UTC' , 'now' , 'Y' ) . substr ( $rr [ 'bd' ], 4 );
/**
*
* Add new birthday event for this person
*
* $bdtext is just a readable placeholder in case the event is shared
* with others . We will replace it during presentation to our $importer
* to contain a sparkle link and perhaps a photo .
*
*/
2012-06-26 06:37:38 +02:00
$bdtext = sprintf ( t ( '%s\'s birthday' ), $rr [ 'name' ]);
2012-06-26 06:39:07 +02:00
$bdtext2 = sprintf ( t ( 'Happy Birthday %s' ), ' [url=' . $rr [ 'url' ] . ']' . $rr [ 'name' ] . '[/url]' ) ;
2011-10-14 09:20:37 +02:00
2012-06-26 06:37:38 +02:00
$r = q ( " INSERT INTO `event` (`uid`,`cid`,`created`,`edited`,`start`,`finish`,`summary`,`desc`,`type`,`adjust`)
VALUES ( % d , % d , '%s' , '%s' , '%s' , '%s' , '%s' , '%s' , '%s' , '%d' ) " ,
2011-10-14 09:20:37 +02:00
intval ( $rr [ 'uid' ]),
intval ( $rr [ 'id' ]),
dbesc ( datetime_convert ()),
dbesc ( datetime_convert ()),
dbesc ( datetime_convert ( 'UTC' , 'UTC' , $nextbd )),
dbesc ( datetime_convert ( 'UTC' , 'UTC' , $nextbd . ' + 1 day ' )),
dbesc ( $bdtext ),
2012-06-26 06:37:38 +02:00
dbesc ( $bdtext2 ),
2011-10-14 09:20:37 +02:00
dbesc ( 'birthday' ),
intval ( 0 )
);
2014-03-11 23:52:32 +01:00
2011-10-14 09:20:37 +02:00
// update bdyear
2014-03-11 23:52:32 +01:00
q ( " UPDATE `contact` SET `bdyear` = '%s', `bd` = '%s' WHERE `uid` = %d AND `id` = %d " ,
2011-10-14 09:20:37 +02:00
dbesc ( substr ( $nextbd , 0 , 4 )),
dbesc ( $nextbd ),
intval ( $rr [ 'uid' ]),
intval ( $rr [ 'id' ])
);
}
}
2012-01-02 20:09:25 +01:00
}