Skip to content

Commit

Permalink
Merge branch 'master' into fix/choice-type-name
Browse files Browse the repository at this point in the history
  • Loading branch information
rudiedirkx committed Nov 28, 2024
2 parents b3cddd2 + 0dbb803 commit 17c1d2e
Show file tree
Hide file tree
Showing 12 changed files with 155 additions and 35 deletions.
35 changes: 22 additions & 13 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,23 @@ env:

jobs:
test:
name: "Build"
name: "Lara ${{ matrix.laravel }} PHP ${{ matrix.php }} Unit ${{ matrix.phpunit }}"
runs-on: ubuntu-latest
strategy:
max-parallel: 12
max-parallel: 6 # 12
fail-fast: false
matrix:
php: ['7.4', '8.0', '8.1', '8.2']
package-release: [dist]
laravel: [9, 10, 11]
php: ['8.1', '8.2', '8.3']
phpunit: [9, 10]
exclude:
- {laravel: 11, php: '8.1'}
- {laravel: 9, phpunit: 10}
- {phpunit: 9}
include:
- {laravel: 9, php: '8.1', phpunit: 9}
- {laravel: 9, php: '8.2', phpunit: 9}
- {laravel: 9, php: '8.3', phpunit: 9}
steps:
- name: Checkout repository
uses: actions/checkout@v3
Expand All @@ -37,21 +46,21 @@ jobs:
uses: actions/cache@v3
with:
path: ${{ steps.composer-cache.outputs.dir }}
key: composer-${{ runner.os }}-${{ matrix.php }}-${{ matrix.package-release }}-${{ hashFiles('**/composer.json') }}
key: composer-${{ runner.os }}-${{ matrix.php }}-${{ matrix.laravel }}-${{ hashFiles('**/composer.json') }}
restore-keys: |
composer-${{ runner.os }}-${{ matrix.php }}-${{ matrix.package-release }}-${{ env.cache-name }}-
composer-${{ runner.os }}-${{ matrix.php }}-${{ matrix.package-release }}-
composer-${{ runner.os }}-${{ matrix.php }}-${{ matrix.laravel }}-${{ env.cache-name }}-
composer-${{ runner.os }}-${{ matrix.php }}-${{ matrix.laravel }}-
composer-${{ runner.os }}-${{ matrix.php }}-
composer-${{ runner.os }}-
- name: Install composer dependencies
run: composer install --no-progress --no-interaction --prefer-${{ matrix.package-release }}
run: composer require --no-progress --no-interaction illuminate/database:^${{ matrix.laravel }}.0 illuminate/validation:^${{ matrix.laravel }}.0 phpunit/phpunit:^${{ matrix.phpunit }}.0

- name: Run unit tests
run: vendor/bin/phpunit --coverage-text --coverage-clover=coverage.clover

