You are here

me.module in me aliases 7

Same filename and directory in other branches
  1. 8 me.module
  2. 5 me.module
  3. 6.2 me.module
  4. 6 me.module

Provides 'me' aliases to allow users to enter 'me' in common paths instead of their user id.

File

me.module
View source
<?php

//$Id$

/**
 * @file
 *
 * Provides 'me' aliases to allow users to enter 'me' in common paths instead of their user id.
 */

/**
 * Constants defining the different ways paths can be matched.
 */

// Exclude paths
define('ME_PATH_EXCLUDE', 0);

// Include paths
define('ME_PATH_INCLUDE', 1);

// PHP for paths
define('ME_PATH_PHP', 2);

/**
 * Implements hook_help().
 */
function me_help($path, $arg) {
  switch ($path) {
    case 'admin/help#me':
      return t("Allows a user to enter user/me, blog/me etc.. using 'me' in place of their user id.");
  }
}

/**
 * Implements hook_theme_registry_alter().
 *
 * There is a different registry version for each theme,
 * and this function will be called for each of them.
 */
function me_theme_registry_alter(&$theme_registry) {
  if (isset($theme_registry['menu_item_link']['function'])) {

    // remember the original function
    $theme_registry['menu_item_link']['me_original_function'] = $theme_registry['menu_item_link']['function'];
    $theme_registry['menu_item_link']['function'] = 'me_theme_menu_item_link';
  }
}

/**
 * Implementaiton of moduleName_preprocess_hook() for theme_menu_link.
 */
function me_preprocess_menu_link(&$vars) {
  _me_check_path($vars['element']);
}

/**
 * Helper function to check if a path can be rewritten or not.
 *
 * By this stage, the path is already rewritten, so we need to
 * reverse the process.
 *
 * @param &$link
 *   The link object to check.
 */
function _me_check_path(&$link) {

  // If the link has been rewritten, and we are not supposed to be handling this
  // path, then rewite it back to its original.
  if (isset($link['#href']) && me_variable_get('me_rewrite_link') && !_me_handle_path($link['#href'])) {
    $path_parts = explode('/', $link['#href'], MENU_MAX_PARTS);

    // The wildcarded path will either be in $link['path'], or $link['router_path'].
    $wild_parts = explode('/', isset($link['#original_link']['link_path']) ? $link['#original_link']['link_path'] : $link['#original_link']['router_path'], MENU_MAX_PARTS);

    // Go over each of the path parts and if one is equal to the me alias, make sure it is a wildcard,
    // and if so, switch it back out.
    foreach ($path_parts as $key => $val) {
      if (_me_is_alias($val) && $wild_parts[$key] == '%') {
        $path_parts[$key] = $GLOBALS['user']->uid;
      }
    }
    $link['#href'] = implode('/', $path_parts);
    $link['#original_link']['href'] = implode('/', $path_parts);
  }
}

/**
 * Helper function to keep all the variable gets in one place.
 *
 * @param $name
 *   The variable we wish to retrieve.
 *
 * @return mixed
 *   The value of the requested variable.
 */
function me_variable_get($name) {
  static $defaults = array(
    'me_alias' => 'me',
    'me_case_insensitive' => FALSE,
    'me_redirect' => FALSE,
    'me_path_rule' => ME_PATH_EXCLUDE,
    'me_paths' => '',
    'me_redirect_anonymous' => '',
    'me_theme_menu_item_link' => '',
    'me_rewrite_link' => TRUE,
    'me_user_override' => FALSE,
  );
  return variable_get($name, $defaults[$name]);
}

/**
 * Helper function to check if me should handle a given path.
 *
 * @param $path
 *   The path to check
 *
 * @return boolean
 *   TRUE if the path is handled by the me module. FALSE otherwise.
 */
function _me_handle_path($path) {

  // Match path if necessary
  $paths = me_variable_get('me_paths');
  $path_rule = me_variable_get('me_path_rule');
  $path_match = TRUE;
  if (!empty($paths)) {
    if ($path_rule !== ME_PATH_PHP) {
      $path = drupal_get_path_alias($_GET['q']);

      // Compare with the internal and path alias (if any).
      $path_match = drupal_match_path($path, $paths);
      if ($path != $_GET['q']) {
        $path_match = $path_match || drupal_match_path($_GET['q'], $paths);
      }

      // When $path_rule has a value of ME_PATH_EXCLUDE, then me works on
      // all paths except those listed in $paths. When set to ME_PATH_INCLUDE, it
      // is used only on those pages listed in $paths.
      $path_match = !($path_rule xor $path_match);
    }
    else {
      if (module_exists('php')) {
        $path_match = php_eval($paths);
      }
    }
  }
  return $path_match;
}

