From 725fbb231a1de86c28b270649596610d7a70c07b Mon Sep 17 00:00:00 2001 From: Wilmer Arambula Date: Tue, 21 Jan 2025 09:56:41 -0300 Subject: [PATCH 1/3] Refactor `NavLink` class to use constructor property promotion and add immutable methods. --- src/NavLink.php | 149 +++++++++++++++++++++++++++++++----------- tests/NavLinkTest.php | 5 ++ tests/NavTest.php | 4 +- 3 files changed, 117 insertions(+), 41 deletions(-) diff --git a/src/NavLink.php b/src/NavLink.php index b32bddbd..36178e6d 100644 --- a/src/NavLink.php +++ b/src/NavLink.php @@ -27,19 +27,64 @@ */ final class NavLink { - private bool $active = false; - private array $attributes = []; - private bool $encodeLabel = true; - private bool $disabled = false; - private string|Stringable $label = ''; - private string|null $url = ''; - private array $urlAttributes = []; - /** * Use {@see NavLink::to()} to create an instance. */ - private function __construct() + private function __construct( + private bool $active = false, + private array $attributes = [], + private bool $encodeLabel = true, + private bool $disabled = false, + private string|Stringable $label = '', + private string|null $url = '', + private array $urlAttributes = [], + ) { + } + + /** + * Creates a nav {@see NavLink} instance. + * + * @param string|Stringable $label The label of the link. + * @param string|null $url The URL of the link. + * @param bool $active Whether the link is active. + * @param bool $disabled Whether the link is disabled. + * @param bool $encodeLabel Whether the label should be encoded. + * @param array $attributes The HTML attributes for the nav item. + * @param array $urlAttributes The HTML attributes for the nav item link. + * + * @throws InvalidArgumentException If the link is both active and disabled. + * + * @return self A new instance with the specified attributes. + */ + public static function to( + string|Stringable $label = '', + string|null $url = null, + bool $active = false, + bool $disabled = false, + bool $encodeLabel = true, + array $attributes = [], + array $urlAttributes = [], + ): self { + if ($active === true && $disabled === true) { + throw new InvalidArgumentException('A nav link cannot be both active and disabled.'); + } + + return new self($active, $attributes, $encodeLabel, $disabled, $label, $url, $urlAttributes); + } + + /** + * Sets the active state of the nav item. + * + * @param bool $value Whether the nav item is active. + * + * @return self A new instance with the specified active state. + */ + public function active(bool $value): self { + $new = clone $this; + $new->active = $value; + + return $new; } /** @@ -60,54 +105,80 @@ public function attributes(array $values): self } /** - * Sets the HTML attributes for the nav item link. + * Sets the disabled state of the nav item. * - * @param array $values Attribute values indexed by attribute names. + * @param bool $value Whether the nav item is disabled. * - * @return self A new instance with the specified attributes. + * @return self A new instance with the specified disabled state. + */ + public function disabled(bool $value): self + { + $new = clone $this; + $new->disabled = $value; + + return $new; + } + + /** + * Sets whether to HTML-encode the label. * - * @see {\Yiisoft\Html\Html::renderTagAttributes()} for details on how attributes are being rendered. + * @param bool $value Whether to encode the label + * + * @return self New instance with the specified encode setting. */ - public function urlAttributes(array $values): self + public function encodeLabel(bool $value): self { $new = clone $this; - $new->urlAttributes = $values; + $new->encodeLabel = $value; return $new; } /** - * Creates a nav item. + * Sets the label text for the nav item. * - * @param string|Stringable $label The label of the link. - * @param string|null $url The URL of the link. - * @param bool $active Whether the link is active. - * @param bool $disabled Whether the link is disabled. + * @param string|Stringable $value The label text or Stringable object * - * @throws InvalidArgumentException If the link is both active and disabled. + * @return self New instance with the specified label text. + */ + public function label(string|Stringable $value): self + { + $new = clone $this; + $new->label = $value; + + return $new; + } + + /** + * Sets the URL for the nav item. * - * @return self A new instance with the specified attributes. + * @param string|null $value The URL or `null` for no URL. + * + * @return self New instance with the specified URL. */ - public static function to( - string|Stringable $label = '', - string|null $url = null, - bool $active = false, - bool $disabled = false, - bool $encodeLabel = true - ): self { - $navlink = new self(); + public function url(string|null $value): self + { + $new = clone $this; + $new->url = $value; - if ($active === true && $disabled === true) { - throw new InvalidArgumentException('A nav link cannot be both active and disabled.'); - } + return $new; + } - $navlink->active = $active; - $navlink->disabled = $disabled; - $navlink->encodeLabel = $encodeLabel; - $navlink->label = $label; - $navlink->url = $url; + /** + * Sets HTML attributes for the nav item link. + * + * @param array $values Attribute values indexed by attribute names + * + * @return self New instance with the specified link attributes + * + * @see \Yiisoft\Html\Html::renderTagAttributes() for details on how attributes are rendered + */ + public function urlAttributes(array $values): self + { + $new = clone $this; + $new->urlAttributes = $values; - return $navlink; + return $new; } /** diff --git a/tests/NavLinkTest.php b/tests/NavLinkTest.php index 2e4fbe6e..6e0c4758 100644 --- a/tests/NavLinkTest.php +++ b/tests/NavLinkTest.php @@ -18,7 +18,12 @@ public function testImmutability(): void { $navLink = NavLink::to('Home', '/', true); + $this->assertNotSame($navLink, $navLink->active(false)); $this->assertNotSame($navLink, $navLink->attributes([])); + $this->assertNotSame($navLink, $navLink->disabled(false)); + $this->assertNotSame($navLink, $navLink->encodeLabel(false)); + $this->assertNotSame($navLink, $navLink->label('')); + $this->assertNotSame($navLink, $navLink->url('')); $this->assertNotSame($navLink, $navLink->urlAttributes([])); } diff --git a/tests/NavTest.php b/tests/NavTest.php index b470ff02..bd71e234 100644 --- a/tests/NavTest.php +++ b/tests/NavTest.php @@ -649,7 +649,7 @@ public function testNavLinkWithAttributes(): void HTML, Nav::widget() - ->items(NavLink::to('Active', '#', active: true)->attributes(['data-test' => 'test'])) + ->items(NavLink::to('Active', '#', active: true, attributes: ['data-test' => 'test'])) ->render(), ); } @@ -665,7 +665,7 @@ public function testNavLinkWithUrlAttributes(): void HTML, Nav::widget() - ->items(NavLink::to('Active', '#', active: true)->urlAttributes(['data-test' => 'test'])) + ->items(NavLink::to('Active', '#', active: true, urlAttributes: ['data-test' => 'test'])) ->render(), ); } From 08279a26341e8d3c692605574cc6e91dc68f6863 Mon Sep 17 00:00:00 2001 From: Wilmer Arambula Date: Tue, 21 Jan 2025 16:56:22 -0300 Subject: [PATCH 2/3] Apply fixed review. --- src/NavLink.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/NavLink.php b/src/NavLink.php index 36178e6d..f6b0eeb3 100644 --- a/src/NavLink.php +++ b/src/NavLink.php @@ -42,7 +42,7 @@ private function __construct( } /** - * Creates a nav {@see NavLink} instance. + * Creates a {@see NavLink} instance. * * @param string|Stringable $label The label of the link. * @param string|null $url The URL of the link. @@ -65,7 +65,7 @@ public static function to( array $attributes = [], array $urlAttributes = [], ): self { - if ($active === true && $disabled === true) { + if ($active && $disabled) { throw new InvalidArgumentException('A nav link cannot be both active and disabled.'); } @@ -122,7 +122,7 @@ public function disabled(bool $value): self /** * Sets whether to HTML-encode the label. * - * @param bool $value Whether to encode the label + * @param bool $value Whether to encode the label. * * @return self New instance with the specified encode setting. */ @@ -167,11 +167,11 @@ public function url(string|null $value): self /** * Sets HTML attributes for the nav item link. * - * @param array $values Attribute values indexed by attribute names + * @param array $values Attribute values indexed by attribute names. * * @return self New instance with the specified link attributes * - * @see \Yiisoft\Html\Html::renderTagAttributes() for details on how attributes are rendered + * @see \Yiisoft\Html\Html::renderTagAttributes() for details on how attributes are rendered. */ public function urlAttributes(array $values): self { From a6050b7dad8747b845df565985b873ba9a461b08 Mon Sep 17 00:00:00 2001 From: Wilmer Arambula Date: Tue, 21 Jan 2025 16:57:40 -0300 Subject: [PATCH 3/3] More fixed review. --- src/NavLink.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/NavLink.php b/src/NavLink.php index f6b0eeb3..9b416ef2 100644 --- a/src/NavLink.php +++ b/src/NavLink.php @@ -169,7 +169,7 @@ public function url(string|null $value): self * * @param array $values Attribute values indexed by attribute names. * - * @return self New instance with the specified link attributes + * @return self New instance with the specified link attributes. * * @see \Yiisoft\Html\Html::renderTagAttributes() for details on how attributes are rendered. */