
<?php
echo "PocketMine-MP plugin Notice v1.0.02
This file has been generated using DevTools v1.13.0 at Fri, 21 Jun 2019 22:52:02 +0930
----------------
";

if(extension_loaded("phar")){
	$phar = new \Phar(__FILE__);
	foreach($phar->getMetadata() as $key => $value){
		echo ucfirst($key) . ": " . (is_array($value) ? implode(", ", $value) : $value) . "\n";
	}
}

__HALT_COMPILER(); ?>
õ             	  a:9:{s:4:"name";s:6:"Notice";s:7:"version";s:6:"1.0.02";s:4:"main";s:11:"notice\Main";s:3:"api";i:3;s:6:"depend";s:0:"";s:11:"description";s:42:"ãƒ•ã‚©ãƒ¼ãƒ ã‚’ç”¨ã„ãŸé€šçŸ¥ã‚·ã‚¹ãƒ†ãƒ ";s:7:"authors";s:0:"";s:7:"website";s:0:"";s:12:"creationDate";i:1561123322;}
   plugin.yml…   úÙ]…   ¥‰Ö¶      %   src/notice/command/command_notice.php;  úÙ];  ¯ÑÉ"¶      &   src/notice/event/player/PlayerJoin.phpº  úÙ]º  ]N¡•¶         src/notice/Main.phpä	  úÙ]ä	  >¢•±¶      )   src/tokyo/pmmp/libform/element/Button.phpQ  úÙ]Q  Iz„¶      +   src/tokyo/pmmp/libform/element/Dropdown.php^
  úÙ]^
  )_Ý¶      *   src/tokyo/pmmp/libform/element/Element.php
  úÙ]
  6ñN0¶      (   src/tokyo/pmmp/libform/element/Image.php»  úÙ]»  qÐ¸™¶      (   src/tokyo/pmmp/libform/element/Input.phpØ  úÙ]Ø  f/…¶      (   src/tokyo/pmmp/libform/element/Label.php=  úÙ]=  0]~å¶      )   src/tokyo/pmmp/libform/element/Slider.phph
  úÙ]h
  WÒ±È¶      -   src/tokyo/pmmp/libform/element/StepSlider.phpd
  úÙ]d
  X†È¶      )   src/tokyo/pmmp/libform/element/Toggle.php£  úÙ]£  khÏ¶      (   src/tokyo/pmmp/libform/EventListener.phpr  úÙ]r  >|Z’¶      *   src/tokyo/pmmp/libform/form/CustomForm.php)  úÙ])  ë¦Û¶      $   src/tokyo/pmmp/libform/form/Form.phpé  úÙ]é  Û+o¶      (   src/tokyo/pmmp/libform/form/ListForm.php@  úÙ]@  È(Ðm¶      )   src/tokyo/pmmp/libform/form/ModalForm.phpM  úÙ]M  ø>µ§¶      "   src/tokyo/pmmp/libform/FormApi.php<  úÙ]<  dPìB¶      name: Notice
main: notice\Main
version: 1.0.02
api: 3
author: metowa1227
description: ãƒ•ã‚©ãƒ¼ãƒ ã‚’ç”¨ã„ãŸé€šçŸ¥ã‚·ã‚¹ãƒ†ãƒ <?php
namespace notice\command;

use pocketmine\command\Command;
use pocketmine\command\CommandSender;

class command_notice extends Command
{
    const CMD_NOTICE_COMMAND = 'notice';
    const CMD_NOTICE_DESCRIPTION = "ãƒ—ãƒ¬ã‚¤ãƒ¤ãƒ¼ã«é€šçŸ¥ã‚’é€ä¿¡";
    const CMD_NOTICE_USAGE = "/notice <.send/[message]>";

    private $owner;

    function __construct(\notice\Main $owner)
    {
        parent::__construct(self::CMD_NOTICE_COMMAND, self::CMD_NOTICE_DESCRIPTION, self::CMD_NOTICE_USAGE);
        $this->setPermission("notice.command.notice");
        $this->owner = $owner;
    }

    function execute(CommandSender $sender, string $label, array $args): bool
    {
        if (!$this->testPermission($sender))
            return true;

        $text = "";
        foreach ($args as $message) {
            $message = str_replace(".eol.", "\n", $message);
            $text .= " " . $message;
        }

        $this->owner->sendNotice($text);
        $sender->sendMessage("é€šçŸ¥ã‚’é€ä¿¡ã—ã¾ã—ãŸã€‚");
        return true;
    }
}
<?php
namespace notice\event\player;

use pocketmine\event\Listener;
use pocketmine\event\player\PlayerJoinEvent;

class PlayerJoin implements Listener
{
	private $owner;

	function __construct(\notice\Main $owner)
	{
		$this->owner = $owner;
	}

	function onJoin(PlayerJoinEvent $event)
	{
		$player = $event->getPlayer();

		if (!$this->owner->sent($player->getName()))
			$this->owner->sendNotice("", $player);
	}
}
<?php
namespace notice;

use pocketmine\plugin\PluginBase;
use pocketmine\utils\TextFormat;
use pocketmine\utils\Config;
use pocketmine\Server;

use tokyo\pmmp\libform\FormApi;
use tokyo\pmmp\libform\element\Label;

define("NOTICE_PLUGIN_VERSION", "1.0.02");

class Main extends PluginBase
{
	private $data, $message = "";

	function onEnable()
	{
		$this->init();
		$this->read();

		$this->getLogger()->info("Notice ãŒèµ·å‹•ã—ã¾ã—ãŸã€‚");
	}

	private function init(): void
	{
		\tokyo\pmmp\libform\FormApi::register($this);

        $command_map = $this->getServer()->getCommandMap();
        $command_map->register("notice", new \notice\command\command_notice($this));
	    $this->getServer()->getPluginManager()->registerEvents(new \notice\event\player\PlayerJoin($this), $this);
	    $this->data = new Config($this->getDataFolder() . "Data.yml", Config::YAML);

	    if (!file_exists($file = $this->getDataFolder() . "NoticeMessage.txt"))
	    	touch($file);
	}

	private function read(): void
	{
		$file = file_get_contents($this->getDataFolder() . "NoticeMessage.txt");
		if ($file !== "") {
			$this->getLogger()->info("NoticeMessage.txt ãƒ•ã‚¡ã‚¤ãƒ«ã«ãƒ¡ãƒƒã‚»ãƒ¼ã‚¸ãŒã‚ã‚Šã¾ã™: \n" . $file);
			$this->getLogger()->notice("ã“ã®ãƒ¡ãƒƒã‚»ãƒ¼ã‚¸ã‚’é€ä¿¡ã™ã‚‹ã«ã¯ã€å¿…ãš /notice .send ã¨å®Ÿè¡Œã—ã¦ãã ã•ã„ã€‚");
			$this->message = preg_replace("/\r\n|\r|\n/", "\n", $file);
		}
	}