/**
 * A special menu callback function that either redirects to
 * a page with the uid in the path, or calls the real menu handler.
 *
 * @param $parts
 *   The menu parts we are working with.
 * @param $callback
 *   The page callback to call.
 * @param ...
 *   count($parts) arguments for each part of the actual path
 * @param ...
 *   Any extra arguments will be the real page arguments.
 *
 * @return mixed
 *   Whatever the real page callback returns.
 */
function me_handler($parts, $callback) {

  // Get the arguments, and shift off $parts and $callback.

  /*$parts and $callback are left here for compatability, they are not going to be used after the fix for
   * http://drupal.org/node/1630044*/
  $args = func_get_args();
  $callback = array_shift($args);
  $parts = array_shift($args);

  // If we want the uid shown in the address bar, we need to do a redirect.
  if (me_variable_get('me_redirect') || _me_user_disabled() || !_me_handle_path($_GET['q'])) {
    $redirect = FALSE;

    // Get the menu path arguments.
    $menu_parts = explode('/', $_GET['q'], MENU_MAX_PARTS);

    // Loop over each part. If it's a %me wildcard, then
    // check the corresponding menu part for the me alias,
    // if so, replace it out with the user id so we can redirect correctly.
    // If no changes are required, then call the required function.
    foreach ($parts as $key => $val) {
      if (0 === strpos($val, '%me') && _me_is_alias($menu_parts[$key])) {
        $redirect = TRUE;
        $menu_parts[$key] = $GLOBALS['user']->uid;
      }
    }
    if ($redirect) {
      $path = implode('/', $menu_parts);

      // Save on an extra redirect by also checking the anonymous redirect here.
      $redirect_path = me_variable_get('me_redirect_anonymous');
      if ($GLOBALS['user']->uid == 0 && !empty($redirect_path)) {
        $path = $redirect_path;
      }
      drupal_goto($path);
    }
  }

  // Before going any further, set the current menu router item to include
  // paths with %user, which allows modules to use menu_get_object() instead
  // of arg() in blocks and the like.
  $router_item = menu_get_item();
  foreach ($router_item['load_functions'] as $index => $function) {

    // If the function is a me handled function, then swap the handler out with user.
    if (0 === strpos($function, 'me')) {
      $router_item['load_functions'][$index] = 'user_load';
    }
  }
  menu_set_item($_GET['q'], $router_item);
  return call_user_func_array($callback, $args);
}

/**
 * Helper function to check if a user can have, and has me disabled.
 *
 * @return boolean
 *   TRUE if the user has me disabled. FALSE otherwise.
 */
function _me_user_disabled() {
  return me_variable_get('me_user_override') && !empty($GLOBALS['user']->me_disable);
}

/**
 * Implements hook_menu_alter().
 */
