array('through'=>'room_children'), ); public function filters() { return Arr::merge(parent::filters(),array( 'dob'=>array(array(array($this,'date'), array(':value'))), )); } protected $_display_filters = array( 'date_orig'=>array( array('Site::Date',array(':value')), ), 'date_last'=>array( array('Site::Date',array(':value')), ), 'dob'=>array( array('Site::Date',array(':value')), ), ); protected $_sub_items_load = array( 'rooms'=>array('date_start','date_stop'), ); private function _dob() { $x = new DateTime(); return $x->setTimestamp($this->dob); } public function age($asat=NULL,$format='%Yy%Mm') { if (is_null($asat)) $asat = time(); $dob = $this->_dob(); $today = new DateTime(); $today->setTimestamp($asat); return $format == '%w' ? sprintf('%02dw',$dob->diff($today)->days/7) : $dob->diff($today)->format($format); } public function date($value) { return is_numeric($value) ? $value : strtotime($value); } public function date_enrol_min() { $dob = $this->_dob(); $dob->add(new DateInterval('P'.$this->_start)); return $format ? $result->format(Kohana::$config->load('config')->date_format) : $result->format('U'); } public function date_enrol_max($format=FALSE) { $dob = $this->_dob(); $dob->add(new DateInterval('P'.$this->_max)); $last = new DateTime(sprintf('%s-%s',$dob->format('Y'),$this->_max_date)); $x = $dob->diff($last); $result = new DateTime(sprintf('%s-%s',$dob->format('Y')+($x->invert ? 1 : 0),$this->_max_return)); return $format ? $result->format(Company::instance()->date_format()) : $result->format('U'); } public function days($room_id,$date_start,$days,$code,$markup=FALSE) { $result = ''; $date_end = $date_start+$days*86400; $open_dates = Company::instance()->so()->open_dates($date_start,$days); $o = $this->room->where('code','=',$code); $o->where_startstop($date_start,$date_end); if (! is_null($room_id)) $o->where('room_id','=',$room_id); // Set all open dayes to 0 foreach ($open_dates as $k=>$v) if ($v === TRUE) $open_dates[$k] = 0; foreach ($o->find_all() as $date => $rco) { foreach ($open_dates as $day=>$open) { if ($open === FALSE or $rco->date_start > $day OR $rco->date_stop < $day) continue; $open_dates[$day] = $rco->day(date('w',$day)); } } foreach ($open_dates as $day=>$open) { $dayname = substr(date('D',$day),0,1); if ($open === FALSE) $result .= $markup ? sprintf('%s',$dayname) : '-'; elseif ($open) $result .= $markup ? sprintf('%s',($code=='P' ? 'fa-circle' : 'fa-circle-o'),($code=='P' ? 'white' : 'black'),$dayname) : $dayname; else $result .= $markup ? sprintf('%s',$dayname) : strtolower($dayname); } return $result; } public function name() { return sprintf('%s, %s',strtoupper($this->family_name),$this->first_name); } public function save(Validation $validation=NULL) { $changed = $this->changed(); parent::save($validation); // Process our Sub-Items and Validate them. Sort::MASort($this->_sub_items,array('code','room_id','date_start','date_stop')); $last = NULL; foreach ($this->_sub_items as $rco) { // If no dates are selected, clear this record. if (! $rco->have_days()) { if ($rco->loaded()) $rco->delete(); continue; } // If there is no last item, we'll accept this as is. if (is_null($last) OR ($last->date_stop <= $rco->date_start)) { $rco->save($validation); $last = $rco; continue; } // @todo: If our dates overlap, fix that // @todo: Check that casual days dont overlap with permanent days // @todo: Check that absent days are attending days // @todo: Check that waitlist days dont overlap with permanent days if ($rco->changed() AND (! $rco->save())) $rco->reload(); } return $this->reload(); } } ?>