restws_field_collection.module in RESTful Web Services Field Collection 7
RESTful Web Services Field collection module.
File
restws_field_collection.moduleView source
<?php
/**
* @file
* RESTful Web Services Field collection module.
*/
/**
* Get information about field collections provided by modules.
*/
function restws_field_collection_info() {
$info =& drupal_static(__FUNCTION__);
if (!isset($info)) {
$info = module_invoke_all('restws_field_collection_info');
}
return $info;
}
/**
* Implements hook_entity_property_info_alter().
*/
function restws_field_collection_entity_property_info_alter(&$info) {
// Get information about field collections.
$field_collections = restws_field_collection_info();
// Iterate through entity types.
foreach ($info as $entity_type => &$entity_info) {
// If the entity type doesn't have any bundles, skip it.
if (empty($entity_info['bundles'])) {
continue;
}
// Iterate through the entity type bundles.
foreach ($entity_info['bundles'] as $bundle => &$bundle_info) {
// Iterate through the field collections defined above.
foreach ($field_collections as $fc_name => $fc_info) {
// If the bundle doesn't contain the field collection, skip it.
if (!array_key_exists($fc_name, $bundle_info['properties'])) {
continue;
}
// If the field collection doesn't have an alias, label, or field info,
// skip it.
if (empty($fc_info['alias']) || empty($fc_info['label']) || empty($fc_info['fields'])) {
continue;
}
// If the field collection supports multiple values, make it a list.
$type = 'struct';
if (!empty($fc_info['multiple'])) {
$type = 'list<' . $type . '>';
}
// Add a new property for the field collection using its alias.
$bundle_info['properties'][$fc_info['alias']] = array(
'type' => $type,
'label' => $fc_info['label'],
'getter callback' => 'restws_field_collection_property_get',
'setter callback' => 'restws_field_collection_property_set',
'property info' => array(),
);
// Assemble property info based on the field info.
foreach ($fc_info['fields'] as $field_name => $field_info) {
// If the field supports multiple values, make it a list.
$type = $field_info['field_type'];
if (!empty($field_info['multiple'])) {
$type = 'list<' . $type . '>';
}
// Set the field property info.
$bundle_info['properties'][$fc_info['alias']]['property info'][$field_name] = array(
'type' => $type,
'label' => $field_info['field_label'],
);
}
}
}
}
}
/**
* Get a field collection property.
*/
function restws_field_collection_property_get($data, array $options, $name, $type, $info) {
// Start an empty property array.
$property = array();
// Get information about field collections.
$field_collections = restws_field_collection_info();
// Iterate through the field collections.
foreach ($field_collections as $fc_name => $fc_info) {
// If the property name does not match the field collection alias, skip it.
if ($name != $fc_info['alias']) {
continue;
}
// If the field collection is empty in the entity, return.
if (empty($data->{$fc_name})) {
return $property;
}
// Load the field collection items.
foreach ($data->{$fc_name}[LANGUAGE_NONE] as $fc_ref) {
// Start an empty property fields array.
$property_fields = array();
// If the field collection item ID is empty, skip it.
if (empty($fc_ref['value'])) {
continue;
}
// Load the field collection item.
$fc_item = field_collection_item_load($fc_ref['value']);
// If the item didn't load, skip it.
if (empty($fc_item)) {
continue;
}
// Map field values from the field collection item to the property.
foreach ($fc_info['fields'] as $alias => $field_info) {
// Create an empty property field.
$property_fields[$alias] = '';
// Get value(s) for the property field.
$values = array();
if (!empty($fc_item->{$field_info['field_name']}[LANGUAGE_NONE])) {
foreach ($fc_item->{$field_info['field_name']}[LANGUAGE_NONE] as $delta => $field_value) {
$values[] = $field_value[$field_info['field_value']];
}
}
// If the field does not support multiple values, only use the first.
if (empty($field_info['multiple'])) {
$values = reset($values);
}
// Add the value(s) to the property field.
$property_fields[$alias] = $values;
}
// If the property fields aren't empty, add them to the property.
if (!empty($property_fields)) {
$property[] = $property_fields;
}
}
// If the field collection does not support multiple values, only use the
// first.
if (empty($fc_info['multiple'])) {
$property = reset($property);
}
// Return the property value(s).
return $property;
}
}
/**
* Sets a field collection property.
*/
function restws_field_collection_property_set(&$data, $name, $values, $langcode, $type, $info) {
// Get information about field collections.
$field_collections = restws_field_collection_info();
// Figure out what field collection this name maps to.
$field_name = '';
foreach ($field_collections as $fc_name => $fc_info) {
if ($name == $fc_info['alias']) {
$field_name = $fc_name;
break;
}
}
// If a field collection field name wasn't found, bail.
if (empty($field_name)) {
return;
}
// If this is an existing entity, delete existing field collection item(s).
//
// This works because $data (the entity) does not get reloaded between
// subsequent calls to this function. So if a field collection supports
// multiple values, and we are replacing old field collection items on the
// entity, we can see what the old ones were in $data and delete those.
// Creating new field collection items will not update $data, so we don't run
// the risk of deleting the new ones right after we create them.
if (empty($data->is_new)) {
if (!empty($data->{$field_name}[LANGUAGE_NONE])) {
foreach ($data->{$field_name}[LANGUAGE_NONE] as $old_fc) {
if (!empty($old_fc['value'])) {
field_collection_item_delete($old_fc['value']);
}
}
}
}
// If the field collection does not support multiple values, wrap the values
// in an array.
if (empty($field_collections[$field_name]['multiple'])) {
$values = array(
$values,
);
}
// Iterate through the values.
foreach ($values as $key => $value) {
// If all of the field values are empty, skip it.
$empty = TRUE;
foreach ($field_collections[$field_name]['fields'] as $field_alias => $field_info) {
if (!empty($value[$field_alias])) {
$empty = FALSE;
break;
}
}
if ($empty) {
continue;
}
// Create a new field collection item.
restws_field_collection_item_create($field_name, $type, $data, $value);
}
}
/**
* Create a field collection item and attach it to an entity.
*
* @param $field_name
* The field collection field name.
* @param $entity_type
* The host entity type.
* @param $entity
* The host entity.
* @param $values
* The field values.
*/
function restws_field_collection_item_create($field_name, $entity_type, $entity, $values) {
// Create a new field_collection attached to the entity.
$field_collection = entity_create('field_collection_item', array(
'field_name' => $field_name,
));
$field_collection
->setHostEntity($entity_type, $entity);
// Get information about field collections.
$field_collections = restws_field_collection_info();
// If there are no fields in this field collection, bail.
if (empty($field_collections[$field_name]['fields'])) {
return;
}
// Iterate through the field collection fields.
foreach ($field_collections[$field_name]['fields'] as $field_alias => $field_info) {
// If no value is available for this field, skip it.
if (empty($values[$field_alias])) {
continue;
}
// If the value is an array, it might be an entity reference, so look for
// an ID.
if (is_array($values[$field_alias]) && !empty($values[$field_alias]['id'])) {
$values[$field_alias] = $values[$field_alias]['id'];
}
// If the field name is empty, skip it.
if (empty($field_info['field_name'])) {
continue;
}
// Get the values for this field.
$field_values = $values[$field_alias];
// If the field values are not an array, wrap it.
if (!is_array($field_values)) {
$field_values = array(
$field_values,
);
}
// Iterate through the field values and save them to the field collection.
foreach ($field_values as $key => $field_value) {
$field_collection->{$field_info['field_name']}[LANGUAGE_NONE][$key] = array(
$field_info['field_value'] => $field_value,
);
}
}
// Save the field collection.
entity_save('field_collection_item', $field_collection);
}
/**
* Implements hook_restws_response_alter().
*/
function restws_field_collection_restws_response_alter(&$response, $function, $formatName, $resourceController) {
// If this is not JSON, bail.
if ($formatName != 'json') {
return;
}
// Get information about field collections.
$field_collections = restws_field_collection_info();
// Remove field collection fields from the response.
foreach ($field_collections as $fc_name => $fc_info) {
if (isset($response[$fc_name])) {
unset($response[$fc_name]);
}
}
}
Functions
Name | Description |
---|---|
restws_field_collection_entity_property_info_alter | Implements hook_entity_property_info_alter(). |
restws_field_collection_info | Get information about field collections provided by modules. |
restws_field_collection_item_create | Create a field collection item and attach it to an entity. |
restws_field_collection_property_get | Get a field collection property. |
restws_field_collection_property_set | Sets a field collection property. |
restws_field_collection_restws_response_alter | Implements hook_restws_response_alter(). |