function me_menu_alter(&$callbacks) {

  // Loop over each of the paths, finding all %user* loaders,
  // and replace them with a %me equivelant. This should catch
  // all drupal modules that use the %user loader to load up
  // user objects, which should be most well written D6 modules.
  // Certainly all of core.
  $processed = array();

  //XXX: For now, we only handle known user loaders. I might make a module hook, or a configuration

  // area to allow these to be exteneded if users make the requests.
  $handlers = array(
    '%user' => '%me',
    '%user_uid_optional' => '%me_uid_optional',
    '%user_category' => '%me_category',
  );
  foreach ($callbacks as $path => $data) {
    $found = FALSE;
    $parts = explode('/', $path, MENU_MAX_PARTS);
    foreach ($handlers as $user_handler => $me_handler) {
      if (isset($user_handler) && in_array($user_handler, $parts)) {
        $found = TRUE;
        break;
      }
    }
    if ($found) {

      // We need to make sure that the correct files are loaded up. when the path is used.
      if (isset($data['file']) && !isset($data['file path'])) {
        $data['file path'] = drupal_get_path('module', $data['module']);
      }

      // We need to find the right page callback and page arguments to make
      // the me handler work correctly.
      $new_parts = array();
      foreach ($parts as $key => $val) {
        if (array_key_exists($val, $handlers)) {
          $val = $handlers[$val];
        }
        $new_parts[] = $val;
      }
      $new_path = implode('/', $new_parts);

      // We need to be careful with load arguments due too http://drupal.org/node/373568.
      // We therefore only add load arguments if there are some there already.
      // The only load argument that needs to be passed by reference is map.
      // We make sure that we have map in the right place to be passed by reference.
      if (isset($data['load arguments']) && is_array($data['load arguments'])) {

        // Find the current map index, and add our load arguments, putting map
        // in the place we expect it to be.
        if (FALSE !== ($map_index = array_search('%map', $data['load arguments']))) {
          unset($data['load arguments'][$map_index]);
          array_unshift($data['load arguments'], '%map', '%index', strval($map_index));
        }
      }

      // First, we need to find the parent.
      $parent_path = implode('/', array_slice($parts, 0, count($parts) - 1));
      if (!array_key_exists($parent_path, $callbacks)) {
        $parent_path = $path;
      }
      if (in_array($parent_path, $processed)) {
        $parts = explode('/', $new_path, MENU_MAX_PARTS);
        $parent_path = implode('/', array_slice($parts, 0, count($parts) - 1));
        if (!array_key_exists($parent_path, $callbacks)) {
          $parent_path = $path;
        }
      }
      if (isset($callbacks[$parent_path])) {
        $parent = $callbacks[$parent_path];
        if (!isset($data['page callback']) && isset($parent['page callback'])) {
          $data['page callback'] = $parent['page callback'];
          if (!isset($data['page arguments']) && isset($parent['page arguments'])) {
            $data['page arguments'] = $parent['page arguments'];
          }
          if (!isset($data['file']) && isset($parent['file'])) {
            $data['file'] = $parent['file'];
          }
          if (!isset($data['file path']) && isset($parent['file path'])) {
            $data['file path'] = $parent['file path'];
          }
        }
      }
      if (isset($data['page callback'])) {
        if (isset($data['page arguments']) && !is_array($data['page arguments'])) {
          $data['page arguments'] = array();
        }
        $parts = explode('/', $new_path, MENU_MAX_PARTS);
        if (isset($data['page arguments'])) {
          $data['page arguments'] = array_merge(array(
            $data['page callback'],
            $parts,
          ), $data['page arguments']);
        }
        else {
          $data['page arguments'] = array(
            $data['page callback'],
            $parts,
          );
        }
        $data['page callback'] = 'me_handler';
      }
      $callbacks[$new_path] = $data;
      unset($callbacks[$path]);
      $processed[] = $path;
    }
  }
}

/**
 * Helper function to set up arguments in meun _load callbacks.
 */
function _me_load_arguments($uid, &$map = NULL, $index = NULL, $map_index = FALSE, $args = array(), $function = 'user_load', $reset = FALSE) {
  global $user;
  static $cache = array();
  if ($reset) {
    $cache = array();
  }

  // We need to get all the arguments, remove our custom ones,
  // put %map in the right place, then call the menu load callack.
  array_splice($args, 0, min(4, count($args)));
  if (!is_null($map) && FALSE !== $map_index) {
    $insert = array(
      &$map,
    );
    array_splice($args, $map_index, 0, $insert);
    $map[$index] = _me_check_arg($uid);
  }
  array_unshift($args, _me_check_arg($uid));

  // If we have a valid function to call, call it.
  $result = FALSE;
  if (function_exists($function)) {
    if ($function == 'user_load' || $function == 'user_category_load') {
      if (!isset($cache[$function][$args[0]])) {

        // Call user_load and store in cache:
        $cache[$function][$args[0]] = call_user_func_array($function, $args);
      }

      // Use cached user's object:
      $result = $cache[$function][$args[0]];
    }
    else {
      $result = call_user_func_array($function, $args);
    }
  }
  return $result;
}

/**
 * Menu load callback in place of user_load().
 */
function me_load($uid, &$map = NULL, $index = NULL, $map_index = FALSE) {
  return _me_load_arguments($uid, $map, $index, $map_index);
}

/**
 * Menu load callback in place of user_uid_optional_load().
 */
function me_uid_optional_load($uid, &$map = NULL, $index = NULL, $map_index = FALSE) {
  if (!isset($uid)) {
    if (!$GLOBALS['user']->uid) {
      return;
    }
    $uid = $GLOBALS['user']->uid;
  }
  $args = func_get_args();
  return _me_load_arguments($uid, $map, $index, $map_index, $args);
}

/**
 * Menu load callback in place of user_category_load().
 */
