Forgive me -- this is my first attempt at writing a module. This is the admin menu for a module that will perform external auth with an in-house system we have at my company. I'm going to implement that with hook_boot(). But that's later. First, a few easier questions:
1. I had to "steal" some code from system_settings_form() because, as far as I could tell, in a system form, you can't override the #submit handler. I was finding that the my_auth_admin_submit function was never being called. I wanted to save my settings into a custom database table rather than the variables table, and this was the only way I could figure out how to do it. Is this the right approach?
2. I found that in my_auth_admin_submit, if I attempted to foreach through $form_state['values'], I could get the "new" item submitted, but for all the other form items, $form_state['values'] was being overwritten with the values already in the database and not the ones just posted! The only way I could figure out how to get at the newly-posted values was to use $form['#post'] instead. But this doesn't seem right and doesn't look like most of the examples I've seen. What am I doing wrong?
Thanks!
Code below:
function my_auth_help($path, $arg) {
$output = '';
switch ($path) {
case "admin/help#my_auth" :
$output = '<p>' . t ( "Provides external auth functionality" ) . '</p>';
break;
}
return $output;
}
function my_auth_perm() {
return array ('configure my_auth' );
}
function my_auth_admin() {
// get existing configuration
$sql = "select apps.id as app_pk, apps.app_name, apps.enabled, apps.login_type, apps.default_role, pages.id as page_pk, pages.app_id, pages.page_pattern from {my_auth_applications} apps, {my_auth_applications_pages} pages where apps.id = pages.app_id order by apps.app_name";
$result = db_query ( $sql );
$form = array ();
while ( $data = db_fetch_object ( $result ) ) {
$form [$data->app_pk] = array ('#type' => 'fieldset', '#collapsible' => TRUE, '#collapsed' => TRUE, '#title' => 'External Auth Application ' . $data->app_name, '#description' => 'Configuration for External Auth Application ' . $data->app_name );
$form [$data->app_pk] ['app_enabled_' . $data->app_pk] = array ('#title' => 'Enabled', '#description' => 'Make this restriction active', '#type' => 'checkbox', '#required' => TRUE, '#value' => $data->enabled == 'Y' );
$form [$data->app_pk] ['app_name_' . $data->app_pk] = array ('#title' => 'External Auth Application ID', '#description' => 'The ID of the External Auth Application registered with IT', '#type' => 'textfield', '#required' => TRUE, '#value' => $data->app_name );
$form [$data->app_pk] ['app_type_' . $data->app_pk] = array ('#title' => 'Restriction Type', '#description' => 'ANON = Protect page only (anonymous Drupal user); AUTO = Auto-provision new Drupal users into specified default role; PROV = Only allow pre-provisioned Drupal users', '#type' => 'select', '#required' => TRUE, '#value' => $data->login_type, '#options' => array ('ANON' => 'ANON', 'AUTO' => 'AUTO', 'PROV' => 'PROV' ) );
$form [$data->app_pk] ['app_role_' . $data->app_pk] = array ('#title' => 'Default Role', '#description' => 'The role that should be assigned to auto-provisioned users (only applies to type PROV)', '#type' => 'textfield', '#required' => FALSE, '#value' => $data->default_role );
$form [$data->app_pk] ['app_pattern_' . $data->app_pk] = array ('#title' => 'Page Pattern Match', '#description' => 'The URL pattern to apply to this External Auth Application (if multiple applications match a page, the first one to match is the one that will be used)', '#type' => 'textarea', '#required' => TRUE, '#value' => $data->page_pattern );
}
$form ['new'] = array ('#type' => 'fieldset', '#collapsible' => TRUE, '#collapsed' => TRUE, '#title' => 'New External Auth Application', '#description' => 'Configuration a new External Auth Application' );
$form ['new'] ['app_enabled_new'] = array ('#title' => 'Enabled', '#description' => 'Make this restriction active', '#type' => 'checkbox', '#required' => TRUE, '#default_value' => TRUE );
$form ['new'] ['app_name_new'] = array ('#title' => 'External Auth Application ID', '#description' => 'The ID of the External Auth Application registered with IT', '#type' => 'textfield', '#required' => TRUE );
$form ['new'] ['app_type_new'] = array ('#title' => 'Restriction Type', '#description' => 'ANON = Protect page only (anonymous Drupal user); AUTO = Auto-provision new Drupal users into specified default role; PROV = Only allow pre-provisioned Drupal users', '#type' => 'select', '#required' => TRUE, '#options' => array ('ANON' => 'ANON', 'AUTO' => 'AUTO', 'PROV' => 'PROV' ) );
$form ['new'] ['app_role_new'] = array ('#title' => 'Default Role', '#description' => 'The role that should be assigned to auto-provisioned users (only applies to type PROV)', '#type' => 'textfield', '#required' => FALSE );
$form ['new'] ['app_pattern_new'] = array ('#title' => 'Page Pattern Match', '#description' => 'The URL pattern to apply to this External Auth Application (if multiple applications match a page, the first one to match is the one that will be used)', '#type' => 'textarea', '#required' => TRUE );
// borrowed from modules/system/system.module system_settings_form() because normally you can't override the system forms submit handler
$form ['buttons'] ['submit'] = array ('#type' => 'submit', '#value' => t ( 'Save configuration' ) );
if (! empty ( $_POST ) && form_get_errors ()) {
drupal_set_message ( t ( 'The settings have not been saved because of the errors.' ), 'error' );
}
$form ['#submit'] [] = 'my_auth_admin_submit';
$form ['#theme'] = 'system_settings_form';
return $form;
}
function my_auth_menu() {
$items = array ();
$items ['admin/settings/my_auth'] = array ('title' => 'my Auth module settings', 'description' => 'my Auth module settings', 'page callback' => 'drupal_get_form', 'page arguments' => array ('my_auth_admin' ), 'access arguments' => array ('configure my_auth' ), 'type' => MENU_NORMAL_ITEM );
return $items;
}
function my_auth_admin_submit($form, &$form_state) {
// borrowed from modules/system/system.module system_settings_form_submit() because normally you can't override the system forms submit handler
foreach ( $form ['#post'] as $key => $value ) {
if (strstr ( $key, "app_name_" ) != FALSE) {
preg_match ( "/^app_name_(.*)$/", $key, $matches );
$id = $matches [1];
$app_name = $form ['#post'] ['app_name_' . $id];
$enabled = $form_state ['values'] ['app_enabled_' . $id] == 1 ? 'Y' : 'N';
$login_type = $form ['#post'] ['app_type_' . $id];
$default_role = $form ['#post'] ['app_role_' . $id];
$pattern = $form ['#post'] ['app_pattern_' . $id];
if ($id == "new") {
// new record
$sql = "insert into {my_auth_applications} (app_name, enabled, login_type, default_role) values ('%s', '%s', '%s', '%s')";
$result = db_query ( $sql, $app_name, $enabled, $login_type, $default_role );
$sql = "select id from {my_auth_applications} where app_name = '%s'";
$result = db_query ( $sql, $app_name );
$data = db_fetch_object ( $result );
$id = $data->id;
$sql = "insert into {my_auth_applications_pages} (app_id, page_pattern) values (%d, '%s')";
$result = db_query ( $sql, $id, $pattern );
} else {
// existing record
$sql = "update {my_auth_applications} set app_name = '%s', enabled = '%s', login_type = '%s', default_role = '%s' where id = %d";
$result = db_query ( $sql, $app_name, $enabled, $login_type, $default_role, $id );
$sql = "update {my_auth_applications_pages} set page_pattern = '%s' where app_id = %d";
$result = db_query ( $sql, $pattern, $id );
}
}
}
drupal_set_message ( t ( 'The configuration options have been saved.' ) );
cache_clear_all ();
drupal_rebuild_theme_registry ();
}
Comments
...
Do
instead of
('#value' is used to tell the browser what to show in the field. In other words, it's for FAPI to figure out. Usually not for you. On the other hand, #value is also used for fields that don't get input from the user; e.g., buttons, hidden fields, value fields.)
You can unset its submit handler:
But removing this submit handler, which is probably the only useful thing about system_settings_form, also removes much of the reason to use system_settings_form in the first place.
Thanks for the help with the
Thanks for the help with the #value vs #default_value confusion!
As for the system_settings_form, since I want to save my values into a custom table, I may as well skip system_settings_form and just roll my own?
- m
...
Yes. You don't need to use system_settings_form().