Skip to content

Commit

Permalink
update to PM5
Browse files Browse the repository at this point in the history
  • Loading branch information
Frago9876543210 committed Apr 14, 2024
1 parent 521f8f5 commit 3e932ef
Show file tree
Hide file tree
Showing 28 changed files with 122 additions and 130 deletions.
2 changes: 2 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# Auto detect text files and perform LF normalization
* text=auto
*.php text eol=lf
*.neon text eol=lf

# Custom for Visual Studio
*.cs diff=csharp
Expand Down
5 changes: 2 additions & 3 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
version: 2
updates:
- package-ecosystem: composer
- package-ecosystem: github-actions
directory: "/"
schedule:
interval: weekly
open-pull-requests-limit: 10
interval: monthly
42 changes: 30 additions & 12 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,37 @@ on:
workflow_dispatch:

jobs:
check:
if: "!contains(github.event.head_commit.message, '[ci skip]')"
name: Check code quality
runs-on: ubuntu-20.04
build:
name: PHPStan analysis
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
php:
- "8.1"
- "8.2"
- "8.3"

steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v4

- name: Install PHP
run: echo "PHP_BINARY=$(sudo ./scripts/ci/download_php.sh | tail -1)" >> $GITHUB_ENV
- name: Setup PHP
uses: pmmp/[email protected]
with:
php-version: ${{ matrix.php }}
install-path: "./bin"
pm-version-major: 5

- name: PHPStan analysis
run: |
wget https://getcomposer.org/download/latest-stable/composer.phar
$PHP_BINARY composer.phar install
$PHP_BINARY vendor/bin/phpstan.phar analyze
- name: Restore Composer package cache
id: composer-cache
uses: actions/cache@v4
with:
path: "~/.cache/composer"
key: "php-${{ matrix.php }}-composer-${{ hashFiles('**/composer.json') }}"
restore-keys: "php-${{ matrix.php }}-composer-"

- name: Install PHPStan Composer dependencies
run: composer install --prefer-dist --no-interaction

- name: Run PHPStan
run: vendor/bin/phpstan analyze
4 changes: 2 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -216,5 +216,5 @@ pip-log.txt
#Mr Developer
.mr.developer.cfg

/vendor/
/composer.lock
vendor/
composer.lock
9 changes: 7 additions & 2 deletions .poggit.yml
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
--- # Poggit-CI Manifest. Open the CI at https://poggit.pmmp.io/ci/Frago9876543210/forms
build-by-default: true
branches:
- master
- master
projects:
forms:
path: ""
lint: false
libforms:
path: ""
type: library
model: virion
lint: false
...
19 changes: 11 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
# forms

