New plugin - help needed with users list and permission

Hi.
I’m developing a new plugin, and I would need to retrieve a list of all registered users who have the permission to edit every submitted item/collection (their own and the one submitted by others).
I think the best way would be to retrieve the list of all users, loop through it and check if they had the correct (“Edit”?) permission, and in that case act. Of course, if it was possible to retrieve just the list of all users who have the correct permission, that would speed up things.
As I’m not at all familiar with ZEND ACL, is there anybody who could help me with a code snippet?
Thanks.

Anybody could help here? Thanks

It’s a little clunky, but the most straightforward approach is just to go to the list of users, sort by role, and anyone who is an Admin or Super has those permissions.

More complicated checks for each user in the loop you describe would use the is_allowed() function on the loop you describe. That would get at the more granular access for other roles it sounds like you are looking for.

Thanks, patrickmj. They both seem like good approaches, although I’d personally go for the second, as there could be some other roles with editing permission.
But how could I loop through the list of users? I am not familiar with the syntax of ZEND ACL.

I’ve been trying to use the following code, but with no results:

foreach( $users as $key => $user ):
	if (is_allowed($user, 'edit')):
		//do something
	endif;
endforeach;

Ah. I’m afraid I spoke too quickly, and ended up missing a detail. is_allowed() checks the permissions of the current user, so it doesn’t quite work the way I’d thought. But, it won’t be too much different from what it does. Sorry for the confusion.

First, you need to get the acl object:

$acl = get_acl();

Then, in your loop you can check the permissions using pretty much the same thing that is_allowed() does:

    $allowed = $acl->isAllowed($user, $resource, $privilege);

The $resource is most generally the controller at work. I’m guessing in your case it will be Items. $privilege is the action (show, edit, etc.).

However, when working with Items, some users get more fine-grained access. So, the owner of an Item can edit it, while some others cannot. If you need to check that level of access, make $resource the Item object you want to check about.

Got it, Patrick, thanks.

Now, the new problem: when using a simple code, like f.i.

$acl = get_acl();
foreach( $users as $key => $user ):
	if ($acl->isAllowed($user, 'Items', 'edit')):
		echo html_escape($user->name) . "|";
	endif;
endforeach;

the result is null: it seems like $users is empty. Still, the same variable is used in ADMIN / THEMES / DEFAULT / USERS / BROWSE, where it helps with the listing of all users.

What is it that I’m doing wrong, here? Why $users is empty, instead of containing all my users?

Thanks.

That probably depends on where in the MVC system you are putting this code. It sounds like, since it is a plugin, you are creating your own page, distinct from the admin/users/browse page?

The core code passes along a list of users via the controller (application/controllers/UsersController.php, which pretty much uses application/libraries/Omeka/Controller/AbstractActionController.php for the browse action).

So, if you are putting together a new page with your own controller and view, you’d need to dig up the list of users in your controller, then pass that data along to the view to use the way you anticipate.

If this code is going somewhere else, like using a plugin hook on the users/browse page, it’s a little more mysterious.

The big diagnostic question is therefore what kind of page you are putting together in your plugin. Is it a custom page with its own controller and view, or something that is adding on to a core page via a hook?

My plugin aims to send a notification whenever a new Item or Collection is added; so far, it works fine with messages sent to a given e-mail, and before publishing it I would like to add the option to send a notification to all users with generic ‘edit’ priviledges (so this takes care of the fine granularity you were talking about).

It’s a simple plugin, with a config_form page and a main plugin page, that uses a hook on after_save_record. So, I am not using any special controller, I think it’s more the second case you’re suggesting.

I could surely create a function that loops through the records of the right table, but if I could use something that already exists… well, I’m not particularly interested in reinventing the wheel, if you know what I mean.

Hope this helps, otherwise I could publish the code as it is and you make take a look at it. Let me know, and thanks for your help and precious time.

Thanks. That clarifies a lot. From the hook (more about the hook below), you’d have to dig up all the User records from there. It’d be something along the lines of

$users = get_db()->getTable('Users')->findAll();

So, probably not too bad to get all the users to loop through.

For the permissions check, I want to make sure that you need the more general after_save_record hook, or the more particular after_save_item hook. The former happens when any record is saved (Item, Collection, SimplePage, etc), while the latter only happens for Items. Thus, if you need to check permissions for any save, you’ll want to pass in the record for the ACL check. If you only want to check Items, you can switch to that hook and just pass Items to the check. It sounded like you were only checking Items, and so the more general check would work. But if you are checking everything it’ll need that more granular process.

Hi.
After fighting with the code for a couple of days, I’ve found out that I was supposed to use the singular for the table name:

$users = get_db()->getTable(‘Users’)->findAll();

would never work, while

$users = get_db()->getTable(‘User’)->findAll();

I am not sure why it so, any explanation? In the db, the table is correctly called Users.

Anyway, now the function works correctly, but I cannot tell the users who can edit just their Items from those who can edit all Items. I suppose the problem is the wrong choice of privilege, so which one should it be instead of

$acl->isAllowed($user, ‘Items’, ‘edit’)

?

Thanks.

The table names within the code are usually singular: they’re actually based on the name of the Record class for what’s stored in the table, in this case the User class.

As for the permission, you want editAll to see who can edit all items vs. just their own. You can also use the generic edit privilege in combination with a specific item if you want to know if the given user can edit the given item.

Hello, John.

Thanks for the explanation. The table names rule doesn’t really make too much sense for me (I would expect getTable be fed with the name of the table, and not with the name of a class), but at least it works.

What still doesn’t work is the permission: I’ve tried using editAll but I still see only my Super User user, while I would expect to see the Editor user I’ve created with More User Roles plugin. That user can edit every single item in the repository, but doesn’t show up when I’m using editAll. Any hint?

Thanks.

Hmm… I think that has to do with the specific way More User Roles set up those users… the core roles/rules use the editAll privilege to determine this, but it looks like More User Roles just does things a little differently…

What might work is this: check against an actual (but fake) Item:

$acl->isAllowed($user, new Item, 'edit');

That made the trick, John. Thanks a lot to you and Patrick; now I’m testing the plugin, then I will publish it acknowledging your contribution :slight_smile:

By the way, if anybody is interested in the final code, it is

$acl = get_acl();
$users = get_db()->getTable('User')->findAll();
foreach ($users as $key => $user):
	if ($acl->isAllowed($user, new Item, 'edit')):
		// your action, like f.i.
		// echo $user->name;
	endif;
endforeach;

This topic was automatically closed after 250 days. New replies are no longer allowed.