how to update WordPress role capability value - database

How do I update WordPress user role capability value through the database? i want to add custom capability like as post_limit, then update those post limit value
Below is a screenshot showing the wp_user_roles options;
wp_user_roles => value (i want to update this unserialized value)
Note: i want to update existing capability value not add_role or remove_role

You can create new roles using the command add_role.
add_role( 'custom_role', 'Custom Subscriber', array( 'read' => true, 'level_0' => true ) );
To modify an existing role you would need to remove it first and then add it back in.
remove_role( 'custom_role' );
add_role( 'custom_role', 'Custom Subscriber', array( 'read' => true, 'level_0' => true ) );
Be aware that modifying the capabilities array and re-executing add_role() will not necessarily update the role with the new capabilities list. The add_role() function short-circuits if the role already exists in the database.

Related

Auto Increment number on SuiteCRM Accounts

I tried several answers from suitecrm forum And here. And I can't implement them to the present version of Suite CRM.
Here is the one I tried last and stuck for further clarification.
add a new file in custom/Extension/modules/yourmodule/Ext/Vardefs e.g. autoincrement.php with the following :
<?php
$dictionary['YOUR_MODULE']['fields']['NAME_OF_AUTO_INC_FIELD'] = array(
'name' => 'NAME_OF_AUTO_INC_FIELD',
'vname' => 'LBL_LABEL_OF_AUTO_INC_FIELD',
'type' => 'int',
'readonly' => true,
'len' => 11,
'auto_increment' => true,
'disable_num_format' => true,
);
?>
and also add unique index for the field in that file
<?php
$dictionary['YOUR_MODULE']['indices']['NAME_FOR_INDEX'] = array(
'name' => 'NAME_FOR_INDEX',
'type' => 'unique',
'fields' => array('NAME_OF_AUTO_INC_FIELD'),
);
?>
Run a Quick Rebuild and Repair in Admin -> Repair and execute the changes.
after that it shows an empty text box. There it iterates automatically, when new account saved. But I want to show the next auto increment number here in this Accounts page itself.
Instead of default value, I want to show the next auto value in the new Account form.
This isn't out the box behaviour - you'll need to add some customisations to do this.
I would create a new vardef auto_inc_preview which is a function type field. This can then be used to grab the largest number from the DB and display this + 1.
A possible issue with this would be that the number a user sees may not be the id that gets generated - for example if two or more people create an account at the same time.

How to insert into database Drupal Custom Fields

I retrieve content types with the following code
$form['ct'] = array(
'#type' => 'checkboxes',
'#options' => node_type_get_names(),
'#title' => t('Hangi tür içerikler hakkında bilgi almak istersiniz?'),
);
And It gives the following output
http://i.stack.imgur.com/TOfS6.png
And when I press Create new Account button, the POST Array is so :
http://i.stack.imgur.com/BtxhC.png
My Question is How can I insert into database these values and read?
There are two ways of saving this data and associates with user ID ($user->uid).
Adding a new field for users from 'admin/config/people/accounts/fields'. Say the new field name is 'ct' and it is a list type field. In hook form_alter you can assign this options to 'ct'. Drupal will take care of saving the data.
You can create separate table to keep this information and use db_insert function in hook hook_user_update. To retrieve this information you need to use db_query in hook_user_load.

Simplified and manageable ACL implementation in cakephp

