Drupal: Dynamic IMCE Profiles

  • David Pacassi Torrico

Today I will describe a way to handle multiple teams with their own private file folders using the IMCE module.

Let's pretend that we have to develop a website called awesome-website.com which consists of three (or more) different teams. The team structure could look as followed:

Website Groups

Every team should only be allowed to edit their own pages but no page from any other team. Therefore it would also make sense to separate the team's file folders so that the files can be stored separately to secure its privacy.

Of course, we could simply add three IMCE profiles and define their folder access rights individually there. But what about when working with 10 teams? Or 50? Or even more? Then we definitely would prefer a more flexible solution.

Thankfully, IMCE ships with the ability to define user folders by PHP execution, how awesome! But in order to achieve this, we'll have to set up teams as taxonomy terms first and reference them from our user entities.

Setting up the “Teams” taxonomy vocabulary

First things first: Let's create a new taxonomy vocabulary called “ Teams”. For every team that we will have on our website, we have to create a new taxonomy term in this vocabulary.

Before adding any teams as taxonomy terms though, we'll have to add a new field called “FTP Folder” to the taxonomy vocabulary.

This field will specify the name of every team's root folder. So, naturally it shouldn't contain any spaces or other wicked special characters and it should be URL readable.

In order not to face any unusual results later, it is recommended to configure this field as required.

Afterwards, we can add our three terms, “Team Alpha”, “Team Beta” and “Team Gamma”.

As value for their FTP Folders, we use “team-alpha”, “team-beta” and so on.

That's it for the taxonomy part! Now let's link this information to the team's users.

Adding a taxonomy term reference field to the user entity

In my case, I didn't have multiple roles for the teams. I only had one , called “Team member”. Because every team has exactly the same rights as the others, maintaining only one role suited me best.

For really special cases, I could always just create a new role with the special permissions.

So, how do we link users to their teams the easiest? Exactly, by just adding a taxonomy term reference field to the user entity!

Let's call this field “Team” and reference our previously created taxonomy vocabulary “Teams” with it.

Now, when adding a new user, we can select it's team belonging and IMCE will be able to grab the needed information from there.

Yes, IMCE will be able to do that but it's not doing it yet.

Getting the teams ftp folder for the current user is still something we have to code, so let's proceed to the next step.

Writing a custom function to provide the accessible directories for an user

Now we need to provide IMCE the information that we've set up before.

We've created users belonging to teams, which hold the FTP root folder name for the teams.

What's left to do, is to write a function (ideally in a custom module, in my example the module is called _“awesometeams”), that combines all information and returns it to IMCE.

Following function would do that for us:

function awesome_teams_imce($user) {
  $user_folders = array('cms/teams/all');
  $user_wrapper = entity_metadata_wrapper('user', $user);
  $user_teams = $user_wrapper->field_team->value();

  foreach ($user_teams as $user_team) {
    $user_team_wrapper = entity_metadata_wrapper('taxonomy_term', $user_team);

    array_push($user_folders, 'cms/teams/' . $user_team_wrapper->field_ftp_folder->value());
  }

  return $user_folders;
}

The function expects an user object as argument and will return an array of strings containing all the folder names an user is allowed to access.

Our folder structure would look like this:

  • sites/default/files/cms
  • sites/default/files/cms/teams
  • sites/default/files/cms/teams/all
  • sites/default/files/cms/teams/team-alpha
  • sites/default/files/cms/teams/team-beta
  • sites/default/files/cms/teams/team-gamma

Note: The folder “cms/teams/all” is a special folder and every user is allowed to access it.

It will be used to save files which are used globally over multiple or even all teams.

What our code does, is actually looping over all assigned teams for the given user (yes, an user can be in multiple teams!), and adding the teams ftp folder names to the array of accessible folders.

There is no _“hookimce” hook, the _“imce” in the function name does nothing till now . You can also name your function differently. The link from IMCE to our function is something we have to set up in an IMCE profile.

Let's proceed to the last step then, shall we?

Creating the IMCE profile “Team member”

Now, as the last step, let's create an IMCE profile called “Team member”. You're free to define any settings as you like, there's only one thing that will be special about this profile: The accessible directories path.

Instead of writing something constant as “cms/teams/team-alpha”, we'll write _“php: return awesome_teamsimce($user);” here.

So, the setting should look like this:

imce-profile-settings

Now save the profile and you are done !

As soon as one team member now accesses the IMCE page (either via /imce or by the configured file/image fields), he will only see his team's directories and the special directory “all” which is meant for exchange.

This wasn't that difficult, was it?

I hope I was able to give you an insight on how to solve more complicated file permission issues with IMCE.

Don't forget to give feedback, ask questions and follow our blog if you want to read more about our Drupal experiences at Liip!


Tell us what you think