Drupal7: Token Content Access

David G - DrupalPreviously I’ve written about an application I have running for a client that accepts References for student applications to enroll in a University program. Students have up to 3 external references (people) fill out an online form on their behalf, and based upon the students GPA and reference recommendations they may be allowed into the school program.

I have written about this project with regards to Webforms and Relations, and also about using Field Collections. Recently the client has asked me to add new features to this project and I’m considering revising some of the underlying custom code. This is because I make tokens to access content by hand, and I recently found the Token Content Access (TCA) module which given a new submodule should support my existing use-case!

The existing legacy entity relationships in the system are:

UML overview diagram of the student reference submissions web application.

UML overview diagram of the student reference submissions web application.

As you can see 1 piece of this system is that a Relation of Reference <-> Webform needs to have an access token defined. Creating a simple access token is really really easy using php by simply using something like the php md5 function and simply taking the first 10 characters of the generated value. But, care must be taken to assure all keys are unique (or create your own ticket-system). And what do you know !?! … I’ve written about assuring my token access keys are unique previously in this post called Drupal7: Views Duplicate Content Audit Page.

But ultimately I wrote alot of custom code to create a custom token, and attempt to assure the value is unique … annnd attempt to assure the content accessed (in my case a Webform) is respecting the token access value and examining whether or not a submission has previously been recorded for this item.

In short, I hope to leverage the Token Content Access module to work with I guess Relations in a similar fashion to how the token content access node module works. This module is really new but was originally concieved from Acquia (so hey, that’s Great). From the module page:

Token Content Access allows you to restrict access to individual nodes using URL tokens. In order to view protected nodes, users must provide a unique token via the URL. This allows nodes to be published and viewable to anonymous users (for instance with a special link from an email campaign) but not visible to the public at large. It also automatically hides any TCA-protected content from Views results.

This module is designed with performance in mind, so it doesn’t use traditional solutions like node grants. This also means that it’s not guaranteed to block access in all situations, for instance if you expose node content via means other than Views.

So the core TCA module defines a Field that can be attached Bundles, and it supplies a default Node submodule that enables tokens on Nodes and enforces viewing the nodes requires a valid token. The bulk of the implementation of the is in 2 files of the tca_node module file and the tca_node javascript file.

These 2 files act as the example files, functions and code I would need to implement to make this access token work with a Relation.

For example if I wanted to output a vertical tab on a relation edit page to show if a token has been generated for this relation instance I would mimic this code:

(function($) {
  'use strict';

  Drupal.behaviors.tcaNode = {
    attach: function (context, settings) {

      // Set the summary for the settings form.
      $('fieldset.tca-settings-form').drupalSetSummary(function() {
        var $tcaActive = $('.tca-active-setting input:checked');

        // Get the label of the selected action.
        var summary = $('label[for=' + $tcaActive.attr('id') + ']').text();
        return Drupal.checkPlain(summary);



Then as an example, one can see that a token is created for a Node when the node is saved because the tca_node module implements hook_node_insert:

 * Implements hook_node_insert().
function tca_node_node_insert($node) {
  if ((tca_get_active_entity('node', $node))) {
    $node->tca_token = tca_get_token('node', $node, $value = '');
    db_update('node')->fields(array('tca_token' => $node->tca_token))->condition('nid', $node->nid)->execute();

    if (user_access('administer tca_node')) {
      $token_url = url('node/' . $node->nid, array('absolute' => TRUE, 'query' => array('tca' => $node->tca_token)));
      drupal_set_message(t('URL to bypass Token Access Control for this item: @token', array('@token' => $token_url)));


By following this example it should be possible to extend this module to work with the relation module and tracking if something has been submitted or not. Thus reducing the amount of custom code written in the application (and offloading the logic to contributed modules, woo!).

Mind you my integration may still require some Rules for business logic, but really I think an integration of this module with the Relation module should be useful and straightforward for many projects!

Looking for quality web hosting? Look no further than Arvixe Web Hosting!

Tags: , , | Posted under Drupal | RSS 2.0

Author Spotlight

David Gurba

I am a web programmer currently employed at UCSB. I have been developing web applications professionally for 8+ years now. For the last 5 years I’ve been actively developing websites primarily in PHP using Drupal. I have experience using LAMP and developing data driven websites for clients in aviation, higher education and e-commerce. If you’d like to contact me I can be reached at david.gurba@arvixe.com

Leave a Reply

Your email address will not be published. Required fields are marked *