I went through complete lesson on cakephp's ACL component, but gigantic ACL component do not seem to meet my very simple requirements.
I have only group based access control, three groups are users, managers and administrators the fourth is a anonymous users without logins for which I am not creating any group.
from acl concept it creates three table
aros -> this looks somewhat redundant data copied from groups table, I dont even need to have a group table but just field group_id in users table.
acos -> this is a list of public methods in controllers, I had to use AclExtra plugin to populate over 250+ actions in table, now this is the part which I think un-manageable, I noticed that tool used to populate acos table cannot reliably sync everytime when I do changes in controllers, the same work must be done at remote site for each changes that means terrible thing! this also mean i have to have a database backup during updates and migration.
Other side if I use php file based acos that is again un-manageable because we have to make sure syncing between controller and acl file.
aros_acos -> obviously
can we have a simpler mechanism something like i deny all actions using Auth component and then inside each action or maybe in beforeRender method i can specify what methods are open to what group ?
Thanks
There is an undocumented acl class PhpAcl it is much simpler to use than then the database driven ACL and more dynamic than the ini bassed ACL.
In Config/core.php
/**
* The class name and database used in CakePHP's
* access control lists.
*/
Configure::write('Acl.classname', 'PhpAcl');
// Configure::write('Acl.database', 'default');
This tells your ACL to use the PhpAcl
Then open up Config/acl.php
There are some good instructions there
Assumptions:
In your application you created a User model with the following properties: username, group_id, password, email, firstname,
lastname and so on.
You configured AuthComponent to authorize actions via $this->Auth->authorize = array('Actions' => array('actionPath' =>
'controllers/'),...)
Now, when a user (i.e. jeff) authenticates successfully and requests a
controller action (i.e. /invoices/delete) that is not allowed by
default (e.g. via $this->Auth->allow('edit') in the Invoices
controller) then AuthComponent will ask the configured ACL interface
if access is granted. Under the assumptions 1. and 2. this will be
done via a call to Acl->check() with
array('User' => array('username' => 'jeff', 'group_id' => 4, ...))
as ARO and
'/controllers/invoices/delete'
as ACO.
I wanted to use static names for Groups or Roles so you can add a role field to your user table, and then set up the $map like this:
**
* The role map defines how to resolve the user record from your application
* to the roles you defined in the roles configuration.
*/
$config['map'] = array(
'User' => 'User/username',
'Role' => 'User/role',
);
For my app we aren't using user based permissions only role, so we could remove the User from the $map.
Then you need to set up some roles:
/**
* role configuration
*/
$config['roles'] = array(
'Role/admin' => null,
);
Any role not in this array will get 'Role/default'
Now just set up your permissions, they are pretty self explanatory.
/**
* rule configuration
*/
$config['rules'] = array(
'allow' => array(
'*' => 'Role/admin',
'controllers/Reports/*' => 'Role/default',
'controllers/EurRates/*' => 'Role/default',
'controllers/Posts/index' => 'Role/default',
'controllers/Users/(edit|index)' => 'Role/default',
),
'deny' => array(
'controllers/ProtectedController/*' => 'Role/default',
'controllers/EurRates/(edit|add|delete)' => 'Role/default',
'controllers/Reports/(edit|add|delete)' => 'Role/default',
),
);
That's it, now you can allow or deny permission to actions based on role.

CakePHP : Check authorizations in views

