You are here

function availability_calendar_query_available in Availability Calendars 7.3

Same name and namespace in other branches
  1. 7.5 availability_calendar.inc \availability_calendar_query_available()
  2. 7.4 availability_calendar.inc \availability_calendar_query_available()

Adds a where clauses to the given query to filter on availability.

Notes:

  • The query will 'fail' when no calendar has been created yet and the default state is an "available" state. However I'm not sure whether this is a bug or correct behavior.
  • If a field has multiple values, an entity may be returned multiple times. However this function cannot filter on duplicates as it does not know whether just calendars should be returned, or fields or entities, and whether duplicates are expected or not.

Parameters

SelectQuery|views_plugin_query $query: The query to add the clause to. This may be a default Drupal or a Views specific query object.

string $field_table: The name of the (field data) table to join on.

string $cid_field: The name of the field in the table (to join on) that contains the cid.

DateTime $from: The date to start searching for availability.

int|DateTime $to_or_duration: Either the departure day (DateTime) or the duration of the stay (int).

int $default_state: The sid of the state to use for dates without availability assigned.

3 calls to availability_calendar_query_available()
availability_calendar_handler_filter_availability::op_from_duration in ./availability_calendar_handler_filter_availability.inc
availability_calendar_handler_filter_availability::op_from_to in ./availability_calendar_handler_filter_availability.inc
availability_calendar_handler_filter_availability::op_from_to1 in ./availability_calendar_handler_filter_availability.inc

File

./availability_calendar.inc, line 543
General helper methods for Availability Calendar

Code

function availability_calendar_query_available($query, $field_table, $cid_field, $from, $to_or_duration, $default_state) {

  // Process parameters
  if (!$from instanceof DateTime) {
    return;
  }
  if ($to_or_duration instanceof DateTime) {
    $to = $to_or_duration;

    //PHP5.3: $duration = $arrival->diff($to)->days + 1;
    $timestamp_from = (int) $from
      ->format('U');
    $timestamp_to = (int) $to
      ->format('U');
    $diff = (int) round(($timestamp_to - $timestamp_from) / (60 * 60 * 24));
    $duration = $diff + 1;
  }
  else {
    $duration = (int) $to_or_duration;
    $diff = $duration - 1;
    $to = clone $from;
    $to
      ->modify("+{$diff} days");
  }

  // Check parameters.
  if ($duration <= 0) {
    return;
  }

  // Determine whether default availability state is to be treated as available.
  $states = availability_calendar_get_states();
  if (isset($states[$default_state])) {
    $default_state = $states[$default_state];
    $default_is_available = $default_state['is_available'] == 1;
  }
  else {

    // I have to make a choice :( (I could try to find out if there is only 1
    // calendar field or if the default is always the same or if the defaults
    // are always to be treated as either available or not available.)
    $default_is_available = FALSE;
  }
  $sids = array_keys(availability_calendar_get_states(!$default_is_available));
  $subquery = db_select('availability_calendar_availability', 'availability_calendar_availability')
    ->where("availability_calendar_availability.cid = {$field_table}.{$cid_field}")
    ->condition('availability_calendar_availability.date', array(
    $from
      ->format(AC_ISODATE),
    $to
      ->format(AC_ISODATE),
  ), 'BETWEEN')
    ->condition('availability_calendar_availability.sid', $sids, 'IN');
  if ($default_is_available) {

    // Default status = available: so no single day may be marked as non
    // available. Check by doing a check on the existence of a non available day
    // in the given period.
    $subquery
      ->addExpression('1');
    if (is_a($query, 'views_plugin_query')) {
      $query
        ->add_where(0, '', $subquery, 'NOT EXISTS');
    }
    else {
      $query
        ->notexists($subquery);
    }
  }
  else {

    // Default status = not available: so all days must be marked as available.
    // Check by doing a count on the available days in the given period which
    // should equal the total number of days.
    $subquery
      ->addExpression('count(*)');
    if (is_a($query, 'views_plugin_query')) {
      $query
        ->add_where(0, $duration, $subquery, 'IN');
    }
    else {
      $query
        ->condition($duration, $subquery, 'IN');
    }
  }
}