- name: Upload to Scrutinizer
continue-on-error: true
run: |
composer global require scrutinizer/ocular
~/.composer/vendor/bin/ocular code-coverage:upload --format=php-clover coverage.clover
# - name: Upload to Scrutinizer
# continue-on-error: true
# run: |
# composer global require scrutinizer/ocular
# ~/.composer/vendor/bin/ocular code-coverage:upload --format=php-clover coverage.clover
13 changes: 7 additions & 6 deletions composer.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "kris/laravel-form-builder",
"description": "Laravel form builder - symfony like",
"keywords": ["laravel", "form", "builder","symfony"],
"keywords": ["laravel", "form", "builder", "symfony"],
"license": "MIT",
"authors": [
{
Expand All @@ -10,13 +10,14 @@
}
],
"require": {
"php": ">=7.4",
"laravelcollective/html": "^6",
"illuminate/database": "^6 || ^7 || ^8 || ^9 || ^10",
"illuminate/validation": "^6 || ^7 || ^8 || ^9 || ^10"
"php": "^8.0",
"rdx/laravelcollective-html": "^6",
"illuminate/database": "^6 || ^7 || ^8 || ^9 || ^10 || ^11",
"illuminate/validation": "^6 || ^7 || ^8 || ^9 || ^10 || ^11"
},
"require-dev": {
"orchestra/testbench": "^6.13 || ^7.0 || ^8"
"orchestra/testbench": "^6.13 || ^7 || ^8 || ^9",
"phpunit/phpunit": "^10.0"
},
"extra": {
"branch-alias": {
Expand Down
5 changes: 5 additions & 0 deletions phpstan-extension.neon
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
services:
-
class: Kris\LaravelFormBuilder\PhpStan\FormGetFieldExtension
tags:
- phpstan.broker.dynamicMethodReturnTypeExtension
10 changes: 9 additions & 1 deletion src/Kris/LaravelFormBuilder/Fields/ChildFormType.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,17 @@

use Kris\LaravelFormBuilder\Form;

/**
* @template TFormType of Form
*
* @extends ParentType<FormField>
*/
class ChildFormType extends ParentType
{

/**
* @var Form
* @phpstan-var TFormType
*/
protected $form;

Expand All @@ -22,6 +28,7 @@ protected function getTemplate()

/**
* @return Form
* @phpstan-return TFormType
*/
public function getForm()
{
Expand Down Expand Up @@ -96,6 +103,7 @@ protected function createChildren()

/**
* @return Form
* @phpstan-return TFormType
* @throws \Exception
*/
protected function getClassFromOptions()
Expand All @@ -116,7 +124,7 @@ protected function getClassFromOptions()
$options = [
'model' => $this->getOption($this->valueProperty) ?: $this->parent->getModel(),
'name' => $this->name,
'language_name' => $this->parent->getLanguageName(),
'language_name' => $this->getOption('language_name') ?: $this->parent->getLanguageName(),
'translation_template' => $this->parent->getTranslationTemplate(),
];

Expand Down
3 changes: 3 additions & 0 deletions src/Kris/LaravelFormBuilder/Fields/ChoiceType.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@

use Illuminate\Support\Arr;

/**
* @extends ParentType<FormField>
*/
class ChoiceType extends ParentType
{
/**
Expand Down
12 changes: 11 additions & 1 deletion src/Kris/LaravelFormBuilder/Fields/CollectionType.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,18 @@
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Collection;

/**
* @template TType of FormField
*
* @extends ParentType<TType>
*/
class CollectionType extends ParentType
{
/**
* Contains template for a collection element.
*
* @var FormField
* @phpstan-var TType
*/
protected $proto;

Expand Down Expand Up @@ -49,6 +55,7 @@ protected function getDefaults()
* Get the prototype object.
*
* @return FormField
* @phpstan-return TType
* @throws \Exception
*/
public function prototype()
Expand Down Expand Up @@ -237,6 +244,10 @@ protected function setupChild(FormField $field, $name, $value = null)
['attr' => array_merge(['id' => $newFieldName], $this->getOption('attr'))]
);

if (isset($firstFieldOptions['label'])) {
$firstFieldOptions['label'] = value($firstFieldOptions['label'], $value, $field);
}

$field->setName($newFieldName);
$field->setOptions($firstFieldOptions);

Expand All @@ -249,7 +260,6 @@ protected function setupChild(FormField $field, $name, $value = null)

$field->setValue($value);


return $field;
}

Expand Down
7 changes: 7 additions & 0 deletions src/Kris/LaravelFormBuilder/Fields/ParentType.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,15 @@
use Illuminate\Support\Arr;
use Kris\LaravelFormBuilder\Form;

/**
* @template TChildType of FormField
*/
abstract class ParentType extends FormField
{

/**
* @var FormField[]
* @phpstan-var TChildType[]
*/
protected $children;

Expand Down Expand Up @@ -71,6 +75,7 @@ public function render(array $options = [], $showLabel = true, $showField = true
* Get all children of the choice field.
*
* @return mixed
* @phpstan-return TChildType[]
*/
public function getChildren()
{
Expand All @@ -81,6 +86,7 @@ public function getChildren()
* Get a child of the choice field.
*
* @return mixed
* @phpstan-return ?TChildType
*/
public function getChild($key)
{
Expand Down Expand Up @@ -152,6 +158,7 @@ public function isRendered()
*
* @param string $name
* @return FormField
* @phpstan-return TChildType
*/
public function __get($name)
{
Expand Down
3 changes: 3 additions & 0 deletions src/Kris/LaravelFormBuilder/Fields/RepeatedType.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@

use Illuminate\Support\Arr;

/**
* @extends ParentType<FormField>
*/
class RepeatedType extends ParentType
{

Expand Down
9 changes: 5 additions & 4 deletions src/Kris/LaravelFormBuilder/FormBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -56,10 +56,11 @@ public function fireEvent($event)
/**
* Create a Form instance.
*
* @param string $formClass The name of the class that inherits \Kris\LaravelFormBuilder\Form.
* @param array $options|null
* @param array $data|null
* @return Form
* @template T
* @param class-string<T> $formClass
* @param array<string, mixed> $options
* @param array<string, mixed> $data
* @return T
*/
public function create($formClass, array $options = [], array $data = [])
{
Expand Down
18 changes: 9 additions & 9 deletions src/Kris/LaravelFormBuilder/FormBuilderServiceProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@
use Collective\Html\HtmlBuilder;
use Illuminate\Support\ServiceProvider;
use InvalidArgumentException;
use Kris\LaravelFormBuilder\Traits\ValidatesWhenResolved;
use Kris\LaravelFormBuilder\Form;
use Kris\LaravelFormBuilder\Traits\ValidatesWhenResolved;

class FormBuilderServiceProvider extends ServiceProvider
{
Expand Down Expand Up @@ -105,15 +105,15 @@ public function boot()
__DIR__ . '/../../config/config.php' => config_path('laravel-form-builder.php')
]);

$form = $this->app[static::FORM_ABSTRACT];

$form->macro('customLabel', function($name, $value, $options = [], $escape_html = true) use ($form) {
if (isset($options['for']) && $for = $options['for']) {
unset($options['for']);
return $form->label($for, $value, $options, $escape_html);
}
$this->callAfterResolving(static::FORM_ABSTRACT, function (LaravelForm $form) {
$form->macro('customLabel', function($name, $value, $options = [], $escapeHtml = true) use ($form) {
if (isset($options['for']) && $for = $options['for']) {
unset($options['for']);
return $form->label($for, $value, $options, $escapeHtml);
}

return $form->label($name, $value, $options, $escape_html);
return $form->label($name, $value, $options, $escapeHtml);
});
});
}

Expand Down
73 changes: 73 additions & 0 deletions src/Kris/LaravelFormBuilder/PhpStan/FormGetFieldExtension.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
<?php

namespace Kris\LaravelFormBuilder\PhpStan;

use Kris\LaravelFormBuilder\Fields\ChildFormType;
use Kris\LaravelFormBuilder\Form;
use Kris\LaravelFormBuilder\FormHelper;
use Larastan\Larastan\Concerns\HasContainer;
use PHPStan\Analyser\Scope;
use PHPStan\Reflection\Annotations\AnnotationPropertyReflection;
use PHPStan\Reflection\MethodReflection;
use PHPStan\Reflection\ReflectionProvider;
use PHPStan\Type\DynamicMethodReturnTypeExtension;
use PHPStan\Type\ObjectType;
use PHPStan\Type\Type;
use PHPStan\Type\TypeWithClassName;
use PhpParser\Node\Expr;
use PhpParser\Node\Expr\Array_;
use PhpParser\Node\Expr\ClassConstFetch;
use PhpParser\Node\Expr\MethodCall;
use PhpParser\Node\Scalar\String_;

class FormGetFieldExtension implements DynamicMethodReturnTypeExtension
{

public function __construct(
protected ReflectionProvider $reflectionProvider,
) {}

public function getClass(): string {
return Form::class;
}

public function isMethodSupported(MethodReflection $methodReflection): bool {
return $methodReflection->getName() == 'getField';
}

public function getTypeFromMethodCall(MethodReflection $methodReflection, MethodCall $methodCall, Scope $scope): ?Type {
return $this->getTypeFromMethodCallGetField($methodReflection, $methodCall, $scope);
}

protected function getTypeFromMethodCallGetField(MethodReflection $methodReflection, MethodCall $methodCall, Scope $scope): ?Type
{
if (count($methodCall->getArgs()) < 1) {
return null;
}

$fieldNameArg = $methodCall->getArgs()[0]->value;
if (!($fieldNameArg instanceof String_)) {
return null;
}

$fieldName = $fieldNameArg->value;

$calledOnType = $scope->getType($methodCall->var);
assert($calledOnType instanceof TypeWithClassName);
$formClass = $calledOnType->getClassName();

$formClassReflection = $this->reflectionProvider->getClass($formClass);

if (!$formClassReflection->hasProperty($fieldName)) {
return null;
}

$formClassFieldProperty = $formClassReflection->getProperty($fieldName, $scope);
if (!($formClassFieldProperty instanceof AnnotationPropertyReflection)) {
return null;
}

return $formClassFieldProperty->getReadableType();
}

}
2 changes: 1 addition & 1 deletion src/Kris/LaravelFormBuilder/RulesParser.php
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,7 @@ protected function numeric()
}

return [
'pattern' => '[-+]?[0-9]*[.,]?[0-9]+',
'pattern' => '[\\-+]?[0-9]*[.,]?[0-9]+',
'title' => $this->getTitle('numeric'),
];
}
Expand Down

0 comments on commit 17c1d2e

Please sign in to comment.