Created
November 29, 2010 10:35
-
-
Save nils-werner/719806 to your computer and use it in GitHub Desktop.
Original Version
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
Class fieldDate extends Field{ | |
const SIMPLE = 0; | |
const REGEXP = 1; | |
const RANGE = 3; | |
const ERROR = 4; | |
private $key; | |
function __construct(&$parent){ | |
parent::__construct($parent); | |
$this->_name = __('Date'); | |
$this->key = 1; | |
} | |
function allowDatasourceOutputGrouping(){ | |
return true; | |
} | |
function allowDatasourceParamOutput(){ | |
return true; | |
} | |
function canFilter(){ | |
return true; | |
} | |
public function canImport(){ | |
return true; | |
} | |
function displayPublishPanel(&$wrapper, $data = null, $error = null, $prefix = null, $postfix = null) { | |
$name = $this->get('element_name'); | |
$value = null; | |
// New entry: | |
if (is_null($data) && $this->get('pre_populate') == 'yes') { | |
$value = DateTimeObj::get(__SYM_DATETIME_FORMAT__, null); | |
} | |
// Empty entry: | |
else if (isset($data['gmt']) && !is_null($data['gmt'])) { | |
$value = DateTimeObj::get(__SYM_DATETIME_FORMAT__, $data['gmt']); | |
} | |
$label = Widget::Label($this->get('label')); | |
$label->appendChild(Widget::Input("fields{$prefix}[{$name}]", $value)); | |
$label->setAttribute('class', 'date'); | |
if (!is_null($error)) { | |
$label = Widget::wrapFormElementWithError($label, $error); | |
} | |
$wrapper->appendChild($label); | |
} | |
function checkPostFieldData($data, &$message, $entry_id=NULL){ | |
if(empty($data)) return self::__OK__; | |
$message = NULL; | |
if(!self::__isValidDateString($data)){ | |
$message = __("The date specified in '%s' is invalid.", array($this->get('label'))); | |
return self::__INVALID_FIELDS__; | |
} | |
return self::__OK__; | |
} | |
public function processRawFieldData($data, &$status, $simulate=false, $entry_id=NULL){ | |
$status = self::__OK__; | |
$timestamp = null; | |
if (is_null($data) || $data == '') { | |
if ($this->get('pre_populate') == 'yes') { | |
$timestamp = strtotime(DateTimeObj::get(__SYM_DATETIME_FORMAT__, null)); | |
} | |
} | |
else { | |
$timestamp = strtotime($data); | |
} | |
if (!is_null($timestamp)) { | |
return array( | |
'value' => DateTimeObj::get('c', $timestamp), | |
'local' => strtotime(DateTimeObj::get('c', $timestamp)), | |
'gmt' => strtotime(DateTimeObj::getGMT('c', $timestamp)) | |
); | |
} | |
return array( | |
'value' => null, | |
'local' => null, | |
'gmt' => null | |
); | |
} | |
public function appendFormattedElement(&$wrapper, $data, $encode = false) { | |
if (isset($data['gmt']) && !is_null($data['gmt'])) { | |
$wrapper->appendChild(General::createXMLDateObject($data['local'], $this->get('element_name'))); | |
} | |
} | |
public function prepareTableValue($data, XMLElement $link=NULL) { | |
$value = null; | |
if (isset($data['gmt']) && !is_null($data['gmt'])) { | |
$value = DateTimeObj::get(__SYM_DATETIME_FORMAT__, $data['gmt']); | |
} | |
return parent::prepareTableValue(array('value' => $value), $link); | |
} | |
public function getParameterPoolValue($data){ | |
return DateTimeObj::get('Y-m-d H:i:s', $data['local']); | |
} | |
function groupRecords($records){ | |
if(!is_array($records) || empty($records)) return; | |
$groups = array('year' => array()); | |
foreach($records as $r){ | |
$data = $r->getData($this->get('id')); | |
$info = getdate($data['local']); | |
$year = $info['year']; | |
$month = ($info['mon'] < 10 ? '0' . $info['mon'] : $info['mon']); | |
if(!isset($groups['year'][$year])) $groups['year'][$year] = array('attr' => array('value' => $year), | |
'records' => array(), | |
'groups' => array()); | |
if(!isset($groups['year'][$year]['groups']['month'])) $groups['year'][$year]['groups']['month'] = array(); | |
if(!isset($groups['year'][$year]['groups']['month'][$month])) $groups['year'][$year]['groups']['month'][$month] = array('attr' => array('value' => $month), | |
'records' => array(), | |
'groups' => array()); | |
$groups['year'][$year]['groups']['month'][$month]['records'][] = $r; | |
} | |
return $groups; | |
} | |
function buildSortingSQL(&$joins, &$where, &$sort, $order='ASC'){ | |
$joins .= "LEFT OUTER JOIN `tbl_entries_data_".$this->get('id')."` AS `ed` ON (`e`.`id` = `ed`.`entry_id`) "; | |
$sort = 'ORDER BY ' . (in_array(strtolower($order), array('random', 'rand')) ? 'RAND()' : "`ed`.`gmt` $order"); | |
} | |
function buildDSRetrivalSQL($data, &$joins, &$where, $andOperation=false){ | |
if(self::isFilterRegex($data[0])) return parent::buildDSRetrivalSQL($data, $joins, $where, $andOperation); | |
$parsed = array(); | |
foreach($data as $string){ | |
$type = self::__parseFilter($string); | |
if($type == self::ERROR) return false; | |
if(!is_array($parsed[$type])) $parsed[$type] = array(); | |
$parsed[$type][] = $string; | |
} | |
foreach($parsed as $type => $value){ | |
switch($type){ | |
case self::RANGE: | |
$this->__buildRangeFilterSQL($value, $joins, $where, $andOperation); | |
break; | |
case self::SIMPLE: | |
$this->__buildSimpleFilterSQL($value, $joins, $where, $andOperation); | |
break; | |
} | |
} | |
return true; | |
} | |
protected function __buildSimpleFilterSQL($data, &$joins, &$where, $andOperation=false){ | |
$field_id = $this->get('id'); | |
if($andOperation): | |
foreach($data as $date){ | |
$joins .= " LEFT JOIN `tbl_entries_data_$field_id` AS `t$field_id".$this->key."` ON `e`.`id` = `t$field_id".$this->key."`.entry_id "; | |
$where .= " AND `t$field_id".$this->key."`.value = '".DateTimeObj::get('c', strtotime($date))."' "; | |
$this->key++; | |
} | |
else: | |
$joins .= " LEFT JOIN `tbl_entries_data_$field_id` AS `t$field_id".$this->key."` ON `e`.`id` = `t$field_id".$this->key."`.entry_id "; | |
$where .= " AND `t$field_id".$this->key."`.value IN ("; | |
foreach($data as $date){ | |
$where .= "'" . DateTimeObj::get('c', strtotime($date)) . "'"; | |
if($date != end($data)) | |
$where .= ","; | |
} | |
$where .= ") "; | |
$this->key++; | |
endif; | |
} | |
protected function __buildRangeFilterSQL($data, &$joins, &$where, $andOperation=false){ | |
$field_id = $this->get('id'); | |
if(empty($data)) return; | |
if($andOperation): | |
foreach($data as $date){ | |
$joins .= " LEFT JOIN `tbl_entries_data_$field_id` AS `t$field_id".$this->key."` ON `e`.`id` = `t$field_id".$this->key."`.entry_id "; | |
$where .= " AND (`t$field_id".$this->key."`.value >= '".DateTimeObj::get('c', strtotime($date['start']))."' | |
AND `t$field_id".$this->key."`.value <= '".DateTimeObj::get('c', strtotime($date['end']))."') "; | |
$this->key++; | |
} | |
else: | |
$tmp = array(); | |
foreach($data as $date){ | |
$tmp[] = "(`t$field_id".$this->key."`.value >= '".DateTimeObj::get('c', strtotime($date['start']))."' | |
AND `t$field_id".$this->key."`.value <= '".DateTimeObj::get('c', strtotime($date['end']))."') "; | |
} | |
$joins .= " LEFT JOIN `tbl_entries_data_$field_id` AS `t$field_id".$this->key."` ON `e`.`id` = `t$field_id".$this->key."`.entry_id "; | |
$where .= " AND (".@implode(' OR ', $tmp).") "; | |
$this->key++; | |
endif; | |
} | |
protected static function __cleanFilterString($string){ | |
$string = trim($string); | |
$string = trim($string, '-/'); | |
return $string; | |
} | |
protected static function __parseFilter(&$string){ | |
$string = self::__cleanFilterString($string); | |
## Check its not a regexp | |
if(preg_match('/^regexp:/i', $string)){ | |
$string = str_replace('regexp:', '', $string); | |
return self::REGEXP; | |
} | |
## Look to see if its a shorthand date (year only), and convert to full date | |
elseif(preg_match('/^(1|2)\d{3}$/i', $string)){ | |
$string = "$string-01-01 to $string-12-31"; | |
} | |
## Human friendly terms | |
elseif(preg_match('/^(equal to or )?(earlier|later) than (.*)$/i', $string, $match)){ | |
$string = $match[3]; | |
if(!self::__isValidDateString($string)) return self::ERROR; | |
$time = strtotime($string); | |
if($match[1] == "equal to or "){ | |
$later = DateTimeObj::get('Y-m-d H:i:s', $time); | |
$earlier = $later; | |
} | |
else { | |
$later = DateTimeObj::get('Y-m-d H:i:s', $time+1); | |
$earlier = DateTimeObj::get('Y-m-d H:i:s', $time-1); | |
} | |
switch($match[2]){ | |
case 'later': $string = $later . ' to 2038-01-01'; break; | |
case 'earlier': $string = '1970-01-03 to ' . $earlier; break; | |
} | |
} | |
## Look to see if its a shorthand date (year and month), and convert to full date | |
elseif(preg_match('/^(1|2)\d{3}[-\/]\d{1,2}$/i', $string)){ | |
$start = "{$string}-01"; | |
if(!self::__isValidDateString($start)) return self::ERROR; | |
$string = "{$start} to {$string}-" . date('t', strtotime($start)); | |
} | |
## Match for a simple date (Y-m-d), check its ok using checkdate() and go no further | |
elseif(!preg_match('/to/i', $string)){ | |
if(preg_match('/^(1|2)\d{3}[-\/]\d{1,2}[-\/]\d{1,2}$/i', $string)){ | |
$string = "{$string} to {$string}"; | |
} | |
else{ | |
if(!self::__isValidDateString($string)) return self::ERROR; | |
$string = DateTimeObj::get('Y-m-d H:i:s', strtotime($string)); | |
return self::SIMPLE; | |
} | |
} | |
## Parse the full date range and return an array | |
if(!$parts = preg_split('/to/', $string, 2, PREG_SPLIT_NO_EMPTY)) return self::ERROR; | |
$parts = array_map(array('self', '__cleanFilterString'), $parts); | |
list($start, $end) = $parts; | |
if(!self::__isValidDateString($start) || !self::__isValidDateString($end)) return self::ERROR; | |
$string = array('start' => $start, 'end' => $end); | |
return self::RANGE; | |
} | |
protected static function __isValidDateString($string){ | |
$string = trim($string); | |
if(empty($string)) return false; | |
## Its not a valid date, so just return it as is | |
if(!$info = getdate(strtotime($string))) return false; | |
elseif(!checkdate($info['mon'], $info['mday'], $info['year'])) return false; | |
return true; | |
} | |
function isSortable(){ | |
return true; | |
} | |
function commit(){ | |
if(!parent::commit()) return false; | |
$id = $this->get('id'); | |
if($id === false) return false; | |
$fields = array(); | |
$fields['field_id'] = $id; | |
$fields['pre_populate'] = ($this->get('pre_populate') ? $this->get('pre_populate') : 'no'); | |
Symphony::Database()->query("DELETE FROM `tbl_fields_".$this->handle()."` WHERE `field_id` = '$id' LIMIT 1"); | |
Symphony::Database()->insert($fields, 'tbl_fields_' . $this->handle()); | |
} | |
function findDefaults(&$fields){ | |
if(!isset($fields['pre_populate'])) $fields['pre_populate'] = 'yes'; | |
} | |
public function displaySettingsPanel(&$wrapper, $errors = null) { | |
parent::displaySettingsPanel($wrapper, $errors); | |
$label = Widget::Label(); | |
$input = Widget::Input('fields['.$this->get('sortorder').'][pre_populate]', 'yes', 'checkbox'); | |
if($this->get('pre_populate') == 'yes') $input->setAttribute('checked', 'checked'); | |
$label->setValue(__('%s Pre-populate this field with today\'s date', array($input->generate()))); | |
$wrapper->appendChild($label); | |
$this->appendShowColumnCheckbox($wrapper); | |
} | |
function createTable(){ | |
return Symphony::Database()->query( | |
"CREATE TABLE IF NOT EXISTS `tbl_entries_data_" . $this->get('id') . "` ( | |
`id` int(11) unsigned NOT NULL auto_increment, | |
`entry_id` int(11) unsigned NOT NULL, | |
`value` varchar(80) default NULL, | |
`local` int(11) default NULL, | |
`gmt` int(11) default NULL, | |
PRIMARY KEY (`id`), | |
KEY `entry_id` (`entry_id`), | |
KEY `value` (`value`) | |
) TYPE=MyISAM;" | |
); | |
} | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment