project_settings: Converting a hook_settings implementation (Easy)
Overview
The first form to investigate is the project module's settings form. This is a very straight-forward form conversion which only requires taking existing form_* function calls and converting them into arrays.
Project settings form

Original function
The following is the original project_settings function which generates this form:
function project_settings() {
$project_directory = file_create_path(variable_get('project_directory_issues', 'issues'));
if (!file_check_directory($project_directory)) {
$error['project_directory_issues'] = theme('error', t('Directory does not exist, or is not writable.'));
}
$versions = array(-1 => t('all')) + project_releases_list();
** $output = form_textfield(t('Release directory'), 'project_release_directory', variable_get('project_release_directory', ''), 50, 255, t('Leave this blank if project maintainers are to create their own release packages. This is useful if releases are generated by an external tool.'));
** $output .= form_radios(t('Unmoderate projects with releases'), 'project_release_unmoderate', variable_get('project_release_unmoderate', 0), array('Disabled', 'Enabled'));
** $output .= form_checkbox(t('Browse projects by releases'), 'project_browse_releases', 1, variable_get('project_browse_releases', 1), t('Checking this box will cause the project browsing page to have version subtabs.'));
** $output .= form_radios(t('Default release overview'), 'project_release_overview', variable_get('project_release_overview', -1), $versions, t('Default release version to list on the overview page'));
** $output .= form_textfield(t('Issue directory'), 'project_directory_issues', variable_get('project_directory_issues', 'issues'), 30, 255, t("Subdirectory in the directory '%dir' where attachment to issues will be stored.", array('%dir' => variable_get('file_directory_path', 'files') .'/')));
if (module_exist('mailhandler')) {
// TODO: move this stuff to mailhandler.module ?
$items = array(t('
<none>'));
$result = db_query('SELECT mail FROM {mailhandler} ORDER BY mail');
while ($mail = db_result($result, $i++)) {
$items[$mail] = $mail;
}
** $output .= form_select(t('Reply-to address on e-mail notifications'), 'project_reply_to', variable_get('project_reply_to', ''), $items);
}
** return $output;
}Note that lines prefixed with ** indicate a line that will cause problems with Drupal 4.7.
Form conversion
Begin by navigating to administer >> settings >> project. You will receive an error:
Fatal error: Call to undefined function: form_textfield() in \modules\project\project.module on line 119
The error tells the name of the file from which the error is originating: project.module. Copy and paste the contents of this file into the Form Updater module, and it will identify six calls to the old forms API (out of seven lines identified as problematic). Here is the first call as an example:
form_textfield(t('Release directory'), 'project_release_directory', variable_get('project_release_directory', ''), 50, 255, t('Leave this blank if project maintainers are to create their own release packages. This is useful if releases are generated by an external tool.'));This creates a textfield with:
- a title of Release Directory
- an internal name of project_release_directory
- a default value containing either the contents of the project_release_directory variable in the Drupal variable table, or an empty string if that does not exist
- a size (or length) of 50 characters
- a maximum length of 255 characters
- a description of "Leave this blank if project maintainers are to create their own release packages. This is useful if releases are generated by an external tool."
In the new API, this translates to:
$form['project_release_directory'] = array(
'#type' => 'textfield',
'#title' => t('Release directory'),
'#default_value' => variable_get('project_release_directory', ''),
'#size' => 50,
'#maxlength' => 255,
'#description' => t('Leave this blank if project maintainers are to create their own release packages. This is useful if releases are generated by an external tool.'),
);Notice that the element name is now moved to the name of the array index in $form (in this case, project_release_directory). Also note that each array index is labeled specifically what it means. #title => t('Release Directory') is the form element's title (or text displayed above it). #default_value is its default value, and so on. You are no longer required to memorize what order function arguments go in, or to refer to the API reference to determine this. Attributes can be placed in any order (although it is customary to keep them in the same order throughout), or even removed altogether if they are not required.
Replace the form_textfield call with the code generated by Form Updater. Repeat for each element that Form Updater finds.
hook_settings changes in 4.7
Save project.module at this point and reload the settings page.
Project settings page after replacing form values

While there is no longer an error displayed, something is clearly amiss. Where did the form go? Check the very last highlighted line for the answer:
return $output;
In Drupal 4.6, hook_settings returned an HTML string containing the form output. In Drupal 4.7, hook_settings (as well as hook_form) return the actual $form array instead. Change this line to:
return $form;
Upon reloading the page, you should see the full form as expected.
Default values
One last minor thing is that there are a series of default values (determined by the system_elements function) assigned to form elements. These are redundant if declared again in your form. In this case, the only setting that applies is the #return_value => 1 in the checkbox field.
Converted function
The following is the completed code after translating project_settings:
function project_settings() {
$project_directory = file_create_path(variable_get('project_directory_issues', 'issues'));
if (!file_check_directory($project_directory)) {
$error['project_directory_issues'] = theme('error', t('Directory does not exist, or is not writable.'));
}
$versions = array(-1 => t('all')) + project_releases_list();
$form['project_release_directory'] = array(
'#type' => 'textfield',
'#title' => t('Release directory'),
'#default_value' => variable_get('project_release_directory', ''),
'#size' => 50,
'#maxlength' => 255,
'#description' => t('Leave this blank if project maintainers are to create their own release packages. This is useful if releases are generated by an external tool.'),
);
$form['project_release_unmoderate'] = array(
'#type' => 'radios',
'#title' => t('Unmoderate projects with releases'),
'#default_value' => variable_get('project_release_unmoderate', 0),
'#options' => array('Disabled', 'Enabled'),
);
$form['project_browse_releases'] = array(
'#type' => 'checkbox',
'#title' => t('Browse projects by releases'),
'#default_value' => variable_get('project_browse_releases', 1),
'#description' => t('Checking this box will cause the project browsing page to have version subtabs.'),
);
$form['project_release_overview'] = array(
'#type' => 'radios',
'#title' => t('Default release overview'),
'#default_value' => variable_get('project_release_overview', -1),
'#options' => $versions,
'#description' => t('Default release version to list on the overview page'),
);
$form['project_directory_issues'] = array(
'#type' => 'textfield',
'#title' => t('Issue directory'),
'#default_value' => variable_get('project_directory_issues', 'issues'),
'#size' => 30,
'#maxlength' => 255,
'#description' => t("Subdirectory in the directory '%dir' where attachment to issues will be stored.", array('%dir' => variable_get('file_directory_path', 'files') .'/')),
);
if (module_exist('mailhandler')) {
// TODO: move this stuff to mailhandler.module ?
$items = array(t('<none>'));
$result = db_query('SELECT mail FROM {mailhandler} ORDER BY mail');
while ($mail = db_result($result, $i++)) {
$items[$mail] = $mail;
}
$form['project_reply_to'] = array(
'#type' => 'select',
'#title' => t('Reply-to address on e-mail notifications'),
'#default_value' => variable_get('project_reply_to', ''),
'#options' => $items,
);
}
return $form;
}