0

I have a type downloadable_item which has a field field_roles_allowed that is based on the Role Field Module.

My goal is to have a field_download of file type that will show the file for download if the user in a role selected in the field_roles_allowed and a message that they need to request access otherwise.

I am attempting to add a formatter for the file field type using the Custom Formatters Module. I found this tutorial on how to use the Custom Formatters module, however, they use the "HTML + Tokens" option. I will need to use the PHP option to be able to output either the download button or a message depending on whether the user is in a role in the field_roles_allowed.

I cannot figure out how to get the roles that are allowed, download file information, and current user's roles for comparison.

My question is really "How do I do these things that I cannot figure out?", but if someone believes I am going about this totally in the wrong way... I am open to another way.


EDIT: I solved my own problem below, but not really in a preferable way. How could this be done without writing PHP logic in field?

3
  • I have a question. Do you have views and panels installed? If so you can do this in a round-about way using Panels and Views. I did this on a site I run where we sell digital downloads. The download links are only showed to users that have the appropriate role (that gets added in the checkout process).
    – Brady
    Commented Jan 31, 2015 at 10:11
  • Could you post your solution after "EDIT" section?
    – milkovsky
    Commented Feb 1, 2015 at 9:16
  • @milkovsky, I posted as an answer
    – Smern
    Commented Feb 1, 2015 at 16:05

2 Answers 2

1
+100

As always with Drupal. There are often many solutions to your problem. Here are two ways of doing this.

Views and Panels The power of views and panels can be leveraged to do this.

First step would be to build a view containing various panes built for the different displays you want per security role. You would want to use panes because they are only accessible to Panels and cannot be used by anything else on your Drupal website, this will be important for step two. In your case you would have a pane that did not show the download link then a pane that shows the download link. This can be done in one view with multiple panes.

Second step build a panel page. Panels has a unique capability of variations of a page "Called Variants in the Panel UI". The variants can be assigned selection rules to each variant. Here is where the security layer comes in and why you want to build your views as panel panes and not just view pages. Panes ensures that only Panels can access your views you have created with your protected content. The first variation will use a selection rule of User:role with the role you want to use to allow access to the protected content. The second variation will use no selection rules as this will be what the user sees if they do not have the role. Panel variations and selection rules work in the first one satisfied in the order of the variations. The first variation with the user selection rule will be shown before the last variation if the user does not have the role Panels goes to the next variation till it can find one that can be satisfied - if one exists. This has many other applications but I have used this feature to serve protected content to users based on their roles.

Themeing layer

Another way to approach this is to use Drupal's themeing layer. If you are using core node displays to show your content to the user this works very well. Using Drupal's node templates you can overide the display of the nodes containing the protected fields and use some simple PHP statements to hide or show the field with the download link. Example core pieces of the code in the template would be:

global $user;

foreach ($this_user->roles as $rid => $role) {
  switch ($role) {
    case 'has access':
      print render($content['field_download_link'])
      break;

  }
}
14
  • Thanks for the response. I've only started using Drupal about 2 weeks ago. In my case, I have a ContentType/View called downloadable_item with the download button. I have a ContentType/View on top of that called downloadable_group which uses the ViewsFieldView module and contextual filter to house multiple downloadable_item. The downloadable_group view pane is then placed on a page and uses contextual filters as well and may contain multiple downloadable_groups. I don't know if this changes anything or not and I will look into how these solutions will work in my project on Monday.
    – Smern
    Commented Jan 31, 2015 at 15:32
  • The reason I posted the above is that I am concerned about whether or the way I have things set up will conflict with the solutions. Also, in the first solution you mention "a selection rule of User:role with the role you want to use to allow access to the protected content", I am not at my workstation so I cannot look now, but I am not sure where or how I would create a rule that has the ability to look into the User's role and all of the fields contained in the UserRole field and compare the two. The UserRole field will have multiple roles that will be allowed.
    – Smern
    Commented Jan 31, 2015 at 15:42
  • Do you have a live dev site?
    – Brady
    Commented Feb 1, 2015 at 14:08
  • This is an internal company thing which I cannot share. Did you need any additional information from me?
    – Smern
    Commented Feb 1, 2015 at 16:04
  • I am just confused when you say ContentType/View. A View is a very specific thing in Drupal, it involves the Views module. So you build Views of your ContentTypes? Correct?
    – Brady
    Commented Feb 1, 2015 at 16:39
1

After some digging... I found that I am able to get field information like...

$variables["#object"]->field_roles_allowed["und"]; //array containing id's of roles allowed
$variables["#object"]->field_download["und"]; //array containing information about the file

and that I can get the current user's roles like...

global $user;
$user->roles; //array containing current user's roles

Then I can compare the field roles allowed with the current user's roles and determine what to output from there.

Still not very happy with this, I would prefer something where I don't have to write PHP logic in a field.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.