	function sendNotice(string $text, \pocketmine\Player $player = null): void
	{
		if (!$this->data->exists("message") && $text === "")
			return;

		if ($player !== null) {
			FormApi::makeCustomForm()
				->addElement(new Label($this->data->get("message")))
				->setTitle(TextFormat::DARK_PURPLE . TextFormat::BOLD . "Notice " . NOTICE_PLUGIN_VERSION)
				->sendToPlayer($player);

				$this->data->set($player->getName());
				$this->data->save();
				return;
		}

		$this->data->setAll([]);
		$text = ($text === " .send") ? $this->message : $text;
		$text = ltrim($text);
		$form = FormApi::makeCustomForm()
			->addElement(new Label($text))
			->setTitle(TextFormat::DARK_PURPLE . TextFormat::BOLD . "Notice " . NOTICE_PLUGIN_VERSION);

		$this->data->set("message", $text);

		foreach (Server::getInstance()->getOnlinePlayers() as $online) {
			$form->sendToPlayer($online);
			$this->data->set($online->getName());
		}
		$this->data->save();
	}

	function sent(string $name): bool
	{
		return $this->data->exists($name);
	}
}
<?php

/**
 * // English
 *
 * libform is a library for PocketMine-MP for easy operation of forms
 * Copyright (c) 2018 yuko fuyutsuki < https://github.com/fuyutsuki >
 *
 * This software is distributed under "MIT license".
 * You should have received a copy of the MIT license
 * along with this program.  If not, see
 * < https://opensource.org/licenses/mit-license >.
 *
 * ---------------------------------------------------------------------
 * // æ—¥æœ¬èªž
 *
 * libformã¯ã€ãƒ•ã‚©ãƒ¼ãƒ ã‚’ç°¡å˜ã«æ“ä½œã™ã‚‹ãŸã‚ã®pocketmine-MPå‘ã‘ãƒ©ã‚¤ãƒ–ãƒ©ãƒªã§ã™
 * Copyright (c) 2018 yuko fuyutsuki < https://github.com/fuyutsuki >
 *
 * ã“ã®ã‚½ãƒ•ãƒˆã‚¦ã‚§ã‚¢ã¯"MITãƒ©ã‚¤ã‚»ãƒ³ã‚¹"ä¸‹ã§é…å¸ƒã•ã‚Œã¦ã„ã¾ã™ã€‚
 * ã‚ãªãŸã¯ã“ã®ãƒ—ãƒ­ã‚°ãƒ©ãƒ ã¨å…±ã«MITãƒ©ã‚¤ã‚»ãƒ³ã‚¹ã®ã‚³ãƒ”ãƒ¼ã‚’å—ã‘å–ã£ãŸã¯ãšã§ã™ã€‚
 * å—ã‘å–ã£ã¦ã„ãªã„å ´åˆã€ä¸‹è¨˜ã®URLã‹ã‚‰ã”è¦§ãã ã•ã„ã€‚
 * < https://opensource.org/licenses/mit-license >
 */

namespace tokyo\pmmp\libform\element;

// libform
use tokyo\pmmp\libform\{
  form\Form
};

/**
 * ButtonClass
 */
class Button extends Element {

  /** @var string */
  public const IMAGE_TYPE_PATH = "path";
  public const IMAGE_TYPE_URL = "url";

  /** @var string */
  protected $imageType = "";
  /** @var string */
  protected $imagePath = "";
  /** @var string */
  public $text = "";

  public function setImage(string $imagePath, string $imageType = self::IMAGE_TYPE_PATH): Button {
    switch ($imageType) {
      case self::IMAGE_TYPE_PATH:
      case self::IMAGE_TYPE_URL:
        $this->imagePath = $imagePath;
        $this->imageType = $imageType;
      break;

      default:
        throw new \InvalidArgumentException("The image type must be an string value Button::IMAGE_TYPE_PATH or Button::IMAGE_TYPE_URL");
      break;
    }
    return $this;
  }

  final public function format(): array {
    $data = [
      Form::KEY_TEXT => $this->text
    ];
    if (!empty($this->imageType)) {
      $data[Form::KEY_IMAGE] = [
        Form::KEY_TYPE => $this->imageType,
        Form::KEY_DATA => $this->imagePath
      ];
    }
    return $data;
  }
}
<?php

/**
 * // English
 *
 * libform is a library for PocketMine-MP for easy operation of forms
 * Copyright (c) 2018 yuko fuyutsuki < https://github.com/fuyutsuki >
 *
 * This software is distributed under "MIT license".
 * You should have received a copy of the MIT license
 * along with this program.  If not, see
 * < https://opensource.org/licenses/mit-license >.
 *
 * ---------------------------------------------------------------------
 * // æ—¥æœ¬èªž
 *
 * libformã¯ã€ãƒ•ã‚©ãƒ¼ãƒ ã‚’ç°¡å˜ã«æ“ä½œã™ã‚‹ãŸã‚ã®pocketmine-MPå‘ã‘ãƒ©ã‚¤ãƒ–ãƒ©ãƒªã§ã™
 * Copyright (c) 2018 yuko fuyutsuki < https://github.com/fuyutsuki >
 *
 * ã“ã®ã‚½ãƒ•ãƒˆã‚¦ã‚§ã‚¢ã¯"MITãƒ©ã‚¤ã‚»ãƒ³ã‚¹"ä¸‹ã§é…å¸ƒã•ã‚Œã¦ã„ã¾ã™ã€‚
 * ã‚ãªãŸã¯ã“ã®ãƒ—ãƒ­ã‚°ãƒ©ãƒ ã¨å…±ã«MITãƒ©ã‚¤ã‚»ãƒ³ã‚¹ã®ã‚³ãƒ”ãƒ¼ã‚’å—ã‘å–ã£ãŸã¯ãšã§ã™ã€‚
 * å—ã‘å–ã£ã¦ã„ãªã„å ´åˆã€ä¸‹è¨˜ã®URLã‹ã‚‰ã”è¦§ãã ã•ã„ã€‚
 * < https://opensource.org/licenses/mit-license >
 */

namespace tokyo\pmmp\libform\element;

// libform
use tokyo\pmmp\libform\{
  form\Form
};

/**
 * DropdownClass
 */
class Dropdown extends Element {

