Not for 'how-to' coding questions but PHP theory instead, this forum is here for those of us who wish to learn about design aspects of programming with PHP.
in your first scenario, the if is ending at CAN_POST, so that makes sense.
if you're going to use if / else if blocks like that, you just need to make sure you order them correctly (highest to lowest).
I'm trying to think of a scenario when that would be necessary and drawing blanks.
Also the user's permission level would not be added up like that (I know you probably did it for the sake of demonstration, but it would already be predetermined). He'll need to have some kind of translation table (not even necessarily in a db) that identifies what role each user level means.
a more practical example would be something like this:
// find out if this is a moderator and if the edit post button should be displayed:
if($_SESSION['user_level'] & CAN_EDIT)
echo "<input type=\"button\" value=\"Edit Post\" onClick=\"eatBacon()\">";
you could certainly do that though I'd create a public property for the user's level or instantiate it with the object so you don't have to pass it as an argument every time.
I don't know guys... binary is cool and everything, and it stores in a huge INT in your database, but just try selecting users who can mail their underwear to japan from a database... Makes more sense to have a permissions table...
Also, binary permissions are just that: binary. Yes or No. You can't have options or values or anything.
If you don't like arrays, why not objects?
If you created user objects, you could support default permissions easily, and you could also have permission "functions"... by using the magic __get and __set methods:
class user {
var $_conditions = array();
function __construct($user_id){
// get conditions and permissions from the database based on userid, group memberships, assigned roles, etc
// we'll inject what a few might look like here
$_conditions['can_mail_underwear_to_japan'] = "date('l')!='Tuesday'"; // can't mail underwear to japan on a Tuesday
var $can_eat_noodles_sideways = TRUE;
var $post_limit = '5';
}
function __get($perm){
// return conditional permission if there is one
if(in_array($perm,$_conditions)) return eval($_conditions[$perm]);
// return object var if there is one
$obj_vars = get_object_vars($this);
if(in_array($attr,array_keys($obj_vars))) return $obj_vars[$attr];
}
}
$frank = new user('42');
// so if it's Tuesday
echo $frank['can_mail_underwear_to_japan']; // FALSE
echo $frank['can_eat_noodles_sideways']; // TRUE
echo $frank['post_limit']; // 5
// but on Wednesday
echo $frank['can_mail_underwear_to_japan']; // TRUE
echo $frank['can_eat_noodles_sideways']; // TRUE
if($frank['post_limit']>$posts){ /* YES */ }
Last edited by Kieran Huggins on Wed Jan 03, 2007 5:22 pm, edited 1 time in total.
I would create usergroups, and give those groups default permissions for each section. Each user could belong to one or more groups, their permissions being the merged set of those along with their personal permissions.
Sally is in marketing, so she would have marketing's permissions merged with her own (if she has any special permissions).
Bob is in IT and Finance, so he has the combined permissions for those departments. (+ his own, if any)
First, I don't think you can get around having to be specific about each permission, such as Section HR_Add, HR_Edit and Finance_Add, Finance_Edit. If you want the granularity of control then you need the specificity.
I use a system somewhere between the bitmask and Kieran's yes/no schemes -- probably just because I am lazy. I don't like having to make sure that the defines have always been included/updated, so I just use the string constants. So array('Section HR_Add', 'HR_Edit', 'Finance_Add') allows those permissions. And I don't use the yes/no states ... if a values is in the array it is yes, if not it is no. They can be merged, intersected and unioned as needed with the array functions. It is slower than the bit check because it uses array functions, but I can have any number of values without monkeying around with bit fields. They are easy to store in db tables either in separate records or together (I usually pipe delimit and explode()).