function me_category_load($uid, &$map = NULL, $index = NULL, $map_index = FALSE) {
  $args = func_get_args();
  return _me_load_arguments($uid, $map, $index, $map_index, $args, 'user_category_load');
}

/**
 * Menu to_arg function for %me.
 */
function me_to_arg($arg, $map, $index) {
  $uid = user_uid_optional_to_arg($arg, $map, $index);
  if (me_variable_get('me_rewrite_link') && !_me_user_disabled()) {
    $uid = $uid == $GLOBALS['user']->uid ? _me_get_me_alias() : $uid;
  }
  return $uid;
}

/**
 * Menu to_arg function for %me_uid_optional.
 */
function me_uid_optional_to_arg($arg, $map, $index) {

  //return me_to_arg($arg, $map, $index);
  return user_uid_optional_to_arg($arg, $map, $index);
}

/**
 * Menu to_arg function for %me_category.
 */
function me_category_to_arg($arg, $map, $index) {
  return me_to_arg($arg, $map, $index);
}

/**
 * A Helper function to check for the 'me' alias.
 *
 * @param $arg
 *   The argument to check.
 * @param $username
 *   If TRUE, will return the username instead of the users id.
 * @param $redirect
 *   When TRUE, anonymous users will be redirected if a path is available.
 *
 * @return mixed
 *   The current user id if a match is found, or the given argument
 *   if no match.
 */
function _me_check_arg($arg, $username = FALSE, $redirect = TRUE) {
  $return = _me_is_alias($arg) ? $username ? $GLOBALS['user']->name : $GLOBALS['user']->uid : $arg;
  $redirect_path = me_variable_get('me_redirect_anonymous');
  if ($redirect && $GLOBALS['user']->uid == 0 && !empty($redirect_path)) {

    // Copied from menu_get_item(). We can't call that here as it might cause a recursion loop.
    $original_map = arg(NULL, $_GET['q']);
    $parts = array_slice($original_map, 0, MENU_MAX_PARTS);
    $ancestors = menu_get_ancestors($parts);
    if (($router_item = db_query_range('SELECT * FROM {menu_router} WHERE path IN (:ancestors) ORDER BY fit DESC', 0, 1, array(
      ':ancestors' => $ancestors,
    ))
      ->fetchAssoc()) && $router_item['page_callback'] == 'me_handler') {

      // Not unsetting the destination can cause evil redirect loops.
      unset($_GET['destination'], $_REQUEST['edit']['destination']);
      drupal_goto($redirect_path);
    }
  }
  return $return;
}

/**
 * Helper function to return the me alias.
 *
 * @param $print_name
 *   Shows a friendly print name of the alias instead
 *   of the actual alias itself. This argument is only
 *   checked if the token module is installed.
 *
 * @return string
 *   The me alias, token replaced if appropriate.
 */
function _me_get_me_alias($print = FALSE) {
  $alias = me_variable_get('me_alias');

  // Replace with any global tokens that might have been used in the alias.
  //   if (module_exists('token')) {
  $replaced_alias = token_replace($alias);

  // They will not match if a replacement happened.
  if ($print && $replaced_alias != $alias) {
    $alias = ucwords(str_replace(array(
      '-',
      '[',
      ']',
    ), array(
      ' ',
      '',
    ), $alias));
  }
  else {
    $alias = $replaced_alias;
  }

  //   }
  return $alias;
}

/**
 * A helper function to check if a string is equal to the 'me' alias.
 *
 * @param $arg
 *   The argument to check.
 *
 * @return boolean
 *   TRUE if the argument given is a 'me' alias. FALSE otherwise.
 */
function _me_is_alias($arg) {
  $compare_function = me_variable_get('me_case_insensitive') ? 'strcasecmp' : 'strcmp';
  return $compare_function($arg, _me_get_me_alias()) === 0;
}

/**
 * Implements hook_menu().
 */
function me_menu() {
  $items = array();
  $items['admin/config/people/me'] = array(
    'title' => "'Me' Aliases",
    'description' => "Configure the 'me' aliases, and how they're matched.",
    'page callback' => 'drupal_get_form',
    'page arguments' => array(
      'me_admin_settings_form',
    ),
    'access arguments' => array(
      'administer site configuration',
    ),
    'type' => MENU_NORMAL_ITEM,
  );
  return $items;
}

/**
 * Implements hook_permission().
 */
