You are here

avatar_selection.module in Avatar Selection 5

File

avatar_selection.module
View source
<?php

/**
 * Display help and module information
 * @param section which section of the site we're displaying help
 * @return help text for section
 */
function avatar_selection_help($section = '') {
  $output = '';
  switch ($section) {
    case "admin/help#avatar_selection":
      $output .= '<p>' . t("Allows the user to pick an avatar from a list.") . '</p>';
      return $output;
    case "admin/modules#description":
      return t("Allows the user to pick an avatar from a list.");
    case "admin/settings/avatar_selection/images":
      return t("Upload images to display as a user avatar.  These images can be anything you like, but it is recommended that you maintain a uniform icon size for all of your avatars.  Maximum dimensions are 85x85 and the maximum size is 30 kB");
  }
}

/**
 * Implementation of hook_perm().
 * Define the permissions this module uses
 */
function avatar_selection_perm() {
  return array(
    'administer avatar selection',
    'access avatars',
  );
}

/**
 * Implementation of hook_access().
 */
function avatar_selection_access($op, $node) {
  if ($op == 'view') {
    return user_access('access avatars');
  }
  else {
    if ($op == 'create' || $op == 'update' || $op == 'delete') {
      return user_access('administer avatar selection');
    }
  }
}

/**
 * Implementation of hook_menu().
 */
function avatar_selection_menu($may_cache) {
  $access = user_access('administer avatar selection');
  $items = array();
  if ($may_cache) {
    $items[] = array(
      'path' => 'admin/settings/avatar_selection',
      'title' => t('Avatar Selection'),
      'callback' => 'avatar_selection_settings_page',
      'access' => $access,
      'description' => t('Allows the user to upload and delete avatars.'),
    );
    $items[] = array(
      'path' => 'admin/settings/avatar_selection/config',
      'title' => t('Configure'),
      'description' => t('Allows the user to configure avatar settings.'),
      'callback' => 'drupal_get_form',
      'callback arguments' => array(
        'avatar_selection_config_form',
      ),
      'access' => $access,
      'type' => MENU_DEFAULT_LOCAL_TASK,
      'weight' => -10,
    );
    $items[] = array(
      'path' => 'admin/settings/avatar_selection/images',
      'title' => t('Upload'),
      'description' => t('Allows the user to upload avatars.'),
      'callback' => 'drupal_get_form',
      'callback arguments' => array(
        'avatar_selection_images_form',
      ),
      'access' => $access,
      'type' => MENU_LOCAL_TASK,
      'weight' => -9,
    );
    $items[] = array(
      'path' => 'admin/settings/avatar_selection/edit',
      'title' => t('Manage avatars'),
      'description' => t('Allows the user to modify or delete an avatar from a list.'),
      'callback' => 'drupal_get_form',
      'callback arguments' => array(
        'avatar_selection_edit_form',
      ),
      'access' => $access,
      'type' => MENU_LOCAL_TASK,
    );
  }
  return $items;
}

/**
 * Implementation of hook_form_alter().
 */
