Changeset 2337

Show
Ignore:
Timestamp:
03/24/2008 02:17:38 PM (8 months ago)
Author:
Shadowhand
Message:

Updated Calendar:

  • Added Easter as a supported holiday
  • Optimized Calendar_Event->notify() a bit

Also, minor tweaks to Event_Subject and Event_Observer

Location:
trunk/system
Files:
5 modified

Legend:

Unmodified
Added
Removed
  • trunk/system/libraries/Calendar.php

    r2336 r2337  
    7474                                $this->attach($holiday->condition('month', 1)->condition('day', 1)); 
    7575 
     76                                // Attach New Years 
     77                                $holiday = clone $event; 
     78                                $this->attach($holiday->condition('easter', TRUE)); 
     79 
    7680                                // Attach Memorial Day 
    7781                                $holiday = clone $event; 
  • trunk/system/libraries/Calendar_Event.php

    r2336 r2337  
    7676                ); 
    7777 
    78                 if ($condition['current'] === TRUE) 
     78                // Tested conditions 
     79                $tested = array(); 
     80 
     81                foreach ($condition as $key => $value) 
    7982                { 
    80                         if (isset($this->conditions['weekend'])) 
     83                        // Test basic conditions first 
     84                        if (isset($this->conditions[$key]) AND $this->conditions[$key] !== $value) 
     85                                return FALSE; 
     86 
     87                        // Condition has been tested 
     88                        $tested[$key] = TRUE; 
     89                } 
     90 
     91                if (isset($this->conditions['weekend'])) 
     92                { 
     93                        // Weekday vs Weekend 
     94                        $condition['weekend'] = ($condition['day_of_week'] === 0 OR $condition['day_of_week'] === 6); 
     95                } 
     96 
     97                if (isset($this->conditions['first_day'])) 
     98                { 
     99                        // First day of month 
     100                        $condition['first_day'] = ($condition['day'] === 1); 
     101                } 
     102 
     103                if (isset($this->conditions['last_day'])) 
     104                { 
     105                        // Last day of month 
     106                        $condition['last_day'] = ($condition['day'] === (int) date('t', $timestamp)); 
     107                } 
     108 
     109                if (isset($this->conditions['occurrence'])) 
     110                { 
     111                        // Get the occurance of the current day 
     112                        $condition['occurrence'] = $this->day_occurrence($timestamp); 
     113                } 
     114 
     115                if (isset($this->conditions['last_occurrence'])) 
     116                { 
     117                        // Test if the next occurance of this date is next month 
     118                        $condition['last_occurrence'] = ((int) date('n', strtotime(date('Y/m/d', $timestamp).' +1 week')) !== $condition['month']); 
     119                } 
     120 
     121                if (isset($this->conditions['easter'])) 
     122                { 
     123                        if ($condition['month'] === 3 OR $condition['month'] === 4) 
    81124                        { 
    82                                 // Weekday vs weekend 
    83                                 $condition['weekend'] = ($condition['day_of_week'] === 0 OR $condition['day_of_week'] === 6); 
     125                                // This algorithm is from Practical Astronomy With Your Calculator, 2nd Edition by Peter 
     126                                // Duffett-Smith. It was originally from Butcher's Ecclesiastical Calendar, published in 
     127                                // 1876. This algorithm has also been published in the 1922 book General Astronomy by 
     128                                // Spencer Jones; in The Journal of the British Astronomical Association (Vol.88, page 
     129                                // 91, December 1977); and in Astronomical Algorithms (1991) by Jean Meeus. 
     130 
     131                                /** 
     132                                 * @todo I imagine Geert will have a party with this one... 
     133                                 */ 
     134                                $a = $condition['year'] % 19; 
     135                                $b = (int) ($condition['year'] / 100); 
     136                                $c = $condition['year'] % 100; 
     137                                $d = (int) ($b / 4); 
     138                                $e = $b % 4; 
     139                                $f = (int) (($b + 8) / 25); 
     140                                $g = (int) (($b - $f + 1) / 3); 
     141                                $h = (19 * $a + $b - $d - $g + 15) % 30; 
     142                                $i = (int) ($c / 4); 
     143                                $k = $c % 4; 
     144                                $l = (32 + 2 * $e + 2 * $i - $h - $k) % 7; 
     145                                $m = (int) (($a + 11 * $h + 22 * $l) / 451); 
     146                                $p = ($h + $l - 7 * $m + 114) % 31; 
     147 
     148                                $month = (int) (($h + $l - 7 * $m + 114) / 31); 
     149                                $day = $p + 1; 
     150 
     151                                $condition['easter'] = ($condition['month'] === $month AND $condition['day'] === $day); 
    84152                        } 
    85  
    86                         if (isset($this->conditions['first_day'])) 
     153                        else 
    87154                        { 
    88                                 // First day of month 
    89                                 $condition['first_day'] = ($condition['day'] === 1); 
    90                         } 
    91  
    92                         if (isset($this->conditions['last_day'])) 
    93                         { 
    94                                 // Last day of month 
    95                                 $condition['last_day'] = ($condition['day'] === (int) date('t', $timestamp)); 
    96                         } 
    97  
    98                         if (isset($this->conditions['occurrence'])) 
    99                         { 
    100                                 // Get the occurance of the current day 
    101                                 $condition['occurrence'] = $this->day_occurrence($timestamp); 
    102                         } 
    103  
    104                         if (isset($this->conditions['last_occurrence'])) 
    105                         { 
    106                                 // Test if the next occurance of this date is next month 
    107                                 $condition['last_occurrence'] = ((int) date('n', strtotime(date('Y/m/d', $timestamp).' +1 week')) !== $condition['month']); 
     155                                // Easter can only happen in March or April 
     156                                $condition['easter'] = FALSE; 
    108157                        } 
    109158                } 
    110159 
    111                 foreach ($this->conditions as $key => $value) 
     160                if (isset($this->conditions['callback'])) 
    112161                { 
    113                         if (isset($condition[$key]) AND $condition[$key] !== $value) 
     162                        // Use a callback to determine validity 
     163                        $condition['callback'] = call_user_func($this->conditions['callback'], $condition); 
     164                } 
     165 
     166                foreach (array_diff_key($this->conditions, $tested) as $key => $value) 
     167                { 
     168                        // Test advanced conditions 
     169                        if ($condition[$key] !== $value) 
    114170                                return FALSE; 
    115171                } 
  • trunk/system/libraries/Event_Observer.php

    r2330 r2337  
    2323        public function __construct(SplSubject $caller) 
    2424        { 
    25                 if ( ! ($caller instanceof Event_Subject)) 
    26                         throw new Kohana_Exception('event.invalid_subject', get_class($caller), get_class($this)); 
    27  
    28                 // Set the caller 
    29                 $this->caller = $caller; 
     25                // Update the caller 
     26                $this->update($caller); 
    3027        } 
    3128 
  • trunk/system/libraries/Event_Subject.php

    r2330 r2337  
    4242        public function detach(SplObserver $obj) 
    4343        { 
    44                 if ( ! ($obj instanceof Event_Observer)) 
    45                         throw new Kohana_Exception('eventable.invalid_observer', get_class($obj), get_class($this)); 
    46  
    47                 // Notify the observer of removal 
    48                 $this->listeners[spl_object_hash($obj)]->remove(); 
    49  
    5044                // Remove the listener 
    5145                unset($this->listeners[spl_object_hash($obj)]); 
  • trunk/system/views/kohana_calendar.php

    r2331 r2337  
    11<?php 
    2  
    3 $first_day = mktime(1, 0, 0, $month, 1, $year); 
    4 $today = (date('Y/m') === date('Y/m', $first_day)) ? (int) date('j') : FALSE; 
    52 
    63/** 
     
    118?> 
    129<table class="calendar"> 
    13 <caption><?php echo strftime('%B %Y', $first_day) ?></caption> 
     10<caption><?php echo strftime('%B %Y', mktime(0, 0, 0, $month, 1, $year)) ?></caption> 
    1411<tr> 
    1512<?php 
     
    4845} 
    4946 
    50 if ($current === FALSE) 
    51 { 
    52         $classes[] = 'prev-next'; 
    53 } 
    54 elseif ($today > 0 AND $day[0] === $today) 
    55 { 
    56         $classes[] = 'today';; 
    57 } 
    58  
    5947?> 
    6048<td class="<?php echo implode(' ', $classes) ?>"><span class="day"><?php echo $day[0] ?></span><?php echo $output ?></td>