Forum OpenACS Q&A: Groups API in 4.x
API on 4.x? I'v read through "Groups, Context, Permissions" document,
but it only describes the system.
I am working on a 4.x application (Oracle for now, will be ported to
PG) that will make use of the groups system, but I am having trouble
understanding how it all works, and how to work with it.
Pointers are highly appreciated.
I did however get some insights on how groups, relational segments, and relational constraints operate by playing around with the test code for acs-kernel. Look in openacs-4/packages/acs-kernel/sql/postgresq/test. The rel-constraints.sql file is especially instructive, once you get the hang of how things are supposed to work.
The main problem with figuring out the groups usage, is that terms like object_id_one, object_id_two and relational side one and relational side two are not very descriptive or intuitive.
I've been in this same fruitless search for documentation on ACS 4.x in general, and it can be very frustrating. And I agree with you that some of the terms are not intuitive.
Especifically, it was hard for me to visualize how the whole system worked together. parties, groups, membership, composition, relationship, etc. Anybody else has comments on this?
In the acs 4.x groups system, the relation to a group is represented by the party object regardless of whether the relation is between a group and a person or a group and another group. The implication of this is that a person or another group can be a member in a group.
As far as relationships, composition or membership relations determine whether memberships are transitive. If you have a membership relation with group A and group A has a composition relation with group B, then you are also considered to be a member of B. Group A is like a sub-grouping of group B in this case.
On the other hand, if you have a memberhip relation with group A, and group A has a membership relation with group B, you are not then considered a member of B. composition relations are transitive while membership relations are not.
Regarding composition and membership, I understood how they work, but what I haven't figured out yet (haven't looked hard enough) is how do I tell this:
Say a user is a member of group A, which is the "parent group" of B. How do I tell that he should have access to what group B owns (since A is a parent of B)?
This seems to be accomplished with the group_approved_member_map view, but I don't know which arguments I should put in the WHERE clause to get the answer to my question.
It sounds like you're saying that the user has a membership relation with A, and B has a composition relation with A. Is that correct? In such case, B is like a sub-grouping of A, and it doesn't necessarily make sense to think of A as being the parent of B. A party that has special privleges over a group, should probably be represnted as a sub-component of a larger group.
Perhaps, I'm missing what you're after.
So I should say:
user X --- membership --> group A
group B -- composition --> group B
So in my world, user X would be able to access things "owned" by group B. But how do I find out that the user can do it?
user X --- membership --> group A group B -- composition --> group A
If so then you could use the group_element_map view to find what you're looking for:
select count(*) from group_element_map m1, group_element_map m2 where m1.group_id = m2.group_id and m1.element_id = :group_b_id and m2.element_id = :user_x_id;
The preceeding query will tell you if they belong to a common group either by compostion or by membership. If you need to ensure that they belong to a specific common group, then you could change it to use the following:
select count(*) from group_element_map m1, group_element_map m2 where m1.group_id = m2.group_id and m1.group_id = :group_a_id and m1.element_id = :group_b_id and m2.element_id = :user_x_id;
But yes, you knocked it out! That's what I was looking for. Thanks.
I don't see group_element_map in the "Parties in ACS 4" doc. It should be there.
select count(*) from group_component_map c, group_member_map m where c.group_id = m.group_id and c.component_id = :group_b_id and m.member_id = :user_x_id;
For example, from PL/SQL, the correct way to create a new ACS user is
acs.add_user() - NOT with
acs_user.new APPEARS to
work, but does not quite do all the right things.) But the only way
to realize this it to read the Tcl code.
For adding a user to a group, on the other hand, this:
v_rel_id := membership_rel.new( object_id_one => v_group_id ,object_id_two => v_person_id );
does the right thing, as you might expect. But it sounds like you already figured all that out, despite the cryptic nature of object "one" vs. "two".
I have studied both the docs and the code, and I think I understand the basic concepts behind the groups and relational segments models--but I'm still having a heck of a time trying to use the ACS 4 UI to accomplish even a simple task.
I would be tremendously grateful if someone could explain how the simple "real-world" example of classes, students, and instructors would be handled. That is, students as members of a specific group which represents an instance of a class group-type and instructors who are members of an instructor group but who are "assigned to" but not members of a given class/group.
I can handle the group/membership part but the "assigned to" part eludes me.
Since I have been swimming in this lately (to get it to work for a project I am doing), I wanted to see if I understood the problem.
To my dismay, it seems I cannot accomplish this with the GUI!@#$% My best approach was to try to make a Relationship Type for the assigned-to relation. The problem I had was that the GUI would only allow a relationship type which is a sub-type of Composition or Membership. I wanted to make a type that inherits from the supertype of these relations (I think this is group-type=group). The out-of-the-box UI only allows it the other way.
So I ended up with a sub-type of Membership as the assigned-to relation. I was able to make an instance (segment?) of it by creating some members. I have the impression that since this segment is in no way specialized when compared to Membership, that there is no value to this (sub-)type.
I have not done it yet, but I would guess that two possible approaches are (both not possible from the UI):
- add a contraint to this new segment (maybe this is the type) to make this different from Membership.
- create a new relationship type for the assigned-to relation and create the specific attributes you need at that time.
I have just figured out how to do the simple example of a making a subsite/group containing a sub-group of admins. This is also pathetically designed in terms of the current screens. I now know how to modify the current screens, code, and default settings to make this no harder than it needs to be.
My intent is to post the results of that work to this board.
Any improvements to the UI will be welcome, that's for sure ... you might want to start a thread in the 4.x design forum describing exactly what you intend to provide. That way others can chime in with whatever additions or changes might be needed based on their experience.
Even if you don't have time to accomodate other people's ideas, having the discussion up-front might be useful.