Commit 466ef999 authored by catch's avatar catch

Issue #2110951 by Xano: Remove hook_forms().

parent c3b21826
......@@ -98,7 +98,6 @@ class FormBuilder implements FormBuilderInterface {
/**
* An array of known forms.
*
* @see hook_forms()
* @see self::retrieveForms()
*
* @var array
......@@ -495,39 +494,6 @@ public function retrieveForm($form_id, &$form_state) {
$callback = array($form_state['build_info']['callback_object'], 'buildForm');
}
// We first check to see if there is a valid form builder callback defined.
// If there is, we simply pass the arguments on to it to get the form.
if (!is_callable($callback)) {
// In cases where many form_ids need to share a central constructor
// function, such as the node editing form, modules can implement
// hook_forms(). It maps one or more form_ids to the correct constructor
// functions.
//
// We cache the results of that hook to save time, but that only works for
// modules that know all their form_ids in advance. (A module that adds a
// small 'rate this comment' form to each comment in a list would need a
// unique form_id for each one, for example.)
//
// So, we call the hook if $this->forms isn't yet populated, OR if it
// doesn't yet have an entry for the requested form_id.
if (!isset($this->forms) || !isset($this->forms[$form_id])) {
$this->forms = $this->moduleHandler->invokeAll('forms', array($form_id, $args));
}
$form_definition = $this->forms[$form_id];
if (isset($form_definition['callback arguments'])) {
$args = array_merge($form_definition['callback arguments'], $args);
}
if (isset($form_definition['callback'])) {
$callback = $form_definition['callback'];
$form_state['build_info']['base_form_id'] = $callback;
}
// In case $form_state['wrapper_callback'] is not defined already, we also
// allow hook_forms() to define one.
if (!isset($form_state['wrapper_callback']) && isset($form_definition['wrapper_callback'])) {
$form_state['wrapper_callback'] = $form_definition['wrapper_callback'];
}
}
$form = array();
// Assign a default CSS class name based on $form_id.
// This happens here and not in self::prepareForm() in order to allow the
......@@ -543,20 +509,6 @@ public function retrieveForm($form_id, &$form_state) {
// passed explicitly.
$args = array_merge(array($form, &$form_state), $args);
// When the passed $form_state (not using self::getForm()) defines a
// 'wrapper_callback', then it requests to invoke a separate (wrapping) form
// builder function to pre-populate the $form array with form elements,
// which the actual form builder function ($callback) expects. This allows
// for pre-populating a form with common elements for certain forms, such as
// back/next/save buttons in multi-step form wizards. See self::buildForm().
if (isset($form_state['wrapper_callback'])) {
$form = call_user_func_array($form_state['wrapper_callback'], $args);
// Put the prepopulated $form into $args.
$args[0] = $form;
}
// If $callback was returned by a hook_forms() implementation, call it.
// Otherwise, call the function named after the form id.
$form = call_user_func_array($callback, $args);
// If the form returns some kind of response, deliver it.
if ($form instanceof Response) {
......
......@@ -39,11 +39,7 @@ public function getFormId($form_arg, &$form_state);
* @param \Drupal\Core\Form\FormInterface|string $form_arg
* A form object to use to build the form, or the unique string identifying
* the desired form. If $form_arg is a string and a function with that
* name exists, it is called to build the form array. Modules that need to
* generate the same form (or very similar forms) using different $form_ids
* can implement hook_forms(), which maps different $form_id values to the
* proper form constructor function. Examples may be found in node_forms(),
* and search_forms().
* name exists, it is called to build the form array.
* @param ...
* Any additional arguments are passed on to the functions called by
* drupal_get_form(), including the unique form constructor function. For
......@@ -68,11 +64,7 @@ public function getForm($form_arg);
*
* @param $form_id
* The unique string identifying the desired form. If a function with that
* name exists, it is called to build the form array. Modules that need to
* generate the same form (or very similar forms) using different $form_ids
* can implement hook_forms(), which maps different $form_id values to the
* proper form constructor function. Examples may be found in node_forms(),
* and search_forms().
* name exists, it is called to build the form array.
* @param array $form_state
* An array which stores information about the form. This is passed as a
* reference so that the caller can use it to examine what in the form
......@@ -97,8 +89,8 @@ public function getForm($form_arg);
* Use form_load_include() to add include files from a form constructor.
* - form_id: Identification of the primary form being constructed and
* processed.
* - base_form_id: Identification for a base form, as declared in a
* hook_forms() implementation.
* - base_form_id: Identification for a base form, as declared in the form
* class's \Drupal\Core\Form\BaseFormIdInterface::getBaseFormId() method.
* - rebuild_info: Internal. Similar to 'build_info', but pertaining to
* self::rebuildForm().
* - rebuild: Normally, after the entire form processing is completed and
......@@ -213,14 +205,6 @@ public function getForm($form_arg);
* need to or should not be cached during the whole form workflow; e.g.,
* data that needs to be accessed during the current form build process
* only. There is no use-case for this functionality in Drupal core.
* - wrapper_callback: Modules that wish to pre-populate certain forms with
* common elements, such as back/next/save buttons in multi-step form
* wizards, may define a form builder function name that returns a form
* structure, which is passed on to the actual form builder function.
* Such implementations may either define the 'wrapper_callback' via
* hook_forms() or have to invoke self::buildForm() (instead of
* self::getForm()) on their own in a custom menu callback to prepare
* $form_state accordingly.
* Information on how certain $form_state properties control redirection
* behavior after form submission may be found in self::redirectForm().
*
......@@ -255,11 +239,7 @@ public function getFormStateDefaults();
*
* @param string $form_id
* The unique string identifying the desired form. If a function with that
* name exists, it is called to build the form array. Modules that need to
* generate the same form (or very similar forms) using different $form_ids
* can implement hook_forms(), which maps different $form_id values to the
* proper form constructor function. Examples may be found in node_forms()
* and search_forms().
* name exists, it is called to build the form array.
* @param array $form_state
* A keyed array containing the current state of the form.
* @param array|null $old_form
......@@ -302,11 +282,7 @@ public function setCache($form_build_id, $form, $form_state);
* @param \Drupal\Core\Form\FormInterface|string $form_arg
* A form object to use to build the form, or the unique string identifying
* the desired form. If $form_arg is a string and a function with that
* name exists, it is called to build the form array. Modules that need to
* generate the same form (or very similar forms) using different $form_ids
* can implement hook_forms(), which maps different $form_id values to the
* proper form constructor function. Examples may be found in node_forms()
* and search_forms().
* name exists, it is called to build the form array.
* @param $form_state
* A keyed array containing the current state of the form. Most important is
* the $form_state['values'] collection, a tree of data used to simulate the
......@@ -354,9 +330,6 @@ public function submitForm($form_arg, &$form_state);
* @param string $form_id
* The unique string identifying the desired form. If a function
* with that name exists, it is called to build the form array.
* Modules that need to generate the same form (or very similar forms)
* using different $form_ids can implement hook_forms(), which maps
* different $form_id values to the proper form constructor function.
* @param array $form_state
* A keyed array containing the current state of the form, including the
* additional arguments to self::getForm() or self::submitForm() in the
......
<?php
/**
* @file
* Definition of Drupal\system\Tests\Form\WrapperTest.
*/
namespace Drupal\system\Tests\Form;
use Drupal\simpletest\WebTestBase;
/**
* Test wrapper form callbacks.
*/
class WrapperTest extends WebTestBase {
/**
* Modules to enable.
*
* @var array
*/
public static $modules = array('form_test');
public static function getInfo() {
return array(
'name' => 'Form wrapper callback',
'description' => 'Tests form wrapper callbacks to pass a prebuilt form to form builder functions.',
'group' => 'Form API',
);
}
/**
* Tests using the form in a usual way.
*/
function testWrapperCallback() {
$this->drupalGet('form_test/wrapper-callback');
$this->assertText('Form wrapper callback element output.', 'The form contains form wrapper elements.');
$this->assertText('Form builder element output.', 'The form contains form builder elements.');
}
}
......@@ -963,9 +963,6 @@ function hook_form_FORM_ID_alter(&$form, &$form_state, $form_id) {
* one exists) check the $form_state. The base form ID is stored under
* $form_state['build_info']['base_form_id'].
*
* See hook_forms() for more information on how to implement base forms in
* Drupal.
*
* Form alter hooks are called in the following order: hook_form_alter(),
* hook_form_BASE_FORM_ID_alter(), hook_form_FORM_ID_alter(). See
* hook_form_alter() for more details.
......@@ -981,7 +978,6 @@ function hook_form_FORM_ID_alter(&$form, &$form_state, $form_id) {
* @see hook_form_alter()
* @see hook_form_FORM_ID_alter()
* @see drupal_prepare_form()
* @see hook_forms()
*/
function hook_form_BASE_FORM_ID_alter(&$form, &$form_state, $form_id) {
// Modification for the form with the given BASE_FORM_ID goes here. For
......@@ -996,85 +992,6 @@ function hook_form_BASE_FORM_ID_alter(&$form, &$form_state, $form_id) {
);
}
/**
* Map form_ids to form builder functions.
*
* By default, when drupal_get_form() is called, the system will look for a
* function with the same name as the form ID, and use that function to build
* the form. If no such function is found, Drupal calls this hook. Modules
* implementing this hook can then provide their own instructions for mapping
* form IDs to constructor functions. As a result, you can easily map multiple
* form IDs to a single form constructor (referred to as a 'base' form).
*
* Using a base form can help to avoid code duplication, by allowing many
* similar forms to use the same code base. Another benefit is that it becomes
* much easier for other modules to apply a general change to the group of
* forms; hook_form_BASE_FORM_ID_alter() can be used to easily alter multiple
* forms at once by directly targeting the shared base form.
*
* Two example use cases where base forms may be useful are given below.
*
* First, you can use this hook to tell the form system to use a different
* function to build certain forms in your module; this is often used to define
* a form "factory" function that is used to build several similar forms. In
* this case, your hook implementation will likely ignore all of the input
* arguments. See node_forms() for an example of this. Note, node_forms() is the
* hook_forms() implementation; the base form itself is defined in node_form().
*
* Second, you could use this hook to define how to build a form with a
* dynamically-generated form ID. In this case, you would need to verify that
* the $form_id input matched your module's format for dynamically-generated
* form IDs, and if so, act appropriately.
*
* @param $form_id
* The unique string identifying the desired form.
* @param $args
* An array containing the original arguments provided to drupal_get_form()
* or drupal_form_submit(). These are always passed to the form builder and
* do not have to be specified manually in 'callback arguments'.
*
* @return
* An associative array whose keys define form_ids and whose values are an
* associative array defining the following keys:
* - callback: The name of the form builder function to invoke. This will be
* used for the base form ID, for example, to target a base form using
* hook_form_BASE_FORM_ID_alter().
* - callback arguments: (optional) Additional arguments to pass to the
* function defined in 'callback', which are prepended to $args.
* - wrapper_callback: (optional) The name of a form builder function to
* invoke before the form builder defined in 'callback' is invoked. This
* wrapper callback may prepopulate the $form array with form elements,
* which will then be already contained in the $form that is passed on to
* the form builder defined in 'callback'. For example, a wrapper callback
* could setup wizard-alike form buttons that are the same for a variety of
* forms that belong to the wizard, which all share the same wrapper
* callback.
*/
function hook_forms($form_id, $args) {
// Simply reroute the (non-existing) $form_id 'mymodule_first_form' to
// 'mymodule_main_form'.
$forms['mymodule_first_form'] = array(
'callback' => 'mymodule_main_form',
);
// Reroute the $form_id and prepend an additional argument that gets passed to
// the 'mymodule_main_form' form builder function.
$forms['mymodule_second_form'] = array(
'callback' => 'mymodule_main_form',
'callback arguments' => array('some parameter'),
);
// Reroute the $form_id, but invoke the form builder function
// 'mymodule_main_form_wrapper' first, so we can prepopulate the $form array
// that is passed to the actual form builder 'mymodule_main_form'.
$forms['mymodule_wrapped_form'] = array(
'callback' => 'mymodule_main_form',
'wrapper_callback' => 'mymodule_main_form_wrapper',
);
return $forms;
}
/**
* Alter an email message created with the drupal_mail() function.
*
......
......@@ -742,37 +742,6 @@ function form_label_test_form() {
return $form;
}
/**
* Menu callback; Invokes a form builder function with a wrapper callback.
*
* @deprecated \Drupal\form_test\Controller\FormTestController::wrapperCallback()
*/
function form_test_wrapper_callback($form_id) {
$form_state = array(
'build_info' => array('args' => array()),
'wrapper_callback' => 'form_test_wrapper_callback_wrapper',
);
return drupal_build_form($form_id, $form_state);
}
/**
* Form wrapper for form_test_wrapper_callback_form().
*/
function form_test_wrapper_callback_wrapper($form, &$form_state) {
$form['wrapper'] = array('#markup' => 'Form wrapper callback element output.');
return $form;
}
/**
* Form builder for form wrapper callback test.
*
* @deprecated Use \Drupal\form_test\testWrapperCallback()
*/
function form_test_wrapper_callback_form($form, &$form_state) {
$form['builder'] = array('#markup' => 'Form builder element output.');
return $form;
}
/**
* Form builder for form_state_values_clean() test.
*
......
......@@ -68,15 +68,6 @@ form_test.autocomplete_2:
requirements:
_permission: 'access autocomplete test'
form_test.wrapper:
path: '/form_test/wrapper-callback'
defaults:
_title: 'Form wrapper callback test'
_content: '\Drupal\form_test\Controller\FormTestController::wrapperCallback'
form_id: 'form_test_wrapper_callback_form'
requirements:
_access: 'TRUE'
form_test.alter_form:
path: '/form-test/alter'
defaults:
......
......@@ -35,11 +35,4 @@ public function twoFormInstances() {
return $return;
}
/**
* @todo Remove form_test_wrapper_callback().
*/
public function wrapperCallback($form_id) {
return form_test_wrapper_callback($form_id);
}
}
......@@ -129,15 +129,6 @@ public function testStorage() {
return drupal_get_form('form_test_storage_form');
}
/**
* Wraps form_test_wrapper_callback_form().
*
* @todo Remove form_test_wrapper_callback_form().
*/
public function testWrapperCallback() {
return drupal_get_form('form_test_wrapper_callback_form');
}
/**
* Wraps form_test_form_state_values_clean_form().
*
......
......@@ -341,31 +341,6 @@ public function testBuildFormWithObject() {
$this->assertSame($form_id, $form['#id']);
}
/**
* Tests the buildForm() method with a hook_forms() based form ID.
*/
public function testBuildFormWithHookForms() {
$form_id = 'test_form_id_specific';
$base_form_id = 'test_form_id';
$expected_form = $base_form_id();
// Set the module handler to return information from hook_forms().
$this->moduleHandler->expects($this->once())
->method('invokeAll')
->with('forms', array($form_id, array()))
->will($this->returnValue(array(
'test_form_id_specific' => array(
'callback' => $base_form_id,
),
)));
$form_state = array();
$form = $this->formBuilder->buildForm($form_id, $form_state);
$this->assertFormElement($expected_form, $form, 'test');
$this->assertSame($form_id, $form_state['build_info']['form_id']);
$this->assertSame($form_id, $form['#id']);
$this->assertSame($base_form_id, $form_state['build_info']['base_form_id']);
}
/**
* Tests the rebuildForm() method.
*/
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment