[HOWTO] Add new permission & have it assigned to role via sc

Discussion forum for MOD Writers regarding MOD Development.
Locked
User avatar
poyntesm
Registered User
Posts: 1671
Joined: Tue Jan 18, 2005 11:19 am
Location: Dublin, Ireland
Contact:

[HOWTO] Add new permission & have it assigned to role via sc

Post by poyntesm » Thu May 24, 2007 1:05 pm

So you want your MOD to add permissions and you want to have the roles updated with that permission so no manual work on install for you users???

Providing you have a script doing the DB work then this is how I do it. Note this just handles the DB work and you need to have a permissions_yourpermission.php file in the language/en/acp/ directory as well.

Code: Select all

function get_role_by_name($name)
{
	global $db;

	$data = null;

	$sql = "SELECT *
		FROM " . ACL_ROLES_TABLE . "
		WHERE role_name = '$name'";
	$result = $db->sql_query($sql);
	$data = $db->sql_fetchrow($result);
	$db->sql_freeresult($result);

	return $data;
}

/**
* Set role-specific ACL options without deleting enter existing options. If option already set it will NOT be updated.
* 
* @param int $role_id role id to update (a role_id has to be specified)
* @param mixed $auth_options auth_options to grant (a auth_option has to be specified)
* @param ACL_YES|ACL_NO|ACL_NEVER $auth_setting defines the mode acl_options are getting set with
 *
*/
function acl_update_role($role_id, $auth_options, $auth_setting = ACL_YES)
{
	global $db, $cache, $auth;

	$acl_options_ids = get_acl_option_ids($auth_options);

	$role_options = array();
	$sql = "SELECT auth_option_id
		FROM " . ACL_ROLES_DATA_TABLE . "
		WHERE role_id = " . (int) $role_id . "
		GROUP BY auth_option_id";
	$result = $db->sql_query($sql);
	while ($row = $db->sql_fetchrow($result))
	{
		$role_options[] = $row;
	}
	$db->sql_freeresult($result);

	$sql_ary = array();
	for ($i = 0, $count = sizeof($acl_options_ids);$i < $count; $i++)
	{
		if (in_array($acl_options_ids[$i]['auth_option_id'], $role_options))
		{
			continue;
		}
		$sql_ary[] = array(
			'role_id'		=> (int) $role_id,
			'auth_option_id'	=> (int) $acl_options_ids[$i]['auth_option_id'],
			'auth_setting'		=> $auth_setting, 
		);
	}

	$db->sql_multi_insert(ACL_ROLES_DATA_TABLE, $sql_ary);

	$cache->destroy('acl_options');
	$auth->acl_clear_prefetch();
}

/**
* Get ACL option ids
*
* @param mixed $auth_options auth_options to grant (a auth_option has to be specified)
*/
function get_acl_option_ids($auth_options)
{
	global $db;

	$data = array();
	$sql = "SELECT auth_option_id
		FROM " . ACL_OPTIONS_TABLE . "
		WHERE " . $db->sql_in_set('auth_option', $auth_options) . "
		GROUP BY auth_option_id";
	$result = $db->sql_query($sql);
	while ($row = $db->sql_fetchrow($result))
	{
		$data[] = $row;
	}
	$db->sql_freeresult($result);

	return $data;
}

//Setup $auth_admin class so we can add permission options
include($phpbb_root_path . '/includes/acp/auth.' . $phpEx);
$auth_admin = new auth_admin();

//Lets Add The Required New Permissions
$permissions = array(
	'local'		=> array(),
	'global'	=> array(
		'a_your_role',
));
$auth_admin->acl_add_option($permissions);

$role = get_role_by_name('ROLE_ADMIN_STANDARD');
if ($role)
{
	acl_update_role($role['role_id'], array('a_your_role'));
}
The updating of the role allows you do deliver you MOD with predefined permissions and not have the admin misconfigure something. It allows you deliver a known state.

User avatar
Jhong
Registered User
Posts: 538
Joined: Thu Aug 10, 2006 6:53 pm
Location: In a theme sandwich
Contact:

Re: [HOWTO] Add new permission & have it assigned to role via sc

Post by Jhong » Fri May 25, 2007 4:45 am

Thank you -- this is extremely helpful. It would be nice if such functions were rolled into phpBB3 to make our lives easier.
phpBB<->WordPress Integration: www.wp-united.com

User avatar
poyntesm
Registered User
Posts: 1671
Joined: Tue Jan 18, 2005 11:19 am
Location: Dublin, Ireland
Contact:

Re: [HOWTO] Add new permission & have it assigned to role via sc

Post by poyntesm » Fri Jun 08, 2007 1:56 pm

Small update.. if you want to do it on a user level I have a new function. Again this example shows the adding of the new role to the DB and the granting it to the user in this case ANONYMOUS

Code: Select all

/**
* Set user specific ACL options without deleting enter existing options. If option already set it will NOT be updated.
* 
* @param int $user_id user id to update (a user_id has to be specified)
* @param mixed $auth_options auth_options to grant (a auth_option has to be specified)
* @param ACL_YES|ACL_NO|ACL_NEVER $auth_setting defines the mode acl_options are getting set with
 *
*/
function acl_update_user($user_id, $auth_options, $auth_setting = ACL_YES)
{
	global $db, $cache, $auth;

	$acl_options_ids = get_acl_option_ids($auth_options);

	$role_options = array();
	$sql = "SELECT auth_option_id
		FROM " . ACL_USERS_TABLE . "
		WHERE user_id = " . (int) $user_id . "
		GROUP BY auth_option_id";
	$result = $db->sql_query($sql);
	while ($row = $db->sql_fetchrow($result))
	{
		$user_options[] = $row;
	}
	$db->sql_freeresult($result);

	$sql_ary = array();
	for ($i = 0, $count = sizeof($acl_options_ids);$i < $count; $i++)
	{
		if (in_array($acl_options_ids[$i]['auth_option_id'], $user_options))
		{
			continue;
		}
		$sql_ary[] = array(
			'user_id'		=> (int) $user_id,
			'auth_option_id'	=> (int) $acl_options_ids[$i]['auth_option_id'],
			'auth_setting'		=> $auth_setting, 
		);
	}

	$db->sql_multi_insert(ACL_USERS_TABLE, $sql_ary);

	$cache->destroy('acl_options');
	$auth->acl_clear_prefetch();
}

/**
* Get ACL option ids
*
* @param mixed $auth_options auth_options to grant (a auth_option has to be specified)
*/
function get_acl_option_ids($auth_options)
{
   global $db;

   $data = array();
   $sql = "SELECT auth_option_id
      FROM " . ACL_OPTIONS_TABLE . "
      WHERE " . $db->sql_in_set('auth_option', $auth_options) . "
      GROUP BY auth_option_id";
   $result = $db->sql_query($sql);
   while ($row = $db->sql_fetchrow($result))
   {
      $data[] = $row;
   }
   $db->sql_freeresult($result);

   return $data;
}

//Setup $auth_admin class so we can add permission options
include($phpbb_root_path . '/includes/acp/auth.' . $phpEx);
$auth_admin = new auth_admin();

//Lets Add The Required New Permissions
$permissions = array(
   'local'      => array(),
   'global'   => array(
      'a_your_role',
));
$auth_admin->acl_add_option($permissions);

acl_update_user(ANONYMOUS, array('a_your_role'));

}

User avatar
Jhong
Registered User
Posts: 538
Joined: Thu Aug 10, 2006 6:53 pm
Location: In a theme sandwich
Contact:

Re: [HOWTO] Add new permission & have it assigned to role via sc

Post by Jhong » Mon Jun 11, 2007 4:34 pm

I'm using the first bit of code in an install script.

I noticed that the SQL fails complaining about a duplicate entry if the permission has already been applied.

Since I can't guarantee that the permission hasn't already been applied, but want my install script to create a known baseline configuration, I added in a check to see if the permission already exists.

[

Code: Select all

]
Last edited by Jhong on Tue Jun 12, 2007 2:23 am, edited 1 time in total.
phpBB<->WordPress Integration: www.wp-united.com

User avatar
poyntesm
Registered User
Posts: 1671
Joined: Tue Jan 18, 2005 11:19 am
Location: Dublin, Ireland
Contact:

Re: [HOWTO] Add new permission & have it assigned to role via sc

Post by poyntesm » Mon Jun 11, 2007 4:42 pm

Thanks for the feedback, although the function should already check that. It pulls the roles current options_id sets them to $role_options & then checks if the option you are adding is already there.

Code: Select all

      if (in_array($acl_options_ids[$i]['auth_option_id'], $role_options))
      {
         continue;
      }
I will have a look and see why it might not be working.

User avatar
Jhong
Registered User
Posts: 538
Joined: Thu Aug 10, 2006 6:53 pm
Location: In a theme sandwich
Contact:

Re: [HOWTO] Add new permission & have it assigned to role via sc

Post by Jhong » Mon Jun 11, 2007 11:52 pm

That's what I thought... it was late and so sql seemed like a more attractive option than debugging code at that time :-)

The problem is in_array -- $role_options is a multidimensional array, and the values it's looking for are in the bottom-most dimension. Searching for $acl_options_ids[$i] instead of $acl_options_ids[$i]['auth_option_id'] works.

I rewrote it to use a foreach loop, as that's what this is, plus it's lighter and more intuitive without the superfluous $i and $count...

This works as you designed...

Code: Select all

function acl_update_role($role_id, $auth_options, $auth_setting = ACL_YES)
{
   global $db, $cache, $auth;

	$acl_options_ids = get_acl_option_ids($auth_options);

	$role_options = array();
	$sql = "SELECT auth_option_id
		FROM " . ACL_ROLES_DATA_TABLE . "
		WHERE role_id = " . (int) $role_id . "
		GROUP BY auth_option_id";
	$result = $db->sql_query($sql);
	while ($row = $db->sql_fetchrow($result))
	{
		$role_options[] = $row;
	}
	$db->sql_freeresult($result);

	$sql_ary = array();
	foreach($acl_options_ids as $option)
	{
		if (!in_array($option, $role_options))
		{
			$sql_ary[] = array(
				'role_id'      		=> (int) $role_id,
				'auth_option_id'	=> (int) $option['auth_option_id'],
				'auth_setting'      => $auth_setting
			);	
		}
	}

   $db->sql_multi_insert(ACL_ROLES_DATA_TABLE, $sql_ary);

   $cache->destroy('acl_options');
   $auth->acl_clear_prefetch();
}

Blitze
Registered User
Posts: 390
Joined: Tue Nov 29, 2005 5:06 pm

Re: [HOWTO] Add new permission & have it assigned to role via sc

Post by Blitze » Sun Jun 17, 2007 9:33 pm

Excellent set of functions.

Is it possible to do the reverse ie if you remove the mod can you strip it's permissions from users and roles as well?

Thanks ;)
My Extensions: phpBB SiteMaker

User avatar
poyntesm
Registered User
Posts: 1671
Joined: Tue Jan 18, 2005 11:19 am
Location: Dublin, Ireland
Contact:

Re: [HOWTO] Add new permission & have it assigned to role via sc

Post by poyntesm » Mon Jun 18, 2007 7:05 am

I am sure I can rustle something up :D

Locked

Return to “[3.0.x] MOD Writers Discussion”