You are here

function ca_add_conditions in Ubercart 7.3

Reads a predicate's conditions array and add them to a component.

Parameters

&$component: A RulesConditionContainer or a Rule to receive conditions.

$conditions: A predicate's array of conditions.

2 calls to ca_add_conditions()
ca_convert_predicate in uc_store/includes/ca.inc
Base helper function to convert CA predicates to Rules configurations.
ca_extract_conditions in uc_store/includes/ca.inc
Saves the conditions of the predicate as a separate component.

File

uc_store/includes/ca.inc, line 64
Helper functions for upgrade from Ubercart 2.x to Ubercart 3.x.

Code

function ca_add_conditions(&$component, $conditions) {
  foreach ($conditions as $condition) {

    // Handle condition containers.
    if (isset($condition['#conditions'])) {
      switch ($condition['#operator']) {
        case 'AND':
          $sub_tree = rules_and();
          break;
        case 'OR':
          $sub_tree = rules_or();
          break;
      }

      // Recurse.
      ca_add_conditions($sub_tree, $condition['#conditions']);
      if ($sub_tree
        ->getIterator()
        ->hasChildren()) {
        $component
          ->condition($sub_tree);
      }
    }
    else {

      // Handle certain conditions as a generic "data_is" condition.
      $map = ca_data_map();
      if (isset($map[$condition['#name']])) {
        $name = 'data_is';
      }
      else {
        $name = $condition['#name'];
      }
      $settings = array();

      // The argument maps are like data selectors pointing to event variables.
      foreach ($condition['#argument_map'] as $key => $value) {
        if ($name == 'data_is') {
          $settings['data:select'] = $map[$condition['#name']]['data'];
        }
        elseif ($name == 'uc_attribute_ordered_product_option' && $key == 'order') {
          $settings['product:select'] = $value;
        }
        else {
          $key .= ':select';
          $settings[$key] = $value;
        }
      }
      $negate = FALSE;
      foreach ($condition['#settings'] as $key => $value) {

        // Save negation for later.
        if ($key == 'negate') {
          $negate = TRUE;
          continue;
        }
        if ($condition['#name'] == 'ca_condition_date' && $key == 'date') {
          $settings['date'] = $settings['date']['year'] . '/' . $settings['date']['month'] . '/' . $settings['date']['day'];
        }
        else {
          $settings[$key] = $value;
        }
      }
      if ($name == 'data_is') {
        $settings['#info'] = $map[$condition['#name']]['#info'];

        // data_is doesn't handle multiple values. Use a condition container.
        if (count($settings[$map[$condition['#name']]['value']]) > 1) {
          if (isset($map[$condition['#name']]['op']) && $settings[$map[$condition['#name']]['op']] == 'AND') {
            $rules_condition = rules_and();
          }
          else {
            $rules_condition = rules_or();
          }
          foreach ($settings[$map[$condition['#name']]['value']] as $value) {
            $rules_condition
              ->condition('data_is', array(
              'data:select' => $settings['data:select'],
              'op' => 'contains',
              'value' => $value,
              '#info' => $settings['#info'],
            ));
          }
        }
        elseif (is_array($settings[$map[$condition['#name']]['value']])) {
          $rules_condition = rules_condition('data_is', array(
            'data:select' => $settings['data:select'],
            'op' => 'contains',
            'value' => $settings[$map[$condition['#name']]['value']],
            '#info' => $settings['#info'],
          ));
        }
        else {

          // Translate operator settings.
          if (isset($map[$condition['#name']]['op'])) {
            switch ($settings[$map[$condition['#name']]['op']]) {
              case 'before':
              case 'less':
                $ops = '<';
                break;
              case 'less_equal':
                $ops = array(
                  '<',
                  '==',
                );
                break;
              case 'only':
              case 'equal':
                $ops = '==';
                break;
              case 'not':
                $negate = !$negate;
                $settings['operator'] = '==';
                break;
              case 'after':
              case 'greater':
                $ops = '>';
                break;
              case 'greater_equal':
                $ops = array(
                  '>',
                  '==',
                );
                break;
              case 'begins':
              case 'contains':
              case 'ends':
                $settings['operator'] = 'contains';
                break;
              case 'yes':
                $settings['operator'] = '==';
                $settings['value'] = TRUE;
                break;
              case 'no':
                $settings['operator'] = '==';
                $settings['value'] = FALSE;
                break;
            }
            if ($condition['#name'] == 'node_field_comparison') {
              switch ($settings['field']) {
                case 'nid':
                case 'vid':
                case 'uid':
                  $type = 'integer';
                  break;
                case 'type':
                case 'title':
                  $type = 'text';
                  break;
                case 'status':
                case 'promote':
                case 'sticky':
                  $type = 'boolean';
                  break;
              }
              $settings = array(
                'data:select' => array_shift($settings) . ':' . $settings['field'],
                'op' => $settings['operator'],
                'value' => $settings['value'],
                '#info' => array(
                  'parameter' => array(
                    'value' => array(
                      'type' => $type,
                    ),
                  ),
                ),
              );
            }

            // data_is only provides <, =, and > for numeric data. Use two
            // separate conditions for <= and >= cases.
            if (is_array($ops)) {
              $data_condition = data_or();
              foreach ($ops as $op) {
                $data_condition
                  ->condition('data_is', array(
                  'data:select' => $settings['data:select'],
                  'op' => $op,
                  'value' => $settings[$map[$condition['#name']]['value']],
                  '#info' => $settings['#info'],
                ));
              }
              $rules_condition = rules_condition($data_condition);
            }
            else {
              $rules_condition = rules_condition('data_is', array(
                'data:select' => $settings['data:select'],
                'op' => $ops,
                'value' => $settings[$map[$condition['#name']]['value']],
                '#info' => $settings['#info'],
              ));
            }
          }
          else {
            $rules_condition = rules_condition('data_is', array(
              'data:select' => $settings['data:select'],
              'value' => $settings[$map[$condition['#name']]['value']],
              '#info' => $settings['#info'],
            ));
          }
        }
      }
      else {
        if ($name == 'ca_condition_custom_php') {
          $name = 'php_eval';
          $settings = array(
            'code' => $settings['php'],
          );
        }
        $rules_condition = rules_condition($name, $settings);
      }
      if ($negate) {
        $rules_condition
          ->negate();
      }
      $component
        ->condition($rules_condition);
    }
  }
}