Hi,
I'm using services to exchange data with a JavaClient. Now I need to retrieve a user by searching a value in a custom field that I add to the user account (in admin/config/people/accounts/fields). I did not find how to do this with the actual methods, so I create a new method "index_and_cckfield".
This is working for me, so I posted it in case that somone else need this use case.
The method "user.index_and_cckfield" take the same parameters that "user.index", plus one : an array of custom user fields and his value. For example : array ( 'field_example_name' => 'a_value') .
/**
*
* Implements hook_services_resources
*
*/
function parcours_pedagogique_services_resources() {
return array(
'user' => array(
'actions' => array (
'index_and_cckfield' => array(
//'file' => array('type' => 'inc', 'module' => 'services', 'name' => 'resources/user_resource'),
'callback' => '_user_resource_index_and_cckfield',
'access callback' => '_group_resource_access',
'access arguments' => array('view'),
'access arguments append' => TRUE,
'args' => array(
array(
'name' => 'page',
'optional' => TRUE,
'type' => 'int',
'description' => 'The zero-based index of the page to get, defaults to 0.',
'default value' => 0,
'source' => array('path' => '0'),
),
array(
'name' => 'fields',
'optional' => TRUE,
'type' => 'string',
'description' => 'The fields to get.',
'default value' => '*',
'source' => array('path' => '0'),
),
array(
'name' => 'parameters',
'optional' => TRUE,
'type' => 'array',
'description' => 'Parameters',
'default value' => array(),
'source' => array('path' => '0'),
),
array(
'name' => 'cck_fields',
'optional' => TRUE,
'type' => 'array',
'description' => 'The cck field to get',
'default value' => array(),
'source' => array('path' => '0'),
),
),
),
),
),
);
}
/**
*
* This code is from the user_resources.inc file of the services module.
* The name of the method was _user_resource_index.
* There's just one line added (calling _services_resources_build_cck_field_query)
*
* @param $page
* Page number of results to return (in pages of 20).
* @param $fields
* The fields you want returned.
* @param $parameters
* An object containing fields and values used to build a sql WHERE clause indicating
* what items should be deleted.
* @param $cck_fields
* An object containing the name of the user fields and value (created in admin/config/people/accounts/fields)
* This build a INNERJOIN clause and a WHERE clause.
* Example of the object : array ( 'field_example_name' => 'a_value')
* @return
* An array of user objects.
*
*/
function _user_resource_index_and_cckfield($page, $fields, $parameters, $cck_fields){
$user_select = db_select('users', 't')
->orderBy('created', 'DESC');
services_resource_build_index_query($user_select, $page, $fields, $parameters);
_services_resources_build_cck_field_query($user_select, $page, $cck_fields);
$results = $user_select->execute();
return services_resource_build_index_list($results, 'user', 'uid');
}
/**
* Helper function to build index queries.
*
* @param $query
* Object database query object.
* @param $page
* Integer page number we are requesting.
* @param $fields
* Array of the user account fields to return.
*/
function _services_resources_build_cck_field_query($query, $page, $cck_fields =array()) {
$page_size = variable_get('services_index_page_size', 20);
$query->range($page * $page_size, $page_size);
foreach($cck_fields as $f => $val){
$t = 'field_data_'.$f;
//$val = $field['value'];
$query->innerjoin($t,$f, $f.'.entity_id=t.uid');
$query->condition($f.'.'.$f.'_value',$val);
$query->fields($f,array($f.'_value'));
}
}
Hope this could be usefull ;)
Comments
Comment #1
marcingy commentedThis really makes a case for utilising efq rather than direct database queries then holds true for any fieldable entity in drupal using the current metheod.
Comment #2
Jackinloadup commentedIs it possible to switch to using efq in 3.x or will this need to wait for 4.x?
Seems like services isn't nearly as useful when custom fields are not being pulled from users and such.
Comment #3
kylebrowning commentedefq can be/will be a dot release in 3.x but I dont know when.
Comment #4
Jackinloadup commentedare you accepting patches for specific resources or will this be a broad change?
Comment #5
kylebrowning commentedAlways accepting patches;P
Comment #6
kylebrowning commentedComment #7
kylebrowning commentedStill no patch, so closing.