You are here

user_resource.inc in Services 6.3

Same filename and directory in other branches
  1. 7.3 resources/user_resource.inc

This file will define the resources for dealing with the user object

File

resources/user_resource.inc
View source
<?php

/**
 * @file
 * This file will define the resources for dealing with the user object
 */
function _user_resource_definition() {
  return array(
    'user' => array(
      'operations' => array(
        'retrieve' => array(
          'help' => 'Retrieves a user',
          'callback' => '_user_resource_retrieve',
          'file' => array(
            'type' => 'inc',
            'module' => 'services',
            'name' => 'resources/user_resource',
          ),
          'access callback' => '_user_resource_access',
          'access arguments' => array(
            'view',
          ),
          'access arguments append' => TRUE,
          'args' => array(
            array(
              'name' => 'uid',
              'type' => 'int',
              'description' => 'The uid of the user to retrieve.',
              'source' => array(
                'path' => '0',
              ),
              'optional' => FALSE,
            ),
          ),
        ),
        'create' => array(
          'help' => 'Creates a user',
          'callback' => '_user_resource_create',
          'file' => array(
            'type' => 'inc',
            'module' => 'services',
            'name' => 'resources/user_resource',
          ),
          'access callback' => '_user_resource_access',
          'access arguments' => array(
            'create',
          ),
          'access arguments append' => TRUE,
          'args' => array(
            array(
              'name' => 'account',
              'type' => 'array',
              'description' => 'The user data',
              'source' => 'data',
              'optional' => FALSE,
            ),
          ),
        ),
        'update' => array(
          'help' => 'Updates a user',
          'callback' => '_user_resource_update',
          'file' => array(
            'type' => 'inc',
            'module' => 'services',
            'name' => 'resources/user_resource',
          ),
          'access callback' => '_user_resource_access',
          'access arguments' => array(
            'update',
          ),
          'access arguments append' => TRUE,
          'args' => array(
            array(
              'name' => 'uid',
              'type' => 'int',
              'description' => 'Unique identifier for this user',
              'source' => array(
                'path' => 0,
              ),
              'optional' => FALSE,
            ),
            array(
              'name' => 'data',
              'type' => 'array',
              'description' => 'The user data with updated information',
              'source' => 'data',
              'optional' => FALSE,
            ),
          ),
        ),
        'delete' => array(
          'help' => 'Deletes a user',
          'callback' => '_user_resource_delete',
          'file' => array(
            'type' => 'inc',
            'module' => 'services',
            'name' => 'resources/user_resource',
          ),
          'access callback' => '_user_resource_access',
          'access arguments' => array(
            'delete',
          ),
          'access arguments append' => TRUE,
          'args' => array(
            array(
              'name' => 'uid',
              'type' => 'int',
              'description' => 'The id of the user to delete',
              'source' => array(
                'path' => '0',
              ),
              'optional' => FALSE,
            ),
          ),
        ),
        'index' => array(
          'file' => array(
            'type' => 'inc',
            'module' => 'services',
            'name' => 'resources/user_resource',
          ),
          'callback' => '_user_resource_index',
          '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(
                'param' => 'page',
              ),
            ),
            array(
              'name' => 'fields',
              'optional' => TRUE,
              'type' => 'string',
              'description' => 'The fields to get.',
              'default value' => '*',
              'source' => array(
                'param' => 'fields',
              ),
            ),
            array(
              'name' => 'parameters',
              'optional' => TRUE,
              'type' => 'array',
              'description' => 'Parameters',
              'default value' => NULL,
              'source' => array(
                'param' => 'parameters',
              ),
            ),
            array(
              'name' => 'pagesize',
              'optional' => TRUE,
              'type' => 'int',
              'description' => 'Number of records to get per page.',
              'default value' => variable_get('services_user_index_page_size', 20),
              'source' => array(
                'param' => 'pagesize',
              ),
            ),
          ),
          'access arguments' => array(
            'access user profiles',
          ),
          'access arguments append' => FALSE,
        ),
      ),
      'actions' => array(
        'login' => array(
          'help' => 'Login a user for a new session',
          'callback' => '_user_resource_login',
          'args' => array(
            array(
              'name' => 'username',
              'type' => 'string',
              'description' => 'A valid username',
              'source' => array(
                'data' => 'username',
              ),
              'optional' => FALSE,
            ),
            array(
              'name' => 'password',
              'type' => 'string',
              'description' => 'A valid password',
              'source' => array(
                'data' => 'password',
              ),
              'optional' => FALSE,
            ),
          ),
          'access callback' => 'services_access_menu',
          'file' => array(
            'type' => 'inc',
            'module' => 'services',
            'name' => 'resources/user_resource',
          ),
        ),
        'logout' => array(
          'file' => array(
            'type' => 'inc',
            'module' => 'services',
            'name' => 'resources/user_resource',
          ),
          'help' => 'Logout a user session',
          'callback' => '_user_resource_logout',
          'access callback' => 'services_access_menu',
        ),
        'register' => array(
          'help' => 'Registers a user. (anonymous only)',
          'callback' => '_user_resource_create',
          'file' => array(
            'type' => 'inc',
            'module' => 'services',
            'name' => 'resources/user_resource',
          ),
          'access callback' => '_user_resource_access',
          'access arguments' => array(
            'register',
          ),
          'access arguments append' => TRUE,
          'args' => array(
            array(
              'name' => 'account',
              'type' => 'array',
              'description' => 'The user data',
              'source' => 'data',
              'optional' => FALSE,
            ),
          ),
        ),
      ),
    ),
  );
}

