Skip to content

Commit 454e643

Browse files
committed
Container, BaseControl: extension methods are implemented independently on ObjectMixin
1 parent bdab5d6 commit 454e643

File tree

4 files changed

+82
-6
lines changed

4 files changed

+82
-6
lines changed

src/Forms/Container.php

+9-3
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,9 @@
2121
*/
2222
class Container extends Nette\ComponentModel\Container implements \ArrayAccess
2323
{
24+
/** @var callable[] extension methods */
25+
private static $extMethods = [];
26+
2427
/** @var callable[] function (Container $sender); Occurs when the form is validated */
2528
public $onValidate;
2629

@@ -410,19 +413,22 @@ public function addContainer($name): self
410413

411414
public function __call(string $name, array $args)
412415
{
413-
if ($callback = Nette\Utils\ObjectMixin::getExtensionMethod(__CLASS__, $name)) {
416+
if (isset(self::$extMethods[$name])) {
417+
return (self::$extMethods[$name])($this, ...$args);
418+
} elseif ($callback = Nette\Utils\ObjectMixin::getExtensionMethod($class = __CLASS__, $name)) {
419+
trigger_error("Define extension method '$name' via $class::extensionMethod('$name', ...), don't use Nette\\Object or Nette\\Utils\\ObjectMixin.", E_USER_DEPRECATED);
414420
return Nette\Utils\Callback::invoke($callback, $this, ...$args);
415421
}
416422
return parent::__call($name, $args);
417423
}
418424

419425

420-
public static function extensionMethod($name, /*callable*/ $callback = NULL): void
426+
public static function extensionMethod($name, /*callable*/ $callback): void
421427
{
422428
if (strpos($name, '::') !== FALSE) { // back compatibility
423429
[, $name] = explode('::', $name);
424430
}
425-
Nette\Utils\ObjectMixin::setExtensionMethod(__CLASS__, $name, $callback);
431+
self::$extMethods[$name] = $callback;
426432
}
427433

428434

src/Forms/Controls/BaseControl.php

+15-3
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,9 @@ abstract class BaseControl extends Nette\ComponentModel\Component implements ICo
4040
/** @var string */
4141
public static $idMask = 'frm-%s';
4242

43+
/** @var callable[][] extension methods */
44+
private static $extMethods = [];
45+
4346
/** @var string|object textual caption or label */
4447
public $caption;
4548

@@ -556,19 +559,28 @@ public function getOptions(): array
556559

557560
public function __call(string $name, array $args)
558561
{
559-
if ($callback = Nette\Utils\ObjectMixin::getExtensionMethod(get_class($this), $name)) {
562+
$class = static::class;
563+
do {
564+
if (isset(self::$extMethods[$name][$class])) {
565+
return (self::$extMethods[$name][$class])($this, ...$args);
566+
}
567+
$class = get_parent_class($class);
568+
} while ($class);
569+
570+
if ($callback = Nette\Utils\ObjectMixin::getExtensionMethod($class = static::class, $name)) {
571+
trigger_error("Define extension method '$name' via $class::extensionMethod('$name', ...), don't use Nette\\Object or Nette\\Utils\\ObjectMixin.", E_USER_DEPRECATED);
560572
return Nette\Utils\Callback::invoke($callback, $this, ...$args);
561573
}
562574
return parent::__call($name, $args);
563575
}
564576

565577

566-
public static function extensionMethod(string $name, /*callable*/ $callback = NULL): void
578+
public static function extensionMethod($name, /*callable*/ $callback): void
567579
{
568580
if (strpos($name, '::') !== FALSE) { // back compatibility
569581
[, $name] = explode('::', $name);
570582
}
571-
Nette\Utils\ObjectMixin::setExtensionMethod(get_called_class(), $name, $callback);
583+
self::$extMethods[$name][static::class] = $callback;
572584
}
573585

574586
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
use Nette\Forms\Controls\TextBase;
6+
use Nette\Forms\Controls\TextInput;
7+
use Nette\Forms\Controls\Checkbox;
8+
use Nette\Forms\Controls\Button;
9+
use Tester\Assert;
10+
11+
12+
require __DIR__ . '/../bootstrap.php';
13+
14+
15+
TextBase::extensionMethod('test', function ($control, $a, $b) {
16+
Assert::type(TextInput::class, $control);
17+
Assert::same(1, $a);
18+
Assert::same(2, $b);
19+
return 'TextInput';
20+
});
21+
22+
Checkbox::extensionMethod('test', function ($control, $a, $b) {
23+
Assert::type(Checkbox::class, $control);
24+
Assert::same(1, $a);
25+
Assert::same(2, $b);
26+
return 'Checkbox';
27+
});
28+
29+
$control1 = new TextInput;
30+
Assert::same('TextInput', $control1->test(1, 2));
31+
32+
$control2 = new Checkbox;
33+
Assert::same('Checkbox', $control2->test(1, 2));
34+
35+
Assert::exception(function () {
36+
$control3 = new Button;
37+
$control3->test(1, 2);
38+
}, Nette\MemberAccessException::class);
+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
use Nette\Forms\Form;
6+
use Tester\Assert;
7+
8+
9+
require __DIR__ . '/../bootstrap.php';
10+
11+
12+
Nette\Forms\Container::extensionMethod('test', function ($form, $a, $b) {
13+
Assert::type(Nette\Forms\Form::class, $form);
14+
Assert::same(1, $a);
15+
Assert::same(2, $b);
16+
return 3;
17+
});
18+
19+
$form = new Form;
20+
Assert::same(3, $form->test(1, 2));

0 commit comments

Comments
 (0)