For a site that I'm implementing I need to be able to give the administrators the right to add a menu item to a specific menu, but only for the 'Page' content type. When they add a 'Story' this should not be visible. This to make it clear the difference between Pages and Stories. Which in this site a Page is content with a link in a menu which should stay available over time and a Story is temporary content that becomes less interesting.

Now, I can do this by implementing a module that adds a specific permission for this and removes the unauthorized Menus from the drop-down but I was wondering if this is (partially) achievable by configuration?

I think it's not possible without programming because in "Access Control" you only have "menu module > administer menu" and enabling this shows the Menu fieldset for all content types, not only the ones I want.

Comments

techczech’s picture

I think you're right - this is not possible right out of the box but it would make a great module.

______________________
Dominik Lukes
http://www.dominiklukes.net
http://www.hermeneuticheretic.net
http://www.czechupdate.com
http://www.techwillow.com

Jax’s picture

First you enable "administer menu" for a role and with the following module you can remove the menu for specific content-types. If you rename mymodule make sure it's called something that comes after "menu" alphabetically or else the unset will do nothing.


function mymodule_perm() {
  foreach (node_get_types() as $type) {
    if ($type->module == 'node') {
      $name = check_plain($type->type);
      $perms[] = "hide menu fieldset on $name";
    }
  }
  return $perms;
}

function mymodule_form_alter($form_id, &$form) {
	global $user;
	$type = $form['type']['#value'];
	if($user->uid != 1 && user_access("hide menu fieldset on $type")) {
		unset($form['menu']);
	}
}

Any other/better suggestions?

Jax’s picture

The solution I proposed is actually not a good one. Ideally the check use_access("administer menu") should return true or false when I want it. Now I just remove the data from the form after the fact.

My approach doesn't work when you want to enable to "anonymous users" to be able to post to the content-type Forum but not on Story. On Story for example only authenticated users can comment. Can one achieve this?

Jax’s picture

With the runkit extension (pecl install "channel://pecl.php.net/runkit-0.9") one can override functions in PHP. With the following approach you can redefine most permissions. The following code enables everyone to post comments on stories but nowhere else:

function mymodule_nodeapi(&$node, $op, $a3 = NULL, $a4 = NULL) {
	if($op == 'load') {
		if($node->type == 'story') {
			runkit_function_rename('user_access', 'user_access_core');
			$func = '
				if(strpos($a, "post comments") !== FALSE) return true;			
				return user_access_core($a, $b);
			';
			runkit_function_add('user_access', '$a, $b = NULL', $func);
		}
	}
}

Of course this can be improved by defining permissions with hook_perm, this is just a POC. Anyone knows a better method for implementing a finer grained access control?