/**
 * Get user details.
 *
 * @param $uid
 *   UID of the user to be loaded.
 *
 * @return
 *   A user object.
 *
 * @see user_load()
 */
function _user_resource_retrieve($uid) {
  $account = user_load($uid);
  if (empty($account)) {
    return services_error(t('There is no user with such ID.'), 404);
  }
  services_remove_user_data($account);

  // Everything went right.
  return $account;
}

/**
 * Create a new user.
 *
 * This function uses drupal_execute() and as such exepects all input to match
 * the submitting form in question.
 *
 * @param $account
 *   A object containing account information. The $account object should
 *   contain, at minimum, the following properties:
 *     - name (user name)
 *     - mail (email address)
 *     - pass (plain text unencrypted password)
 *
 *   These properties can be passed but are optional
 *     - status (0 for blocked, otherwise will be active by default)
 *     - notify (1 to notify user of new account, will not notify by default)
 *
 *  Roles can be passed in a roles property which is an associative
 *  array formatted with '<role id>' => '<role id>', not including
 *  the authenticated user role, which is given by default.
 *
 * @return
 *   The user object of the newly created user.
 */
function _user_resource_create($account) {

  // Adds backwards compatability with regression fixed in #1083242
  $account = _services_arg_value($account, 'account');

  // Load the required includes for saving profile information
  // with drupal_execute().
  module_load_include('inc', 'user', 'user.pages');

  // register a new user
  $form_state['values'] = $account;
  $form_state['values']['pass'] = array(
    'pass1' => $account['pass'],
    'pass2' => $account['pass'],
  );
  $form_state['values']['op'] = variable_get('services_user_create_button_resource_create', t('Create new account'));

  // execute the register form
  drupal_execute('user_register', $form_state);

  // Error if needed.
  if ($errors = form_get_errors()) {
    return services_error(implode(" ", $errors), 406, array(
      'form_errors' => $errors,
    ));
  }
  else {
    $user = array(
      'uid' => $form_state['user']->uid,
    );
    if ($uri = services_resource_uri(array(
      'user',
      $user['uid'],
    ))) {
      $user['uri'] = $uri;
    }
    return $user;
  }
}

/**
 * Update an existing user.
 *
 * This function uses drupal_execute() and as such exepects all input to match
 * the submitting form in question.
 *
 * @param $uid
 *   Unique identifier for this user
 * @param $account
 *   Fields to modify for this user.
 *
 * @return
 *   The modified user object.
 */
function _user_resource_update($uid, $account) {

  // Adds backwards compatability with regression fixed in #1083242
  $account = _services_arg_value($account, 'data');
  $account['uid'] = $uid;
  $account_loaded = user_load($uid);

  // Load the required includes for saving profile information
  // with drupal_form_submit().
  module_load_include('inc', 'user', 'user.pages');

  // If a profile category was passed in, use it. Otherwise default
  // to 'account' (for saving core user data.)
  $category = 'account';
  if (isset($account['category'])) {
    $category = $account['category'];
    unset($account['category']);
  }

  // Drop any passed in values into the $account var. Anything
  // unused by the form just gets ignored. We handle roles and
  // password separately.
  foreach ($account as $key => $value) {
    if ($key != 'pass' && $key != 'roles') {
      $form_state['values'][$key] = $value;
    }
  }

  // Prepare values of roles. Check user's permission before allowing changes to roles.
  if (!isset($account['roles']) || !user_access('administer users')) {
    $account['roles'] = $account_loaded->roles;
  }
  foreach ($account['roles'] as $key => $value) {
    if (!empty($value)) {
      $form_state['values']['roles'][$key] = $key;
    }
  }
  unset($form_state['values']['roles'][2]);

  // Prepare values for password.
  if (isset($account['pass'])) {
    $form_state['values']['pass']['pass1'] = $account['pass'];
    $form_state['values']['pass']['pass2'] = $account['pass'];
  }

  // If user is changing name, make sure they have permission.
  if (isset($account['name']) && $account['name'] != $account_loaded->name && !(user_access('change own username') || user_access('administer users'))) {
    return services_error(t('You are not allowed to change your username.'), 406);
  }
  $form_state['values']['op'] = variable_get('services_user_save_button_resource_update', t('Save'));
  $form_state['values']['#user_category'] = $category;
  $form_state['values']['#account'] = $account_loaded;
  $form_state['programmed_bypass_access_check'] = FALSE;
  $ret = drupal_execute('user_profile_form', $form_state, $account_loaded, $category);

  // Error if needed.
  if ($errors = form_get_errors()) {
    return services_error(implode(" ", $errors), 406, array(
      'form_errors' => $errors,
    ));
  }
  else {
    services_remove_user_data($account);
    return $account;
  }
}

