| [ Index ] |
PHP Cross Reference of Drupal 6 (yi-drupal) |
[Summary view] [Print] [Text view]
1 <?php 2 /** 3 * @file 4 * 5 * This module creates a form element that allows users to select 6 * repeat rules for a date, and reworks the result into an iCal 7 * RRULE string that can be stored in the database. 8 * 9 * The module also parses iCal RRULEs to create an array of dates 10 * that meet their criteria. 11 * 12 * Other modules can use this API to add self-validating form elements 13 * to their dates, and identify dates that meet the RRULE criteria. 14 * 15 */ 16 /** 17 * Implementation of hook_elements(). 18 */ 19 function date_repeat_elements() { 20 $type['date_repeat_rrule'] = array( 21 '#input' => TRUE, 22 '#process' => array('date_repeat_rrule_process'), 23 '#element_validate' => array('date_repeat_rrule_validate'), 24 ); 25 return $type; 26 } 27 28 /** 29 * Implementation of hook_menu. 30 */ 31 function date_repeat_menu() { 32 $items = array(); 33 $items['date_repeat_get_exception_form_ajax'] = array( 34 'page callback' => 'date_repeat_get_exception_form_ajax', 35 'page arguments' => array(1, 2), 36 'file' => 'date_repeat_form.inc', 37 'access arguments' => array('access content'), 38 'type' => MENU_CALLBACK 39 ); 40 return $items; 41 } 42 43 function date_repeat_theme() { 44 return array( 45 'date_repeat' => array('arguments' => array('element' => NULL)), 46 'date_repeat_current_exceptions' => array('arguments' => array('element' => NULL)), 47 'date_repeat_current_additions' => array('arguments' => array('element' => NULL)), 48 ); 49 } 50 51 /** 52 * Helper function for FREQ options. 53 */ 54 function FREQ_options() { 55 return array( 56 'NONE' => t('-- Period'), 57 'DAILY' => date_t('Days', 'datetime_plural'), 58 'WEEKLY' => date_t('Weeks', 'datetime_plural'), 59 'MONTHLY' => date_t('Months', 'datetime_plural'), 60 'YEARLY' => date_t('Years', 'datetime_plural'), 61 ); 62 } 63 64 function INTERVAL_options() { 65 $options = array( 66 0 => t('-- Frequency'), 67 1 => date_t('Every', 'date_order'), 68 ); 69 for ($i = 2; $i < 367; $i++) { 70 $options[$i] = t('Every @number', array('@number' => $i)); 71 } 72 return $options; 73 } 74 75 /** 76 * Helper function for FREQ options. 77 * 78 * Translated and untranslated arrays of the iCal day of week names. 79 * We need the untranslated values for date_modify(), translated 80 * values when displayed to user. 81 */ 82 function date_repeat_dow_day_options($translated = TRUE) { 83 return array( 84 'SU' => $translated ? date_t('Sunday', 'day_name') : 'Sunday', 85 'MO' => $translated ? date_t('Monday', 'day_name') : 'Monday', 86 'TU' => $translated ? date_t('Tuesday', 'day_name') : 'Tuesday', 87 'WE' => $translated ? date_t('Wednesday', 'day_name') : 'Wednesday', 88 'TH' => $translated ? date_t('Thursday', 'day_name') : 'Thursday', 89 'FR' => $translated ? date_t('Friday', 'day_name') : 'Friday', 90 'SA' => $translated ? date_t('Saturday', 'day_name') : 'Saturday', 91 ); 92 } 93 94 function date_repeat_dow_day_options_ordered($week_start) { 95 $unordered = date_repeat_dow_day_options(FALSE); 96 if (variable_get('date_first_day', 1) > 0) { 97 for ($i = 1; $i <= variable_get('date_first_day', 1); $i++) { 98 $last = array_shift($weekdays); 99 array_push($weekdays, $last); 100 } 101 } 102 return $weekdays; 103 } 104 105 /** 106 * Helper function for BYDAY options. 107 */ 108 function date_repeat_dow_count_options() { 109 return array('' => date_t('Every', 'date_order')) + date_order_translated(); 110 } 111 112 /** 113 * Helper function for BYDAY options. 114 * 115 * Creates options like -1SU and 2TU 116 */ 117 function date_repeat_dow_options() { 118 $options = array(); 119 foreach (date_repeat_dow_count_options() as $count_key => $count_value) { 120 foreach (date_repeat_dow_day_options() as $dow_key => $dow_value) { 121 $options[$count_key . $dow_key] = $count_value .' '. $dow_value; 122 } 123 } 124 return $options; 125 } 126 127 /** 128 * Translate a day of week position to the iCal day name. 129 * 130 * Used with date_format($date, 'w') or get_variable('date_first_day'), 131 * which return 0 for Sunday, 1 for Monday, etc. 132 * 133 * dow 2 becomes 'TU', dow 3 becomes 'WE', and so on. 134 */ 135 function date_repeat_dow2day($dow) { 136 $days_of_week = array_keys(date_repeat_dow_day_options(FALSE)); 137 return $days_of_week[$dow]; 138 } 139 140 /** 141 * Shift the array of iCal day names into the right order 142 * for a specific week start day. 143 */ 144 function date_repeat_days_ordered($week_start_day) { 145 $days = array_flip(array_keys(date_repeat_dow_day_options(FALSE))); 146 $start_position = $days[$week_start_day]; 147 $keys = array_flip($days); 148 if ($start_position > 0) { 149 for ($i = 1; $i <= $start_position; $i++) { 150 $last = array_shift($keys); 151 array_push($keys, $last); 152 } 153 } 154 return $keys; 155 } 156 157 /** 158 * Build a description of an iCal rule. 159 * 160 * Constructs a human-readable description of the rule. 161 */ 162 function date_repeat_rrule_description($rrule, $format = 'D M d Y') { 163 // Empty or invalid value. 164 if (empty($rrule) || !strstr($rrule, 'RRULE')) { 165 return; 166 } 167 168 require_once('./'. drupal_get_path('module', 'date_api') .'/date_api_ical.inc'); 169 require_once('./'. drupal_get_path('module', 'date_repeat') .'/date_repeat_calc.inc'); 170 171 // Make sure there will be an empty description for any unused parts. 172 $description = array( 173 '!interval' => '', 174 '!byday' => '', 175 '!bymonth' => '', 176 '!count' => '', 177 '!until' => '', 178 '!except' => '', 179 '!additional' => '', 180 '!week_starts_on' => '', 181 ); 182 $parts = date_repeat_split_rrule($rrule); 183 $additions = $parts[2]; 184 $exceptions = $parts[1]; 185 $rrule = $parts[0]; 186 $interval = INTERVAL_options(); 187 switch ($rrule['FREQ']) { 188 case 'WEEKLY': 189 $description['!interval'] = format_plural($rrule['INTERVAL'], 'every week', 'every @count weeks') .' '; 190 break; 191 case 'MONTHLY': 192 $description['!interval'] = format_plural($rrule['INTERVAL'], 'every month', 'every @count months') .' '; 193 break; 194 case 'YEARLY': 195 $description['!interval'] = format_plural($rrule['INTERVAL'], 'every year', 'every @count years') .' '; 196 break; 197 default: 198 $description['!interval'] = format_plural($rrule['INTERVAL'], 'every day', 'every @count days') .' '; 199 break; 200 } 201 202 if (!empty($rrule['BYDAY'])) { 203 $days = date_repeat_dow_day_options(); 204 $counts = date_repeat_dow_count_options(); 205 $results = array(); 206 foreach ($rrule['BYDAY'] as $byday) { 207 $day = substr($byday, -2); 208 $count = intval(str_replace(' '. $day, '', $byday)); 209 if ($count = intval(str_replace(' ' . $day, '', $byday))) { 210 $results[] = trim(t('!repeats_every_interval on the !date_order !day_of_week', array('!repeats_every_interval ' => '', '!date_order' => strtolower($counts[substr($byday, 0, 2)]), '!day_of_week' => $days[$day]))); 211 } 212 else { 213 $results[] = trim(t('!repeats_every_interval every !day_of_week', array('!repeats_every_interval ' => '', '!day_of_week' => $days[$day]))); 214 } 215 } 216 $description['!byday'] = implode(' '. t('and') .' ', $results); 217 } 218 if (!empty($rrule['BYMONTH'])) { 219 if (sizeof($rrule['BYMONTH']) < 12) { 220 $results = array(); 221 $months = date_month_names(); 222 foreach ($rrule['BYMONTH'] as $month) { 223 $results[] = $months[$month]; 224 } 225 if (!empty($rrule['BYMONTHDAY'])) { 226 $description['!bymonth'] = trim(t('!repeats_every_interval on the !month_days of !month_names', array('!repeats_every_interval ' => '', '!month_days' => implode(', ', $rrule['BYMONTHDAY']), '!month_names' => implode(', ', $results)))); 227 } 228 else { 229 $description['!bymonth'] = trim(t('!repeats_every_interval on !month_names', array('!repeats_every_interval ' => '', '!month_names' => implode(', ', $results)))); 230 } 231 } 232 } 233 if ($rrule['INTERVAL'] < 1) { 234 $rrule['INTERVAL'] = 1; 235 } 236 if (!empty($rrule['COUNT'])) { 237 $description['!count'] = trim(t('!repeats_every_interval !count times', array('!repeats_every_interval ' => '', '!count' => $rrule['COUNT']))); 238 } 239 if (!empty($rrule['UNTIL'])) { 240 $until = date_ical_date($rrule['UNTIL'], 'UTC'); 241 date_timezone_set($until, date_default_timezone()); 242 $description['!until'] = trim(t('!repeats_every_interval until !until_date', array('!repeats_every_interval ' => '', '!until_date' => date_format_date($until, 'custom', $format)))); 243 } 244 if ($exceptions) { 245 $values = array(); 246 foreach ($exceptions as $exception) { 247 $values[] = date_format_date(date_ical_date($exception), 'custom', $format); 248 } 249 $description['!except'] = trim(t('!repeats_every_interval except !except_dates', array('!repeats_every_interval ' => '', '!except_dates' => implode(', ', $values)))); 250 } 251 if ($additions) { 252 $values = array(); 253 foreach ($additions as $addition) { 254 $values[] = date_format_date(date_ical_date($addition), 'custom', $format); 255 } 256 $description['!additional'] = trim(t('Also includes !additional_dates.', array('!additional_dates' => implode(', ', $values)))); 257 } 258 if (!empty($rrule['WKST'])) { 259 $day_names = date_repeat_dow_day_options(); 260 $description['!week_starts_on'] = trim(t('!repeats_every_interval where the week start on !day_of_week', array('!repeats_every_interval ' => '', '!day_of_week' => $day_names[trim($rrule['WKST'])]))); 261 } 262 return t('Repeats !interval !bymonth !byday !count !until !except. !additional', $description); 263 } 264 265 /** 266 * Parse an iCal rule into a parsed RRULE array and an EXDATE array. 267 */ 268 function date_repeat_split_rrule($rrule) { 269 $parts = explode("\n", str_replace("\r\n", "\n", $rrule)); 270 $rrule = array(); 271 $exceptions = array(); 272 $additions = array(); 273 foreach ($parts as $part) { 274 if (strstr($part, 'RRULE')) { 275 $RRULE = str_replace('RRULE:', '', $part); 276 $rrule = (array) date_ical_parse_rrule('RRULE:', $RRULE); 277 } 278 elseif (strstr($part, 'EXDATE')) { 279 $EXDATE = str_replace('EXDATE:', '', $part); 280 $exceptions = (array) date_ical_parse_exceptions('EXDATE:', $EXDATE); 281 unset($exceptions['DATA']); 282 } 283 elseif (strstr($part, 'RDATE')) { 284 $RDATE = str_replace('RDATE:', '', $part); 285 $additions = (array) date_ical_parse_exceptions('RDATE:', $RDATE); 286 unset($additions['DATA']); 287 } 288 } 289 return array($rrule, $exceptions, $additions); 290 } 291 292 /** 293 * Analyze a RRULE and return dates that match it. 294 */ 295 function date_repeat_calc($rrule, $start, $end, $exceptions = array(), $timezone = NULL, $additions = array()) { 296 require_once('./'. drupal_get_path('module', 'date_repeat') .'/date_repeat_calc.inc'); 297 return _date_repeat_calc($rrule, $start, $end, $exceptions, $timezone, $additions); 298 } 299 300 /** 301 * Generate the repeat rule setting form. 302 */ 303 function date_repeat_rrule_process($element, $edit, $form_state, $form) { 304 require_once('./'. drupal_get_path('module', 'date_repeat') .'/date_repeat_form.inc'); 305 return _date_repeat_rrule_process($element, $edit, $form_state, $form); 306 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
| Generated: Mon Jul 9 18:01:44 2012 | Cross-referenced by PHPXref 0.7 |