function avatar_selection_form_alter($form_id, &$form) {

  // we need the pager global variables
  global $user;

  // If user pictures aren't enabled, nothing to do here.
  if (!variable_get('user_pictures', 0)) {
    return;
  }
  if ('user_edit' == $form_id && is_array($form['picture'])) {
    drupal_add_css(drupal_get_path('module', 'avatar_selection') . '/avatar_selection.css');
    $access = user_access('access avatars');
    $disable_upload = variable_get('avatar_selection_disable_user_upload', 0);
    $force_choose = variable_get('avatar_selection_force_user_avatar', 0);

    // If upload support has been disabled, remove the ability to upload and
    // delete pictures
    if ($disable_upload) {
      unset($form['picture']['picture_delete']);
      unset($form['picture']['picture_upload']);
    }

    // If user has access to choose an avatar, show selection options
    $selects = _avatar_selection_image_list($user);
    if ($access && count($selects['avatars'])) {
      $user_form = drupal_retrieve_form($form_id);
      $form['picture']['select_avatar'] = array(
        '#type' => 'radios',
        '#title' => $disable_upload ? t('Select an avatar') : t('Or simply select an icon'),
        '#options' => $selects['avatars'],
        '#default_value' => $user_form['_account']['#value']->picture,
        '#required' => $force_choose ? TRUE : FALSE,
        '#attributes' => array(
          'class' => 'user_avatar_select',
        ),
      );
    }

    // If user can't do either, remove the fielset altogether
    if (!$access && $disable_upload) {
      unset($form['picture']);
    }

    // Don't allow user to delete a selected avatar
    $path = '/avatar_selection/';
    if ($form['picture']['current_picture']['#value'] && preg_match($path, $form['picture']['current_picture']['#value'])) {
      unset($form['picture']['picture_delete']);
    }
    $num_images_per_page = variable_get('avatar_selection_avatar_per_page', 30);
    $js_settings = array(
      'num_images_per_page' => $num_images_per_page ? $num_images_per_page : 1,
      'num_images' => $selects['total'],
    );
    drupal_add_js(array(
      'avatar_selection' => $js_settings,
    ), 'setting');
    drupal_add_js(drupal_get_path('module', 'avatar_selection') . '/js/avatar_selection.js', 'module', 'header');
  }
  else {
    if ('user_register' == $form_id) {
      $anon_user = drupal_anonymous_user();
      $force_choose = variable_get('avatar_selection_force_user_avatar_reg', 0);
      $selects = _avatar_selection_image_list($anon_user);
      if (count($selects['avatars'])) {
        drupal_add_css(drupal_get_path('module', 'avatar_selection') . '/avatar_selection.css');
        $form['picture'] = array(
          '#type' => 'fieldset',
          '#title' => t('Picture'),
          '#weight' => 1,
        );
        $form['picture']['select_avatar'] = array(
          '#type' => 'radios',
          '#title' => t('Select an avatar'),
          '#options' => $selects['avatars'],
          '#required' => $force_choose ? TRUE : FALSE,
          '#attributes' => array(
            'class' => 'user_avatar_select',
          ),
        );
      }
      $num_images_per_page = variable_get('avatar_selection_avatar_per_page', 30);
      $js_settings = array(
        'num_images_per_page' => $num_images_per_page ? $num_images_per_page : 1,
        'num_images' => $selects['total'],
      );
      drupal_add_js(array(
        'avatar_selection' => $js_settings,
      ), 'setting');
      drupal_add_js(drupal_get_path('module', 'avatar_selection') . '/js/avatar_selection.js', 'module', 'header');
    }
  }
  return $form;
}

/*
 * Implementation of hook_user().
 */
