Assume a (contributed) D7 module, say module ABC, comes with only a few permissions (which can be set on the typical /admin/people/permissions page). For example:

  • Administer module ABC.
  • Access (view) "all results" produced by module ABC.

Whereas "all results" can be found within a site via a combination of URLs (with corresponding menu items also) like:

  • ABC/SomethingX (X=1, 2, ...).
  • ABC/SomethingElseY (Y=1, 2, ...).
  • node/*/ABC.

Which site building techniques can be used (without hacking the module), to grant access to such URLs as in this example:

  • Access to ABC/SomethingX is allowed for anybody.
  • ABC/SomethingElseY is only allowed for authenticated users.
  • node/*/ABC is only allowed for authenticated users.
  • For any URL that is only allowed for authenticated users, its corresponding menu item should be visible to anonymous also. This to show such users that such menu item is available, but with some type of Drupal message to inform them that login is required to actually use such link.

Real world situations (use cases):

  • The question about "content access + menu block => not shown all links in menu block": by using the Content Access module access to selected nodes is restricted (of course). But how can menu items corresponding to such selected nodes remain visible for anonymous users anyway?
  • The Visitors module: replace 'ABC' by 'visitors' in the example above, and assume that you want to grant access to "some" reports (= ABC/SomethingX) for anybody, but not to "some other" reports (= ABC/SomethingElseY).

    If permission Access (view) "all results" produced by module ABC would be set to "authenticated", then anonymous users cannot see any URL. While if that permission would be set to "anybody" (= either "anonymous" or "authenticated"), then anonymous users also have access to (eg) ABC/SomethingElseY (which is not what is desired).

How can menu items corresponding to ABC/SomethingElseY remain visible for anonymous users anyway?

up vote 0 down vote accepted

Rules (the module) is your friend ... Here is the rule (in Rules export format), that does exactly what this question is about (using the Visitors module as an example, like the ABC in the question):

{ "rules_limit_access_to_some_urls_related_to_visitors_" : {
    "LABEL" : "Limit access to some URLs containing \u0027visitors\u0027",
    "PLUGIN" : "reaction rule",
    "OWNER" : "rules",
    "REQUIRES" : [ "rules" ],
    "ON" : { "init" : [] },
    "IF" : [
      { "user_has_role" : {
          "account" : [ "site:current-user" ],
          "roles" : { "value" : { "1" : "1" } }
        }
      },
      { "OR" : [
          { "data_is" : {
              "data" : [ "site:current-page:path" ],
              "op" : "IN",
              "value" : { "value" : [
                  "visitors\/hosts",
                  "visitors\/hits",
                  "visitors\/referers",
                  "visitors\/user_activity",
                  "visitors\/pages"
                ]
              }
            }
          },
          { "text_matches" : {
              "text" : [ "site:current-page:url" ],
              "match" : "node\/\\d+\/visitors",
              "operation" : "regex"
            }
          }
        ]
      }
    ],
    "DO" : [
      { "redirect" : { "url" : "visitors" } },
      { "drupal_message" : {
          "message" : "Access to the content located at \u0022\u003Cstrong\u003E[site:current-page:path]\u003C\/strong\u003E\u0022 is not allowed.\r\n\u003Cbr \/\u003E\r\nAnonymous users can only see its corresponding menu item (login required).",
          "type" : "warning"
        }
      }
    ]
  }
}

After you enable the above rule, you can safely grant Access (view) "all results" produced by module ABC permission to anybody. That will make the menu items visible to anonymous users also (of course). The above rule will ensure that anonymous users will NOT be able to actually "view" the specified URLs. Instead they'll get a message starting with "Access to the report located at ...".

To make the above rule work in similar situations, just adapt the URLs (change 'visitors' to whatever fits), and the message to be shown for those who are not allowed to access those URLs.

Possible variations: instead of using the above rule for anonymous versus authenticated users, it can also be used for any combination of 2 roles. eg: "authenticated" versus "editors" (or whatever other role), in which case you'd grant the permission to "authenticated" (and use the role id for authenticated users).

Remarks:

  • This won't prevent the path from being omitted from menus. But that is exactly what is desired (as mentioned in the last phrase of the question).

  • What is above does not relate to any "other places" where path checks happen that aren't direct page access. But whenever one attempts to use those paths in those "other places" to actually visit such paths (URLs), the above rule will catch those situations also (provided such URL is correctly mentioned in either of the Rules Conditions in my sample above).

Your Answer

 
discard

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

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