Skip to content

Commit e401209

Browse files
Merge pull request #52 from TheDragonCode/1.x
Improved feed class generation
2 parents 4ac49a9 + ef613ce commit e401209

29 files changed

+366
-49
lines changed

composer.json

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -66,13 +66,7 @@
6666
"clear": "@php vendor/bin/testbench package:purge-skeleton --ansi",
6767
"prepare": "@php vendor/bin/testbench package:discover --ansi",
6868
"style": "vendor/bin/pint --parallel --ansi",
69-
"test": [
70-
"@clear",
71-
"@php vendor/bin/pest --colors=always"
72-
],
73-
"test:update": [
74-
"@clear",
75-
"@php vendor/bin/pest --colors=always --update-snapshots"
76-
]
69+
"test": "@php vendor/bin/pest --colors=always",
70+
"test:update": "@php vendor/bin/pest --colors=always --update-snapshots"
7771
}
7872
}

docs/topics/generation.topic

Lines changed: 48 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -12,39 +12,64 @@
1212

1313
<show-structure depth="2" />
1414

15-
<snippet id="generate">
15+
<chapter title="Generate all feeds" id="generate_all_feeds">
16+
<snippet id="generate">
17+
<p>
18+
To generate feeds, create the classes of feeds and its element, add links to the file
19+
<code>%config-filename%</code>, next call the console command:
20+
</p>
21+
22+
<code-block lang="bash">
23+
%command-generate%
24+
</code-block>
25+
</snippet>
26+
</chapter>
27+
28+
<chapter title="Generate a single feed" id="generate_a_single_feed">
29+
<note>
30+
Please note that the specified feed will be executed even if it is disabled in the settings file.
31+
</note>
32+
33+
<p>
34+
To generate a specific feed class, specify the class reference or name relative to the
35+
<code>App\Feeds</code> namespace.
36+
</p>
37+
1638
<p>
17-
To generate feeds, create the classes of feeds and its element, add links to the file
18-
<code>%config-filename%</code>, next call the console command:
39+
For example:
1940
</p>
2041

2142
<code-block lang="bash">
22-
%command-generate%
43+
%command-generate% App\Feeds\UserFeed
44+
%command-generate% UserFeed
45+
%command-generate% User
2346
</code-block>
24-
</snippet>
47+
</chapter>
2548

26-
<p>
27-
Each feed can be created in a certain folder of a certain storage.
28-
</p>
49+
<chapter title="Change location" id="change_location">
50+
<p>
51+
Each feed can be created in a certain folder of a certain storage.
52+
</p>
2953

30-
<p>
31-
To indicate the storage, override the property of <code>$storage</code> in the feed class:
32-
</p>
54+
<p>
55+
To indicate the storage, override the property of <code>$storage</code> in the feed class:
56+
</p>
3357

34-
<code-block lang="php" src="generation-feed-storage.php" include-lines="5-" />
58+
<code-block lang="php" src="generation-feed-storage.php" include-lines="5-" />
3559

36-
<p>
37-
By default, storage is <code>public</code>.
38-
</p>
60+
<p>
61+
By default, storage is <code>public</code>.
62+
</p>
3963

40-
<p>
41-
The path to the file inside the storage is indicated in the <code>filename</code> method:
42-
</p>
64+
<p>
65+
The path to the file inside the storage is indicated in the <code>filename</code> method:
66+
</p>
4367

44-
<code-block lang="php" src="generation-feed-filename.php" include-lines="5-" />
68+
<code-block lang="php" src="generation-feed-filename.php" include-lines="5-" />
4569

46-
<p>
47-
By default, the class name in <code>kebab-case</code> is used.
48-
For example, <code>user-feed.xml</code> for <code>UserFeed</code> class.
49-
</p>
70+
<p>
71+
By default, the class name in <code>kebab-case</code> is used.
72+
For example, <code>user-feed.xml</code> for <code>UserFeed</code> class.
73+
</p>
74+
</chapter>
5075
</topic>

src/Console/Commands/FeedGenerateCommand.php

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
namespace DragonCode\LaravelFeed\Console\Commands;
66

