You are here

function duration_field_alter_query_recursive in Duration Field 8.2

Same name and namespace in other branches
  1. 3.0.x duration_field.module \duration_field_alter_query_recursive()

Recursively alters an array of nested database queries.

Alters conditions that query duration fields, allowing for queries based on duration strings.

Parameters

array $conditions: An array of conditions to be altered.

array $tables: An array of db tables that contain duration field data. The key is the table name, the value is the field name.

1 call to duration_field_alter_query_recursive()
duration_field_query_duration_string_alter in ./duration_field.module
Implements hook_query_TAG_alter().

File

./duration_field.module, line 73
Holds hooks for the Duration Field module.

Code

function duration_field_alter_query_recursive(array &$conditions, array $tables) {
  $applicable_operators = [
    '>',
    '<',
    '>=',
    '<=',
    '=',
  ];
  foreach (Element::children($conditions) as $index) {

    // Conditions can be nested. Test if the element contains nested conditions.
    if (is_a($conditions[$index]['field'], '\\Drupal\\Core\\Database\\Query\\Condition')) {

      // Get the nested conditions.
      $subconditions =& $conditions[$index]['field']
        ->conditions();

      // Recursively call the function with the sub conditions, to swap their
      // values.
      duration_field_alter_query_recursive($subconditions, $tables);
    }
    else {
      $duration_service = \Drupal::service('duration_field.service');

      // Loop through each of the tables that contain duration field data.
      foreach ($tables as $table => $field) {

        // Only act if the operator is mathematical.
        if (in_array($conditions[$index]['operator'], $applicable_operators)) {

          // Check if current condition is based on a duration field.
          if ($conditions[$index]['field'] == $field . '_duration') {
            $date_interval = $duration_service
              ->getDateIntervalFromDurationString(strtoupper($conditions[$index]['value']));

            // Switch the condition to work on the {$field}_seconds table
            // instead of the {$field}_duration table.
            $conditions[$index]['field'] = $field . '_seconds';

            // Convert the duration to seconds.
            $conditions[$index]['value'] = $duration_service
              ->getSecondsFromDateInterval($date_interval);

            // The operator will not change.
            $conditions[$index]['operator'] = $conditions[$index]['operator'];
          }
          elseif (preg_match('/^(.*?)\\.' . $field . '_duration$/', $conditions[$index]['field'], $matches)) {
            $date_interval = $duration_service
              ->getDateIntervalFromDurationString(strtoupper($conditions[$index]['value']));
            $conditions[$index]['field'] = $matches[1] . '.' . $field . '_seconds';
            $conditions[$index]['value'] = $duration_service
              ->getSecondsFromDateInterval($date_interval);
            $conditions[$index]['operator'] = $conditions[$index]['operator'];
          }
        }
      }
    }
  }
}