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