From 6ab58ecb4db8c3a59a29a278831014a507510050 Mon Sep 17 00:00:00 2001 From: Quentin Gabriele Date: Fri, 13 Sep 2024 23:30:03 +0200 Subject: [PATCH] deep clone --- src/OpenGraph/Locale.php | 3 ++ src/OpenGraph/OpenGraph.php | 3 ++ src/OpenGraph/Verticals/Vertical.php | 3 ++ src/Schemas/Schema.php | 3 ++ src/SeoManager.php | 2 ++ src/SeoTags.php | 3 ++ src/Standard/Standard.php | 3 ++ src/Tags/TagVoid.php | 3 ++ src/Traits/DeepClone.php | 25 +++++++++++++ src/Twitter/Cards/Card.php | 3 ++ tests/Units/SeoManagerTest.php | 53 ++++++++++++++++++++++++++++ 11 files changed, 104 insertions(+) create mode 100644 src/Traits/DeepClone.php diff --git a/src/OpenGraph/Locale.php b/src/OpenGraph/Locale.php index 597f18f..a4baac0 100644 --- a/src/OpenGraph/Locale.php +++ b/src/OpenGraph/Locale.php @@ -5,9 +5,12 @@ use Elegantly\Seo\Contracts\Taggable; use Elegantly\Seo\SeoTags; use Elegantly\Seo\Tags\Meta; +use Elegantly\Seo\Traits\DeepClone; class Locale implements Taggable { + use DeepClone; + /** * @param string[] $alternate */ diff --git a/src/OpenGraph/OpenGraph.php b/src/OpenGraph/OpenGraph.php index c530695..ced8fda 100644 --- a/src/OpenGraph/OpenGraph.php +++ b/src/OpenGraph/OpenGraph.php @@ -7,11 +7,14 @@ use Elegantly\Seo\OpenGraph\Verticals\Website; use Elegantly\Seo\SeoTags; use Elegantly\Seo\Tags\Meta; +use Elegantly\Seo\Traits\DeepClone; use Illuminate\Support\Facades\App; use Illuminate\Support\Facades\Request; class OpenGraph implements Taggable { + use DeepClone; + public function __construct( public string $title, public string $url, diff --git a/src/OpenGraph/Verticals/Vertical.php b/src/OpenGraph/Verticals/Vertical.php index 2a013e4..a85f24a 100644 --- a/src/OpenGraph/Verticals/Vertical.php +++ b/src/OpenGraph/Verticals/Vertical.php @@ -7,10 +7,13 @@ use Elegantly\Seo\Contracts\Taggable; use Elegantly\Seo\SeoTags; use Elegantly\Seo\Tags\Meta; +use Elegantly\Seo\Traits\DeepClone; use Illuminate\Support\Arr; abstract class Vertical implements Taggable { + use DeepClone; + abstract public function getType(): string; public function getNamespace(): string diff --git a/src/Schemas/Schema.php b/src/Schemas/Schema.php index d980716..cdd182f 100644 --- a/src/Schemas/Schema.php +++ b/src/Schemas/Schema.php @@ -5,6 +5,7 @@ use Elegantly\Seo\Contracts\Taggable; use Elegantly\Seo\SeoTags; use Elegantly\Seo\Tags\Script; +use Elegantly\Seo\Traits\DeepClone; use Illuminate\Support\Collection; /** @@ -12,6 +13,8 @@ */ class Schema extends Collection implements Taggable { + use DeepClone; + public function toTags(): SeoTags { return new SeoTags([ diff --git a/src/SeoManager.php b/src/SeoManager.php index cc497e3..80b5a26 100644 --- a/src/SeoManager.php +++ b/src/SeoManager.php @@ -10,6 +10,7 @@ use Elegantly\Seo\Schemas\WebPage; use Elegantly\Seo\Standard\Alternate; use Elegantly\Seo\Standard\Standard; +use Elegantly\Seo\Traits\DeepClone; use Elegantly\Seo\Twitter\Cards\Card; use Elegantly\Seo\Twitter\Cards\Summary; use Illuminate\Contracts\Support\Htmlable; @@ -20,6 +21,7 @@ class SeoManager implements Htmlable, Stringable, Taggable { use Conditionable; + use DeepClone; /** * @param null|Schema[] $schemas diff --git a/src/SeoTags.php b/src/SeoTags.php index b1d409b..c973728 100644 --- a/src/SeoTags.php +++ b/src/SeoTags.php @@ -3,6 +3,7 @@ namespace Elegantly\Seo; use Elegantly\Seo\Tags\TagVoid; +use Elegantly\Seo\Traits\DeepClone; use Illuminate\Contracts\Support\Htmlable; use Illuminate\Support\Collection; @@ -11,6 +12,8 @@ */ class SeoTags extends Collection implements Htmlable { + use DeepClone; + public function toHtml(): string { return $this->map(fn (TagVoid $tag) => $tag->toHtml())->join("\n"); diff --git a/src/Standard/Standard.php b/src/Standard/Standard.php index f6619ed..fb6d8da 100644 --- a/src/Standard/Standard.php +++ b/src/Standard/Standard.php @@ -7,6 +7,7 @@ use Elegantly\Seo\Tags\Link; use Elegantly\Seo\Tags\Meta; use Elegantly\Seo\Tags\Title; +use Elegantly\Seo\Traits\DeepClone; use Illuminate\Support\Facades\Request; /** @@ -14,6 +15,8 @@ */ class Standard implements Taggable { + use DeepClone; + /** * @param null|string|string[] $keywords * @param null|Alternate[] $alternates diff --git a/src/Tags/TagVoid.php b/src/Tags/TagVoid.php index 2e45ba9..009df4e 100644 --- a/src/Tags/TagVoid.php +++ b/src/Tags/TagVoid.php @@ -2,11 +2,14 @@ namespace Elegantly\Seo\Tags; +use Elegantly\Seo\Traits\DeepClone; use Illuminate\Contracts\Support\Htmlable; use Illuminate\Support\Collection; abstract class TagVoid implements Htmlable { + use DeepClone; + public string $tag; /** diff --git a/src/Traits/DeepClone.php b/src/Traits/DeepClone.php new file mode 100644 index 0000000..d918e61 --- /dev/null +++ b/src/Traits/DeepClone.php @@ -0,0 +1,25 @@ + $value) { + if (is_object($value)) { + $this->{$property} = clone $value; + } + + if (is_array($value)) { + $this->{$property} = array_map(function ($item) { + if (is_object($item)) { + return clone $item; + } + + return $item; + }, $value); + } + } + } +} diff --git a/src/Twitter/Cards/Card.php b/src/Twitter/Cards/Card.php index 3592a1f..3349e4b 100644 --- a/src/Twitter/Cards/Card.php +++ b/src/Twitter/Cards/Card.php @@ -5,10 +5,13 @@ use Elegantly\Seo\Contracts\Taggable; use Elegantly\Seo\SeoTags; use Elegantly\Seo\Tags\Meta; +use Elegantly\Seo\Traits\DeepClone; use Elegantly\Seo\Twitter\Image; abstract class Card implements Taggable { + use DeepClone; + public function toTags(): SeoTags { $tags = new SeoTags; diff --git a/tests/Units/SeoManagerTest.php b/tests/Units/SeoManagerTest.php index ee1de96..1c9999e 100644 --- a/tests/Units/SeoManagerTest.php +++ b/tests/Units/SeoManagerTest.php @@ -4,9 +4,13 @@ use Elegantly\Seo\OpenGraph\Locale; use Elegantly\Seo\OpenGraph\OpenGraph; use Elegantly\Seo\OpenGraph\Verticals\Website; +use Elegantly\Seo\Schemas\Schema; +use Elegantly\Seo\Schemas\WebPage; use Elegantly\Seo\SeoManager; +use Elegantly\Seo\SeoTags; use Elegantly\Seo\Standard\Alternate; use Elegantly\Seo\Standard\Standard; +use Elegantly\Seo\Tags\Meta; use Elegantly\Seo\Twitter\Cards\Summary; use Elegantly\Seo\Twitter\Image as TwitterImage; @@ -80,3 +84,52 @@ '', ])); }); + +it('can clone itself with new references', function () { + $base = new SeoManager( + standard: new Standard( + title: 'foo', + canonical: 'bar', + alternates: [ + new Alternate( + hreflang: 'foo', + href: 'bar' + ), + ] + ), + opengraph: new OpenGraph( + title: 'foo', + url: 'bar', + image: new Image( + url: 'foo', + ) + ), + twitter: new Summary( + title: 'foo', + ), + webpage: new WebPage, + schemas: [ + new Schema, + ], + customTags: new SeoTags([ + new Meta( + name: 'foo', + content: 'bar' + ), + ]) + ); + + $clone = clone $base; + + expect($clone)->not->toBe($base); + + expect($clone->standard)->not->toBe($base->standard); + expect($clone->opengraph)->not->toBe($base->opengraph); + expect($clone->twitter)->not->toBe($base->twitter); + expect($clone->webpage)->not->toBe($base->webpage); + expect($clone->schemas)->not->toBe($base->schemas); + expect($clone->schemas[0])->not->toBe($base->schemas[0]); + expect($clone->customTags)->not->toBe($base->customTags); + expect($clone->customTags[0])->not->toBe($base->customTags[0]); + expect($clone->customTags[0]->properties)->not->toBe($base->customTags[0]->properties); +});