function me_permission() {
  return array(
    'use PHP for me alias paths' => array(
      'title' => t('use PHP for me alias paths'),
      'description' => t('use PHP for me alias paths'),
    ),
  );
}

/**
 * Form callback for the admin settings form.
 */
function me_admin_settings_form($form, &$form_state) {
  $form = array();
  $form['me_alias'] = array(
    '#type' => 'textfield',
    '#title' => t("'Me' Alias"),
    '#description' => t('The alias to use to represent the current users uid.'),
    '#default_value' => me_variable_get('me_alias'),
    '#required' => TRUE,
  );
  $form['me_token_help'] = array(
    '#title' => t('Replacement patterns for me alias'),
    '#type' => 'fieldset',
    '#collapsible' => TRUE,
    '#collapsed' => TRUE,
    'help' => array(
      '#type' => 'markup',
      '#markup' => theme('token_tree'),
    ),
  );
  $form['me_case_insensitive'] = array(
    '#type' => 'checkbox',
    '#title' => t('Case Insensitive Alias Checking'),
    '#description' => t('When checked, "Me" will be matched the same as "me", "ME", and "mE".'),
    '#default_value' => me_variable_get('me_case_insensitive'),
  );
  $form['me_rewrite_link'] = array(
    '#type' => 'checkbox',
    '#title' => t('Rewrite links generated by the drupal menu system'),
    '#description' => t('When checked, links output by the drupal menu system will replace uid with the me alias.'),
    '#default_value' => me_variable_get('me_rewrite_link'),
  );
  $form['me_user_override'] = array(
    '#type' => 'checkbox',
    '#title' => t('Allow users to turn off me for their account'),
    '#default_value' => me_variable_get('me_user_override'),
  );
  $form['me_redirect'] = array(
    '#type' => 'checkbox',
    '#title' => t('Redirect to uid'),
    '#description' => t('When checked, perform a redirect so the users uid is shown in the address bar instead of the me alias.'),
    '#default_value' => me_variable_get('me_redirect'),
  );
  $form['me_redirect_anonymous'] = array(
    '#type' => 'textfield',
    '#title' => t('Redirect anonymous users'),
    '#description' => t('When this is non-empty, anonymous users will be redirected to the specified drupal path.'),
    '#default_value' => me_variable_get('me_redirect_anonymous'),
  );
  $access = user_access('use PHP for me alias paths');
  $path_rule = me_variable_get('me_path_rule');
  $paths = me_variable_get('me_paths');
  if ($path_rule == ME_PATH_PHP && !$access) {
    $form['me_paths_settings'] = array();
    $form['me_paths_settings']['me_path_rule'] = array(
      '#type' => 'value',
      '#value' => $path_rule,
    );
    $form['me_paths_settings']['me_paths'] = array(
      '#type' => 'value',
      '#value' => $paths,
    );
  }
  else {
    $options = array(
      ME_PATH_EXCLUDE => t('Use me alias on every path except the listed paths.'),
      ME_PATH_INCLUDE => t('Use me alias only on the listed paths.'),
    );
    $description = t("Enter one path per line as Drupal paths. The '*' character is a wildcard. Example paths are %blog for the blog page and %blog-wildcard for every personal blog. %front is the front page.", array(
      '%blog' => 'blog',
      '%blog-wildcard' => 'blog/*',
      '%front' => '<front>',
    ));
    if ($access) {
      $options[ME_PATH_PHP] = t('Use me alias if the following PHP code returns <code>TRUE</code> (PHP-mode, experts only).');
      $description .= ' ' . t('If the PHP-mode is chosen, enter PHP code between %php. Note that executing incorrect PHP-code can break your Drupal site.', array(
        '%php' => '<?php ?>',
      ));
    }
    $form['me_paths_settings']['me_path_rule'] = array(
      '#type' => 'radios',
      '#title' => t('Use me alias on specific paths'),
      '#options' => $options,
      '#default_value' => $path_rule,
    );
    $form['me_paths_settings']['me_paths'] = array(
      '#type' => 'textarea',
      '#title' => t('Paths'),
      '#default_value' => $paths,
      '#description' => $description . t('<p>NOTE: This option simply ensures that the browser address bar for these paths have the uid and not me. The me alias will still work for these paths. It will have no effect on specific uids in paths, but if the path includes the me alias, then me will be affected for those paths. This will only affect paths that me can already handle. It will not allow me to work for unknown paths.</p>'),
    );
  }
  $form['#validate'] = array(
    'me_admin_settings_form_validate',
  );
  $form = system_settings_form($form);

  // Quite a few options only have an affect on theme and menu rebuilds. We just do them here
  // to make sure the options have an instant effect.
  $form['#submit'][] = 'menu_rebuild';
  $form['#submit'][] = 'drupal_theme_rebuild';
  return $form;
}