![build](https://img.shields.io/github/workflow/status/Frago9876543210/forms/CI)
![php](https://img.shields.io/badge/php-8.0-informational)
![api](https://img.shields.io/badge/pocketmine-4.0-informational)
![build](https://img.shields.io/github/actions/workflow/status/Frago9876543210/forms/main.yml)
![php](https://img.shields.io/badge/php-8.1-informational)
![api](https://img.shields.io/badge/pocketmine-5.0-informational)

Modern version of pocketmine forms API, ported to PHP 8.0+ with high quality code and phpstan integration
Modern version of pocketmine forms API, ported to PHP 8.1+ with high quality code and phpstan integration

## Code samples

Expand Down Expand Up @@ -51,6 +51,9 @@ $player->sendForm(ModalForm::confirm("Teleport request", "Do you want to accept

#### Using MenuForm to display buttons with icons from URL and path

> [!NOTE]
> If you are having trouble loading images, try installing https://github.com/Muqsit/FormImagesFix
```php
$player->sendForm(new MenuForm("Select server", "Choose server", [
//buttons without icon
Expand All @@ -76,7 +79,7 @@ $player->sendForm(MenuForm::withOptions("Select option", "List of options:", [
"opt1", "opt2", "opt3",
"default branch #1",
"default branch #2",
], fn(Player $player, Button $selected) => match ($selected->getValue()) {
], fn(Player $player, Button $selected) => match($selected->getValue()){
0 => $player->sendMessage("message #1"), //opt1
1 => $player->sendMessage("message #2"), //opt2
2 => $player->sendMessage("message #3"), //opt3
Expand All @@ -92,7 +95,7 @@ $player->sendForm(MenuForm::withOptions("Select option", "List of options:", [
//appending form data if Player has enough permissions
$form = MenuForm::withOptions("Player info", "Username: " . $player->getName(), [
"view statistics", //accessible for all
], fn(Player $player, Button $selected) => match ($selected->getValue()) {
], fn(Player $player, Button $selected) => match($selected->getValue()){
0 => $player->sendMessage("*statistics*"),
1 => $player->kick("kick message"),
2 => $player->sendMessage("*logs*"),
Expand Down Expand Up @@ -134,7 +137,7 @@ $player->sendForm(new CustomForm("Enter data", [
$player->sendMessage("You selected: " . $stepSlider->getSelectedOption());

$toggle = $response->getToggle();
$player->setGamemode($toggle->getValue() ? GameMode::CREATIVE() : GameMode::SURVIVAL());
$player->setGamemode($toggle->getValue() ? GameMode::CREATIVE : GameMode::SURVIVAL);
}));
```

Expand All @@ -156,7 +159,7 @@ $player->sendForm(new CustomForm("Enter data", [
$player->sendMessage("Your name is $username");
$player->sendMessage("Count: $count");
$player->sendMessage("You selected: $product2");
$player->setGamemode($enableCreative ? GameMode::CREATIVE() : GameMode::SURVIVAL());
$player->setGamemode($enableCreative ? GameMode::CREATIVE : GameMode::SURVIVAL);
}));
```

Expand Down
26 changes: 16 additions & 10 deletions composer.json
Original file line number Diff line number Diff line change
@@ -1,19 +1,25 @@
{
"name": "frago9876543210/forms",
"require": {
"phpstan/phpstan": "0.12.99",
"pocketmine/pocketmine-mp": "dev-master",
"phpstan/phpstan-strict-rules": "0.12.11",
"phpstan/extension-installer": "1.1.0"
"require-dev": {
"phpstan/phpstan": "^1.10",
"pocketmine/pocketmine-mp": "^5.14",
"phpstan/phpstan-strict-rules": "^1.0",
"phpstan/extension-installer": "^1.0"
},
"autoload": {
"psr-4": {
"forms\\": "src/"
"": "src/"
}
},
"minimum-stability": "dev",
"prefer-stable" : true,
"require-dev": {
"jetbrains/phpstorm-attributes": "^1.0"
"config": {
"allow-plugins": {
"phpstan/extension-installer": true
}
},
"extra":{
"virion": {
"spec": "3.0",
"namespace-root": "forms"
}
}
}
3 changes: 1 addition & 2 deletions plugin.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
name: forms
main: forms\bootstrap\Main
src-namespace-prefix: forms
version: 1.0.0
api: 4.0.0
api: 5.0.0
22 changes: 0 additions & 22 deletions scripts/ci/download_php.sh

This file was deleted.

2 changes: 0 additions & 2 deletions scripts/phpstan

This file was deleted.

4 changes: 1 addition & 3 deletions src/BaseForm.php → src/forms/BaseForm.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,11 @@

namespace forms;

use JetBrains\PhpStorm\Immutable;
use pocketmine\form\Form;

#[Immutable]
abstract class BaseForm implements Form{

public function __construct(public /*readonly*/ string $title){ }
public function __construct(public readonly string $title){ }

abstract protected function getType() : string;

Expand Down
18 changes: 8 additions & 10 deletions src/CustomForm.php → src/forms/CustomForm.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,7 @@

namespace forms;

use forms\element\BaseElement;
use JetBrains\PhpStorm\Immutable;
use forms\element\BaseElementWithValue;
use pocketmine\form\FormValidationException;
use pocketmine\player\Player;
use pocketmine\utils\Utils;
Expand All @@ -17,27 +16,25 @@
class CustomForm extends BaseForm{

/**
* @phpstan-param list<BaseElement&element\BaseElementWithValue<mixed>> $elements
* @phpstan-param list<element\BaseElementWithValue<mixed>> $elements
* @phpstan-param \Closure(Player, CustomFormResponse) : mixed $onSubmit
* @phpstan-param (\Closure(Player) : mixed)|null $onClose
*/
public function __construct(
string $title,
private array $elements,
#[Immutable] private /*readonly*/ \Closure $onSubmit,
#[Immutable] private /*readonly*/ ?\Closure $onClose = null,
private readonly \Closure $onSubmit,
private readonly ?\Closure $onClose = null,
){
/** @phpstan-ignore-next-line */
Utils::validateCallableSignature(function(Player $player, CustomFormResponse $response){ }, $onSubmit);
if($onClose !== null){
/** @phpstan-ignore-next-line */
Utils::validateCallableSignature(function(Player $player){ }, $onClose);
}
parent::__construct($title);
}

/** @phpstan-param BaseElement&element\BaseElementWithValue<mixed> ...$elements */
public function appendElements(BaseElement ...$elements) : void{
/** @phpstan-param element\BaseElementWithValue<mixed> ...$elements */
public function appendElements(BaseElementWithValue ...$elements) : void{
foreach($elements as $element){
$this->elements[] = $element;
}
Expand All @@ -58,6 +55,7 @@ private function validateElements(Player $player, array $data) : void{
}

foreach($data as $index => $value){
/** @var BaseElementWithValue<mixed> $element */
$element = $this->elements[$index] ?? throw new FormValidationException("Element at offset $index does not exist");
try{
$element->setValue($value);
Expand All @@ -70,7 +68,7 @@ private function validateElements(Player $player, array $data) : void{
}

final public function handleResponse(Player $player, mixed $data) : void{
match (true) {
match(true){
is_null($data) => $this->onClose?->__invoke($player),
is_array($data) => $this->validateElements($player, $data),
default => throw new FormValidationException("Expected array or null, got " . gettype($data)),
Expand Down
17 changes: 9 additions & 8 deletions src/CustomFormResponse.php → src/forms/CustomFormResponse.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,29 +4,30 @@

namespace forms;

use forms\element\BaseElement;
use forms\element\BaseElementWithValue;
use forms\element\Dropdown;
use forms\element\Input;
use forms\element\Label;
use forms\element\Slider;
use forms\element\StepSlider;
use forms\element\Toggle;
use function array_shift;
use function is_null;

class CustomFormResponse{

/** @phpstan-param list<BaseElement&element\BaseElementWithValue<mixed>> $elements */
/** @phpstan-param list<element\BaseElementWithValue<mixed>> $elements */
public function __construct(private array $elements){ }

/**
* @template T&BaseElement&element\BaseElementWithValue<mixed>
* @phpstan-param class-string<T&BaseElement&element\BaseElementWithValue<mixed>> $expected
* @phpstan-return T&BaseElement&element\BaseElementWithValue<mixed>
* @template T&element\BaseElementWithValue<mixed>
* @phpstan-param class-string<T&element\BaseElementWithValue<mixed>> $expected
* @phpstan-return T&element\BaseElementWithValue<mixed>
* @throws \UnexpectedValueException
*/
public function get(string $expected) : BaseElement{
public function get(string $expected) : BaseElementWithValue{
$element = array_shift($this->elements);
return match (true) {
return match(true){
is_null($element) => throw new \UnexpectedValueException("There are no elements in the container"),
$element instanceof Label => $this->get($expected), //skip labels
!($element instanceof $expected) => throw new \UnexpectedValueException("Unexpected type of element"),
Expand All @@ -53,7 +54,7 @@ public function getValues() : array{
continue;
}

$values[] = match (true) {
$values[] = match(true){
$element instanceof Dropdown => $element->getSelectedOption(),
default => $element->getValue(),
};
Expand Down
11 changes: 4 additions & 7 deletions src/MenuForm.php → src/forms/MenuForm.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
namespace forms;

use forms\menu\Button;
use JetBrains\PhpStorm\Immutable;
use pocketmine\form\FormValidationException;
use pocketmine\player\Player;
use pocketmine\utils\Utils;
Expand All @@ -22,17 +21,15 @@ class MenuForm extends BaseForm{
*/
public function __construct(
string $title,
#[Immutable] public /*readonly*/ string $content = "",
public readonly string $content = "",
private array $buttons = [],
#[Immutable] private /*readonly*/ ?\Closure $onSubmit = null,
#[Immutable] private /*readonly*/ ?\Closure $onClose = null,
private readonly ?\Closure $onSubmit = null,
private readonly ?\Closure $onClose = null,
){
if($onSubmit !== null){
/** @phpstan-ignore-next-line */
Utils::validateCallableSignature(function(Player $player, Button $selected){ }, $onSubmit);
}
if($onClose !== null){
/** @phpstan-ignore-next-line */
Utils::validateCallableSignature(function(Player $player){ }, $onClose);
}
parent::__construct($title);
Expand Down Expand Up @@ -80,7 +77,7 @@ private function getButton(int $index) : Button{
}

final public function handleResponse(Player $player, mixed $data) : void{
match (true) {
match(true){
is_null($data) => $this->onClose?->__invoke($player),
is_int($data) => $this->onSubmit?->__invoke($player, $this->getButton($data)->setValue($data)),
default => throw new FormValidationException("Expected int or null, got " . gettype($data)),
Expand Down
Loading

0 comments on commit 3e932ef

Please sign in to comment.