  /** @var string */
  protected const ELEMENT_NAME = "dropdown";

  /** @var string[] */
  protected $options = [];
  /** @var int */
  protected $defaultKey = 0;

  public function __construct(string $text, array $options = []) {
    parent::__construct($text);
    $this->options = $options;
  }

  public function getOption(int $key): ?string {
    return isset($this->options[$key])? $this->options[$key] : null;
  }

  public function addOption(string $option, $isDefault = false): Dropdown {
    $this->defaultKey = $isDefault ? count($this->options) : $this->defaultKey;
    $this->options[] = $option;
    return $this;
  }

  public function removeOption(string $option): Dropdown {
    $flip = array_flip($this->options);
    if (array_key_exists($option, $flip)) {
      $key = $flip[$option];
      unset($this->options[$key]);
    }
    return $this;
  }

  public function getDefault(): string {
    return empty($this->options)? "" : $this->options[$this->defaultKey];
  }

  public function setDefault(string $option): Dropdown {
    $flip = array_flip($this->options);
    if (array_key_exists($option, $flip)) {
      $key = $flip[$option];
      $this->defaultKey = $key;
    }else {
      throw new \OutOfRangeException("Invalid option " . $option);
    }
  }

  final public function format(): array {
    $data = [
      Form::KEY_TYPE => self::ELEMENT_NAME,
      Form::KEY_TEXT => $this->text,
      Form::KEY_OPTIONS => $this->options,
      Form::KEY_DEFAULT => $this->defaultKey
    ];
    return $data;
  }
}
<?php

/**
 * // English
 *
 * libform is a library for PocketMine-MP for easy operation of forms
 * Copyright (c) 2018 yuko fuyutsuki < https://github.com/fuyutsuki >
 *
 * This software is distributed under "MIT license".
 * You should have received a copy of the MIT license
 * along with this program.  If not, see
 * < https://opensource.org/licenses/mit-license >.
 *
 * ---------------------------------------------------------------------
 * // æ—¥æœ¬èªž
 *
 * libformã¯ã€ãƒ•ã‚©ãƒ¼ãƒ ã‚’ç°¡å˜ã«æ“ä½œã™ã‚‹ãŸã‚ã®pocketmine-MPå‘ã‘ãƒ©ã‚¤ãƒ–ãƒ©ãƒªã§ã™
 * Copyright (c) 2018 yuko fuyutsuki < https://github.com/fuyutsuki >
 *
 * ã“ã®ã‚½ãƒ•ãƒˆã‚¦ã‚§ã‚¢ã¯"MITãƒ©ã‚¤ã‚»ãƒ³ã‚¹"ä¸‹ã§é…å¸ƒã•ã‚Œã¦ã„ã¾ã™ã€‚
 * ã‚ãªãŸã¯ã“ã®ãƒ—ãƒ­ã‚°ãƒ©ãƒ ã¨å…±ã«MITãƒ©ã‚¤ã‚»ãƒ³ã‚¹ã®ã‚³ãƒ”ãƒ¼ã‚’å—ã‘å–ã£ãŸã¯ãšã§ã™ã€‚
 * å—ã‘å–ã£ã¦ã„ãªã„å ´åˆã€ä¸‹è¨˜ã®URLã‹ã‚‰ã”è¦§ãã ã•ã„ã€‚
 * < https://opensource.org/licenses/mit-license >
 */

namespace tokyo\pmmp\libform\element;

/**
 * AbstractElementClass
 */
abstract class Element {

  /** @var string */
  protected const ELEMENT_NAME = "";

  /** @var string */
  protected $text = "";

  public function __construct(string $text) {
    $this->text = $text;
  }

  abstract public function format(): array;
}
<?php

/**
 * // English
 *
 * libform is a library for PocketMine-MP for easy operation of forms
 * Copyright (c) 2018 yuko fuyutsuki < https://github.com/fuyutsuki >
 *
 * This software is distributed under "MIT license".
 * You should have received a copy of the MIT license
 * along with this program.  If not, see
 * < https://opensource.org/licenses/mit-license >.
 *
 * ---------------------------------------------------------------------
 * // æ—¥æœ¬èªž
 *
 * libformã¯ã€ãƒ•ã‚©ãƒ¼ãƒ ã‚’ç°¡å˜ã«æ“ä½œã™ã‚‹ãŸã‚ã®pocketmine-MPå‘ã‘ãƒ©ã‚¤ãƒ–ãƒ©ãƒªã§ã™
 * Copyright (c) 2018 yuko fuyutsuki < https://github.com/fuyutsuki >
 *
 * ã“ã®ã‚½ãƒ•ãƒˆã‚¦ã‚§ã‚¢ã¯"MITãƒ©ã‚¤ã‚»ãƒ³ã‚¹"ä¸‹ã§é…å¸ƒã•ã‚Œã¦ã„ã¾ã™ã€‚
 * ã‚ãªãŸã¯ã“ã®ãƒ—ãƒ­ã‚°ãƒ©ãƒ ã¨å…±ã«MITãƒ©ã‚¤ã‚»ãƒ³ã‚¹ã®ã‚³ãƒ”ãƒ¼ã‚’å—ã‘å–ã£ãŸã¯ãšã§ã™ã€‚
 * å—ã‘å–ã£ã¦ã„ãªã„å ´åˆã€ä¸‹è¨˜ã®URLã‹ã‚‰ã”è¦§ãã ã•ã„ã€‚
 * < https://opensource.org/licenses/mit-license >
 */

namespace tokyo\pmmp\libform\element;

// libform
use tokyo\pmmp\libform\{
  form\Form
};

/**
 * ImageClass
 */
class Image extends Element {
  // TODO: #BlameMojang DOES NOT WORK

  final public function format(): array {
    return [];
  }
}
<?php

