Skip to content

Commit f2376ca

Browse files
committed
Merge branch 'develop'
2 parents 314b3c1 + 862fb3e commit f2376ca

File tree

5 files changed

+47
-4
lines changed

5 files changed

+47
-4
lines changed

CHANGELOG.md

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,18 @@
11
# Changelog
22

3-
## [Unreleased](https://github.com/clickfwd/yoyo/compare/0.12.0...develop)
3+
## [Unreleased](https://github.com/clickfwd/yoyo/compare/0.13.1...develop)
4+
5+
## [0.13.1 (2025-08-15)](https://github.com/clickfwd/yoyo/compare/0.13.0...0.13.1)
6+
7+
- Fix parameter validation to correctly handle optional parameters in component actions
48

59
## [0.13.0 (2025-08-15)](https://github.com/clickfwd/yoyo/compare/0.12.0...0.13.0)
610

711
- Fix spinners stop working when target is different than current element
812
- Add support for variadic parameters in component actions using PHP's `...$params` syntax
13+
- Add automatic dependency injection for typed parameters in component actions
14+
- Add new ClassHelpers methods: `methodHasVariadicParameter()` and `getMethodParametersWithTypes()`
15+
- Enhanced ComponentManager to handle methods with variadic parameters
916
- Improved parameter validation to support methods with only typed (DI) parameters
1017
- Container integration now properly handles mixed regular, typed, and variadic parameters
1118

composer.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
"framework",
66
"yoyo"
77
],
8-
"version": "0.11.1",
98
"license": "MIT",
109
"homepage": "https://github.com/Clickfwd/yoyo",
1110
"support": {

src/yoyo/ComponentManager.php

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -191,9 +191,21 @@ private function processDynamicComponent($action, $variables = [], $attributes =
191191
throw new \InvalidArgumentException("Too few parameters passed to [{$this->name}::{$action}]");
192192
}
193193
} else {
194+
// Check if all regular parameters are optional
195+
$requiredCount = 0;
196+
foreach ($regularParams as $param) {
197+
if (! $param['optional']) {
198+
$requiredCount++;
199+
}
200+
}
201+
194202
// Only validate regular parameters (not typed/DI parameters)
195-
if (count($parameterNames) == count($parameters)) {
196-
$args = array_combine($parameterNames, $parameters);
203+
if (count($parameters) >= $requiredCount && count($parameters) <= count($parameterNames)) {
204+
// Parameters count is valid (between required and total)
205+
$args = [];
206+
for ($i = 0; $i < count($parameterNames); $i++) {
207+
$args[$parameterNames[$i]] = $parameters[$i] ?? null;
208+
}
197209
} elseif (empty($parameterNames) && empty($parameters)) {
198210
// Method has only typed parameters (or no parameters at all)
199211
$args = [];

tests/Feature/DynamicComponentTest.php

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -205,3 +205,19 @@
205205

206206
expect(yoyo_update())->toContain('Post: the comment title, Tags: ["php","laravel","yoyo"]');
207207
});
208+
209+
it('handles action with typed and optional regular parameter without value', function () {
210+
mockYoyoPostRequest('/', 'dependency-injection-action/typedWithOptional', 'dependency-injection-action', [
211+
'actionArgs' => [],
212+
]);
213+
214+
expect(yoyo_update())->toContain('Post: the comment title, Status: default');
215+
});
216+
217+
it('handles action with typed and optional regular parameter with value', function () {
218+
mockYoyoPostRequest('/', 'dependency-injection-action/typedWithOptional', 'dependency-injection-action', [
219+
'actionArgs' => ['active'],
220+
]);
221+
222+
expect(yoyo_update())->toContain('Post: the comment title, Status: active');
223+
});

tests/app/Yoyo/DependencyInjectionAction.php

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,15 @@ public function typedWithVariadic(Post $post, ...$tags)
4242
$this->result = "Post: {$post->title()}, Tags: " . json_encode($tags);
4343
}
4444

45+
/**
46+
* Test action with typed and optional regular parameter
47+
*/
48+
public function typedWithOptional(Post $post, ?string $status = null)
49+
{
50+
$statusText = $status ?? 'default';
51+
$this->result = "Post: {$post->title()}, Status: {$statusText}";
52+
}
53+
4554
public function render()
4655
{
4756
return $this->view('dependency-injection-action', ['result' => $this->result]);

0 commit comments

Comments
 (0)