/**
 * Delete a user.
 *
 * @param $uid
 *   UID of the user to be deleted.
 *
 * @see user_delete()
 */
function _user_resource_delete($uid) {
  $account = user_load($uid);
  if (empty($account)) {
    return services_error(t('There is no user with such ID.'), 404);
  }
  user_delete($account, $uid);

  // Everything went right.
  return TRUE;
}

/**
 * Login a user using the specified credentials.
 *
 * Note this will transfer a plaintext password.
 *
 * @param $username
 *   Username to be logged in.
 * @param $password
 *   Password, must be plain text and not hashed.
 *
 * @return
 *   A valid session object.
 */
function _user_resource_login($username, $password) {
  global $user;
  if ($user->uid) {

    // user is already logged in
    return services_error(t('Already logged in as !user.', array(
      '!user' => $user->name,
    )), 406);
  }
  if (user_is_blocked($username)) {
    return services_error(t('@user is blocked.', array(
      '@user' => $username,
    )), 406);
  }
  user_authenticate(array(
    'name' => $username,
    'pass' => $password,
  ));
  if (isset($user->uid) && $user->uid) {

    // Regenerate the session ID to prevent against session fixation attacks.
    sess_regenerate();
    $return = new stdClass();
    $return->sessid = session_id();
    $return->session_name = session_name();
    services_remove_user_data($user);
    $return->user = $user;
    return $return;
  }
  session_destroy();
  return services_error(t('Wrong username or password.'), 401);
}

/**
 * Logout the current user.
 */
function _user_resource_logout() {
  global $user;
  if (!$user->uid) {

    // User is not logged in
    return services_error(t('User is not logged in.'), 406);
  }
  watchdog('user', 'Session closed for %name.', array(
    '%name' => theme('placeholder', $user->name),
  ));
  $null = NULL;

  // Only variables can be passed by reference workaround
  user_module_invoke('logout', $null, $user);

  // Destroy the current session.
  session_destroy();

  // Load the anonymous user
  $user = drupal_anonymous_user();
  return TRUE;
}

/**
 * Return an array of optionally paged nids baed on a set of criteria.
 *
 * An example request might look like
 *
 * http://domain/endpoint/user?fields=uid,name,mail&parameters[uid]=1
 *
 * This would return an array of objects with only uid, name and mail defined,
 * where uid = 1.
 *
 * @param $page
 *   Page number of results to return (in pages of 20).
 * @param $fields
 *   The fields you want returned.
 * @param $parameters
 *   An array containing fields and values used to build a sql WHERE clause
 *   indicating items to retrieve.
 * @param $page_size
 *   Integer number of items to be returned.
 * @return
 *   An array of user objects.
 *
 * @see _node_resource_index()
 */
function _user_resource_index($page, $fields, $parameters, $page_size) {
  if (!user_access('administer users')) {
    $parameters['status'] = 1;
  }
  $query = services_resource_build_index_query('users', 'u.created DESC', $page, $fields, $parameters, 'u', 'uid', $page_size, 'user');
  $results = array();
  while ($user = db_fetch_object($query)) {
    $results[] = $user;
  }
  return services_resource_build_index_list($results, 'user', 'uid');
}

/**
 * Access check callback for user resource.
 */
function _user_resource_access($op = 'view', $args = array()) {

  // Adds backwards compatability with regression fixed in #1083242
  $args[0] = _services_access_value($args[0], array(
    'account',
    'data',
  ));

  // Check if the user exists if appropriate.
  if ($op != 'create' && $op != 'register') {
    $account = user_load($args[0]);
    if (!$account) {
      return services_error(t('There is no user with ID @uid.', array(
        '@uid' => $args[0],
      )), 406);
    }
  }
  global $user;
  switch ($op) {
    case 'view':
      return user_view_access($account);
    case 'update':
      return $user->uid == $account->uid || user_access('administer users');
    case 'create':
      return user_access('administer users');
    case 'register':

      //Verify user is not logged in, and verify that visitors can create accounts.
      if (!$user->uid && variable_get('user_register', 1) != 0) {
        return TRUE;
      }
      else {
        return FALSE;
      }
    case 'delete':
      return user_access('administer users');
  }
}

Functions

Namesort descending Description
_user_resource_access Access check callback for user resource.
_user_resource_create Create a new user.
_user_resource_definition @file This file will define the resources for dealing with the user object
_user_resource_delete Delete a user.
_user_resource_index Return an array of optionally paged nids baed on a set of criteria.
_user_resource_login Login a user using the specified credentials.
_user_resource_logout Logout the current user.
_user_resource_retrieve Get user details.
_user_resource_update Update an existing user.