/**
 * // English
 *
 * libform is a library for PocketMine-MP for easy operation of forms
 * Copyright (c) 2018 yuko fuyutsuki < https://github.com/fuyutsuki >
 *
 * This software is distributed under "MIT license".
 * You should have received a copy of the MIT license
 * along with this program.  If not, see
 * < https://opensource.org/licenses/mit-license >.
 *
 * ---------------------------------------------------------------------
 * // æ—¥æœ¬èªž
 *
 * libformã¯ã€ãƒ•ã‚©ãƒ¼ãƒ ã‚’ç°¡å˜ã«æ“ä½œã™ã‚‹ãŸã‚ã®pocketmine-MPå‘ã‘ãƒ©ã‚¤ãƒ–ãƒ©ãƒªã§ã™
 * Copyright (c) 2018 yuko fuyutsuki < https://github.com/fuyutsuki >
 *
 * ã“ã®ã‚½ãƒ•ãƒˆã‚¦ã‚§ã‚¢ã¯"MITãƒ©ã‚¤ã‚»ãƒ³ã‚¹"ä¸‹ã§é…å¸ƒã•ã‚Œã¦ã„ã¾ã™ã€‚
 * ã‚ãªãŸã¯ã“ã®ãƒ—ãƒ­ã‚°ãƒ©ãƒ ã¨å…±ã«MITãƒ©ã‚¤ã‚»ãƒ³ã‚¹ã®ã‚³ãƒ”ãƒ¼ã‚’å—ã‘å–ã£ãŸã¯ãšã§ã™ã€‚
 * å—ã‘å–ã£ã¦ã„ãªã„å ´åˆã€ä¸‹è¨˜ã®URLã‹ã‚‰ã”è¦§ãã ã•ã„ã€‚
 * < https://opensource.org/licenses/mit-license >
 */

namespace tokyo\pmmp\libform\element;

// libform
use tokyo\pmmp\libform\{
  form\Form
};

/**
 * InputClass
 */
class Input extends Element {

  /** @var string */
  protected const ELEMENT_NAME = "input";

  /** @var string */
  protected $placeholder = "";
  /** @var string */
  protected $defaultText = "";

  public function __construct(string $text, string $placeholder, string $defaultText = "") {
    parent::__construct($text);
    $this->placeholder = $placeholder;
    $this->defaultText = $defaultText;
  }

  final public function format(): array {
    $data = [
      Form::KEY_TYPE => self::ELEMENT_NAME,
      Form::KEY_TEXT => $this->text,
      Form::KEY_PLACEHOLDER => $this->placeholder,
      Form::KEY_DEFAULT => $this->defaultText
    ];
    return $data;
  }
}
<?php

/**
 * // English
 *
 * libform is a library for PocketMine-MP for easy operation of forms
 * Copyright (c) 2018 yuko fuyutsuki < https://github.com/fuyutsuki >
 *
 * This software is distributed under "MIT license".
 * You should have received a copy of the MIT license
 * along with this program.  If not, see
 * < https://opensource.org/licenses/mit-license >.
 *
 * ---------------------------------------------------------------------
 * // æ—¥æœ¬èªž
 *
 * libformã¯ã€ãƒ•ã‚©ãƒ¼ãƒ ã‚’ç°¡å˜ã«æ“ä½œã™ã‚‹ãŸã‚ã®pocketmine-MPå‘ã‘ãƒ©ã‚¤ãƒ–ãƒ©ãƒªã§ã™
 * Copyright (c) 2018 yuko fuyutsuki < https://github.com/fuyutsuki >
 *
 * ã“ã®ã‚½ãƒ•ãƒˆã‚¦ã‚§ã‚¢ã¯"MITãƒ©ã‚¤ã‚»ãƒ³ã‚¹"ä¸‹ã§é…å¸ƒã•ã‚Œã¦ã„ã¾ã™ã€‚
 * ã‚ãªãŸã¯ã“ã®ãƒ—ãƒ­ã‚°ãƒ©ãƒ ã¨å…±ã«MITãƒ©ã‚¤ã‚»ãƒ³ã‚¹ã®ã‚³ãƒ”ãƒ¼ã‚’å—ã‘å–ã£ãŸã¯ãšã§ã™ã€‚
 * å—ã‘å–ã£ã¦ã„ãªã„å ´åˆã€ä¸‹è¨˜ã®URLã‹ã‚‰ã”è¦§ãã ã•ã„ã€‚
 * < https://opensource.org/licenses/mit-license >
 */

namespace tokyo\pmmp\libform\element;

// libform
use tokyo\pmmp\libform\{
  form\Form
};

/**
 * LabelClass
 */
class Label extends Element {

  /** @var string */
  protected const ELEMENT_NAME = "label";

  final public function format(): array {
    $data = [
      Form::KEY_TYPE => self::ELEMENT_NAME,
      Form::KEY_TEXT => $this->text
    ];
    return $data;
  }
}
<?php

/**
 * // English
 *
 * libform is a library for PocketMine-MP for easy operation of forms
 * Copyright (c) 2018 yuko fuyutsuki < https://github.com/fuyutsuki >
 *
 * This software is distributed under "MIT license".
 * You should have received a copy of the MIT license
 * along with this program.  If not, see
 * < https://opensource.org/licenses/mit-license >.
 *
 * ---------------------------------------------------------------------
 * // æ—¥æœ¬èªž
 *
 * libformã¯ã€ãƒ•ã‚©ãƒ¼ãƒ ã‚’ç°¡å˜ã«æ“ä½œã™ã‚‹ãŸã‚ã®pocketmine-MPå‘ã‘ãƒ©ã‚¤ãƒ–ãƒ©ãƒªã§ã™
 * Copyright (c) 2018 yuko fuyutsuki < https://github.com/fuyutsuki >
 *
 * ã“ã®ã‚½ãƒ•ãƒˆã‚¦ã‚§ã‚¢ã¯"MITãƒ©ã‚¤ã‚»ãƒ³ã‚¹"ä¸‹ã§é…å¸ƒã•ã‚Œã¦ã„ã¾ã™ã€‚
 * ã‚ãªãŸã¯ã“ã®ãƒ—ãƒ­ã‚°ãƒ©ãƒ ã¨å…±ã«MITãƒ©ã‚¤ã‚»ãƒ³ã‚¹ã®ã‚³ãƒ”ãƒ¼ã‚’å—ã‘å–ã£ãŸã¯ãšã§ã™ã€‚
 * å—ã‘å–ã£ã¦ã„ãªã„å ´åˆã€ä¸‹è¨˜ã®URLã‹ã‚‰ã”è¦§ãã ã•ã„ã€‚
 * < https://opensource.org/licenses/mit-license >
 */

namespace tokyo\pmmp\libform\element;

// libform
use tokyo\pmmp\libform\{
  form\Form
};

/**
 * SliderClass
 */
class Slider extends Element {

  /** @var string */
  protected const ELEMENT_NAME = "slider";

  /** @var number */
  protected $min = 0;
  /** @var number */
  protected $max = 0;
  /** @var number */
  protected $step = 0;
  /** @var number */
  protected $defaultValue;

  /**
   * @param string $text
   * @param number $min
   * @param number $max
   * @param int $step
   */
  public function __construct(string $text, $min, $max, $step = 0) {
    if ($min > $max) throw new \InvalidArgumentException("Minimum value must be less than maximum value");
    parent::__construct($text);
    $this->min = $min;
    $this->max = $max;
    $this->defaultValue = $min;
    $this->setStep($step);
  }

