I've got a quite large website with over 20 roles and permissions. However, it are always the same permissions, but depending on who created the content, the permissions differ...
So what I do now is this:
// Make the new role
$role = new stdClass;
$role->name = 'Redacteur 1';
$role->weight = 3;
user_role_save($role);
// Permissions to assign to the role.
// Note these are defined in hook_permission()
$perms = array(
'access content','access content overview'
);
// Grant the permissions. This function takes care of all necessary cache resets
user_role_grant_permissions($role->rid, $perms);
// Make the new role
$role = new stdClass;
$role->name = 'Redacteur 2';
$role->weight = 3;
user_role_save($role);
// Permissions to assign to the role.
// Note these are defined in hook_permission()
$perms = array(
'access content','access content overview'
);
// Grant the permissions. This function takes care of all necessary cache resets
user_role_grant_permissions($role->rid, $perms);
Isn't there a way to do this with some kind of array so I don't end up with a 1000 line of code. When you want to change something in the permissions, you have to revise all the roles... This must be easier to do. Any advice?
You could change the fields in the database. I wish I could help you more but I have only done minor adjustments.
I wrote some default function to acomplish this goal:
function _load_permission_settings($role_index = null) {
// Blocks
$perms['administer blocks'] = array(0, 0, 0);
// Comments
$perms['administer comments'] = array(0, 1, 0);
$perms['access comments'] = array(1, 1, 1);
$perms['post comments'] = array(1, 1, 1);
$perms['skip comment approval'] = array(1, 1, 1);
$perms['edit own comments'] = array(1, 1, 1);
...
function _create_users() {
require_once DRUPAL_ROOT . '/' . variable_get('password_inc', 'includes/password.inc');
$roles = user_roles(true);
$users[] = array('an', array(3));
$users[] = array('ben', array(4, 6, 8));
...
function _set_roles_and_permissions() {
// Enable default permissions for system roles.
user_role_grant_permissions(DRUPAL_ANONYMOUS_RID, array('access content'));
user_role_grant_permissions(DRUPAL_AUTHENTICATED_RID, _load_permission_settings(0));
// Permissions to assign to the roles. (all Thema-related roles share the same permissions)
$perms_eind = _load_permission_settings(1);
$perms_red = _load_permission_settings(2);
$user_roles = _load_thema_user_role_names('');
foreach ($user_roles as $name) {
// Role1
$role = new stdClass;
$role->name = 'Role 1 - ' . $name;
user_role_save($role);
user_role_grant_permissions($role->rid, $perms_eind);
// Role2
$role = new stdClass;
$role->name = 'Role 2 - ' . $name;
user_role_save($role);
user_role_grant_permissions($role->rid, $perms_red);
}
}
Related
I'm copying the list of modules from another page in DNN. While doing this I have to set the view permission for all users to view the modules. Even the other page(copying from) module setting is different. Below is the example where I set other properties.
ModuleInfo newModule = new ModuleInfo();
0newModule.ModuleDefID = module.ModuleDefID;
newModule.AllTabs = false;
newModule.PortalID = PortalId;
newModule.ContentItemId = module.ContentItemId;
newModule.ModuleTitle = module.ModuleTitle;
newModule.PaneName = module.PaneName;
newModule.TabID = NewTabInfo.TabID;
newModule.ContainerSrc = module.ContainerSrc;
newModule.ModuleOrder = module.ModuleOrder;
newModule.DisplayPrint = module.DisplayPrint;
newModule.DisplayTitle = module.DisplayTitle;
newModule.IsShareable = module.IsShareable;
newModule.IsShareableViewOnly = module.IsShareableViewOnly;
newModule.ModulePermissions=module.ModulePermissions;
newModule.IsWebSlice = module.IsWebSlice;
newModule.WebSliceTitle = module.WebSliceTitle;
newModule.Footer = module.Footer;
newModule.Header = module.Header;
Here a snippet to dynamically add role permissions to a dotnetnuke module in code behind.
//get the current ModuleInfo
ModuleInfo newModule = ModuleController.Instance.GetModule(ModuleId, TabId, false);
//or create a new module
ModuleInfo newModule = new ModuleInfo();
//clear the old permissions
newModule.ModulePermissions.Clear();
//add admin view permission
ModulePermissionInfo modulePermissionInfo1 = new ModulePermissionInfo();
modulePermissionInfo1.ModuleID = ModuleId;
modulePermissionInfo1.AllowAccess = true;
//view permission id, 1 = view, 2 = edit
modulePermissionInfo1.PermissionID = 1;
//administrator role id (from Roles table in dnn database)
modulePermissionInfo1.RoleID = 0;
//add admin edit permission
ModulePermissionInfo modulePermissionInfo2 = new ModulePermissionInfo();
modulePermissionInfo2.ModuleID = ModuleId;
modulePermissionInfo2.AllowAccess = true;
//view permission id, 1 = view, 2 = edit
modulePermissionInfo2.PermissionID = 2;
//administrator role id (from Roles table in dnn database)
modulePermissionInfo2.RoleID = 0;
//add all users view permission
ModulePermissionInfo modulePermissionInfo3 = new ModulePermissionInfo();
modulePermissionInfo3.ModuleID = ModuleId;
modulePermissionInfo3.AllowAccess = true;
//edit permission id, 1 = view, 2 = edit
modulePermissionInfo3.PermissionID = 1;
//all users role id (from Roles table in dnn database)
modulePermissionInfo3.RoleID = -1;
//add the ModulePermissionInfo to the module
newModule.ModulePermissions.Add(modulePermissionInfo1);
newModule.ModulePermissions.Add(modulePermissionInfo2);
newModule.ModulePermissions.Add(modulePermissionInfo3);
//save the permissions
ModulePermissionController.SaveModulePermissions(newModule);
//clear the dnn cache (if it is the current module, not a new one)
DotNetNuke.Common.Utilities.DataCache.ClearModuleCache(TabId);
DotNetNuke.Common.Utilities.DataCache.ClearTabsCache(PortalId);
DotNetNuke.Common.Utilities.DataCache.ClearPortalCache(PortalId, false);
In this function I would like to see if a user with such email has already been registered, if so the fields have to be updated, if not a new user has to be created.
I have tried to implement it in the following way, but this just does not work.
public function facebook_add(){
if ($this->request->is('post')) {
$User_data = array('User'=>$this->request->data);
$this->User->email = $User_data['User']['email'];
if($this->User->exists()){
if($this->User->save($User_data)){
$message='1';
}else{
$errors = $this->User->invalidFields();
$user_error=array_shift(array_slice($errors, 0, 1));
$message= array_shift(array_slice($user_error, 0, 1));
}
}else{
if($this->User->save($User_data)){
$message='1';
}else{
$errors = $this->User->invalidFields();
$user_error=array_shift(array_slice($errors, 0, 1));
$message= array_shift(array_slice($user_error, 0, 1));
}
}
$this->set(array(
'message' => $message,
'_serialize' => array('message')
));
}
}
The problem is initiating a new user object if there was none user found. Any help to go around it is much appreciated.
As I said in the comments, when you need to create a new record, yout should call $this->User->create() before $this->User->save($User_data) so the data that you are saving is already initialized.
I have just started using CakePHP and love using it! I have created a login system and registration system, however am really struggling with the "forgotten password" section.
I want to use a tokenhash and expiry date in the Users DB so that it cant be abused, users would need to enter username and email to get an activation link emailed to them with a newly generated tokenhash
There are quite a few tutorials out there but I find most of them work for the first part e.g. emailing the activation link/ resetting token and timer but all seem to fail on the change of the password.
Please help me, either with a working tutorial from the net or a solution that applies the above required things.
Thanks in advance
Steve
Below I am writing the code that I wrote for one of my project, this might help you out.
1- I created a new table which contains the unique token for every user.
Table Name:- user_password_resets
Columns : userclient_id, token
2- A email template name as:- change_password.html inside /webroot/template/change_password.html
public function login_send() {
$this->isLoggedIn(); //Check if the user is logged in
if($this->request->is('post')) { #if the form is submitted
$login = $this->data['User']['login'];
$conditions = array('User.login'=>$login);
if($this->User->hasAny($conditions)) {
$users = $this->User->find('first', array('conditions'=>$conditions));
#Generate the token
$token = md5(uniqid(rand(),true));
#Save token and other details in user_password_reset_links table
$users = $this->User->find('first', array('conditions'=>array('User.login'=>$login)));
$my_name = $users['User']['first_name'];
$reset_links = array();
$reset_links['UserPasswordReset']['userclient_id'] = $users['User']['client_id'];
$reset_links['UserPasswordReset']['token'] = $token;
$conditions = array('UserPasswordReset.userclient_id'=>$users['User']['client_id']);
if($this->UserPasswordReset->hasAny($conditions)) {
$user_id = $users['User']['client_id'];
$this->UserPasswordReset->updateAll(array('UserPasswordReset.token'=>"'$token'"), array("UserPasswordReset.userclient_id"=>"$user_id"));
} else {
$this->UserPasswordReset->create();
$this->UserPasswordReset->save($reset_links);
}
$password_reset_link = BASE_URL."users/reset_password/$token";
#Send Welcome Email
$mailContent = file_get_contents(BASE_URL . "templates/change_password.html");
$rootlink = BASE_URL;
$arrMail = array(
"{NICK}" => ucfirst($my_name),
"{rootlink}" => BASE_URL,
"{SITE_TITLE}" => SITE_TITLE,
"{PASSWORD_RESET_LINK}"=>$password_reset_link
);
$mails = explode(',', $users['User']['email']);
$msg = #str_replace(array_keys($arrMail), array_values($arrMail), $mailContent);
$data = array();
$data['to'] = #$mails[0];
$data['body'] = $msg;
$data['subject'] = SITE_TITLE.'- Reset Password.';
$this->send_mail($data);
$this->Session->setFlash('A password reset link has been sent to the email address.', 'default', array('class'=>'successMsg'));
$this->redirect(array('controller'=>'users', 'action'=>'login'));
exit;
} else {
$this->Session->setFlash('The Username entered is not registered with Captain Marketing.', 'default', array('class'=>'errorMsg'));
$this->redirect(array('controller'=>'users', 'action'=>'login_send'));
exit;
}
}
$this->set('title_for_layout', '-Send password reset link');
}
Now I can send push Token from device that has installed a pass already, but I don't know how the feedback work in this point. From apple docs, Apple Push Notification service (APNs) provides feedback to server to tell if pushToken is valid or not. How to get this feedback ? I try this code, but a lot errors. This is the code:
<?php
$cert = '/Applications/MAMP/htdocs/passesWebserver/certificates.pem';
$ctx = stream_context_create();
stream_context_set_option($ctx, 'ssl', 'local_cert', $cert);
stream_context_set_option($ctx, 'ssl', 'verify_peer', false);
$fp = stream_socket_client('ssl://feedback.sandbox.push.apple.com:2196', $error, $errorString, 60, STREAM_CLIENT_CONNECT, $ctx);
// production server is ssl://feedback.push.apple.com:2196
if (!$fp) {
error_log("Failed to connect feedback server: $err $errstr",0);
return;
}
else {
error_log("Connection to feedback server OK",0);
}
error_log("APNS feedback results",0);
while ($devcon = fread($fp, 38))
{
$arr = unpack("H*", $devcon);
$rawhex = trim(implode("", $arr));
$feedbackTime = hexdec(substr($rawhex, 0, 8));
$feedbackDate = date('Y-m-d H:i', $feedbackTime);
$feedbackLen = hexdec(substr($rawhex, 8, 4));
$feedbackDeviceToken = substr($rawhex, 12, 64);
error_log ("TIMESTAMP:" . $feedbackDate, 0);
error_log ( "DEVICE ID:" . $feedbackDeviceToken,0);
}
fclose($fp);
?>
This should work. You don't need to run this with every push request. Depending on how frequently you update, and the number of devices, you could set a daily or weekly cron job.
$cert_file = '/path/to/combined/cert.pem';
$cert_pw = 'top secret';
$stream_context = stream_context_create();
stream_context_set_option($stream_context, 'ssl', 'local_cert', $cert_file);
if (strlen($cert_pw))
stream_context_set_option($stream_context, 'ssl', 'passphrase', $cert_pw);
$apns_connection = stream_socket_client('feedback.push.apple.com:2196', $error_code, $error_message, 60, STREAM_CLIENT_CONNECT, $stream_context);
if($apns_connection === false) {
apns_close_connection($apns_connection);
error_log ("APNS Feedback Request Error: $error_code - $error_message", 0);
}
$feedback_tokens = array();
while(!feof($apns_connection)) {
$data = fread($apns_connection, 38);
if(strlen($data)) {
$feedback_tokens[] = unpack("N1timestamp/n1length/H*devtoken", $data);
}
}
fclose($apns_connection);
if (count($feedback_tokens))
foreach ($feedback_tokens as $k => $token) {
// code to delete record from database
}
The perfect little module for what I am looking to do was made for drupal 6 but to my dismay it doesn't work on drupal 7. I've have learned that drupal 7 has a new api for the database. I have tried to get it to work but I am admittedly out of my league here. I am hoping some one could give me a little guidance. Specifically with the db_query.
function webform_image_validation_webform_validation_validate($validator_name, $items,
$components, $rule) {
$errors = array();
if ($items) {
switch ($validator_name) {
case 'max_image_size':
$dimensions = explode('x', $rule['data']);
foreach ($items as $key => $val) {
if (is_numeric($val['_fid'])) {
$result = db_query("select * from {files} where fid = %d", $val['_fid']);
while ($data = db_fetch_object($result)) {
$thefile = $data;
}
$image_info = image_get_info($thefile->filepath);
if (webform_image_validation_validate_image($image_info, $dimensions[0], $dimensions[1], FALSE) === FALSE) {
$errors[$key] = t('Your image did not match the required width and/or height. (') . $dimensions[0] . t(' x ') . $dimensions[1] . t(')');
}
}
}
This is the error I receive.
Argument 2 passed to db_query() must be an array, string given, called in
/home/designco/public_html/dev/sites/all/modules/webform_image_validation/
webform_image_validation.module on line 69 and defined in
/home/designco/public_html/dev/includes/database/database.inc on line 2310
It appears I need to add an array but I get lost there. Any help would be appreciated. I'm just trying to find out if I'm the right track.
db_query works differently in Drupal7.
$result = db_query("select * from {files} where fid = %d", $val['_fid']);
while ($data = db_fetch_object($result)) {
$thefile = $data;
}
becomes
$results = db_query("select * from {files} where fid = :fid", array(':fid' => $val['_fid']));
foreach($results as $result) {
// Do your thing for each result.
}
Try changing
$result = db_query("select * from {files} where fid = %d", $val['_fid']);
while ($data = db_fetch_object($result)) {
$thefile = $data;
}
to
$query = db_select('files', 'f')
->fields('f')
->condition('fid', $val['_fid']);
$thefile = $query->execute()->fetchObject();
The Drupal 7 database API docs http://drupal.org/node/310069
thanks JurgenR for the answer.
Just to add one more thing: In drupal 6, we use '%s' for strings. In drupal 7, it is same for all.
For example:
$results = db_query("select * from {files}
where filename = :fname", array(':fname' => $filename));
If you want to search for records starting with a pattern then query will be:
$results = db_query("select * from {files}
where filename = :fname", array(':fname' => $filename.'%'));
Hope this is useful.