wsfields_storage.module in Web Service Data 7
Storage controller definitions
@author Mathew Winstone <mwinstone@coldfrontlabs.ca> @author David Pascoe-Deslauriers <dpascoed@coldfrontlabs.ca>
File
modules/wsfields_storage/wsfields_storage.moduleView source
<?php
/**
* @file
* Storage controller definitions
*
* @author Mathew Winstone <mwinstone@coldfrontlabs.ca>
* @author David Pascoe-Deslauriers <dpascoed@coldfrontlabs.ca>
*/
/**
* Implements hook_menu().
*/
function wsfields_storage_menu() {
$items = array();
$items['admin/config/services/wsfields_storage'] = array(
'title' => t('WSField Storage Fields and Settings'),
'description' => t('Configure wsfield fields.'),
'page callback' => 'drupal_get_form',
'page arguments' => array(
'wsfields_storage_settings_form',
),
'file' => 'wsfields_storage.admin.inc',
'access callback' => 'user_access',
'access arguments' => array(
'administer wsfields',
),
);
$items['admin/config/services/wsfields_storage/edit'] = array(
'title' => t('WSField Storage Fields and Settings'),
'description' => t('Configure wsfield fields.'),
'page callback' => 'drupal_get_form',
'page arguments' => array(
'wsfields_storage_edit_field_form',
),
'file' => 'wsfields_storage.admin.inc',
'type' => MENU_CALLBACK,
'access callback' => 'user_access',
'access arguments' => array(
'administer wsfields',
),
);
$items['admin/config/services/wsfields_storage/delete'] = array(
'title' => t('WSField Storage Fields and Settings'),
'description' => t('Configure wsfield fields.'),
'page callback' => 'drupal_get_form',
'page arguments' => array(
'wsfields_storage_delete_field_form',
),
'file' => 'wsfields_storage.admin.inc',
'type' => MENU_CALLBACK,
'access callback' => 'user_access',
'access arguments' => array(
'administer wsfields',
),
);
return $items;
}
/**
* Returns whether the entity_type has a wsfield attached to it
* and cache the result
*/
function wsfields_storage_entity_has_wsfields($entity_type) {
$ret = cache_get('wsfields_storage_entity_has_wsfields:' . $entity_type, 'cache');
if (!$ret) {
$ret = _wsfields_storage_entity_has_wsfields($entity_type);
cache_set('wsfields_storage_entity_has_wsfields:' . $entity_type, $ret, 'cache');
}
else {
$ret = $ret->data;
}
return $ret;
}
/**
* Returns whether the entity_type has a wsfield attached to it
*/
function _wsfields_storage_entity_has_wsfields($entity_type) {
$fields = field_info_fields();
$wsfields = array();
foreach ($fields as $key => $field) {
if ($field['storage']['type'] == 'wsfields_storage') {
$wsfields[$key] = $field;
}
}
$instances = field_info_instances($entity_type);
foreach ($instances as $instance) {
foreach ($instance as $field) {
if (isset($wsfields[$field['field_name']])) {
return TRUE;
}
}
}
return FALSE;
}
/**
* Implements hook_field_storage_info().
*
* The settings array stores the machine name of a wsconfig instance to load.
*/
function wsfields_storage_field_storage_info() {
return array(
'wsfields_storage' => array(
'label' => t('Web Service Storage'),
'description' => t('Stores fields via remote web service using REST.'),
'settings' => array(
'wsconfig_name' => '',
// The machine-name of a wsconfig instance to load
'translation' => FALSE,
'propertymap' => array(
'create' => array(),
'read' => array(),
'update' => array(),
'delete' => array(),
),
// Mapping of the placeholder elements in the CRUD paths to entity properties
'processor' => '',
// Data processor
'remotekey' => '',
),
),
);
}
/**
* Implements hook_field_storage_details().
*/
function wsfields_storage_field_storage_details($field) {
// Nothing right now
// @todo something
}
/**
* Implements hook_field_storage_create_field().
*/
function wsfields_storage_field_storage_create_field($field) {
// Act on when a new field is created
cache_clear_all('wsfields_storage_entity_has_wsfields:*', 'cache', TRUE);
}
/**
* Implements hook_field_storage_update_field().
*/
function wsfields_storage_field_storage_update_field($field, $prior_field, $has_data) {
cache_clear_all('wsfields_storage_entity_has_wsfields:*', 'cache', TRUE);
}
/**
* Implements hook_field_storage_delete_field().
*/
function wsfields_storage_field_storage_delete_field($field) {
cache_clear_all('wsfields_storage_entity_has_wsfields:*', 'cache', TRUE);
}
/**
* Implements hook_field_storage_delete().
*/
function wsfields_storage_field_storage_delete($entity_type, $entity, $fields) {
// @todo something
}
/**
* Implements hook_field_storage_delete_revision().
*/
function wsfields_storage_field_storage_delete_revision($entity_type, $entity, $fields) {
// @todo something
}
/**
* Implements hook_field_storage_delete_instance().
*/
function wsfields_storage_field_storage_delete_instance($instance) {
cache_clear_all('wsfields_storage_entity_has_wsfields:*', 'cache', TRUE);
}
/**
* Implements hook_field_storage_load().
*/
function wsfields_storage_field_storage_load($entity_type, $entities, $age, $fields, $options) {
// Load the list of fields
$field_info = field_info_field_by_ids();
$load_current = $age == FIELD_LOAD_CURRENT;
// Loop through the fields
foreach ($fields as $field_id => $ids) {
$field = $field_info[$field_id];
$field_name = $field['field_name'];
// Load the data for each entity
foreach ($entities as $entityid => $entity) {
// Load the field data into the entity
$entities[$entityid]->{$field_name} = wsfields_data_load($entity_type, $field, $entity);
}
}
}
/**
* Implements hook_field_storage_write().
*/
function wsfields_storage_field_storage_write($entity_type, $entity, $op, $fields) {
foreach ($fields as $field_id) {
$field = field_info_field_by_id($field_id);
$field_name = $field['field_name'];
$all_languages = field_available_languages($entity_type, $field);
$field_languages = array_intersect($all_languages, array_keys((array) $entity->{$field_name}));
foreach ($field_languages as $langcode) {
$items = (array) $entity->{$field_name}[$langcode];
$delta_count = 0;
// Trim the list of items down to what the field has been set to
if ($field['cardinality'] != FIELD_CARDINALITY_UNLIMITED and count($items) > $field['cardinality']) {
$items = array_chunk($items, count($items), TRUE);
$items = reset($items);
}
wsfields_data_write($entity_type, $entity, $op, $field, $items);
}
}
}
/**
* Implements hook_field_storage_query().
*/
function wsfields_storage_field_storage_query($query) {
$groups = array();
if ($query->age == FIELD_LOAD_CURRENT) {
$id_key = 'entity_id';
}
else {
$id_key = 'revision_id';
}
// Add wsconfigs required for the fields used.
// @todo
// Original sql based code
/*
$table_aliases = array();
// Add tables for the fields used.
foreach ($query->fields as $key => $field) {
$tablename = $tablename_function($field);
// Every field needs a new table.
$table_alias = $tablename . $key;
$table_aliases[$key] = $table_alias;
if ($key) {
$select_query->join($tablename, $table_alias, "$table_alias.entity_type = $field_base_table.entity_type AND $table_alias.$id_key = $field_base_table.$id_key");
}
else {
$select_query = db_select($tablename, $table_alias);
$select_query->addTag('entity_field_access');
$select_query->addMetaData('base_table', $tablename);
$select_query->fields($table_alias, array('entity_type', 'entity_id', 'revision_id', 'bundle'));
$field_base_table = $table_alias;
}
if ($field['cardinality'] != 1) {
$select_query->distinct();
}
}
// Add field conditions.
foreach ($query->fieldConditions as $key => $condition) {
// Throw an exception for each field condition which isn't supported
throw new WSFieldsStorageUnsupportedFieldConditionException('Field condition is unsupported.');
// Original sql based code
/*
$table_alias = $table_aliases[$key];
$field = $condition['field'];
// Add the specified condition.
$sql_field = "$table_alias." . _field_sql_storage_columnname($field['field_name'], $condition['column']);
$query->addCondition($select_query, $sql_field, $condition);
// Add delta / language group conditions.
foreach (array('delta', 'language') as $column) {
if (isset($condition[$column . '_group'])) {
$group_name = $condition[$column . '_group'];
if (!isset($groups[$column][$group_name])) {
$groups[$column][$group_name] = $table_alias;
}
else {
$select_query->where("$table_alias.$column = " . $groups[$column][$group_name] . ".$column");
}
}
}
}
// Look in list of deleted fields
// @todo is this supported with web services?
if (isset($query->deleted)) {
$select_query->condition("$field_base_table.deleted", (int) $query->deleted);
}
// Is there a need to sort the query by property?
$has_property_order = FALSE;
foreach ($query->order as $order) {
if ($order['type'] == 'property') {
$has_property_order = TRUE;
}
}
// Check for property conditions
if ($query->propertyConditions || $has_property_order) {
if (empty($query->entityConditions['entity_type']['value'])) {
throw new EntityFieldQueryException('Property conditions and orders must have an entity type defined.');
}
$entity_type = $query->entityConditions['entity_type']['value'];
$entity_base_table = _field_sql_storage_query_join_entity($select_query, $entity_type, $field_base_table);
$query->entityConditions['entity_type']['operator'] = '=';
foreach ($query->propertyConditions as $property_condition) {
$query->addCondition($select_query, "$entity_base_table." . $property_condition['column'], $property_condition);
}
}
foreach ($query->entityConditions as $key => $condition) {
$query->addCondition($select_query, "$field_base_table.$key", $condition);
}
// Order the query.
foreach ($query->order as $order) {
if ($order['type'] == 'entity') {
$key = $order['specifier'];
$select_query->orderBy("$field_base_table.$key", $order['direction']);
}
elseif ($order['type'] == 'field') {
$specifier = $order['specifier'];
$field = $specifier['field'];
$table_alias = $table_aliases[$specifier['index']];
$sql_field = "$table_alias." . _field_sql_storage_columnname($field['field_name'], $specifier['column']);
$select_query->orderBy($sql_field, $order['direction']);
}
elseif ($order['type'] == 'property') {
$select_query->orderBy("$entity_base_table." . $order['specifier'], $order['direction']);
}
}
return $query->finishQuery($select_query, $id_key);*/
}
/**
* Implements hook_entity_query_alter().
*/
function wsfields_storage_entity_query_alter($query) {
// @todo ensure the alter only occurs for entities which have
// web service fields
//$query->executeCallback = 'wsfields_storage_field_storage_query';
}
/**
* Implements hook_field_attach_rename_bundle().
*/
function wsfields_storage_field_attach_rename_bundle($entity_type, $bundle_old, $bundle_new) {
// @todo something
}
/**
* Implements hook_entity_insert().
*/
function wsfields_storage_entity_insert($entity, $entity_type) {
wsfields_storage_field_storage_write($entity_type, $entity, NULL, array(), TRUE);
}
/**
* Implements hook_entity_update().
*/
function wsfields_storage_entity_update($entity, $entity_type) {
wsfields_storage_field_storage_write($entity_type, $entity, NULL, array(), TRUE);
}
/**
* Implements hook_field_attach_delete().
*/
function wsfields_storage_field_attach_delete($entity_type, $entity) {
// @todo something
}
/**
* Implements hook_entity_info_alter().
*/
function wsfields_storage_entity_info_alter(&$entity_info) {
// @todo something
//dpm($entity_info);
}
/**
* Maps the field data to their defined column values
*
* @param array $field
* Field info
* @param array $instance_settings
* Field instance settings
* @return array|boolean
* Returns an array of mapped data, FALSE otherwise.
*/
function _wsfields_storage_columnname($field, $instance_settings) {
// @todo have the wsconfig or parser or something include a map to the field schema names
}
/**
* Exception handling for WS Field Storage
*/
class WSFieldsStorageException extends Exception {
}
class WSFieldsStorageUnsupportedFieldConditionException extends WSFieldsStorageException {
}
class WSFieldsStorageUnsupportedQueryException extends WSFieldsStorageException {
}
/**
* Debug query
*/
function _wsfields_storage_test_query() {
try {
$query = new EntityFieldQuery();
$query
->entityCondition('entity_type', 'user')
->entityCondition('bundler', 'user')
->fieldCondition('uo_user_surname', 'value', 'phehibrufri', '=');
$query
->execute();
} catch (WSFieldsStorageException $e) {
dpm($e
->getMessage());
}
}
Functions
Classes
Name | Description |
---|---|
WSFieldsStorageException | Exception handling for WS Field Storage |
WSFieldsStorageUnsupportedFieldConditionException | |
WSFieldsStorageUnsupportedQueryException |