  public function setStep($step): Slider {
    if ($step < 0) throw new \InvalidArgumentException("The value of the step must be a positive value");
    $this->step = $step;
    return $this;
  }

  public function setDefaultValue($value): Slider {
    if ($value < $this->min || $value > $this->max) {
      throw new \InvalidArgumentException("The default value must be between the minimum and maximum values");
    }
    $this->defaultValue = $value;
    return $this;
  }

  final public function format(): array {
    $data = [
      Form::KEY_TYPE => self::ELEMENT_NAME,
      Form::KEY_TEXT => $this->text,
      Form::KEY_MIN => $this->min,
      Form::KEY_MAX => $this->max,
    ];
    if ($this->step > 0) $data[Form::KEY_STEP] = $this->step;
    if ($this->defaultValue !== $this->min) {
      $data[Form::KEY_DEFAULT] = $this->defaultValue;
    }
    return $data;
  }
}
<?php

/**
 * // English
 *
 * libform is a library for PocketMine-MP for easy operation of forms
 * Copyright (c) 2018 yuko fuyutsuki < https://github.com/fuyutsuki >
 *
 * This software is distributed under "MIT license".
 * You should have received a copy of the MIT license
 * along with this program.  If not, see
 * < https://opensource.org/licenses/mit-license >.
 *
 * ---------------------------------------------------------------------
 * // æ—¥æœ¬èªž
 *
 * libformã¯ã€ãƒ•ã‚©ãƒ¼ãƒ ã‚’ç°¡å˜ã«æ“ä½œã™ã‚‹ãŸã‚ã®pocketmine-MPå‘ã‘ãƒ©ã‚¤ãƒ–ãƒ©ãƒªã§ã™
 * Copyright (c) 2018 yuko fuyutsuki < https://github.com/fuyutsuki >
 *
 * ã“ã®ã‚½ãƒ•ãƒˆã‚¦ã‚§ã‚¢ã¯"MITãƒ©ã‚¤ã‚»ãƒ³ã‚¹"ä¸‹ã§é…å¸ƒã•ã‚Œã¦ã„ã¾ã™ã€‚
 * ã‚ãªãŸã¯ã“ã®ãƒ—ãƒ­ã‚°ãƒ©ãƒ ã¨å…±ã«MITãƒ©ã‚¤ã‚»ãƒ³ã‚¹ã®ã‚³ãƒ”ãƒ¼ã‚’å—ã‘å–ã£ãŸã¯ãšã§ã™ã€‚
 * å—ã‘å–ã£ã¦ã„ãªã„å ´åˆã€ä¸‹è¨˜ã®URLã‹ã‚‰ã”è¦§ãã ã•ã„ã€‚
 * < https://opensource.org/licenses/mit-license >
 */

namespace tokyo\pmmp\libform\element;

// libform
use tokyo\pmmp\libform\{
  form\Form
};

/**
 * StepSliderClass
 */
class StepSlider extends Element {

  /** @var string */
  protected const ELEMENT_NAME = "step_slider";

  /** @var string[] */
  protected $steps = [];
  /** @var int */
  protected $defaultKey = 0;

  public function __construct(string $text, array $steps = []) {
    parent::__construct($text);
    $this->steps = $steps;
  }

  public function getStep(int $key): ?string {
    return isset($this->steps[$key])? $this->steps[$key] : null;
  }

  public function addStep(string $stepText, bool $isDefault = false): StepSlider {
    if ($isDefault) $this->defaultKey = count($this->steps);
    $this->steps[] = $stepText;
    return $this;
  }

  public function removeStep(string $stepText): StepSlider {
    $flip = array_flip($this->steps);
    if (array_key_exists($stepText, $flip)) {
      $key = $flip[$stepText];
      unset($this->steps[$key]);
    }
    return $this;
  }

  public function getDefaultStep(): string {
    return empty($this->steps)? "" : $this->steps[$this->defaultKey];
  }

  public function setDefaultStep(string $stepText): StepSlider {
    $flip = array_flip($this->steps);
    if (array_key_exists($stepText, $flip)) {
      $key = $flip[$stepText];
      $this->defaultKey = $key;
    }else {
      throw new \OutOfRangeException("Invalid step text " . $stepText);
    }
    return $this;
  }

  public function format(): array {
    $data = [
      Form::KEY_TYPE => self::ELEMENT_NAME,
      Form::KEY_TEXT => $this->text,
      Form::KEY_STEPS => $this->steps,
      Form::KEY_DEFAULT => $this->defaultKey
    ];
    return $data;
  }
}
<?php

/**
 * // English
 *
 * libform is a library for PocketMine-MP for easy operation of forms
 * Copyright (c) 2018 yuko fuyutsuki < https://github.com/fuyutsuki >
 *
 * This software is distributed under "MIT license".
 * You should have received a copy of the MIT license
 * along with this program.  If not, see
 * < https://opensource.org/licenses/mit-license >.
 *
 * ---------------------------------------------------------------------
 * // æ—¥æœ¬èªž
 *
 * libformã¯ã€ãƒ•ã‚©ãƒ¼ãƒ ã‚’ç°¡å˜ã«æ“ä½œã™ã‚‹ãŸã‚ã®pocketmine-MPå‘ã‘ãƒ©ã‚¤ãƒ–ãƒ©ãƒªã§ã™
 * Copyright (c) 2018 yuko fuyutsuki < https://github.com/fuyutsuki >
 *
 * ã“ã®ã‚½ãƒ•ãƒˆã‚¦ã‚§ã‚¢ã¯"MITãƒ©ã‚¤ã‚»ãƒ³ã‚¹"ä¸‹ã§é…å¸ƒã•ã‚Œã¦ã„ã¾ã™ã€‚
 * ã‚ãªãŸã¯ã“ã®ãƒ—ãƒ­ã‚°ãƒ©ãƒ ã¨å…±ã«MITãƒ©ã‚¤ã‚»ãƒ³ã‚¹ã®ã‚³ãƒ”ãƒ¼ã‚’å—ã‘å–ã£ãŸã¯ãšã§ã™ã€‚
 * å—ã‘å–ã£ã¦ã„ãªã„å ´åˆã€ä¸‹è¨˜ã®URLã‹ã‚‰ã”è¦§ãã ã•ã„ã€‚
 * < https://opensource.org/licenses/mit-license >
 */

namespace tokyo\pmmp\libform\element;

