You are here

function farm_api_restws_request_alter in farmOS 7

Implements hook_restws_request_alter().

File

modules/farm/farm_api/farm_api.module, line 366
Farm API module.

Code

function farm_api_restws_request_alter(array &$request) {

  // If the format is not JSON, bail.
  if ($request['format']
    ->getName() != 'json') {
    return;
  }

  // Build a field alias map to remove the 'field_farm_' prefix.
  $prefix = 'field_farm_';
  $alias_map = farm_api_field_alias_map($prefix);

  // Get the entity type.
  $entity_type = NULL;
  if (!empty($request['resource']
    ->resource())) {
    $entity_type = $request['resource']
      ->resource();
  }

  // If we are dealing with a taxonomy term, do not alias description or parent.
  if ($entity_type == 'taxonomy_term') {
    unset($alias_map['description']);
    unset($alias_map['parent']);
  }

  // In order to handle URL query string filters, we need to perform the alias
  // translation on all GET parameters. The restws module filters based on the
  // output of drupal_get_query_parameters(), which uses the $_GET global.
  foreach ($_GET as $name => &$value) {
    if (array_key_exists($name, $alias_map)) {
      $_GET[$alias_map[$name]] = $_GET[$name];
      unset($_GET[$name]);
    }
  }

  // Allow filtering by term name in taxonomy term reference fields.
  // eg: /log.json?log_category=Tillage
  foreach ($_GET as $field_name => &$filter_value) {
    $field_info = field_info_field($field_name);
    if (!empty($field_info['type']) && $field_info['type'] == 'taxonomy_term_reference') {
      if ($vocabulary = drupal_array_get_nested_value($field_info, array(
        'settings',
        'allowed_values',
        '0',
        'vocabulary',
      ))) {
        if ($term = farm_term($filter_value, $vocabulary, FALSE)) {
          $_GET[$field_name] = $term->tid;
        }
      }
    }
  }

  // If the payload is empty, bail.
  if (empty($request['payload'])) {
    return;
  }

  // Decode the payload JSON.
  $payload = drupal_json_decode($request['payload']);

  // If the payload could not be decoded, bail.
  if (empty($payload)) {
    return;
  }

  // Keep track of whether or not any changes were made to the payload.
  $changed = FALSE;

  // Iterate through the fields in the payload. If any match a mapped alias,
  // translate it to use the real field name.
  foreach ($payload as $key => $value) {
    if (array_key_exists($key, $alias_map)) {
      $payload[$alias_map[$key]] = $payload[$key];
      unset($payload[$key]);
      $changed = TRUE;
    }
  }

  // If a taxonomy term name is provided, look up its term ID. If it does not
  // exist, create it.
  foreach ($payload as $field_name => $field_values) {

    // Add special logic for the "unit" field in "Quantity" field collections.
    // Field collections are handled by the restws_field_collection module, and
    // they are skipped inside farm_api_field_alias_map(), so we just look for a
    // $field_name of "quantity", process any provided "name" through
    // farm_term(), set the term ID, and then let restws_field_collection do the
    // rest.
    if ($field_name == 'quantity') {

      // Set the vocabulary machine name.
      $vocabulary = 'farm_quantity_units';

      // Iterate through field collection values and convert unit names to tids.
      if (!empty($field_values)) {
        foreach ($field_values as $delta => $field_value) {
          if (!empty($field_value['unit']['name'])) {
            $term = farm_term($field_value['unit']['name'], $vocabulary);
            if (!empty($term->tid)) {
              $payload[$field_name][$delta]['unit']['id'] = $term->tid;
              unset($payload[$field_name][$delta]['unit']['name']);
            }
            $changed = TRUE;
          }
        }
      }

      // We don't need to go any farther than this, so end this iteration.
      continue;
    }

    // Look up the field information and process taxonomy term names.
    $field_info = field_info_field($field_name);
    if (empty($field_info)) {
      continue;
    }
    if ($vocabulary = drupal_array_get_nested_value($field_info, array(
      'settings',
      'allowed_values',
      '0',
      'vocabulary',
    ))) {

      // If the field values contains a "name" property, we assume that it is a
      // single value field, so we convert it to an array and remember to
      // convert it back at the end.
      $single = FALSE;
      if (isset($field_values['name'])) {
        $field_values = array(
          $field_values,
        );
        $single = TRUE;
      }

      // Iterate through the field values and process term names.
      foreach ($field_values as $delta => $field_value) {
        if (!empty($field_value['name'])) {
          $term = farm_term($field_value['name'], $vocabulary);
          if ($single) {
            unset($payload[$field_name]['name']);
            $payload[$field_name]['id'] = $term->tid;
          }
          else {
            unset($payload[$field_name][$delta]['name']);
            $payload[$field_name][$delta]['id'] = $term->tid;
          }
          $changed = TRUE;
        }
      }
    }
  }

  // If we changed the payload, re-encode it as JSON.
  if ($changed) {
    $request['payload'] = drupal_json_encode($payload);
  }
}