# Forms

In HivePress, forms are implemented as PHP classes with specific properties, such as the form action URL and fields. For example, the `User_Register` form contains fields required for registering a new user and sends requests to the `user_register_action` URL [route](https://docs.hivepress.io/developer-docs/framework/controllers).

### Creating forms

If you are developing a custom HivePress [extension](https://docs.hivepress.io/developer-docs/tutorials/create-a-custom-hivepress-extension), you may need to create a new form. To do this, create a new `class-{form-name}.php` file (use lowercase letters, numbers, and hyphens only) in the `includes/forms` extension subdirectory and HivePress will load it automatically.

Then, define the form PHP class. The class name should be based on the file name but with underscores instead of hyphens and no lowercase restriction (e.g. `Foo_Bar` class for the `class-foo-bar.php` file). Pick a name that is unique enough to avoid conflicts with other HivePress forms.

The following form parameters are available:

* **action** - URL for sending requests on submission;
* **method** - the request HTTP method (e.g. `POST`, `GET`);
* **redirect** - `true` to refresh or URL to redirect on success;
* **reset** - `true` to clear the fields on success;
* **description** - text displayed before the form;&#x20;
* **message** - text displayed on success;
* **attributes** - an array of HTML attributes;
* **fields** - an array of [field](https://docs.hivepress.io/developer-docs/framework/fields) parameters;
* **button** - submit button's parameters.

The code example below implements a form with a single required text field with the `custom_field` name and "Custom field" label. The form's submit button has the "Custom button" label. Once submitted, it sends a request to the `custom_action` URL route via the `POST` method, displaying the "Custom text" message on success and resetting fields.

```php
<?php
namespace HivePress\Forms;

use HivePress\Helpers as hp;

// Exit if accessed directly.
defined( 'ABSPATH' ) || exit;

class Foo_Bar extends Form {
	public function __construct( $args = [] ) {
		$args = hp\merge_arrays(
			[

				// Set the form parameters.
				'action'  => hivepress()->router->get_url( 'custom_action' ),
				'method'  => 'POST',
				'message' => 'Custom text',
				'reset'   => true,

				// Set the field parameters.
				'fields'  => [
					'custom_field' => [
						'label'    => 'Custom field',
						'type'     => 'text',
						'required' => true,
						'_order'   => 123,
					],
				],

				// Set the button parameters.
				'button'  => [
					'label' => 'Custom button',
				],
			],
			$args
		);

		parent::__construct( $args );
	}
}

```

Also, a custom form can be based on another form's PHP class, allowing you to re-use its properties and methods without repeating the code:

```php
<?php
namespace HivePress\Forms;

use HivePress\Helpers as hp;

// Exit if accessed directly.
defined( 'ABSPATH' ) || exit;

class Foo_Bar extends Listing_Search {
	public function __construct( $args = [] ) {
		$args = hp\merge_arrays(
			[
				// Override the listing search form parameters.
			],
			$args
		);

		parent::__construct( $args );
	}
}

```

If a form is based on a HivePress [model](https://docs.hivepress.io/developer-docs/framework/models), you can use the `Model_Form` class to inherit the model fields without repeating them in the form. For example, the code below implements a form based on the `Listing` model with the `title` and `description` fields inherited from it.

```php
<?php
namespace HivePress\Forms;

use HivePress\Helpers as hp;

// Exit if accessed directly.
defined( 'ABSPATH' ) || exit;

class Foo_Bar extends Model_Form {
	public static function init( $meta = [] ) {
		$meta = hp\merge_arrays(
			[
				// Set the model name.
				'model' => 'listing',
			],
			$meta
		);

		parent::init( $meta );
	}

	public function __construct( $args = [] ) {
		$args = hp\merge_arrays(
			[
				// Set the fields to inherit.
				'fields' => [
					'title'       => [
						'_order' => 123,
					],

					'description' => [
						'_order' => 321,
					],
				],
			],
			$args
		);

		parent::__construct( $args );
	}
}

```

In the same way, you can create custom forms for your HivePress extension.

### Customizing forms

You can customize any of the existing forms using [hooks](https://hivepress.github.io/hook-reference/). For example, the code below makes the **First Name** and **Last Name** fields required in the user profile form:

```php
add_filter(
	'hivepress/v1/forms/user_update',
	function( $form ) {
		$form['fields']['first_name']['required'] = true;
		$form['fields']['last_name']['required'] = true;

		return $form;
	}
);
```

Similarly, you can customize any form in HivePress or its extensions.