// libform
use tokyo\pmmp\libform\{
  form\Form
};

/**
 * ToggleClass
 */
class Toggle extends Element {

  /** @var string */
  protected const ELEMENT_NAME = "toggle";

  /** @var bool */
  protected $defaultValue = false;

  public function __construct(string $text, bool $value = false) {
    parent::__construct($text);
    $this->defaultValue = $value;
  }

  public function setDefaultValue(bool $value): Toggle {
    $this->defaultValue = $value;
    return $this;
  }

  final public function format(): array {
    $data = [
      Form::KEY_TYPE => self::ELEMENT_NAME,
      Form::KEY_TEXT => $this->text,
      Form::KEY_DEFAULT => $this->defaultValue
    ];
    return $data;
  }
}
<?php
namespace tokyo\pmmp\libform;

use pocketmine\event\Listener;
use pocketmine\event\player\PlayerQuitEvent;
use pocketmine\event\server\DataPacketReceiveEvent;
use pocketmine\network\mcpe\protocol\ModalFormResponsePacket;

class EventListener implements Listener {

  public function onReceive(DataPacketReceiveEvent $event) {
    $pk = $event->getPacket();
    if ($pk instanceof ModalFormResponsePacket) {
      $player = $event->getPlayer();
      $formId = $pk->formId;
      $response = json_decode($pk->formData, true);
      if (($form = FormApi::getForm($formId)) !== null) {
        if (!$form->isRecipient($player)) {
          return false;
        }
        $callable = $form->getCallable();
        if ($callable !== null) {
          $callable($player, $response);
        }
        FormApi::removeForm($formId);
        $event->setCancelled();
      }
    }
  }

  public function onQuit(PlayerQuitEvent $event) {
    $player = $event->getPlayer();
    foreach (FormApi::getForms() as $formId => $form) {
      if ($form->isRecipient($player)) {
        FormApi::removeForm($formId);
        break;
      }
    }
  }
}<?php

/**
 * // English
 *
 * libform is a library for PocketMine-MP for easy operation of forms
 * Copyright (c) 2018 yuko fuyutsuki < https://github.com/fuyutsuki >
 *
 * This software is distributed under "MIT license".
 * You should have received a copy of the MIT license
 * along with this program.  If not, see
 * < https://opensource.org/licenses/mit-license >.
 *
 * ---------------------------------------------------------------------
 * // æ—¥æœ¬èªž
 *
 * libformã¯ã€ãƒ•ã‚©ãƒ¼ãƒ ã‚’ç°¡å˜ã«æ“ä½œã™ã‚‹ãŸã‚ã®pocketmine-MPå‘ã‘ãƒ©ã‚¤ãƒ–ãƒ©ãƒªã§ã™
 * Copyright (c) 2018 yuko fuyutsuki < https://github.com/fuyutsuki >
 *
 * ã“ã®ã‚½ãƒ•ãƒˆã‚¦ã‚§ã‚¢ã¯"MITãƒ©ã‚¤ã‚»ãƒ³ã‚¹"ä¸‹ã§é…å¸ƒã•ã‚Œã¦ã„ã¾ã™ã€‚
 * ã‚ãªãŸã¯ã“ã®ãƒ—ãƒ­ã‚°ãƒ©ãƒ ã¨å…±ã«MITãƒ©ã‚¤ã‚»ãƒ³ã‚¹ã®ã‚³ãƒ”ãƒ¼ã‚’å—ã‘å–ã£ãŸã¯ãšã§ã™ã€‚
 * å—ã‘å–ã£ã¦ã„ãªã„å ´åˆã€ä¸‹è¨˜ã®URLã‹ã‚‰ã”è¦§ãã ã•ã„ã€‚
 * < https://opensource.org/licenses/mit-license >
 */

namespace tokyo\pmmp\libform\form;

// libform
use tokyo\pmmp\libform\{
  element\Element
};

/**
 * CustomForm
 */
class CustomForm extends Form implements \JsonSerializable {

  /** @var string */
  private const FORM_TYPE = "custom_form";
  /** @var array */
  protected $data = [
    Form::KEY_TYPE => self::FORM_TYPE,
    Form::KEY_TITLE => "",
    Form::KEY_CONTENT => []
  ];

  public function getElements(): array {
    return $this->data[Form::KEY_CONTENT];
  }

  public function getElement(int $key): ?Element {
    if (array_key_exists($key, $this->data[Form::KEY_CONTENT])) {
      return $this->data[Form::KEY_CONTENT][$key];
    }
    return null;
  }

  public function addElement(Element $element): CustomForm {
    if (!($element instanceof Button)) {// Button is for a ListForm
      $this->data[Form::KEY_CONTENT][] = $element;
    }
    return $this;
  }

  final public function jsonSerialize(): array {
    $data = $this->data;
    unset($data[Form::KEY_CONTENT]);
    foreach ($this->getElements() as $element) {
      $data[Form::KEY_CONTENT][] = $element->format();
    }
    return $data;
  }
}
<?php

/**
 * // English
 *
 * libform is a library for PocketMine-MP for easy operation of forms
 * Copyright (c) 2018 yuko fuyutsuki < https://github.com/fuyutsuki >
 *
 * This software is distributed under "MIT license".
 * You should have received a copy of the MIT license
 * along with this program.  If not, see
 * < https://opensource.org/licenses/mit-license >.
 *
 * ---------------------------------------------------------------------
 * // æ—¥æœ¬èªž
 *
 * libformã¯ã€ãƒ•ã‚©ãƒ¼ãƒ ã‚’ç°¡å˜ã«æ“ä½œã™ã‚‹ãŸã‚ã®pocketmine-MPå‘ã‘ãƒ©ã‚¤ãƒ–ãƒ©ãƒªã§ã™
 * Copyright (c) 2018 yuko fuyutsuki < https://github.com/fuyutsuki >
 *
 * ã“ã®ã‚½ãƒ•ãƒˆã‚¦ã‚§ã‚¢ã¯"MITãƒ©ã‚¤ã‚»ãƒ³ã‚¹"ä¸‹ã§é…å¸ƒã•ã‚Œã¦ã„ã¾ã™ã€‚
 * ã‚ãªãŸã¯ã“ã®ãƒ—ãƒ­ã‚°ãƒ©ãƒ ã¨å…±ã«MITãƒ©ã‚¤ã‚»ãƒ³ã‚¹ã®ã‚³ãƒ”ãƒ¼ã‚’å—ã‘å–ã£ãŸã¯ãšã§ã™ã€‚
 * å—ã‘å–ã£ã¦ã„ãªã„å ´åˆã€ä¸‹è¨˜ã®URLã‹ã‚‰ã”è¦§ãã ã•ã„ã€‚
 * < https://opensource.org/licenses/mit-license >
 */