I am using CakePHP in my project and I am looking for a proper way to check advanced user rights in my views.
I have several pages in which the contents depend of your rights (you can view some blocks or not, edit some infos or not, etc...)
I searched and the only way I found is to implement an Auth Helper, but I thought the best way to to that is to implement methods in my "UserController" (such as canPerformAction($action, $controller = 'default_controller')), am I wrong ? And if I'm right, how to call that methods properly ?
Thanks.
EDIT : More precisions
For example I have an action "editEventProducts" that a user can perform only if he's the event owner and if the event status is <= 2.
I check that in my controller "isAuthorized" function, works like a charm.
But I have a page called "eventDetails", form which you can perfom several actions such as this one, and I want to show the edit button, only if you can do it.
If fact what I need is the output of the "isAuthorized" function for each action that you can call, but can I properly get it from a view ?
Solution
I implemented a Auth helper who does several check such as this one, which is finally a whitelist check, depending of the status of my event, hope it will help, the code :
App::uses('AppHelper', 'View/Helper');
class AuthHelper extends AppHelper {
var $helpers = array('Session');
private $_whitelist = array(
'controller1' => array(
'events' => array(
'action1' => array(1 => true, 2 => true),
'action2' => array(1 => true, 2 => true),
'action3' => array(3 => true),
'action4' => array(6 => true)
)
),
'user' => array(
'controller1' => array(
'action1' => array(1 => true, 2 => true),
'action2' => array(1 => true, 2 => true)
)
)
);
public function canPerformAction ($action, $event_infos, $controller = 'events') {
return isset($this->_whitelist[$this->Session->read('Auth.User.role')][$controller][$action][$event_infos['Event']['state_id']]);
}
}
It sounds to me like you just want to render some parts of a view based on the permissions of the user. Well, in this case I think a helper is the right choice. The user should already have all the permissions he has loaded - except they're very fine grained and you got thousands of permissions.
Check this AuthHelper, it allows you to check if the user is logged in, for a role or a set of roles in a field. Alternatively implement your own solution to match whatever your permission system is.
Note that the helper relies on passing the user data to the view in a view variable. It can be also configured to read the data from the auth part of the session directly.
Here is the example taken from it's documentation:
if ($this->Auth->isLoggedIn()) {
echo __('Hello %s!', $this->Auth->user('username'));
}
if ($this->Auth->isMe($record['Record']['user_id']) {
// or your edit button here
echo '<h2>' . __('Your records') . '</h2>';
}
if ($this->Auth->hasRole('admin') {
echo $this->Html->link(__('delete'), array('action' => 'delete'));
}
What you need is called authorization, and is the process of granting/denying actions usually built on top of an authentication step, which maps HTTP requests to logical users.
The authorization scheme can be implemented in a number of ways, for example with simple role-based rules, where users are grouped exactly for the purpose of assigning rights, or with more complex ACL (access control lists). Both can be adopted at the same time for different parts of the system, depending on your needs.
Whatever scheme you pick, you absolutely need to query it at the beginning of your controllers actions (if applicable, you may and up with a standardized authorization filter in your AppController), because the HTTP request doesn't need to come from a previously sent HTTP page, but could be a (possibly) malicious, hand-craften one. Also, you'll likely need to adjust the UI after the user rights. Maybe you'll better start with a bunch of if statements, and then after some days of work you'll be able to identify your needs and build your libraries/helpers/blocks/whatever to avoid code duplication and easing reading the templates.
If you have predefined user permissions (like 'admin', 'moderator', 'editor', 'publisher'...) you can just read the user role and current action in the controller function isAuthorized and set it to true or false.
If you want custom permissions per user, you can store those values in the database, read them in the isAuthorized function and make your logic to determine if you should allow him or not.
My solution to this was a separate table user_permissions that was something like this:
user_id | action
where action would be `controller/action' or 'view/block' or whatever you want to save there.
I would read all values for current user in the controller and if the current controller/action was found in the array, i'd set isAuthorized to true. You can apply your logic to the blocks also.
You can call function of controller from view using
requestAction(string $url, array $options)
Or you can create your custom Helper which will do this for you!

Creating muliple users in a loop from array

How does one go about creating multiple new users, say in a loop, from an array in a different controller?
I have an issue where attempting to create multiple users in a form submit fails, but creating a single new user works as designed. It appears the issue may be when saving the new user and then bringing the new user_id back in the return statement. Although the new id comes back, subsequent users (2nd, 3rd, etc) all get the same id value, and it appears that the subsequent $this->save calls modify the first created user rather than create add'l ones. Any none of the new users appear in the database. (again, the problem only happens when more than one new users will be created.)
My one small clue is that if I var_dump($user) in my importPublicLDAPUser() function (user.php) just after the $user = $this->save(array('User' => array( ... ))); then for the first element I see both 'modified' and 'created', whereas I see only 'modified' for the rest. This leads me to believe there's a step missing, like the user needs to be saved or commit (??) before the next user can be be created.
I tried changing this to $user = $this->User->save(array('group_id' => 3, ... and adding a 'create' before: $this->User->create(); but these produce errors 'Call to a member function save() on a non-object' and 'Call to a member function create() on a non-object'.
My application manages documents. Each document can have many authors, so it has controllers for: docs, doc-types, users, groups, and authors.
When a new document is entered, the form allows selection of multiple users to create 'Author' records. In addition to the local users table, it also searches our LDAP server (both via auto-sugggest) and also allows input into a text field. So, Authors are selected from
the existing table of users
via the LDAP helper
free text entry.
This result is two arrays: $Authors (from local users tables), and $badAuthors (LDAP and text-input) which the app then tries to add to the local users table when the form is submitted.
The form works just fine if:
one or more authors are added from local users table;
a single author is added from LDAP (succeeds in creating a new entry in users table), and zero or more local users
a single author is added from text input (also succeeds), and zero or more local users
However if two or more non-local users are added ($badAuthors has more than one element) then the form fails. "fails" means that either the Author or User save routine failed, and so it skips the Document commit $this->Docu->commit(); and I spit out an error via ajaxResponse. Thus, the app works as designed, but only with one new User entry at a time, even though the form is designed to allow Authors/badAuthors to be >1.
What I don't understand is why when I loop through bad authors why it doesn't correctly add the users if $badAuthors has more than one element.
As the user enters each name (which is checked against the users table and LDAP via ajax helpers, etc) and then selected, an author_name_list array is built. And then:
foreach($this->params['form']['author_name_list'] as $author_name){
$user_id = $this->Docu->User->field('id',array('User.name' => $author_name));
if($user_id){
$Authors['Author'][]=array(
'docu_id'=>$this->Docu->id
,'user_id'=>$user_id
);
}else{
$badAuthors[] = array('name'=>$author_name);
}
}
So $badAuthors is now those found in LDAP or entered manually.
So now I try to create/save all badAuthors...
docu controller (docu_controller.php):
if(count($badAuthors)){
foreach($badAuthors as $key => $author){
$this->Memo->User->create(); // ** <-- this was missing!! **
if($ldap_author = $this->Docu->User->importPublicLDAPUser($author['name'])){
unset($badAuthors[$key]);
$Authors['Author'] []= array(
'docu_id'=>$this->Docu->id
,'user_id'=>$ldap_author['User']['id']
,'precedence' => $author['precedence']
);
} elseif ($new_author = $this->Docu->User->newReadonlyUser($author['name'])) {
unset($badAuthors[$key]);
$Authors['Author'] []= array(
'docu_id'=>$this->Docu->id
,'user_id'=>$new_author['User']['id']
,'precedence' => $author['precedence']
);
}
}
}
if(!count($badAuthors)){
$authors_saved = true;
foreach($Authors['Author'] as $author_arr){
$this->Docu->Author->create();
if(!$this->Docu->Author->save(array('Author' => $author_arr))){
$authors_saved = false;
break;
}
}
}
user model (user.php)
function afterSave($created) {
if (!$created) {
$parent = $this->parentNode();
$parent = $this->node($parent);
$node = $this->node();
$aro = $node[0];
$aro['Aro']['parent_id'] = $parent[0]['Aro']['id'];
$this->Aro->save($aro);
}
}
function importPublicLDAPUser($cn){
App::import('Vendor','adLDAP',array('file'=>'adLDAP.php'));
$oLDAP = new adLDAP(Configure::read('LDAP_options.email'));
$oLDAP->authenticate(NULL, NULL);
$filter = '(&(cn='.$oLDAP->ldap_escape($cn).'))';
$ldap_res = #$oLDAP->search($filter, array('cn', 'uid','profitcenter'),1);
if(isset($ldap_res['count']) && ($ldap_res['count'] > 0)){//found it
$user = $this->save(array('User' => array(
'group_id' => 3,
'name' => $ldap_res[0]['cn'][0],
'username' => $ldap_res[0]['uid'][0],
'grpnum' => pc2grpnum($ldap_res[0]['profitcenter'][0])
)));
if($user){
$user['User']['id'] = $this->id;
}
return ($user ? $user : false);
}else{
return false;
}
}
Any suggestions? Thanks!!
It turns out that in my docu_controller.php I was missing a create() call. It seems that without a create, an object can still be saved/created when the other controller does a commit(). So before adding the create(), prior to the commit, in later loop iterations I was still modifying the original object, not any new ones. By adding a create in the controller, the save in the method function acts on the new user for each loop iteration.
in controller:
if(count($badAuthors)){
foreach($badAuthors as $key => $author){
$this->Memo->User->create();
if($ldap_author = $this->Memo->User->importPublicLDAPUser($author['name'])){
in method:
function importPublicLDAPUser($cn){
....
$user = $this->save(array('User' => array(...

Resources