0

It's almost 2 years I don't program modules in D7. I'm creating a module that shows 2 forms. One is public (and to's working) and one is a setup form under /admin space. The issue is that the one in the admin still accessible to anonymous, even when I check the checkbox into the "permission" page. Could you help me please to find out what I miss?

Please here part of the code

function MyModule_permission() {
  return array(
    'administer MyModule' => array(
      'title' => t('Administer MyModulemodule'),
      'description' => t('Perform administration tasks for MyModule module.')
    ),
  );
}

here below the address of the 2 forms

/**
 * Implements hook_menu().
 *
 * Displays module information.
 */
function MyModule_menu() {
  $items = array();

  // It should be accessible by everybody
  $items['fillin'] = array(
    'title' => 'Participation Data',
    'description' => 'Please fill here below the fields in',
    'page callback' => 'drupal_get_form',
    'page arguments' => array('MyModule_form'),
    'access callback' => TRUE
  );

  // it should be accessible only by admin
  $items['admin/config/setup_collection'] = array(
    'title' => 'Participation Text',
    'description' => 'Text for the presentation',
    'page callback' => 'drupal_get_form',
    'page arguments' => array('MyModule_setup_form'),
    'access arguments' => array('administer'),
    'type' => MENU_CALLBACK,
    'access callback' => TRUE
  );

  return $items;
}

Here below the setup form with the default content, that should be accessible only by the administrator

/**
 * Implement hook_form()
 *
 * Creates the form for the setup page
 *
 */
function MyModule_setup_form($form, &$form_state) {
  $form['MyModule_message'] = array(
    '#type' => 'textarea',
    '#title' => t('TEXT '),
    '#wysiwyg' => TRUE,
    '#default_value' => variable_get('MyModule_message', 'Subscribe fill in the form below'),
  );

  $form['submit_button'] = array(
    '#type' => 'submit',
    '#value' => t('SUBMIT'),
  );
  return $form;
}

Here below just a part of the form accessible by the anonymous user

/**
 * Implements hook_form().
 *
 * Creates the form for the user.
 */
function MyModule_form($form, &$form_state) {

  global $conf;

  $form['MyModule_main_message']['hello'] = array(
    '#markup' => variable_get('MyModule_message'),
  );

  $form['first_name'] = array(
    '#type' => 'textfield', 
    '#title' => t('Put your first name'),
    '#size' => 50,
    '#maxlength' => 50,
    '#required' => TRUE,  
  );

            ...
            ...
            ...
3
  1. The problem is you are setting 'access callback' => TRUE this gives access to all.
  2. I also to sure that administer is a valid permission in 'access arguments' => array('administer'), instead try 'access arguments' => array('administer site configuration'),.
  • Ohh remember to flush the cache after the change – garethhallnz Jul 10 '18 at 10:19
  • yes, I did flush it and indeed it works fine now :) – Tormy Van Cool Jul 10 '18 at 10:20
  • Sorry if I disturb you again. When I reinstalled the module, the admin got forbidden to access to the admin page :-/ In order to avoid this, I had to comment this line 'access callback' => FALSE – Tormy Van Cool Jul 10 '18 at 10:54
2

In the "admin/config/setup_collection" array you use:

'access callback' => TRUE

In this way all users can access to this url and it overrides the "access arguments" array.

Remove line with "access callback" and clear cache.

1

As the other answers are telling you, setting the access callback to TRUE is making Drupal allow the access to that page to every user, without checking which permissions they have. Instead of TRUE, you should set the access callback to 'user_access' (yes, a string), or not set it at all, and Drupal will use the default value, which in most cases is 'user_access'.
If you don't want any issue, especially if it's possible you are going to change the route your module defines, and make admin/config/setup_collection a MENU_DEFAULT_LOCAL_TASK route, set the access callback explicitly, even if you are going to use the default value Drupal uses.

What the other answers aren't telling you is that setting the access arguments to array('administer'), you aren't telling Drupal to check the currently logged-in user who is trying to access admin/config/setup_collection has the permission you defined in MyModule_permission(). For that, you would need to use code similar to the following one.

function MyModule_menu() {
  $items = array();

  // It should be accessible by everybody
  $items['fillin'] = array(
    'title' => 'Participation Data',
    'description' => 'Please fill here below the fields in',
    'access callback' => TRUE,
    'page callback' => 'drupal_get_form',
    'page arguments' => array('MyModule_form'),
  );

  // it should be accessible only by admin
  $items['admin/config/setup_collection'] = array(
    'title' => 'Participation Text',
    'description' => 'Text for the presentation',
    'access callback' => 'user_access',
    'access arguments' => array('administer MyModule'),
    'page callback' => 'drupal_get_form',
    'page arguments' => array('MyModule_setup_form'),
    'type' => MENU_CALLBACK,
  );

  return $items;
}

As side note, never use capital letters in the module machine name. While PHP is not case sensitive, you are going to have issues when you will implement hook_update_N() for your module (and usually modules are going to implement that hook) because the Drupal code that gets the list of update hooks implemented from a module is case sensitive, as you can see from the following code used from drupal_get_schema_versions().

// Prepare regular expression to match all possible defined hook_update_N().
$regexp = '/^(?P<module>.+)_update_(?P<version>\\d+)$/';
$functions = get_defined_functions();

// Narrow this down to functions ending with an integer, since all
// hook_update_N() functions end this way, and there are other
// possible functions which match '_update_'. We use preg_grep() here
// instead of foreaching through all defined functions, since the loop
// through all PHP functions can take significant page execution time
// and this function is called on every administrative page via
// system_requirements().
foreach (preg_grep('/_\\d+$/', $functions['user']) as $function) {

  // If this function is a module update function, add it to the list of
  // module updates.
  if (preg_match($regexp, $function, $matches)) {
    $updates[$matches['module']][] = $matches['version'];
  }
}

Since the content of $regexp isn't '/^(?P<module>.+)_update_(?P<version>\\d+)$/i', the regular expression used from Drupal is case-sensitive.

This means that if the machine name of your module is MyModule and, by accident, you define an update hook as mymodule_update_7100(), it will not be recognized as update hook for your module.
It would also be true if the update hook would be named MyModule_UPDATE_7100().

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.