/**
 * Validation callback for me_admin_settings_form.
 */
function me_admin_settings_form_validate($form, &$form_state) {

  // If the token module is installed, we need to also allow a list of tokens
  // that are allowed to match against. We include all global tokens here, even though
  // some of them don't really make sense, but that is up to the end user.
  $token_list = array();

  //$token_list = array_map(create_function('$n', 'return "[$n]";'), array_keys(array_pop(token_info())));
  $tk_types = token_get_global_token_types();
  $options = array(
    'flat' => TRUE,
    'restricted' => FALSE,
    'depth' => 4,
  );
  foreach ($tk_types as $type) {
    $tree = token_build_tree($type, $options);
    $token_list = array_merge($token_list, array_keys($tree));
  }
  if (preg_match('/[^a-zA-Z\\:]/', $form_state['values']['me_alias']) && !in_array($form_state['values']['me_alias'], $token_list)) {
    if (!empty($token_list)) {
      $message = t('The alias can only contain characters from a-z and A-Z, or one of the tokens specified in the "Replacement patterns for me alias" section.');
    }
    else {
      $message = t('The alias can only contain characters from a-z and A-Z.');
    }
    form_set_error('me_alias', $message);
  }
}

/**
 * Implements hook_user_categories().
 */
function me_user_categories() {
  if (me_variable_get('me_user_override')) {
    return array(
      array(
        'name' => 'me',
        'title' => t("'@me' alias", array(
          '@me' => _me_get_me_alias(TRUE),
        )),
        'weight' => 2,
      ),
    );
  }
}

/**
 * Implements hook_user_view().
 */
function me_user_view($account, $view_mode) {
  if (me_variable_get('me_user_override')) {
    $enabled = 'enabled';
    if (!empty($account->me_disable)) {
      $enabled = 'disabled';
    }
    $account->content['me'] = array(
      '#type' => 'markup',
      '#value' => t("'%me' aliases are {$enabled} for this account. Account user id is '@uid'.", array(
        '%me' => _me_get_me_alias(TRUE),
        '@uid' => $account->uid,
      )),
      '#weight' => 10,
    );
  }
}

/**
 * Implements hook_ctools_plugin_directory().
 */
function me_ctools_plugin_directory($module, $plugin) {
  if ($module == 'ctools') {
    return 'plugins/' . $plugin;
  }
}

/**
 * Implements hook_views_api().
 */
function me_views_api() {
  return array(
    'api' => 3,
    'path' => drupal_get_path('module', 'me') . '/includes/views',
  );
}

Functions

Namesort descending Description
me_admin_settings_form Form callback for the admin settings form.
me_admin_settings_form_validate Validation callback for me_admin_settings_form.
me_category_load Menu load callback in place of user_category_load().
me_category_to_arg Menu to_arg function for %me_category.
me_ctools_plugin_directory Implements hook_ctools_plugin_directory().
me_handler A special menu callback function that either redirects to a page with the uid in the path, or calls the real menu handler.
me_help Implements hook_help().
me_load Menu load callback in place of user_load().
me_menu Implements hook_menu().
me_menu_alter Implements hook_menu_alter().
me_permission Implements hook_permission().
me_preprocess_menu_link Implementaiton of moduleName_preprocess_hook() for theme_menu_link.
me_theme_registry_alter Implements hook_theme_registry_alter().
me_to_arg Menu to_arg function for %me.
me_uid_optional_load Menu load callback in place of user_uid_optional_load().
me_uid_optional_to_arg Menu to_arg function for %me_uid_optional.
me_user_categories Implements hook_user_categories().
me_user_view Implements hook_user_view().
me_variable_get Helper function to keep all the variable gets in one place.
me_views_api Implements hook_views_api().
_me_check_arg A Helper function to check for the 'me' alias.
_me_check_path Helper function to check if a path can be rewritten or not.
_me_get_me_alias Helper function to return the me alias.
_me_handle_path Helper function to check if me should handle a given path.
_me_is_alias A helper function to check if a string is equal to the 'me' alias.
_me_load_arguments Helper function to set up arguments in meun _load callbacks.
_me_user_disabled Helper function to check if a user can have, and has me disabled.

Constants