Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Apress.Pro.Drupal.7.Development.3rd.Edition.Dec.2010.pdf
Скачиваний:
73
Добавлен:
14.03.2016
Размер:
12.64 Mб
Скачать

C H A P T E R 1 1

■ ■ ■

The Form API

Drupal features an application programming interface (API) for generating, validating, and processing HTML forms. The form API abstracts forms into a nested array of properties and values. The array is then rendered as part of the process when Drupal renders the page that contains the form. There are several implications of this approach:

Rather than output HTML, we create an array and let the engine generate the HTML.

Since we are dealing with a representation of the form as structured data, we can add, delete, reorder, and change forms. This is especially handy when you want to modify a form created by a different module in a clean and unobtrusive way.

Any form element can be mapped to any theme function.

Additional form validation or processing can be added to any form.

Operations with forms are protected against form injection attacks, where a user modifies a form and then tries to submit it.

In this chapter, we’ll face the learning curve head on. You’ll learn how the form engine works; how to create forms, validate them, and process them; and how to pummel the rendering engine into submission when you want to make an exception to the rule. This chapter covers the form API as implemented in Drupal 7. We will start by examining how the form processing engine works. If you are just starting out with forms in Drupal and want to start with an example, you might want to jump ahead to the section titled “Creating Basic Forms.” If you are looking for details about individual form properties, you’ll find it in the last part of the chapter in the section titled “Form API Properties.”

Understanding Form Processing

Figure 11-1 shows an overview of the form building, validation, and submission process. In the following sections, we’ll be using this figure as a guide and describing what happens along the way.

239

CHAPTER 11 THE FORM API

Download from Wow! eBook <www.wowebook.com>

Figure 11-1. How Drupal handles forms

240

CHAPTER 11 THE FORM API

In order to interact with the forms API intelligently, it’s helpful to know how the engine behind the API works. Modules describe forms to Drupal using associative arrays. Drupal’s form engine takes care of generating HTML for the forms to be displayed and securely processing submitted forms using three phases: validation, submission, and redirection. The following sections explain what happens when you call drupal_get_form().

Initializing the Process

There are three variables that are very important when dealing with forms. The first, $form_id, contains a string identifying the form. The second, $form, is a structured array describing the form. And the third, $form_state, contains information about the form, such as the form’s values and what should happen when form processing is finished. drupal_get_form() begins by initializing $form_state.

Setting a Token

One of the form system’s advantages is that it strives to guarantee that the form being submitted is actually the form that Drupal created, for security and to counteract spammers or would-be site attackers. To do this, Drupal sets a private key for each Drupal installation. The key is generated randomly during the installation process and distinguishes this particular Drupal installation from other installations of Drupal. Once the key is generated, it’s stored in the variables table as drupal_private_key. A pseudo-random token based on the private key is sent out in the form in a hidden field and tested when the form is submitted. See http://drupal.org/node/28420 for background information. Tokens are used for logged-in users only, as pages for anonymous users are usually cached, resulting in a non-unique token.

Setting an ID

A hidden field containing the form ID of the current form is sent to the browser as part of the form. This ID usually corresponds with the function that defines the form and is sent as the first parameter of drupal_get_form(). For example, the function user_register() defines the user registration form and is called this way:

$output = drupal_get_form('user_register');

Collecting All Possible Form Element Definitions

Next, _element_info() is called. This invokes hook_element_info() on all modules that implement it. Within Drupal core, the standard elements, such as radio buttons and check boxes, are defined by modules/system/system.module’s implementation of hook_element_info(). Modules implement this hook if they want to define their own element types. You might implement hook_element_info() in your module because you want a special kind of form element, like an image upload button that shows you a thumbnail during node preview, or because you want to extend an existing form element by defining more properties.

241

CHAPTER 11 THE FORM API

For example, the contributed fivestar module defines its own element type:

/**

*Implements hook_elements().

*Defines 'fivestar' form element type.

*/

function fivestar_element_info() { $type['fivestar'] = array(

'#input' => TRUE, '#stars' => 5, '#widget' => 'stars', '#allow_clear' => FALSE, '#auto_submit' => FALSE,

'#auto_submit_path' => '', '#labels_enable' => TRUE,

'#process' => array('fivestar_expand'),

);

return $type;

}

And the TinyMCE module uses hook_element_info() to potentially modify the default properties of an existing type. TinyMCE adds a #process property to the textarea element type so that when the form is being built, it will call tinymce_process_textarea(), which may modify the element. The #process property is an array of function names to call.

/**

* Implements hook_elements(). */

function tinymce_element_info() { $type = array();

if (user_access('access tinymce')) {

// Let TinyMCE potentially process each textarea. $type['textarea'] = array(

'#process' => array('tinymce_process_textarea'),

);

}

return $type;

}

Looking for a Validation Function

A validation function for a form can be assigned by setting the #validate property in the form to an array with the function name as the value. Multiple validators may be defined in this way:

// We want foo_validate() and bar_validate() to be called during form validation. $form['#validate'][] = 'foo_validate';

$form['#validate'][] = 'bar_validate';

242

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]