function avatar_selection_user($op, &$edit, &$user, $category = 'account') {
  global $form_values;
  switch ($op) {
    case 'validate':
      $file = file_check_upload('picture_upload');
      if (!$file && $edit['select_avatar']) {
        $form_values['picture'] = $edit['select_avatar'];
      }
      else {
        if (!$file && variable_get('avatar_selection_set_random_default', FALSE)) {
          $form_values['picture'] = avatar_selection_get_random_image($user);
        }
      }
      break;
  }
}
function avatar_selection_get_random_image($user) {
  $avatars = _avatar_selection_image_list($user);
  $avatar = array_rand($avatars['avatars'], 1);
  return $avatar;
}
function _avatar_selection_image_list($user = "") {
  $avatars = array();
  $dir = file_create_path('avatar_selection');
  $mask = '.*\\.(gif|GIF|Gif|jpg|JPG|Jpg|jpeg|JPEG|Jpeg|png|PNG|Png)';
  $listings = file_scan_directory($dir, $mask, array(
    '.',
    '..',
    'CVS',
  ), 0, FALSE);
  $result = db_query("SELECT avatar, access, og_access FROM {avatar_selection} avs");
  while ($avatar = db_fetch_object($result)) {
    $avs_image = $avatar->avatar;
    $avs_access = preg_split('/\\s*,\\s*/', $avatar->access);
    $og_access = preg_split('/\\s*,\\s*/', $avatar->og_access);
    $del_avatar = 1;

    // check the organic groups
    if (module_exists("og")) {
      if (!empty($avatar->og_access)) {
        if (!empty($user->og_groups) && is_array($user->og_groups)) {
          foreach ($user->og_groups as $gid => $grp) {
            if (in_array($gid, $og_access)) {
              $del_avatar = 2;
              break;
            }
          }
        }

        // delete it if it's not in one of the valid groups
        if ($del_avatar == 1 && !empty($user) && $user->uid != 1) {
          unset($listings[$avs_image]);
        }
      }
    }

    // check the user roles
    if (!empty($avatar->access)) {
      if (!empty($user->roles) && is_array($user->roles)) {
        foreach ($user->roles as $rid => $role) {
          if (in_array($rid, $avs_access)) {
            $del_avatar = 0;
            break;
          }
        }
      }

      // delete it if it's not in a valid role
      if ($del_avatar != 0 && !empty($user) && $user->uid != 1) {
        unset($listings[$avs_image]);
      }
    }
  }
  $total_avatars = count($listings);
  foreach ($listings as $listing) {
    $avatars[$dir . '/' . $listing->basename] = theme('image', file_create_url($dir . '/' . $listing->basename), $listing->basename, $listing->basename, NULL, FALSE);
  }
  $selects['avatars'] = $avatars;
  $selects['total'] = $total_avatars;
  return $selects;
}
function avatar_selection_settings_page($op = NULL, $aid = NULL) {
  switch ($op) {
    case 'edit':
      if (is_numeric($aid)) {
        $output = drupal_get_form('avatar_selection_config_form', $aid);
      }
      break;
    case 'upload':
      if (is_numeric($aid)) {
        $output = drupal_get_form('avatar_selection_images_form', $aid);
      }
      break;
    case 'list':
      if (is_numeric($aid)) {
        $output = drupal_get_form('avatar_selection_edit_form');
      }
      break;
    default:
      $form[] = array(
        '#type' => 'fieldset',
        '#title' => t('Add another'),
      );
      $output .= drupal_get_form('avatar_selection_config_form');
      break;
  }
  return $output;
}

/**
 * Define a form to configure the module settings
 */
function avatar_selection_config_form() {
  if (!variable_get('user_pictures', 0)) {
    drupal_set_message(t('User Pictures option is disabled.  You will need to enable this option before you can use the Avatar Selection module.  You may configure this setting on the <a href="@url">User settings</a> page.', array(
      '@url' => url('admin/user/settings'),
    )));
  }

  // To store how many avatars per page are displayed.
  $form['update']['avatar_per_page'] = array(
    '#type' => 'textfield',
    '#title' => t('How many avatars per page'),
    '#description' => t('The number of avatars to show per page.'),
    '#default_value' => variable_get('avatar_selection_avatar_per_page', 30),
    '#size' => 3,
  );
  $form['update']['disable_user_upload'] = array(
    '#type' => 'checkbox',
    '#title' => t('Disable users uploading pictures to profile'),
    '#description' => t('Allow users to pick their avatar from the selection but prevent them from uploading new avatars when editing their account.'),
    '#default_value' => variable_get('avatar_selection_disable_user_upload', FALSE),
  );
  $form['update']['force_set_image_reg'] = array(
    '#type' => 'checkbox',
    '#title' => t('Force users to select an avatar image on user registration.'),
    '#description' => t('This only comes into effect on the user registration screen.'),
    '#default_value' => variable_get('avatar_selection_force_user_avatar_reg', FALSE),
  );
  $form['update']['force_set_image'] = array(
    '#type' => 'checkbox',
    '#title' => t('Force users to select an avatar image when editing their account'),
    '#description' => t('This only comes into effect when the user is editing their account details and image uploads are disabled.'),
    '#default_value' => variable_get('avatar_selection_force_user_avatar', FALSE),
  );
  $form['update']['set_random_default'] = array(
    '#type' => 'checkbox',
    '#title' => t('Enable random default avatar image.'),
    '#description' => t('Automatically set a random avatar image to be used when the user doesn\'t set one for their account.'),
    '#default_value' => variable_get('avatar_selection_set_random_default', FALSE),
  );
  $form['update']['submit'] = array(
    '#type' => 'submit',
    '#value' => t('Update'),
  );
  return $form;
}

