PHPackages                             daisukedaisuke/awaitformoptions - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Utility &amp; Helpers](/categories/utility)
4. /
5. daisukedaisuke/awaitformoptions

ActiveLibrary[Utility &amp; Helpers](/categories/utility)

daisukedaisuke/awaitformoptions
===============================

v4.0.2(2mo ago)61282[2 issues](https://github.com/DaisukeDaisuke/AwaitFormOptions/issues)GPL-3.0PHPPHP &gt;=8.2

Since Jun 30Pushed 1w ago1 watchersCompare

[ Source](https://github.com/DaisukeDaisuke/AwaitFormOptions)[ Packagist](https://packagist.org/packages/daisukedaisuke/awaitformoptions)[ RSS](/packages/daisukedaisuke-awaitformoptions/feed)WikiDiscussions main Synced today

READMEChangelogDependencies (5)Versions (38)Used By (0)

AwaitFormOptions
================

[](#awaitformoptions)

Overview
--------

[](#overview)

An option-driven form handler framework built on AwaitForm for `pmmp` plugins.
Designed to modularize complex user interactions and support clean, reusable, async code.

Requirements
------------

[](#requirements)

- [Cosmoverse/AwaitForm](https://github.com/Cosmoverse/AwaitForm)
- [SOF3/await-generator](https://github.com/SOF3/await-generator)

---

Important

If you want to use AwaitFormOptions, put this somewhere in your plugin:

```
if(!AwaitForm::isRegistered()){
    AwaitForm::register($this); //$this must extend pluginbase
}
```

```
use cosmicpe\awaitform\AwaitForm;
```

---

⚠️ Performance Notice
---------------------

[](#️-performance-notice)

Please be advised that AwaitFormOptions is inherently demanding, both in terms of function call overhead and PHP's garbage collection behavior.
Due to its layered design and dynamic generator usage, it may not be suitable for performance-critical paths or tight loops
If maximum performance is your goal, we strongly recommend using AwaitForm directly, rather than through this abstraction layer.
AwaitFormOptions is designed to simplify complex form workflows and improve developer ergonomics—not to optimize execution speed.

---

Note

When using an older version, please refer to the README for that specific version
This README also serves as the specification and documentation, and is continuously updated to reflect the latest version. It does not support older versions.
To view documentation for older versions, please refer to the corresponding tags.

Support Status
1.x series: End of life, There is a significant memory leak
2.x series: End of life, 3.x series: Archived and issues are supported
4.x series: In development

Why?
----

[](#why)

Using AwaitForm directly is simple for small forms:

```
public function a(PlayerItemUseEvent $event): void {
	$player = $event->getPlayer();
	try {
		await::f2c(function() use ($player) {
			$form = AwaitForm::form("form", [
				FormControl::input("Current HP:", "20", (string) $player->getHealth()),
				FormControl::input("Max HP:", "20", (string) $player->getMaxHealth()),
			]);
			[$current, $max] = yield from $form->request($player);
			$player->setHealth((float) $current);
			$player->setMaxHealth((int) $max);
			$player->sendMessage("HP: {$current}/{$max}");
		});
	} catch (AwaitFormException | FormValidationException) {
		// Cancelled or invalid input
	}
}
```

But when handling multiple related form steps in one screen, things get messy fast.
**Too many responsibilities are packed into one place.**

 See demo    m1.mp4    ---

Solution: AwaitFormOptions
--------------------------

[](#solution-awaitformoptions)

Split your form logic into reusable option classes:

```
  public function a(PlayerItemUseEvent $event) : void{
      $player = $event->getPlayer();
      Await::f2c(function() use ($player){
          try{
              yield from AwaitFormOptions::sendFormAsync(
                  player: $player,
                  title: "test",
                  options: [
                      new HPFormOptions($player),
                  ]
              );
          }catch(FormValidationException|AwaitFormOptionsParentException){
              // Form failed validation
          }
      });
  }
```

```
use pocketmine\plugin\PluginBase;
use pocketmine\event\Listener;
use pocketmine\event\player\PlayerItemUseEvent;
use SOFe\AwaitGenerator\Await;
use DaisukeDaisuke\AwaitFormOptions\AwaitFormOptions;
use DaisukeDaisuke\AwaitFormOptions\exception\AwaitFormOptionsParentException;
use pocketmine\form\FormValidationException;
use cosmicpe\awaitform\AwaitForm;
```

---

Example Option Class
--------------------

[](#example-option-class)

Each option will yield from `$this->request($form);` and wait for the response. No more losing context!

Tip

`yield from $this->request()` must be called only once per generator.
Calling it a second time in the same generator will throw a `AwaitFormOptionsExpectedCrashException`.
If you need to re-show a form, return from the current generator and call it again from the parent context.

Additionally, the following exceptions may be thrown from `request()`:

- `AwaitFormOptionsExpectedCrashException`: When `request()` is called more than once in the same generator.
- `AwaitFormOptionsExpectedCrashException`: When the provided form/button array is invalid.
- `AwaitFormOptionsChildException`: If the player rejects the form, input is invalid, or the player logs out.

The try-catch in the child generator may be omitted, but is not recommended.

```
