You are here

function availability_calendar_query_search_api_db_search_alter_walk_conditions in Availability Calendars 7.5

Parameters

QueryConditionInterface $condition:

array $info:

Return value

bool

1 call to availability_calendar_query_search_api_db_search_alter_walk_conditions()
availability_calendar_query_search_api_db_search_alter in ./availability_calendar.inc
Implements hook_query_TAG_alter().

File

./availability_calendar.inc, line 872

Code

function availability_calendar_query_search_api_db_search_alter_walk_conditions(QueryConditionInterface $condition, array $info) {
  static $query;
  if (is_a($condition, 'SelectQueryInterface')) {

    // Keep a reference to the query, as we may need it later to change the list
    // of tables.
    $query = $condition;
  }
  $sub_conditions =& $condition
    ->conditions();
  foreach ($sub_conditions as $key => &$sub_condition) {

    // Skip the "#conjunction" key.
    if (is_numeric($key)) {
      if (is_a($sub_condition['field'], 'QueryConditionInterface')) {

        // Recursively search for the token.
        if (availability_calendar_query_search_api_db_search_alter_walk_conditions($sub_condition['field'], $info)) {

          // and return immediately if found.
          return TRUE;
        }
      }
      else {
        if ($sub_condition['value'] === $info['token']) {

          // We found the dummy condition with the token. Delete it, but keep
          // track of the table alias and the field name for later reference.
          list($table_alias, $field) = explode('.', $sub_condition['field']);
          unset($sub_conditions[$key]);

          // And add the condition that filters on availability.
          if ($info['filtered_availability_table'] === '') {

            // The filtered availability is in the table that the dummy condition
            // pointed to. We remove the join and dummy condition and add a
            // condition that checks there is no non-availability in the given
            // period.
            $tables =& $query
              ->getTables();

            // We use the join condition in the not exists sub query.
            $table_join_condition = $tables[$table_alias]['condition'];
            $table_name = $tables[$table_alias]['table'];
            unset($tables[$table_alias]);

            // Build a sub query that joins ot the table in the outer query and
            // checks for dates within the given period.
            $sub_query = db_select($table_name, $table_alias)
              ->where($table_join_condition)
              ->condition("{$table_alias}.{$field}", array(
              $info['timestamp_from'],
              $info['timestamp_to'],
            ), 'BETWEEN');
            $sub_query
              ->addExpression(1);
            $condition
              ->notExists($sub_query);
          }
          else {

            // The filtered availability is in another table, in another index
            // that indexes availability calendars, but on the same search server.
            // The current table contains cids, so we replace the dummy condition
            // by one that joins to the other table on cid and no
            // non-availability.
            $sub_query = db_select($info['filtered_availability_table'], $info['filtered_availability_table'])
              ->where("{$table_alias}.{$field} = {$info['filtered_availability_table']}.item_id")
              ->condition("{$info['filtered_availability_table']}.{$field}", array(
              $info['timestamp_from'],
              $info['timestamp_to'],
            ), 'BETWEEN');
            $sub_query
              ->addExpression(1);
            $condition
              ->notExists($sub_query);
          }
          return TRUE;
        }
      }
    }
  }
  return FALSE;
}