7+
use DragonCode\LaravelFeed\Helpers\FeedHelper;
78
use DragonCode\LaravelFeed\Services\Generator;
89
use Illuminate\Console\Command;
910
use Laravel\Prompts\Concerns\Colors;
@@ -18,24 +19,33 @@ class FeedGenerateCommand extends Command
1819
{
1920
use Colors;
2021

21-
public function handle(Generator $generator): void
22+
public function handle(Generator $generator, FeedHelper $helper): void
2223
{
23-
foreach ($this->feedable() as $feed => $enabled) {
24+
foreach ($this->feedable($helper) as $feed => $enabled) {
2425
$enabled
2526
? $this->components->task($feed, fn () => $generator->feed(app($feed)))
2627
: $this->components->twoColumnDetail($feed, $this->messageYellow('SKIP'));
2728
}
2829
}
2930

30-
protected function feedable(): array
31+
protected function feedable(FeedHelper $helper): array
3132
{
32-
if ($feed = $this->argument('class')) {
33+
if ($feed = $this->resolveFeedClass($helper)) {
3334
return [$feed => true];
3435
}
3536

3637
return config('feeds.channels');
3738
}
3839

40+
protected function resolveFeedClass(FeedHelper $helper): ?string
41+
{
42+
if (! $class = $this->argument('class')) {
43+
return null;
44+
}
45+
46+
return $helper->find((string) $class);
47+
}
48+
3949
protected function messageYellow(string $message): string
4050
{
4151
if ($this->option('no-ansi')) {
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace DragonCode\LaravelFeed\Exceptions;
6+
7+
use InvalidArgumentException;
8+
9+
class FeedNotFoundException extends InvalidArgumentException
10+
{
11+
public function __construct(string $class)
12+
{
13+
parent::__construct("Feed [$class] not found.");
14+
}
15+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace DragonCode\LaravelFeed\Exceptions;
6+
7+
use DragonCode\LaravelFeed\Feeds\Feed;
8+
use UnexpectedValueException;
9+
10+
class UnexpectedFeedException extends UnexpectedValueException
11+
{
12+
public function __construct(string $class)
13+
{
14+
parent::__construct(
15+
sprintf('The [%s] class must implement %s.', $class, Feed::class)
16+
);
17+
}
18+
}

src/Helpers/FeedHelper.php

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace DragonCode\LaravelFeed\Helpers;
6+
7+
use DragonCode\LaravelFeed\Exceptions\FeedNotFoundException;
8+
use DragonCode\LaravelFeed\Exceptions\UnexpectedFeedException;
9+
use DragonCode\LaravelFeed\Feeds\Feed;
10+
use Illuminate\Foundation\Application;
11+
use Illuminate\Support\Str;
12+
13+
use function class_exists;
14+
use function is_a;
15+
16+
class FeedHelper
17+
{
18+
public function __construct(
19+
protected Application $laravel
20+
) {}
21+
22+
public function find(string $class): string
23+
{
24+
if (class_exists($class)) {
25+
return $this->ensure($class);
26+
}
27+
28+
if (class_exists($class = $this->resolve($class))) {
29+
return $this->ensure($class);
30+
}
31+
32+
throw new FeedNotFoundException($class);
33+
}
34+
35+
protected function resolve(string $class): string
36+
{
37+
return Str::of($class)
38+
->replace('/', '\\')
39+
->ltrim('\\')
40+
->start($this->rootNamespace() . 'Feeds\\')
41+
->finish('Feed')
42+
->toString();
43+
}
44+
45+
protected function ensure(string $class): string
46+
{
47+
if (! is_a($class, Feed::class, true)) {
48+
throw new UnexpectedFeedException($class);
49+
}
50+
51+
return $class;
52+
}
53+
54+
protected function rootNamespace(): string
55+
{
56+
return $this->laravel->getNamespace();
57+
}
58+
}

testbench.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ laravel: '@testbench'
22

33
providers:
44
- DragonCode\LaravelFeed\LaravelFeedServiceProvider
5+
- Workbench\App\Providers\WorkbenchServiceProvider
56

67
migrations:
78
- workbench/database/migrations

0 commit comments

Comments
 (0)