My comments on articles have a required Fivestar rating field called 'Stars' and I hid it with the following custom module (see: https://drupal.stackexchange.com/questions/90629/how-to-hide-rating-field-when-adding-comment-to-own-node):
function hiderating_form_alter(&$form, &$form_state, $form_id) {
global $user;
if ($form_id == "comment_node_article_form") {
if ($form['#node']->uid == $user->uid) {
unset($form['field_stars']);
}
}
}
As an administrator, I've permission to edit comments from other users. Suppose that a user commented on his own article. That means he didn't have to set the 'Stars' field, due to the code above. But when I try to edit that comment, I do have to select a value for the 'Stars'.
How can I prevent this? It's sufficient to check that the uid from the user who wrote the comment differs from the uid from the user who edits the comment. Finally, mark that the obligation to select stars when I leave a new comment myself must be preserved!
Edit: I tried the following code:
function hiderating_form_alter(&$form, &$form_state, $form_id) {
global $user;
$comment->uid = $form_state['values']['uid'];
if ($form_id == "comment_node_article_form") {
if ($comment->uid != $user->uid) {
unset($form['field_stars']);
}
}
}
Apparently, $form_state['values'] isn't well defined, because I get the following error:
"Notice: Undefined index: values in hiderating_form_alter()".
What's the correct code?
The code in the edit doesn't work, because $form_state['values'] isn't present before the submit. This is the correct code:
function hiderating_form_alter(&$form, &$form_state, $form_id) {
global $user;
if ($form_id == "comment_node_article_form") {
if ($form['uid']['#value'] != $user->uid AND $form['uid']['#value'] != 0) {
unset($form['field_stars']);
}
}
}
Using dpm($form), I discovered that $form['uid']['#value'] returns the uid from the user who wrote the comment. The value is only different from 0 if a comment is edited. When a user writes a new comment, the uid from the form is 0. That's why the AND in the second if is necessary.
Related
I am facing a problem when I try to use hook_form_alter to hide fields according to user's roles. I have used unset() and removed the field from the $form array, but it is still showing when the form is rendered.
Here is my code:
function mymodule_form_alter($form, $form_state, $form_id){
global $user;
if($form_id == 'my_content_type'){
if(array_key_exists(5,$user->roles) && !array_key_exists(3,$user->roles)){
if(empty($form_state['field']['args'][0]->title)){
unset($form['field_body']);
}
}
}
}
Instead of using unset() to hide a form element, you should set the #access property to FALSE. This keeps the form build tree intact, which avoids problems if other modules try to access or alter that information. Source
function MYMODULE_form_alter($form, $form_state, $form_id) {
global $user;
$account = $user;
if ($form_id == 'MYCONTENTTYPE_node_form') {
if (user_has_role(5, $account) && !user_has_role(3, $account)) {
if (empty($form_state['field']['args'][0]->title)) {
$form['field_body']['#access'] = FALSE;
}
}
}
}
If this is still not working, double-check your if-requests. Are they really doing something? Are you currently logged-in as a corresponding user?
I have found the solution. I need just added the & with $form and $form_state in hook_form_alter parameters. Like hook_form_alter(&$form, &$form_state, $form_id)
It exists a module which allows to hide fields. For Drupal 9 it handles per-roles, hide-or-disable, exceptions (such as not at creation…).
Look at: https://www.drupal.org/project/jammer
I'm trying to modify the below code snippet / function hook to disable registration if the user is logged in.
<?php
add_filter("gform_disable_registration", "disable_registration", 10, 4);
function disable_registration($is_disabled, $form, $entry, $fulfilled){
//check form id and if not the form being checked status passed in to function
if ($form["id"] != 160)
return $is_disabled;
//check submitted values to decide if registration should be stopped
if ($entry["4"] == "No" && $entry["5"] == "No") {
//disable registration
return true;
}
else{
return false;
}
}
?>
I've tried the following to no avail:
add_filter("gform_disable_registration", "disable_registration", 10, 4);
function disable_registration($is_disabled, $form, $fulfilled){
//check form id and if not the form being checked status passed in to function
if ($form["id"] != 2)
return $is_disabled;
//check user login to decide if registration should be stopped
if( ! is_user_logged_in() ) {
return true;
}
else {
return false;
}
}
Hoping I can get this to work! Thank you.
Here is an article/snippet I wrote to do this... I didn't confirm if this is still the best way to accomplish this, but it certainly is a way that works. :)
http://gravitywiz.com/skip-user-registration-for-logged-in-users/
I believe there's a setting in the Form Settings to allow you require users to be logged in. Is there a reason you can't just use that?
I have a views block (Views 3 / Drupal 7) with a exposed filter form and the ajax mode is enabled. It works fine. I added in hook_form_alter() a validation function. It works too, but the form_set_error message shows only on a page refresh. How can I set it up the message without page reload?
function hook_form_alter(&$form, &$form_state, $form_id) {
if($form['#id'] === 'id_from_views') {
array_unshift($form['#validate'], '_custom_form_validate');
}
}
function _custom_form_validate($form, &$form_state) {
if(!empty($form_state['values']['field'])) {
form_set_error('field', t('Custom error message.'));
}
}
I had a similar problem. The answer is to use ajax callback in the hook_form_alter.
function hook_form_alter(&$form, &$form_state, $form_id) {
if($form['#id'] === 'id_from_views') {
$form['submit']['#ajax'] = array('callback' => '_custom_form_validate');
}
}
I know that I can make two different field types and assign different roles to them.
Because of using views, custom searches, and gmaps, and because this will be applied to Field collection I really need this kind of approach to the problem.
I tried to crate custom module that will limit role staff to only be able to insert two field_text into node but administrator can insert as many as he wont. field_text Number of values is set to Unlimited and Content type name is youtube.
I found this for drupal 6 but I don't know how to code it in drupal 7.
function myformlimit_form_alter(&$form, &$form_state, $form_id) {
if ($form_id == 'youtube') {
global $user;
// Only allow to insert 2 text for role = staff
if (in_array('staff', $user->roles)) {
$text_limit = 2;
$form['#field_info']['field_text']['multiple'] = $text_limit;
$i = 1;
foreach ($form['field_text'] as $key => $value) {
if (is_numeric($key)) {
if ($i > $text_limit) {
unset($form['field_text'][$key]);
}
$i++;
}
}
}
}
}
Well you are half way there. You can use the following code to get you the idea.
Kindly note that I named my field field_test_field, you can replace that with your field's name.
function myformlimit_form_alter(&$form, &$form_state, $form_id)
{
if($form_id == 'youtube_node_form')
{
global $user;
if(in_array('staff', $user->roles))
{
if($form_state['field']['field_test_field'][LANGUAGE_NONE]['items_count'] >= 2)
{
unset($form['field_test_field'][LANGUAGE_NONE]['add_more']);
}
}
}
}
My form contains a model object that contains five child objects that are related using hasMany. When I save the form, I notice that all fields, regardless if they are empty, are saved into the database. Is it possible to set a condition in the beforeSave() callback method to prevent child items that have no values from being saved? I have tried to unset the key in the array containing empty values but the row is still being added into the database.
Here is the code for my 'Mtd' model. The Mtd model contains many Flowratereatments. On my form, I have a checkbox that says 'This is a Flow Rate Based Treatment'. So, if a user clicks on that, then the user can fill it in the fields. However, if the user does not fill it in, I want to prevent a new row from being added with just the foreign key of the Mtd table.
<?php
class Mtd extends AppModel {
public $name = 'Mtd';
public $hasOne = array('Treatmentdesign', 'Volumetreatment');
public $hasMany = 'Flowratetreatment';
function beforeSave() {
if($this->data['Mtd']['is_settling'] != 1){
unset($this->data['Flowratetreatment'][0]);
}
return true;
}
}
?>
Did you tried something like:
class User extends AppModel {
function validates() {
$this->setAction();
#always validate presence of username
$this->validates_presence_of('username');
#validate uniqueness of username when creating a new user
$this->validates_uniqueness_of('username',array('on'=>'create'));
#validate length of username (minimum)
$this->validates_length_of('username',array('min'=>3));
#validate length of username (maximum)
$this->validates_length_of('username',array('max'=>50));
#validate presence of password
$this->validates_presence_of('password');
#validate presence of email
$this->validates_presence_of('email');
#validate uniqueness of email when creating a new user
$this->validates_uniqueness_of('email',array('on'=>'create'));
#validate format of email
$this->validates_format_of('email',VALID_EMAIL);
#if there were errors, return false
$errors = $this->invalidFields();
return (count($errors) == 0);
}
}
?>
in your model
I have used this code:
public function beforeSave() {
if(isset($this->data[$this->alias]['profile_picture'])) {
if($this->data[$this->alias]['profile_picture']['error']==4) {
unset($this->data[$this->alias]['profile_picture']);
}
}
return true;
}
in a previous app, to remove a key from $this->data if the user had not uploaded a file, to prevent the old value being overwritten.
this should work for you (you'll need to adapt it; based on what $this->data contains at this point.
public function beforeSave() {
if(empty($this->data[$this->alias]['the_key'])) {
unset($this->data[$this->alias]['the_key']);
}
//debug($this->data); exit; // this is what will be saved
return true;
}
you mention you tried this already? post your code in your original post.