/**
 * Define a form to upload the avatar images.
 */
function avatar_selection_images_form() {
  if (!variable_get('user_pictures', 0)) {
    drupal_set_message(t('User Pictures option is disabled.  You will need to enable this option before you can use the Avatar Selection module.  You may configure this setting on the <a href="@url">User settings</a> page.', array(
      '@url' => url('admin/user/settings'),
    )));
  }
  $form['#attributes']['enctype'] = 'multipart/form-data';
  $form['picture_upload'] = array(
    '#type' => 'file',
    '#title' => t('Upload image'),
    '#size' => 48,
    '#description' => t('A new avatar image.  Maximum dimensions are %dimensions and the maximum size is %size kB.  Images must have one of the following extensions (case sensitive): png, jpg, jpeg, gif, PNG, JPG, JPEG, GIF.', array(
      '%dimensions' => variable_get('user_picture_dimensions', '85x85'),
      '%size' => variable_get('user_picture_file_size', '30'),
    )) . ' ' . variable_get('user_picture_guidelines', ''),
  );
  $form['permissions'] = array(
    '#type' => 'fieldset',
    '#title' => t('Permissions'),
    '#weight' => 1,
  );
  $form['permissions']['access'] = array(
    '#type' => 'checkboxes',
    '#title' => t('User Roles'),
    '#options' => avatar_selection_handler_filter_role(),
    '#description' => t('Only the checked roles will be able to see this avatar icon; if no roles are checked, access will not be restricted.'),
  );
  if (module_exists("og")) {
    $form['permissions']['og_access'] = array(
      '#type' => 'checkboxes',
      '#title' => t('Organic Groups'),
      '#options' => og_all_groups_options(),
      '#description' => t('Only users in the checked organic groups will be able to see this avatar icon; if no groups are checked, access will not be restricted.'),
    );
  }
  $form['attach'] = array(
    '#type' => 'submit',
    '#value' => t('Upload'),
    '#weight' => 10,
  );
  return $form;
}
function avatar_selection_edit_form($form_values = NULL) {
  if (!variable_get('user_pictures', 0)) {
    drupal_set_message(t('User Pictures option is disabled.  You will need to enable this option before you can use the Avatar Selection module.  You may configure this setting on the <a href="@url">User settings</a> page.', array(
      '@url' => url('admin/user/settings'),
    )));
  }
  drupal_add_css(drupal_get_path('module', 'avatar_selection') . '/avatar_selection.css');
  $selects = _avatar_selection_image_list();
  if (!count($selects['avatars'])) {
    drupal_set_message(t('There are no images configured.'));
  }
  else {
    if (!isset($form_values)) {
      $step = "list";
    }
    else {
      $step = "edit";
    }
    $form['step'] = array(
      '#type' => 'hidden',
      '#value' => $step,
    );
    $form['#multistep'] = TRUE;
    if ($step == "list") {
      $form['#redirect'] = FALSE;
      $form['select_avatar'] = array(
        '#type' => 'radios',
        '#title' => t('Select an avatar to edit'),
        '#options' => $selects['avatars'],
        '#required' => TRUE,
        '#attributes' => array(
          'class' => 'user_avatar_select',
        ),
      );
      $form['search'] = array(
        '#type' => 'submit',
        '#value' => t('Edit'),
      );
      $num_images_per_page = variable_get('avatar_selection_avatar_per_page', 30);
      $js_settings = array(
        'num_images_per_page' => $num_images_per_page ? $num_images_per_page : 1,
        'num_images' => $selects['total'],
      );
      drupal_add_js(array(
        'avatar_selection' => $js_settings,
      ), 'setting');
      drupal_add_js(drupal_get_path('module', 'avatar_selection') . '/js/avatar_selection.js', 'module', 'header');
    }
    else {
      if ($step == "edit") {
        $form['#redirect'] = array(
          'admin/settings/avatar_selection/edit',
        );
        $roles = avatar_selection_handler_filter_role();
        $result = db_query("SELECT avatar, access, og_access FROM {avatar_selection} avs WHERE avatar = '%s'", $form_values['select_avatar']);
        while ($avatar = db_fetch_object($result)) {
          $avs_access = preg_split('/\\s*,\\s*/', $avatar->access);
          $og_access = preg_split('/\\s*,\\s*/', $avatar->og_access);
        }
        $image = theme('image', $form_values['select_avatar']);
        $form['avatar_image'] = array(
          '#value' => $image,
        );
        $form['select_avatar'] = array(
          '#type' => 'hidden',
          '#default_value' => $form_values['select_avatar'],
        );
        $form['permissions'] = array(
          '#type' => 'fieldset',
          '#title' => t('Permissions'),
          '#weight' => 1,
        );
        $form['permissions']['access'] = array(
          '#type' => 'checkboxes',
          '#title' => t('User Roles'),
          '#default_value' => $avs_access,
          '#options' => $roles,
          '#description' => t('Only the checked roles will be able to see this avatar icon; if no roles are checked, access will not be restricted.'),
        );
        if (module_exists("og")) {
          $form['permissions']['og_access'] = array(
            '#type' => 'checkboxes',
            '#title' => t('Organic Groups'),
            '#default_value' => $og_access,
            '#options' => og_all_groups_options(),
            '#description' => t('Only users in the checked organic groups will be able to see this avatar icon; if no groups are checked, access will not be restricted.'),
          );
        }
        $form['update'] = array(
          '#type' => 'submit',
          '#value' => t('Update'),
          '#weight' => 9,
        );
        $form['delete'] = array(
          '#type' => 'submit',
          '#value' => t('Delete'),
          '#weight' => 10,
        );
      }
    }
  }
  return $form;
}