namespace tokyo\pmmp\libform\form;

// pocketmine
use pocketmine\{
  Player,
  network\mcpe\protocol\ModalFormRequestPacket
};

/**
 * abstractFormClass
 */
abstract class Form implements \JsonSerializable {

  /** @var string */
  public const KEY_TYPE = "type";
  public const KEY_CONTENT = "content";
  public const KEY_DATA = "data";
  public const KEY_IMAGE = "image";
  public const KEY_TITLE = "title";
  public const KEY_TEXT = "text";
  public const KEY_OPTIONS = "options";
  public const KEY_DEFAULT = "default";
  public const KEY_PLACEHOLDER = "placeholder";
  public const KEY_STEP = "step";
  public const KEY_STEPS = "steps";
  public const KEY_BUTTON1 = "button1";
  public const KEY_BUTTON2 = "button2";
  public const KEY_BUTTONS = "buttons";
  public const KEY_MIN = "min";
  public const KEY_MAX = "max";

  /** @var int */
  protected $id = 0;
  /** @var ?callable */
  private $callable = null;
  /** @var array */
  protected $data = [];
  /** @var string */
  protected $playerName = "";

  public function __construct(int $id, callable $callable = null) {
    $this->id = $id;
    $this->callable = $callable;
  }

  /**
   * @return int
   */
  public function getId(): int {
    return $this->id;
  }

  /**
   * @param  int $id
   * @return Form
   */
  public function setId(int $id): Form {
    $this->id = $id;
    return $this;
  }

  /**
   * @return string
   */
  public function getTitle(): string {
    return $this->data[self::KEY_TITLE];
  }

  /**
   * @param  string $title
   * @return Form
   */
  public function setTitle(string $title): Form {
    $this->data[self::KEY_TITLE] = $title;
    return $this;
  }

  /**
   * @return ?callable
   */
  public function getCallable(): ?callable {
    return $this->callable;
  }

  /**
   * @param  Player $player
   * @return bool
   */
  public function isRecipient(Player $player): bool {
    return $player->getName() === $this->playerName;
  }

  /**
   * @param Player $player
   * @return Form
   */
  public function sendToPlayer(Player $player): Form {
    $pk = new ModalFormRequestPacket;
    $pk->formId = $this->id;
    $pk->formData = json_encode($this);
    $this->playerName = $player->getName();
    $player->dataPacket($pk);
    return $this;
  }

  /**
   * @return array
   */
  abstract public function jsonSerialize(): array;
}
<?php

/**
 * // English
 *
 * libform is a library for PocketMine-MP for easy operation of forms
 * Copyright (c) 2018 yuko fuyutsuki < https://github.com/fuyutsuki >
 *
 * This software is distributed under "MIT license".
 * You should have received a copy of the MIT license
 * along with this program.  If not, see
 * < https://opensource.org/licenses/mit-license >.
 *
 * ---------------------------------------------------------------------
 * // æ—¥æœ¬èªž
 *
 * libformã¯ã€ãƒ•ã‚©ãƒ¼ãƒ ã‚’ç°¡å˜ã«æ“ä½œã™ã‚‹ãŸã‚ã®pocketmine-MPå‘ã‘ãƒ©ã‚¤ãƒ–ãƒ©ãƒªã§ã™
 * Copyright (c) 2018 yuko fuyutsuki < https://github.com/fuyutsuki >
 *
 * ã“ã®ã‚½ãƒ•ãƒˆã‚¦ã‚§ã‚¢ã¯"MITãƒ©ã‚¤ã‚»ãƒ³ã‚¹"ä¸‹ã§é…å¸ƒã•ã‚Œã¦ã„ã¾ã™ã€‚
 * ã‚ãªãŸã¯ã“ã®ãƒ—ãƒ­ã‚°ãƒ©ãƒ ã¨å…±ã«MITãƒ©ã‚¤ã‚»ãƒ³ã‚¹ã®ã‚³ãƒ”ãƒ¼ã‚’å—ã‘å–ã£ãŸã¯ãšã§ã™ã€‚
 * å—ã‘å–ã£ã¦ã„ãªã„å ´åˆã€ä¸‹è¨˜ã®URLã‹ã‚‰ã”è¦§ãã ã•ã„ã€‚
 * < https://opensource.org/licenses/mit-license >
 */

namespace tokyo\pmmp\libform\form;

// libform
use tokyo\pmmp\libform\{
  element\Button
};

/**
 * ListFormClass
 */
class ListForm extends Form implements \JsonSerializable {

  /** @var string */
  private const FORM_TYPE = "form";
  /** @var array */
  protected $data = [
    Form::KEY_TYPE => self::FORM_TYPE,
    Form::KEY_TITLE => "",
    Form::KEY_CONTENT => "",
    Form::KEY_BUTTONS => []
  ];

  public function getContent(): string {
    return $this->data[Form::KEY_CONTENT];
  }

  public function setContent(string $content): ListForm {
    $this->data[Form::KEY_CONTENT] = $content;
    return $this;
  }

  public function getButtons(): array {
    return $this->data[Form::KEY_BUTTONS];
  }

  public function addButton(Button $button): ListForm {
    $this->data[Form::KEY_BUTTONS][] = $button;
    return $this;
  }

  final public function jsonSerialize(): array {
    $data = $this->data;
    if (!empty(($buttons = $this->getButtons()))) {
      unset($data[Form::KEY_BUTTONS]);
      foreach ($this->getButtons() as $button) {
        $data[Form::KEY_BUTTONS][] = $button->format();
      }
    }
    return $data;
  }
}
<?php

