You are here

function microdata_field_attach_view_alter in Microdata 7

Implements hook_field_attach_view_alter().

For all the fields that are attached, add the relationship between the field and its parent entity. This is done differently for item references, as opposed to compound fields and plain strings.

File

./microdata.module, line 291

Code

function microdata_field_attach_view_alter(&$output, $context) {
  foreach (element_children($output) as $field_name) {
    $element =& $output[$field_name];

    // Ensure this is actually a field.
    if (!field_info_field($field_name)) {
      continue;
    }

    // If this is a partial entity and it has no microdata (which can happen
    // when calling token_replace), then skip.
    if (!isset($element['#object']->microdata)) {
      continue;
    }

    // Gather the info about the subject.
    $subject_entity = $element['#object'];
    $subject_entity_type = $element['#entity_type'];
    $subject_bundle_type = $element['#bundle'];
    $subject_entity_is_item = isset($subject_entity->microdata['#attributes']['itemid']);
    $subject_itemrefs = array();

    // Get the property info to check where microdata should be placed. If
    // there is no property info, then this field does not have the correct
    // integration.
    $entity_properties = entity_get_property_info($subject_entity_type);
    $bundle_properties = $entity_properties['bundles'][$subject_bundle_type]['properties'];
    if (!isset($bundle_properties[$field_name]) || !isset($subject_entity->microdata[$field_name])) {
      continue;
    }
    $field_microdata = $subject_entity->microdata[$field_name];

    // If we haven't assigned an itemprop to this field, then we probably do
    // not want to be doing anything microdata related with it. This will stop
    // the 'non existent identifier' issue where a field that hasn't been
    // assigned an itemprop, will still cause an itemref value to be output
    // for this entity in the metadata markup, causing a mismatch between the
    // amount of itemref references being output for this entity, compared to
    // the number of fields which we have added itemprop values for.
    if (empty($field_microdata['#attributes']['itemprop'])) {
      continue;
    }

    // If this is a reference field which points to another entity, set up the
    // relationship between the subject and the object.
    $type = _microdata_get_field_type($bundle_properties[$field_name]['type']);
    if (microdata_get_value_type($type) == 'item_reference') {
      $object_entity_type = $type;
      $wrapper = entity_metadata_wrapper($subject_entity_type, $subject_entity);
      $object_entities = $wrapper->{$field_name}
        ->value();
      if (isset($object_entities)) {

        // Entity API doesn't treat 1 as a special case of N, but instead
        // returns an object in one case and an array in the other. We need
        // a consistent return, so wrap the object in an array.
        if (is_object($object_entities)) {
          $object_entities = array(
            $object_entities,
          );
        }
        foreach ($object_entities as $delta => $object_entity) {
          if (!empty($object_entity->microdata['#attributes']['itemid'])) {
            $field_id = microdata_get_itemref_id();
            $element[$delta]['#microdata_field_id'] = $field_id;
            $object_attributes = $object_entity->microdata['#attributes'];
            if ($subject_entity_is_item) {

              // Add the referenced entity as an itemref for the subject entity.
              $object_id = microdata_get_itemref_id();
              $object_attributes['id'][] = $object_id;
              $subject_itemrefs[] = $object_id;
            }

            // Add the referenced entity to the microdata item list.
            if (isset($field_microdata['#attributes']['itemprop'])) {
              $object_attributes['itemprop'] = $field_microdata['#attributes']['itemprop'];
            }
            $object_attributes['itemref'][] = $field_id;
            list($entity_id, , ) = entity_extract_ids($object_entity_type, $object_entity);
            microdata_item($object_entity_type, $entity_id, $object_attributes);
          }
          elseif ($subject_entity_is_item) {
            $field_id = microdata_get_itemref_id();
            $element[$delta]['#microdata_field_id'] = $field_id;
            $subject_itemrefs[] = $field_id;
          }
          if ($element['#field_type'] == 'taxonomy_term_reference') {
            if (!empty($object_entity->microdata['title']['#attributes'])) {
              $element[$delta]['#attributes'] = $object_entity->microdata['url']['#attributes'];

              // We have to process the text content's attributes and insert them
              // with #prefix and #suffix. This outputs the <span> outside of the
              // <a> tag, but the only way to nest it inside the <a> would be to
              // change the #title value to include the <span>. This might affect
              // other modules which are altering the taxonomy term reference.
              $text_attributes = drupal_attributes($object_entity->microdata['title']['#attributes']);
              $element[$delta]['#prefix'] = "<span {$text_attributes}>";
              $element[$delta]['#suffix'] = '</span>';
            }
          }
        }
      }
    }
    elseif ($subject_entity_is_item) {
      $field_id = microdata_get_itemref_id();
      $element['#microdata_field_id'] = $field_id;
      $subject_itemrefs[] = $field_id;
    }
    if ($subject_entity_is_item) {

      // Add the subject entity to the microdata item list.
      $attributes = $subject_entity->microdata['#attributes'];
      $attributes['itemref'] = $subject_itemrefs;
      list($entity_id, , ) = entity_extract_ids($subject_entity_type, $subject_entity);
      microdata_item($subject_entity_type, $entity_id, $attributes);
    }
  }
}