/**
 * Validate the submission.
 *
 * Check whether:
 * if any of the settings have changed
 */
function avatar_selection_config_form_validate($form_id, $form_values) {
  $error = FALSE;
  if ($form_values['op'] == t('Update')) {
    if (!is_numeric($form_values['avatar_per_page'])) {
      form_set_error('avatar_per_page', t('Must be a number.'));
      $error = TRUE;
    }
  }
}

/**
 * Validate the submission.
 *
 * Check whether:
 * Upload has been chosen AND the file upload form is not empty.
 */
function avatar_selection_images_form_validate($form_id, $form_values) {
  $error = FALSE;
  if ($form_values['op'] == t('Upload')) {
    if ($file = file_check_upload('picture_upload')) {
      avatar_selection_validate_picture($file);
    }
  }
}

/**
 * Validate the submission.
 *
 * Check whether:
 * Delete has been chosen AND a checkbox has been selected
 */
function avatar_selection_delete_form_validate($form_id, $form_values) {
  if ($form_values['op'] == t('Delete')) {
    if (count(array_filter($form_values['images'])) == 0) {
      form_set_error('images', t('Please select images to delete.'));
    }
  }
}
function avatar_selection_validate_picture($file) {
  global $form_values;

  // Check that uploaded file is an image, with a maximum file size
  // and maximum height/width.
  $info = image_get_info($file->filepath);
  list($maxwidth, $maxheight) = explode('x', variable_get('user_picture_dimensions', '85x85'));
  if (!$info || !$info['extension']) {
    form_set_error('picture_upload', t('The uploaded file was not an image.'));
  }
  else {
    if (image_get_toolkit()) {
      image_scale($file->filepath, $file->filepath, $maxwidth, $maxheight);
    }
    else {
      if (filesize($file->filepath) > variable_get('user_picture_file_size', '30') * 1000) {
        form_set_error('picture_upload', t('The uploaded image is too large; the maximum file size is %size kB.', array(
          '%size' => variable_get('user_picture_file_size', '30'),
        )));
      }
      else {
        if ($info['width'] > $maxwidth || $info['height'] > $maxheight) {
          form_set_error('picture_upload', t('The uploaded image is too large; the maximum dimensions are %dimensions pixels.', array(
            '%dimensions' => variable_get('user_picture_dimensions', '85x85'),
          )));
        }
      }
    }
  }
}
function avatar_selection_config_form_submit($form_id, $form_values) {
  $op = $form_values['op'];
  if ($op == t('Update')) {

    // save system variables
    variable_set('avatar_selection_disable_user_upload', $form_values['disable_user_upload']);
    variable_set('avatar_selection_force_user_avatar_reg', $form_values['force_set_image_reg']);
    variable_set('avatar_selection_force_user_avatar', $form_values['force_set_image']);
    variable_set('avatar_selection_avatar_per_page', $form_values['avatar_per_page']);
    variable_set('avatar_selection_set_random_default', $form_values['set_random_default']);
    drupal_set_message(t('Configuration has been updated.'));
  }
}
function avatar_selection_images_form_submit($form_id, $form_values) {
  $op = $form_values['op'];
  if ($op == t('Upload')) {

    // Save uploaded files
    $dir = file_create_path('avatar_selection');
    $is_writable = file_check_directory($dir, 1);
    if ($is_writable) {
      if ($source = file_check_upload('picture_upload')) {
        if ($file = file_save_upload($source, $dir)) {
          if (image_get_info($file->filepath)) {
            $access = implode(', ', array_keys(array_filter($form_values['access'])));
            if (module_exists("og")) {
              $og = implode(', ', array_keys(array_filter($form_values['og_access'])));
            }
            _avatar_selection_save_avatar_info($file->filepath, $access, $og);
            drupal_set_message(t('New image saved.'));
          }
          else {
            file_delete($file->filepath);
            drupal_set_message('Uploaded file does not appear to be a valid image file. Please try again.');
          }
        }
      }
    }
    else {
      form_set_error('picture_upload', t('Directory not writable: !dir', array(
        '!dir' => $dir,
      )));
    }
  }
}
function avatar_selection_edit_form_submit($form_id, $form_values) {
  $op = $form_values['op'];
  if ($op == t('Update')) {
    $access = implode(', ', array_keys(array_filter($form_values['access'])));
    if (module_exists("og")) {
      $og = implode(', ', array_keys(array_filter($form_values['og_access'])));
    }
    _avatar_selection_save_avatar_info($form_values['select_avatar'], $access, $og);
    drupal_set_message(t('Image updated.'));
  }
  else {
    if ($op == t('Delete')) {
      $image = $form_values['select_avatar'];
      avatar_selection_image_delete($image);
    }
  }
}
function avatar_selection_image_delete($image) {
  if (file_check_location($image, file_create_path('avatar_selection'))) {
    $result = db_query("DELETE FROM {avatar_selection} WHERE avatar = '%s'", $image);
    file_delete($image);
    if (!image_get_info($image)) {
      drupal_set_message(t('Image deleted.'));
    }
  }
}

