View source
<?php
class availability_calendar_handler_filter_availability extends views_handler_filter {
public static $instance;
public function __construct() {
self::$instance = $this;
$this->always_multiple = TRUE;
module_load_include('inc', 'availability_calendar', 'availability_calendar');
}
public function option_definition() {
$options = parent::option_definition();
$options['value'] = array(
'contains' => array(
'from' => array(
'default' => '',
),
'to' => array(
'default' => '',
),
'to1' => array(
'default' => '',
),
'duration' => array(
'default' => '',
),
),
);
$options['operator'] = array(
'default' => 'from_duration',
);
return $options;
}
public function operators() {
$operators = array(
'at' => array(
'title' => t('At (date)'),
'method' => 'op_at',
'summary' => t('at %from'),
'values' => array(
'from',
),
),
'from_to' => array(
'title' => t('From begin up to and including end'),
'method' => 'op_from_to',
'summary' => t('From %from to %to'),
'values' => array(
'from',
'to',
),
),
'from_to1' => array(
'title' => t('From arrival to departure'),
'method' => 'op_from_to1',
'summary' => t('From %from to %to1'),
'values' => array(
'from',
'to1',
),
),
'from_duration' => array(
'title' => t('From begin during duration'),
'method' => 'op_from_duration',
'summary' => t('From %from during %duration days'),
'values' => array(
'from',
'duration',
),
),
);
return $operators;
}
public function operator_options($which = 'title') {
$options = array();
foreach ($this
->operators() as $id => $operator) {
$options[$id] = $operator[$which];
}
return $options;
}
public function operators_by_value($value) {
$options = array();
foreach ($this
->operators() as $id => $operator) {
if (in_array($value, $operator['values'])) {
$options[] = $id;
}
}
return $options;
}
public function value_form(&$form, &$form_state) {
$form['value']['#tree'] = TRUE;
if (empty($form_state['exposed'])) {
$form['value']['#element_validate'][] = 'availability_calendar_handler_filter_availability_validate_value';
}
$dependency_source = null;
if (!empty($form_state['exposed']) && (empty($this->options['expose']['use_operator']) || empty($this->options['expose']['operator_id']))) {
$operators = $this
->operators();
$values = $operators[$this->operator]['values'];
}
else {
$values = array(
'from',
'to',
'to1',
'duration',
);
if (!empty($form['operator'])) {
$dependency_source = $form['operator']['#type'] === 'radios' ? 'radio:options[operator]' : 'edit-options-operator';
}
}
if (in_array('from', $values)) {
$form['value']['from'] = array(
'#type' => 'textfield',
'#title' => $this->operator === 'at' ? t('At') : ($this->operator === 'from_to1' ? t('Arrival date') : t('Start date')),
'#size' => 12,
'#default_value' => $this->value['from'],
);
if (module_exists('date_popup')) {
$this
->change_element_into_date_popup($form['value']['from']);
}
else {
$date_example = availability_calendar_format_entry_date(new DateTime());
$form['value']['from']['#description'] = t('E.g., @date', array(
'@date' => $date_example,
));
}
if ($dependency_source !== null) {
$form['value']['from']['#dependency'] = array(
$dependency_source => $this
->operators_by_value('from'),
);
}
}
if (in_array('to', $values)) {
$form['value']['to'] = array(
'#type' => 'textfield',
'#title' => t('End date'),
'#size' => 12,
'#default_value' => $this->value['to'],
);
if (module_exists('date_popup')) {
$this
->change_element_into_date_popup($form['value']['to']);
}
else {
$date = new DateTime();
$date
->modify('+6 days');
$date_example = availability_calendar_format_entry_date($date);
$form['value']['to']['#description'] = t('E.g., @date', array(
'@date' => $date_example,
));
}
if ($dependency_source !== null) {
$form['value']['to']['#dependency'] = array(
$dependency_source => $this
->operators_by_value('to'),
);
}
}
if (in_array('to1', $values)) {
$form['value']['to1'] = array(
'#type' => 'textfield',
'#title' => t('Departure date'),
'#size' => 12,
'#default_value' => $this->value['to1'],
);
if (module_exists('date_popup')) {
$this
->change_element_into_date_popup($form['value']['to1']);
}
else {
$date = new DateTime();
$date
->modify('+7 days');
$date_example = availability_calendar_format_entry_date($date);
$form['value']['to1']['#description'] = t('E.g., @date', array(
'@date' => $date_example,
));
}
if ($dependency_source !== null) {
$form['value']['to1']['#dependency'] = array(
$dependency_source => $this
->operators_by_value('to1'),
);
}
}
if (in_array('duration', $values)) {
if (false) {
t('1 day');
t('@count days');
t('1 night');
t('@count nights');
}
if ($this->definition['allocation_type'] === ALLOCATION_TYPE_FULLDAY) {
$singular = '1 day';
$plural = '@count days';
}
else {
$singular = '1 night';
$plural = '@count nights';
}
$options = array(
0 => t('- Select duration -'),
);
for ($i = 1; $i <= 28; $i++) {
if ($i % 7 === 0) {
$options[$i] = format_plural($i / 7, '1 week', '@count weeks');
}
else {
if ($i <= 20) {
$options[$i] = format_plural($i, $singular, $plural);
}
}
}
$form['value']['duration'] = array(
'#type' => 'select',
'#title' => t('Duration'),
'#options' => $options,
'#default_value' => $this->value['duration'],
);
if ($dependency_source !== null) {
$form['value']['duration']['#dependency'] = array(
$dependency_source => $this
->operators_by_value('duration'),
);
}
}
}
protected function change_element_into_date_popup(&$element) {
$element['#type'] = 'date_popup';
$element['#date_label_position'] = '';
$element['#date_type'] = 'DATE_ISO';
$element['#date_format'] = variable_get('date_format_availability_calendar_date_entry', '');
$element['#date_year_range'] = '-0:+2';
}
public function exposed_validate(&$form, &$form_state) {
if (empty($this->options['exposed'])) {
return;
}
if (!empty($this->options['expose']['use_operator']) && !empty($this->options['expose']['operator_id'])) {
$operator = $form_state['values'][$this->options['expose']['operator_id']];
}
else {
$operator = $this->operator;
}
$this
->validate_value($form[$this->options['expose']['identifier']], $form_state);
}
public function validate_value(&$element, $form_state) {
if (empty($form_state['exposed'])) {
$required = !$form_state['values']['options']['expose_button']['checkbox']['checkbox'];
$operator = $form_state['values']['options']['operator'];
}
else {
$required = (bool) $this->options['expose']['required'];
$operator = empty($this->options['expose']['use_operator']) ? $this->operator : $form_state['values'][$this->options['expose']['operator_id']];
}
$operators = $this
->operators();
$values = empty($operator) ? array(
'from',
'to',
'to1',
'duration',
) : $operators[$operator]['values'];
$today = new DateTime();
$value = drupal_array_get_nested_value($form_state['values'], $element['#parents']);
$from_valid = FALSE;
if (in_array('from', $values) && array_key_exists('from', $value)) {
$from_valid = $this
->validate_valid_time_1($element['from'], $value['from'], $required, $today, t('Only future availability can be searched.'));
}
if (in_array('to', $values) && array_key_exists('to', $value)) {
$this
->validate_valid_time_1($element['to'], $value['from'], $required || !empty($value['from']), $from_valid, t('The end date should be on or after the start date.'));
}
if (in_array('to1', $values) && array_key_exists('to1', $value)) {
$this
->validate_valid_time_1($element['to1'], $value['from'], $required || !empty($value['from']), $from_valid, t('The departure date should be after the arrival date.'));
}
if (in_array('duration', $values) && array_key_exists('duration', $value)) {
$this
->validate_valid_duration($element['duration'], $value['duration'], $required || !empty($value['from']));
}
}
protected function validate_valid_time_1(&$element, $value, $required, $minimum, $minimum_error_message) {
$valid = TRUE;
if (is_array($value)) {
$value = $value['date'];
}
if (empty($value)) {
if ($required) {
form_error($element, t('Field %field is required.', array(
'%field' => $element['#title'],
)));
$valid = FALSE;
}
}
else {
if (($value = availability_calendar_parse_entry_date($value)) === FALSE) {
form_error($element, t('Invalid date format.'));
$valid = FALSE;
}
else {
if ($minimum instanceof DateTime && $value < $minimum) {
form_error($element, $minimum_error_message);
$valid = FALSE;
}
}
}
return $valid ? $value : $valid;
}
protected function validate_valid_duration(&$element, $value, $required) {
$valid = TRUE;
if (empty($value)) {
if ($required) {
form_error($element, t('Field %field is required.', array(
'%field' => $element['#title'],
)));
$valid = FALSE;
}
}
else {
if (!is_int($value) && !ctype_digit($value) || $value <= 0) {
form_error($element, t('Duration must be a positive number of days.'));
$valid = FALSE;
}
}
return $valid;
}
public function accept_exposed_input($input) {
if (empty($this->options['exposed'])) {
return TRUE;
}
if (!empty($this->options['expose']['use_operator']) && !empty($this->options['expose']['operator_id']) && isset($input[$this->options['expose']['operator_id']])) {
$this->operator = $input[$this->options['expose']['operator_id']];
}
if (!empty($this->options['expose']['identifier'])) {
$this->value = $input[$this->options['expose']['identifier']];
$operators = $this
->operators();
$values = $operators[$this->operator]['values'];
foreach ($values as $value_name) {
if (empty($this->value[$value_name])) {
return FALSE;
}
}
}
return TRUE;
}
public function query() {
$this
->ensure_my_table();
$operators = $this
->operators();
if (isset($operators[$this->operator]['method'])) {
$this
->{$operators[$this->operator]['method']}();
}
}
protected function op_at() {
$this->value['duration'] = 1;
return $this
->op_from_duration();
}
protected function op_from_to() {
module_load_include('inc', 'availability_calendar', 'availability_calendar.widget');
availability_calendar_query_available($this->query, $this->table_alias, $this->real_field, new DateTime($this->value['from']), new DateTime($this->value['to']), $this->definition['default_state']);
}
protected function op_from_to1() {
$from = new DateTime($this->value['from']);
$to = new DateTime($this->value['to1']);
if ($from instanceof DateTime && $to instanceof DateTime) {
if ($to > $from) {
$to
->modify('-1 day');
}
module_load_include('inc', 'availability_calendar', 'availability_calendar.widget');
availability_calendar_query_available($this->query, $this->table_alias, $this->real_field, $from, $to, $this->definition['default_state']);
}
}
protected function op_from_duration() {
module_load_include('inc', 'availability_calendar', 'availability_calendar.widget');
availability_calendar_query_available($this->query, $this->table_alias, $this->real_field, new DateTime($this->value['from']), (int) $this->value['duration'], $this->definition['default_state']);
}
public function admin_summary() {
$output = '';
if (!empty($this->options['exposed'])) {
$output = t('exposed');
}
else {
$operators = $this
->operators();
if (isset($operators[$this->operator]['summary'])) {
$arguments = array();
foreach ($this->value as $key => $value) {
$arguments["@{$key}"] = $value;
}
$output = format_string($operators[$this->operator]['summary'], $arguments);
}
}
return $output;
}
}
function availability_calendar_handler_filter_availability_validate_value(&$element, &$form_state, $form) {
availability_calendar_handler_filter_availability::$instance
->validate_value($element, $form_state);
}
function availability_calendar_handler_filter_availability_js_alter(&$javascript) {
static $adapt = FALSE;
if ($javascript === TRUE) {
$adapt = TRUE;
return;
}
if ($adapt && isset($javascript['settings']['data'])) {
foreach ($javascript['settings']['data'] as &$setting) {
if (is_array($setting) && isset($setting['datePopup'])) {
foreach ($setting['datePopup'] as &$date_popup_settings) {
$date_popup_settings['settings']['minDate'] = 0;
}
}
}
}
}