From 8857c6c676f85482f50326dad336a283780b084b Mon Sep 17 00:00:00 2001 From: Andrey Helldar Date: Sat, 30 Aug 2025 22:39:31 +0300 Subject: [PATCH] Replace `rootItem` and `rootAttributes` methods with `root` method --- README.md | 27 ++++++++++++------- src/Concerns/InteractsWithName.php | 9 +++++++ src/Data/ElementData.php | 13 +++++++++ src/Feeds/Feed.php | 10 +++---- src/Services/Generator.php | 17 ++++++------ stubs/feed.stub | 7 ++--- .../Unit/Console/MakeTest/make_feed.snap | 7 ++--- .../Unit/Console/MakeTest/make_with_item.snap | 7 ++--- workbench/app/Feeds/EmptyFeed.php | 7 +++-- workbench/app/Feeds/FilledFeed.php | 7 +++-- 10 files changed, 74 insertions(+), 37 deletions(-) create mode 100644 src/Data/ElementData.php diff --git a/README.md b/README.md index a4ce7dd..6c88717 100644 --- a/README.md +++ b/README.md @@ -74,6 +74,8 @@ Each feed can be created in a certain folder of a certain storage. To indicate the storage, reduce the property of `$storage` in the feed class: ```php +use DragonCode\LaravelFeed\Feeds\Feed; + class UserFeed extends Feed { protected string $storage = 'public'; @@ -85,6 +87,8 @@ By default, `public`. The path to the file inside the storage is indicated in the `filiname` method: ```php +use DragonCode\LaravelFeed\Feeds\Feed; + class UserFeed extends Feed { public function filename(): string @@ -176,18 +180,17 @@ According to this example, the XML file with the following contents will be gene #### Setting the root element ```php +use DragonCode\LaravelFeed\Data\ElementData; +use DragonCode\LaravelFeed\Feeds\Feed; + class UserFeed extends Feed { - public function rootItem(): ?string - { - return 'users'; - } - - public function rootAttributes(): array + public function root(): ElementData { - return [ - 'foo' => 'some value', - ]; + return new ElementData( + name: 'users', + attributes: ['foo' => 'some value'] + ); } } ``` @@ -195,6 +198,8 @@ class UserFeed extends Feed #### Adding attributes for the main section ```php +use DragonCode\LaravelFeed\Feeds\Items\FeedItem; + class UserFeedItem extends FeedItem { public function attributes(): array @@ -223,6 +228,8 @@ class UserFeedItem extends FeedItem > - `@mixed` ```php +use DragonCode\LaravelFeed\Feeds\Items\FeedItem; + class UserFeedItem extends FeedItem { public function toArray(): array @@ -264,6 +271,8 @@ class UserFeedItem extends FeedItem If it is necessary to change the file cap, override the `header` method in the feed class: ```php +use DragonCode\LaravelFeed\Feeds\Feed; + class UserFeed extends Feed { public function header(): string diff --git a/src/Concerns/InteractsWithName.php b/src/Concerns/InteractsWithName.php index d1117ef..fd57da2 100644 --- a/src/Concerns/InteractsWithName.php +++ b/src/Concerns/InteractsWithName.php @@ -5,6 +5,7 @@ namespace DragonCode\LaravelFeed\Concerns; use Illuminate\Support\Str; +use Illuminate\Support\Stringable; use function class_basename; use function str_replace; @@ -12,6 +13,14 @@ /** @mixin \Illuminate\Console\GeneratorCommand */ trait InteractsWithName { + protected function getNameInput(): string + { + return Str::of(parent::getNameInput()) + ->whenEndsWith('Feed', fn (Stringable $str) => $str->substr(0, -4)) + ->whenEndsWith('FeedItem', fn (Stringable $str) => $str->substr(0, -8)) + ->toString(); + } + protected function qualifyClass($name): string { return Str::finish(parent::qualifyClass($name), $this->type); diff --git a/src/Data/ElementData.php b/src/Data/ElementData.php new file mode 100644 index 0000000..71c1048 --- /dev/null +++ b/src/Data/ElementData.php @@ -0,0 +1,13 @@ +header(); - if ($item = $feed->rootItem()) { - $value .= $feed->rootAttributes() - ? sprintf("\n<%s %s>\n", $item, $this->makeRootAttributes($feed)) - : sprintf("\n<%s>\n", $item); + if ($name = $feed->root()->name) { + $value .= ! empty($feed->root()->attributes) + ? sprintf("\n<%s %s>\n", $name, $this->makeRootAttributes($feed->root())) + : sprintf("\n<%s>\n", $name); } $this->append($file, $value); @@ -69,16 +70,16 @@ protected function performFooter($file, Feed $feed): void { $value = $feed->footer(); - if ($item = $feed->rootItem()) { - $value .= "\n\n"; + if ($name = $feed->root()->name) { + $value .= "\n\n"; } $this->append($file, $value); } - protected function makeRootAttributes(Feed $feed): string + protected function makeRootAttributes(ElementData $item): string { - return collect($feed->rootAttributes()) + return collect($item->attributes) ->map(fn (mixed $value, int|string $key) => sprintf('%s="%s"', $key, $value)) ->implode(' '); } diff --git a/stubs/feed.stub b/stubs/feed.stub index 0b7e125..643cb8f 100644 --- a/stubs/feed.stub +++ b/stubs/feed.stub @@ -4,6 +4,7 @@ declare(strict_types=1); namespace DummyNamespace; +use DragonCode\LaravelFeed\Data\ElementData; use DragonCode\LaravelFeed\Feeds\Feed; use DragonCode\LaravelFeed\Feeds\Items\FeedItem; use Illuminate\Database\Eloquent\Builder; @@ -17,9 +18,9 @@ class DummyClass extends Feed return DummyUser::query(); } - public function rootItem(): ?string + public function root(): ElementData { - return 'users'; + return new ElementData('users'); } public function filename(): string @@ -29,6 +30,6 @@ class DummyClass extends Feed public function item(Model $model): FeedItem { - return new Items\DummyUserFeedItem($model); + return new Items\DummyClassItem($model); } } diff --git a/tests/.pest/snapshots/Unit/Console/MakeTest/make_feed.snap b/tests/.pest/snapshots/Unit/Console/MakeTest/make_feed.snap index bb209f8..cb08c5f 100644 --- a/tests/.pest/snapshots/Unit/Console/MakeTest/make_feed.snap +++ b/tests/.pest/snapshots/Unit/Console/MakeTest/make_feed.snap @@ -4,6 +4,7 @@ declare(strict_types=1); namespace App\Feeds; +use DragonCode\LaravelFeed\Data\ElementData; use DragonCode\LaravelFeed\Feeds\Feed; use DragonCode\LaravelFeed\Feeds\Items\FeedItem; use Illuminate\Database\Eloquent\Builder; @@ -17,9 +18,9 @@ class FooBarFeed extends Feed return User::query(); } - public function rootItem(): ?string + public function root(): ElementData { - return 'users'; + return new ElementData('users'); } public function filename(): string @@ -29,6 +30,6 @@ class FooBarFeed extends Feed public function item(Model $model): FeedItem { - return new Items\UserFeedItem($model); + return new Items\FooBarFeedItem($model); } } diff --git a/tests/.pest/snapshots/Unit/Console/MakeTest/make_with_item.snap b/tests/.pest/snapshots/Unit/Console/MakeTest/make_with_item.snap index 76d19d4..5fe7e1e 100644 --- a/tests/.pest/snapshots/Unit/Console/MakeTest/make_with_item.snap +++ b/tests/.pest/snapshots/Unit/Console/MakeTest/make_with_item.snap @@ -4,6 +4,7 @@ declare(strict_types=1); namespace App\Feeds; +use DragonCode\LaravelFeed\Data\ElementData; use DragonCode\LaravelFeed\Feeds\Feed; use DragonCode\LaravelFeed\Feeds\Items\FeedItem; use Illuminate\Database\Eloquent\Builder; @@ -17,9 +18,9 @@ class QweRtyFeed extends Feed return User::query(); } - public function rootItem(): ?string + public function root(): ElementData { - return 'users'; + return new ElementData('users'); } public function filename(): string @@ -29,6 +30,6 @@ class QweRtyFeed extends Feed public function item(Model $model): FeedItem { - return new Items\UserFeedItem($model); + return new Items\QweRtyFeedItem($model); } } diff --git a/workbench/app/Feeds/EmptyFeed.php b/workbench/app/Feeds/EmptyFeed.php index 4ba2e5f..f53399d 100644 --- a/workbench/app/Feeds/EmptyFeed.php +++ b/workbench/app/Feeds/EmptyFeed.php @@ -4,6 +4,7 @@ namespace Workbench\App\Feeds; +use DragonCode\LaravelFeed\Data\ElementData; use DragonCode\LaravelFeed\Feeds\Feed; use Illuminate\Database\Eloquent\Builder; use Workbench\App\Models\News; @@ -17,8 +18,10 @@ public function builder(): Builder return News::query()->where('id', '<', 0); } - public function rootItem(): ?string + public function root(): ElementData { - return class_basename($this); + return new ElementData( + class_basename($this) + ); } } diff --git a/workbench/app/Feeds/FilledFeed.php b/workbench/app/Feeds/FilledFeed.php index 018838d..e0071a7 100644 --- a/workbench/app/Feeds/FilledFeed.php +++ b/workbench/app/Feeds/FilledFeed.php @@ -4,6 +4,7 @@ namespace Workbench\App\Feeds; +use DragonCode\LaravelFeed\Data\ElementData; use DragonCode\LaravelFeed\Feeds\Feed; use DragonCode\LaravelFeed\Feeds\Items\FeedItem; use Illuminate\Database\Eloquent\Builder; @@ -21,9 +22,11 @@ public function builder(): Builder return News::query()->where('updated_at', '>', now()->subDay()); } - public function rootItem(): ?string + public function root(): ElementData { - return class_basename($this); + return new ElementData( + class_basename($this) + ); } public function filename(): string