/**
 * Implementation of hook_file_download().
 *
 * Ensure that user pictures (avatars) are always downloadable.
 */
function avatar_selection_file_download($file) {
  if (user_access('access content')) {
    $data = explode('/', $file);
    $icon = array_pop($data);
    $folder = implode('/', $data);
    if ('avatar_selection' == $folder) {
      $info = image_get_info(file_create_path($file));
      return array(
        'Content-type: ' . $info['mime_type'],
        'Content-length: ' . $info['file_size'],
      );
    }
    else {
      return null;
    }
  }
}

/*
 * Create a list of roles.
 */
function avatar_selection_handler_filter_role() {
  $rids = array();
  $result = db_query("SELECT r.rid, r.name FROM {role} r ORDER BY r.name");
  while ($obj = db_fetch_object($result)) {
    $rids[$obj->rid] = $obj->name;
  }
  return $rids;
}

/*
 * function to save avatar icon details to the avatar_selection table
 */
function _avatar_selection_save_avatar_info($filepath, $access, $og = "") {
  switch ($GLOBALS['db_type']) {
    case 'mysqli':
    case 'mysql':
      $result = db_query("REPLACE INTO {avatar_selection} (avatar, access, og_access) VALUES('%s', '%s', '%s')", $filepath, $access, $og);
      break;
    case 'pgsql':
      $result = db_query("DELETE FROM {avatar_selection} WHERE avatar = '%s'", $filepath);
      $result = db_query("INSERT INTO {avatar_selection} (avatar, access, og_access) VALUES('%s', '%s', '%s')", $file->filepath, $access, $og);
      break;
  }
}