/**
 * // English
 *
 * libform is a library for PocketMine-MP for easy operation of forms
 * Copyright (c) 2018 yuko fuyutsuki < https://github.com/fuyutsuki >
 *
 * This software is distributed under "MIT license".
 * You should have received a copy of the MIT license
 * along with this program.  If not, see
 * < https://opensource.org/licenses/mit-license >.
 *
 * ---------------------------------------------------------------------
 * // æ—¥æœ¬èªž
 *
 * libformã¯ã€ãƒ•ã‚©ãƒ¼ãƒ ã‚’ç°¡å˜ã«æ“ä½œã™ã‚‹ãŸã‚ã®pocketmine-MPå‘ã‘ãƒ©ã‚¤ãƒ–ãƒ©ãƒªã§ã™
 * Copyright (c) 2018 yuko fuyutsuki < https://github.com/fuyutsuki >
 *
 * ã“ã®ã‚½ãƒ•ãƒˆã‚¦ã‚§ã‚¢ã¯"MITãƒ©ã‚¤ã‚»ãƒ³ã‚¹"ä¸‹ã§é…å¸ƒã•ã‚Œã¦ã„ã¾ã™ã€‚
 * ã‚ãªãŸã¯ã“ã®ãƒ—ãƒ­ã‚°ãƒ©ãƒ ã¨å…±ã«MITãƒ©ã‚¤ã‚»ãƒ³ã‚¹ã®ã‚³ãƒ”ãƒ¼ã‚’å—ã‘å–ã£ãŸã¯ãšã§ã™ã€‚
 * å—ã‘å–ã£ã¦ã„ãªã„å ´åˆã€ä¸‹è¨˜ã®URLã‹ã‚‰ã”è¦§ãã ã•ã„ã€‚
 * < https://opensource.org/licenses/mit-license >
 */

namespace tokyo\pmmp\libform\form;

/**
 * ModalFormClass
 */
class ModalForm extends Form implements \JsonSerializable {

  /** @var string */
  private const FORM_TYPE = "modal";
  /** @var array */
  protected $data = [
    Form::KEY_TYPE => self::FORM_TYPE,
    Form::KEY_TITLE => "",
    Form::KEY_CONTENT => "",
    Form::KEY_BUTTON1 => "",
    Form::KEY_BUTTON2 => ""
  ];

  public function setButtonText(bool $button, string $text): ModalForm {
    if ($button) {
      $this->data[Form::KEY_BUTTON1] = $text;
    }else {
      $this->data[Form::KEY_BUTTON2] = $text;
    }
    return $this;
  }

  public function getContent(): string {
    return $this->data[Form::KEY_CONTENT];
  }

  public function setContent(string $content): ModalForm {
    $this->data[Form::KEY_CONTENT] = $content;
    return $this;
  }

  final public function jsonSerialize(): array {
    return $this->data;
  }
}
<?php

/**
 * // English
 *
 * libform is a library for PocketMine-MP for easy operation of forms
 * Copyright (c) 2018 yuko fuyutsuki < https://github.com/fuyutsuki >
 *
 * This software is distributed under "MIT license".
 * You should have received a copy of the MIT license
 * along with this program.  If not, see
 * < https://opensource.org/licenses/mit-license >.
 *
 * ---------------------------------------------------------------------
 * // æ—¥æœ¬èªž
 *
 * libformã¯ã€ãƒ•ã‚©ãƒ¼ãƒ ã‚’ç°¡å˜ã«æ“ä½œã™ã‚‹ãŸã‚ã®pocketmine-MPå‘ã‘ãƒ©ã‚¤ãƒ–ãƒ©ãƒªã§ã™
 * Copyright (c) 2018 yuko fuyutsuki < https://github.com/fuyutsuki >
 *
 * ã“ã®ã‚½ãƒ•ãƒˆã‚¦ã‚§ã‚¢ã¯"MITãƒ©ã‚¤ã‚»ãƒ³ã‚¹"ä¸‹ã§é…å¸ƒã•ã‚Œã¦ã„ã¾ã™ã€‚
 * ã‚ãªãŸã¯ã“ã®ãƒ—ãƒ­ã‚°ãƒ©ãƒ ã¨å…±ã«MITãƒ©ã‚¤ã‚»ãƒ³ã‚¹ã®ã‚³ãƒ”ãƒ¼ã‚’å—ã‘å–ã£ãŸã¯ãšã§ã™ã€‚
 * å—ã‘å–ã£ã¦ã„ãªã„å ´åˆã€ä¸‹è¨˜ã®URLã‹ã‚‰ã”è¦§ãã ã•ã„ã€‚
 * < https://opensource.org/licenses/mit-license >
 */

namespace tokyo\pmmp\libform;

// pocketmine
use pocketmine\plugin\PluginBase;
use pocketmine\Server;

// libform
use tokyo\pmmp\libform\form\CustomForm;
use tokyo\pmmp\libform\form\Form;
use tokyo\pmmp\libform\form\ListForm;
use tokyo\pmmp\libform\form\ModalForm;

/**
 * FormApiClass
 */
class FormApi {

  /** @var bool */
  private static $activated = false;
  /** @var Form[] */
  private static $forms = [];

  private function __construct() {
    // DONT USE THIS METHOD!
  }

  /**
   * @param PluginBase $plugin
   */
  public static function register(PluginBase $plugin): void {
    if (!self::$activated) {
      Server::getInstance()
        ->getPluginManager()
        ->registerEvents(new EventListener, $plugin);
    }
  }

  /**
   * Generate a custom form
   * @param  callable   $callable
   * @return CustomForm
   */
  public static function makeCustomForm(callable $callable = null): CustomForm {
    $formId = self::makeRandomFormId();
    $form = new CustomForm($formId, $callable);
    if ($callable !== null) self::$forms[$formId] = $form;
    return $form;
  }

  /**
   * Generate a list form
   * @param  callable $callable
   * @return ListForm
   */
  public static function makeListForm(callable $callable = null): ListForm {
    $formId = self::makeRandomFormId();
    $form = new ListForm($formId, $callable);
    if ($callable !== null) self::$forms[$formId] = $form;
    return $form;
  }

  /**
   * Generate a modal form
   * @param  callable  $callable
   * @return ModalForm
   */
  public static function makeModalForm(callable $callable = null): ModalForm {
    $formId = self::makeRandomFormId();
    $form = new ModalForm($formId, $callable);
    if ($callable !== null) self::$forms[$formId] = $form;
    return $form;
  }

  /**
   * Generate random formId
   * @return int formId
   */
  public static function makeRandomFormId(): int {
    return mt_rand(0, mt_getrandmax());
  }

  /**
   * @return array
   */
  public static function getForms(): array {
    return self::$forms;
  }

  /**
   * @param int $formId
   * @return Form|null
   */
  public static function getForm(int $formId): ?Form {
    if (array_key_exists($formId, self::$forms)) {
      return self::$forms[$formId];
    }else {
      return null;
    }
  }

  /**
   * @param int $formId
   */
  public static function removeForm(int $formId): void {
    if (array_key_exists($formId, self::$forms)) {
      unset(self::$forms[$formId]);
    }
  }

  /**
   * Check if the form has been canceled
   * @param  mixed $response
   * @return bool
   */
  public static function formCancelled($response): bool {
    return $response === null? true : false;
  }
}
YÞf_¬žëþ‘å±Æ,®_³ð    GBMB