In the latest 7.x version of my Take Control module for Drupal released a couple of weeks before, I added the ability to specify per role and per user base path for File Browser access. Additionally Tokens were allowed to be present in base path for file browser for additional flexibility.

Available Token tree in DrupalSo I was looking for a way to have Drupal like UI where available tokens are shown in a tree and clicking a particular token inserts it into the last active textbox on the page (as you can see in the screenshot).

I thought the best place to look out for this would be an existing module that displays such a tree in its UI. So I opened up the admin settings file for popular PathAuto module for Drupal and the way to do it was right in front of me:

 

 

    $form[$module]['token_help']['help'] = array(
      '#theme' => 'token_tree',
      '#token_types' => array($settings->token_type),
    );

 

A simple call to the well-known theme function with the hook being token_info and the token_types to be shown was all that was required to generate this tree. The next step was to find out the token_types available out of the box in Drupal.

A search through Drupal’s codebase along with some of the more common and popular modules that use the Token API threw up node, user, current-user etc. as the available types of tokens.

Out of these, the one which was needed by the Take Control module was only current-user. The following code produces the Token tree in Admin UI of Take Control module listing some global tokens (that are automatically available unless you switch them off by using ‘global_types’ => NULL) and the tokens available for the current user:

 

 

  $form['take_control_fb_roles_fieldset']['token_tree'] = array(
    '#type' => 'fieldset',
    '#title' => t('Replacement patterns'),
    '#collapsible' => TRUE,
    '#collapsed' => TRUE,
    '#description' => theme('token_tree', array('token_types' => array('current-user'))),
    '#weight' => 10,
  );

 

Pretty simple, right. Please note that the hook token_tree for the theme method is made available by the Token module (although the core Token Api itself has moved to D7). So you would need to have the Token module installed for this code fragment to work.

The last step was to replace the tokens in an appropriate way in code. The token_replace method does the job and needs to be passed appropriate variables based on allowed token_types. Here’s the _take_control_get_user_root_accessible_dir method from Take Control module demonstrating how it replaces patterns in the user’s base path for file browser access:

 

{syntaxhighlighter brush: php;fontsize: 100; first-line: 1; }function _take_control_get_user_root_accessible_dir () {
global $user;
$id = ‘take_control_fb_user_path’ . $user->uid;

$rootPath = variable_get($id, ”);

if(empty($rootPath)) {
//user_roles returns roles ordered on weight, so highest weighted role with a custom base path specified automatically gets highest precedence below.
foreach(_take_control_fb_get_allowed_roles() as $rid => $name) {
if (take_control_user_has_role($name)) {
$id = ‘take_control_fb_role_path’ . $rid;
$basePath = variable_get($id, ”);

if(!empty($basePath)) {
$rootPath = $basePath;
}
}
}

if(!empty($rootPath)) {
//Replace tokens in role path.
$rootPath = token_replace($rootPath, array(‘current-user’ => $user));
}
}

$appDir = take_control_app_dir();
//User ID 1 always has access to entire file-system.
if (!empty($rootPath) && $user->uid != 1) {
if(substr($appDir, strlen($appDir) -1) != DIRECTORY_SEPARATOR) {
$appDir = $appDir . DIRECTORY_SEPARATOR;
}

$appDir = $appDir . str_replace(‘/’, DIRECTORY_SEPARATOR, $rootPath);
}

return ($appDir);
}{/syntaxhighlighter}

The entire magic happens in this single line:
$rootPath = token_replace($rootPath, array(‘current-user’ => $user));

The rest of the code is specific to Take Control module for finding the correct path to make available to the user.

Please note that you would need to pass an associative array with as many keys as the allowed token_types and appropriate values for the keys. Drupal for example won’t automatically replace node token type tokens with values from current node. You would need to pass the node object explicitly.