Skip to content

Commit 5aa7993

Browse files
vinceAmstoutzsoyuka
andauthoredOct 11, 2024··
feat(laravel): command to generate state providers/processors (#6708)
Co-authored-by: Antoine Bluchet <soyuka@users.noreply.github.com>
1 parent 4bbfff3 commit 5aa7993

17 files changed

+711
-3
lines changed
 

‎.php-cs-fixer.dist.php

+1
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
->in(__DIR__)
1616
->exclude([
1717
'src/Core/Bridge/Symfony/Maker/Resources/skeleton',
18+
'src/Laravel/Console/Maker/Resources/skeleton',
1819
'src/Laravel/config',
1920
'tests/Fixtures/app/var',
2021
'docs/guides',

‎src/Laravel/ApiPlatformProvider.php

+5-1
Original file line numberDiff line numberDiff line change
@@ -1058,7 +1058,11 @@ function (Application $app) {
10581058
});
10591059

10601060
if ($this->app->runningInConsole()) {
1061-
$this->commands([Console\InstallCommand::class]);
1061+
$this->commands([
1062+
Console\InstallCommand::class,
1063+
Console\Maker\MakeStateProcessorCommand::class,
1064+
Console\Maker\MakeStateProviderCommand::class,
1065+
]);
10621066
}
10631067
}
10641068

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the API Platform project.
5+
*
6+
* (c) Kévin Dunglas <dunglas@gmail.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
declare(strict_types=1);
13+
14+
namespace ApiPlatform\Laravel\Console\Maker;
15+
16+
use ApiPlatform\Laravel\Console\Maker\Utils\AppServiceProviderTagger;
17+
use ApiPlatform\Laravel\Console\Maker\Utils\StateTemplateGenerator;
18+
use ApiPlatform\Laravel\Console\Maker\Utils\StateTypeEnum;
19+
use ApiPlatform\Laravel\Console\Maker\Utils\SuccessMessageTrait;
20+
use Illuminate\Console\Command;
21+
use Illuminate\Contracts\Filesystem\FileNotFoundException;
22+
use Illuminate\Filesystem\Filesystem;
23+
24+
abstract class AbstractMakeStateCommand extends Command
25+
{
26+
use SuccessMessageTrait;
27+
28+
public function __construct(
29+
private readonly Filesystem $filesystem,
30+
private readonly StateTemplateGenerator $stateTemplateGenerator,
31+
private readonly AppServiceProviderTagger $appServiceProviderTagger,
32+
) {
33+
parent::__construct();
34+
}
35+
36+
/**
37+
* @throws FileNotFoundException
38+
*/
39+
public function handle(): int
40+
{
41+
$stateName = $this->askForStateName();
42+
43+
$directoryPath = base_path('src/State/');
44+
$this->filesystem->ensureDirectoryExists($directoryPath);
45+
46+
$filePath = $this->stateTemplateGenerator->getFilePath($directoryPath, $stateName);
47+
if ($this->filesystem->exists($filePath)) {
48+
$this->error(\sprintf('[ERROR] The file "%s" can\'t be generated because it already exists.', $filePath));
49+
50+
return self::FAILURE;
51+
}
52+
53+
$this->stateTemplateGenerator->generate($filePath, $stateName, $this->getStateType());
54+
if (!$this->filesystem->exists($filePath)) {
55+
$this->error(\sprintf('[ERROR] The file "%s" could not be created.', $filePath));
56+
57+
return self::FAILURE;
58+
}
59+
60+
$this->appServiceProviderTagger->addTagToServiceProvider($stateName, $this->getStateType());
61+
62+
$this->writeSuccessMessage($filePath, $this->getStateType());
63+
64+
return self::SUCCESS;
65+
}
66+
67+
protected function askForStateName(): string
68+
{
69+
do {
70+
$stateType = $this->getStateType()->name;
71+
$stateName = $this->ask(\sprintf('Choose a class name for your state %s (e.g. <fg=yellow>AwesomeState%s</>)', strtolower($stateType), ucfirst($stateType)));
72+
if (empty($stateName)) {
73+
$this->error('[ERROR] This value cannot be blank.');
74+
}
75+
} while (empty($stateName));
76+
77+
return $stateName;
78+
}
79+
80+
abstract protected function getStateType(): StateTypeEnum;
81+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the API Platform project.
5+
*
6+
* (c) Kévin Dunglas <dunglas@gmail.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
declare(strict_types=1);
13+
14+
namespace ApiPlatform\Laravel\Console\Maker;
15+
16+
use ApiPlatform\Laravel\Console\Maker\Utils\StateTypeEnum;
17+
18+
final class MakeStateProcessorCommand extends AbstractMakeStateCommand
19+
{
20+
protected $signature = 'make:state-processor';
21+
protected $description = 'Creates an API Platform state processor';
22+
23+
protected function getStateType(): StateTypeEnum
24+
{
25+
return StateTypeEnum::Processor;
26+
}
27+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the API Platform project.
5+
*
6+
* (c) Kévin Dunglas <dunglas@gmail.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
declare(strict_types=1);
13+
14+
namespace ApiPlatform\Laravel\Console\Maker;
15+
16+
use ApiPlatform\Laravel\Console\Maker\Utils\StateTypeEnum;
17+
18+
final class MakeStateProviderCommand extends AbstractMakeStateCommand
19+
{
20+
protected $signature = 'make:state-provider';
21+
protected $description = 'Creates an API Platform state provider';
22+
23+
protected function getStateType(): StateTypeEnum
24+
{
25+
return StateTypeEnum::Provider;
26+
}
27+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace {{ namespace }};
6+
7+
use ApiPlatform\Metadata\Operation;
8+
use ApiPlatform\State\ProcessorInterface;
9+
10+
final class {{ class_name }} implements ProcessorInterface
11+
{
12+
public function process(mixed $data, Operation $operation, array $uriVariables = [], array $context = []): void
13+
{
14+
// Handle the state
15+
}
16+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace {{ namespace }};
6+
7+
use ApiPlatform\Metadata\Operation;
8+
use ApiPlatform\State\ProviderInterface;
9+
10+
final class {{ class_name }} implements ProviderInterface
11+
{
12+
public function provide(Operation $operation, array $uriVariables = [], array $context = []): object|array|null
13+
{
14+
// Retrieve the state from somewhere
15+
}
16+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the API Platform project.
5+
*
6+
* (c) Kévin Dunglas <dunglas@gmail.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
declare(strict_types=1);
13+
14+
namespace ApiPlatform\Laravel\Console\Maker\Utils;
15+
16+
use Illuminate\Contracts\Filesystem\FileNotFoundException;
17+
use Illuminate\Filesystem\Filesystem;
18+
19+
final readonly class AppServiceProviderTagger
20+
{
21+
/** @var string */
22+
private const APP_SERVICE_PROVIDER_PATH = 'Providers/AppServiceProvider.php';
23+
24+
/** @var string */
25+
private const ITEM_PROVIDER_USE_STATEMENT = 'use ApiPlatform\State\ProviderInterface;';
26+
27+
/** @var string */
28+
private const ITEM_PROCESSOR_USE_STATEMENT = 'use ApiPlatform\State\ProcessorInterface;';
29+
30+
public function __construct(private Filesystem $filesystem)
31+
{
32+
}
33+
34+
/**
35+
* @throws FileNotFoundException
36+
*/
37+
public function addTagToServiceProvider(string $providerName, StateTypeEnum $stateTypeEnum): void
38+
{
39+
$appServiceProviderPath = app_path(self::APP_SERVICE_PROVIDER_PATH);
40+
if (!$this->filesystem->exists($appServiceProviderPath)) {
41+
throw new \RuntimeException('The AppServiceProvider is missing!');
42+
}
43+
44+
$serviceProviderContent = $this->filesystem->get($appServiceProviderPath);
45+
46+
$this->addUseStatement($serviceProviderContent, $this->getStateTypeStatement($stateTypeEnum));
47+
$this->addUseStatement($serviceProviderContent, \sprintf('use App\\State\\%s;', $providerName));
48+
$this->addTag($serviceProviderContent, $providerName, $appServiceProviderPath, $stateTypeEnum);
49+
}
50+
51+
private function addUseStatement(string &$content, string $useStatement): void
52+
{
53+
if (!str_contains($content, $useStatement)) {
54+
$content = preg_replace(
55+
'/^(namespace\s[^;]+;\s*)(\n)/m',
56+
"$1\n$useStatement$2",
57+
$content,
58+
1
59+
);
60+
}
61+
}
62+
63+
private function addTag(string &$content, string $stateName, string $serviceProviderPath, StateTypeEnum $stateTypeEnum): void
64+
{
65+
$tagStatement = \sprintf("\n\n\t\t\$this->app->tag(%s::class, %sInterface::class);", $stateName, $stateTypeEnum->name);
66+
67+
if (!str_contains($content, $tagStatement)) {
68+
$content = preg_replace(
69+
'/(public function register\(\)[^{]*{)(.*?)(\s*}\s*})/s',
70+
"$1$2$tagStatement$3",
71+
$content
72+
);
73+
74+
$this->filesystem->put($serviceProviderPath, $content);
75+
}
76+
}
77+
78+
private function getStateTypeStatement(StateTypeEnum $stateTypeEnum): string
79+
{
80+
return match ($stateTypeEnum) {
81+
StateTypeEnum::Provider => self::ITEM_PROVIDER_USE_STATEMENT,
82+
StateTypeEnum::Processor => self::ITEM_PROCESSOR_USE_STATEMENT,
83+
};
84+
}
85+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the API Platform project.
5+
*
6+
* (c) Kévin Dunglas <dunglas@gmail.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
declare(strict_types=1);
13+
14+
namespace ApiPlatform\Laravel\Console\Maker\Utils;
15+
16+
use Illuminate\Contracts\Filesystem\FileNotFoundException;
17+
use Illuminate\Filesystem\Filesystem;
18+
19+
final readonly class StateTemplateGenerator
20+
{
21+
public function __construct(private Filesystem $filesystem)
22+
{
23+
}
24+
25+
public function getFilePath(string $directoryPath, string $stateFileName): string
26+
{
27+
return $directoryPath.$stateFileName.'.php';
28+
}
29+
30+
/**
31+
* @throws FileNotFoundException
32+
*/
33+
public function generate(string $pathLink, string $stateClassName, StateTypeEnum $stateTypeEnum): void
34+
{
35+
$namespace = 'App\\State';
36+
$template = $this->loadTemplate($stateTypeEnum);
37+
38+
$content = strtr($template, [
39+
'{{ namespace }}' => $namespace,
40+
'{{ class_name }}' => $stateClassName,
41+
]);
42+
43+
$this->filesystem->put($pathLink, $content);
44+
}
45+
46+
/**
47+
* @throws FileNotFoundException
48+
*/
49+
private function loadTemplate(StateTypeEnum $stateTypeEnum): string
50+
{
51+
$templateFile = match ($stateTypeEnum) {
52+
StateTypeEnum::Provider => 'StateProvider.tpl.php',
53+
StateTypeEnum::Processor => 'StateProcessor.tpl.php',
54+
};
55+
56+
$templatePath = \dirname(__DIR__).'/Resources/skeleton/'.$templateFile;
57+
58+
return $this->filesystem->get($templatePath);
59+
}
60+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the API Platform project.
5+
*
6+
* (c) Kévin Dunglas <dunglas@gmail.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
declare(strict_types=1);
13+
14+
namespace ApiPlatform\Laravel\Console\Maker\Utils;
15+
16+
enum StateTypeEnum
17+
{
18+
case Provider;
19+
case Processor;
20+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the API Platform project.
5+
*
6+
* (c) Kévin Dunglas <dunglas@gmail.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
declare(strict_types=1);
13+
14+
namespace ApiPlatform\Laravel\Console\Maker\Utils;
15+
16+
trait SuccessMessageTrait
17+
{
18+
private function writeSuccessMessage(string $filePath, StateTypeEnum $stateTypeEnum): void
19+
{
20+
$stateText = strtolower($stateTypeEnum->name);
21+
22+
$this->newLine();
23+
$this->line(' <bg=green;fg=white> </>');
24+
$this->line(' <bg=green;fg=white> Success! </>');
25+
$this->line(' <bg=green;fg=white> </>');
26+
$this->newLine();
27+
$this->line('<fg=blue>created</>: <fg=white;options=underscore>'.$filePath.'</>');
28+
$this->newLine();
29+
$this->line("Next: Open your new state $stateText class and start customizing it.");
30+
}
31+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the API Platform project.
5+
*
6+
* (c) Kévin Dunglas <dunglas@gmail.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
declare(strict_types=1);
13+
14+
namespace ApiPlatform\Laravel\Tests\Console\Maker;
15+
16+
use ApiPlatform\Laravel\Tests\Console\Maker\Utils\AppServiceFileGenerator;
17+
use ApiPlatform\Laravel\Tests\Console\Maker\Utils\PathResolver;
18+
use Illuminate\Console\Command;
19+
use Illuminate\Contracts\Filesystem\FileNotFoundException;
20+
use Illuminate\Filesystem\Filesystem;
21+
use Orchestra\Testbench\Concerns\WithWorkbench;
22+
use Orchestra\Testbench\TestCase;
23+
24+
class MakeStateProcessorCommandTest extends TestCase
25+
{
26+
use WithWorkbench;
27+
28+
/** @var string */
29+
private const STATE_PROCESSOR_COMMAND = 'make:state-processor';
30+
/** @var string */
31+
private const CHOSEN_CLASS_NAME = 'Choose a class name for your state processor (e.g. <fg=yellow>AwesomeStateProcessor</>)';
32+
33+
private ?Filesystem $filesystem;
34+
private PathResolver $pathResolver;
35+
private AppServiceFileGenerator $appServiceFileGenerator;
36+
37+
/**
38+
* @throws FileNotFoundException
39+
*/
40+
protected function setup(): void
41+
{
42+
parent::setUp();
43+
44+
$this->filesystem = new Filesystem();
45+
$this->pathResolver = new PathResolver();
46+
$this->appServiceFileGenerator = new AppServiceFileGenerator($this->filesystem);
47+
48+
$this->appServiceFileGenerator->regenerateProviderFile();
49+
}
50+
51+
/**
52+
* @throws FileNotFoundException
53+
*/
54+
public function testMakeStateProviderCommand(): void
55+
{
56+
$processorName = 'MyStateProcessor';
57+
$filePath = $this->pathResolver->generateStateFilename($processorName);
58+
$appServiceProviderPath = $this->pathResolver->getServiceProviderFilePath();
59+
60+
$this->artisan(self::STATE_PROCESSOR_COMMAND)
61+
->expectsQuestion(self::CHOSEN_CLASS_NAME, $processorName)
62+
->expectsOutputToContain('Success!')
63+
->expectsOutputToContain("created: $filePath")
64+
->expectsOutputToContain('Next: Open your new state processor class and start customizing it.')
65+
->assertExitCode(Command::SUCCESS);
66+
67+
$this->assertFileExists($filePath);
68+
69+
$appServiceProviderContent = $this->filesystem->get($appServiceProviderPath);
70+
$this->assertStringContainsString('use ApiPlatform\State\ProcessorInterface;', $appServiceProviderContent);
71+
$this->assertStringContainsString("use App\State\\$processorName;", $appServiceProviderContent);
72+
$this->assertStringContainsString('$this->app->tag(MyStateProcessor::class, ProcessorInterface::class);', $appServiceProviderContent);
73+
74+
$this->filesystem->delete($filePath);
75+
}
76+
77+
public function testWhenStateProviderClassAlreadyExists(): void
78+
{
79+
$processorName = 'ExistingProcessor';
80+
$existingFile = $this->pathResolver->generateStateFilename($processorName);
81+
$this->filesystem->put($existingFile, '<?php // Existing processor');
82+
83+
$expectedError = \sprintf('[ERROR] The file "%s" can\'t be generated because it already exists.', $existingFile);
84+
85+
$this->artisan(self::STATE_PROCESSOR_COMMAND)
86+
->expectsQuestion(self::CHOSEN_CLASS_NAME, $processorName)
87+
->expectsOutput($expectedError)
88+
->assertExitCode(Command::FAILURE);
89+
90+
$this->filesystem->delete($existingFile);
91+
}
92+
93+
public function testMakeStateProviderCommandWithoutGivenClassName(): void
94+
{
95+
$processorName = 'NoEmptyClassName';
96+
$filePath = $this->pathResolver->generateStateFilename($processorName);
97+
98+
$this->artisan(self::STATE_PROCESSOR_COMMAND)
99+
->expectsQuestion(self::CHOSEN_CLASS_NAME, '')
100+
->expectsOutput('[ERROR] This value cannot be blank.')
101+
->expectsQuestion(self::CHOSEN_CLASS_NAME, $processorName)
102+
->assertExitCode(Command::SUCCESS);
103+
104+
$this->assertFileExists($filePath);
105+
106+
$this->filesystem->delete($filePath);
107+
}
108+
109+
/**
110+
* @throws FileNotFoundException
111+
*/
112+
protected function tearDown(): void
113+
{
114+
parent::tearDown();
115+
116+
$this->appServiceFileGenerator->regenerateProviderFile();
117+
}
118+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the API Platform project.
5+
*
6+
* (c) Kévin Dunglas <dunglas@gmail.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
declare(strict_types=1);
13+
14+
namespace ApiPlatform\Laravel\Tests\Console\Maker;
15+
16+
use ApiPlatform\Laravel\Tests\Console\Maker\Utils\AppServiceFileGenerator;
17+
use ApiPlatform\Laravel\Tests\Console\Maker\Utils\PathResolver;
18+
use Illuminate\Console\Command;
19+
use Illuminate\Contracts\Filesystem\FileNotFoundException;
20+
use Illuminate\Filesystem\Filesystem;
21+
use Orchestra\Testbench\Concerns\WithWorkbench;
22+
use Orchestra\Testbench\TestCase;
23+
24+
class MakeStateProviderCommandTest extends TestCase
25+
{
26+
use WithWorkbench;
27+
28+
/** @var string */
29+
private const MAKE_STATE_PROVIDER_COMMAND = 'make:state-provider';
30+
/** @var string */
31+
private const STATE_PROVIDER_CLASS_NAME = 'Choose a class name for your state provider (e.g. <fg=yellow>AwesomeStateProvider</>)';
32+
33+
private ?Filesystem $filesystem;
34+
private PathResolver $pathResolver;
35+
private AppServiceFileGenerator $appServiceFileGenerator;
36+
37+
/**
38+
* @throws FileNotFoundException
39+
*/
40+
protected function setup(): void
41+
{
42+
parent::setUp();
43+
44+
$this->filesystem = new Filesystem();
45+
$this->pathResolver = new PathResolver();
46+
$this->appServiceFileGenerator = new AppServiceFileGenerator($this->filesystem);
47+
48+
$this->appServiceFileGenerator->regenerateProviderFile();
49+
}
50+
51+
/**
52+
* @throws FileNotFoundException
53+
*/
54+
public function testMakeStateProviderCommand(): void
55+
{
56+
$providerName = 'MyStateProvider';
57+
$filePath = $this->pathResolver->generateStateFilename($providerName);
58+
$appServiceProviderPath = $this->pathResolver->getServiceProviderFilePath();
59+
60+
$this->artisan(self::MAKE_STATE_PROVIDER_COMMAND)
61+
->expectsQuestion(self::STATE_PROVIDER_CLASS_NAME, $providerName)
62+
->expectsOutputToContain('Success!')
63+
->expectsOutputToContain("created: $filePath")
64+
->expectsOutputToContain('Next: Open your new state provider class and start customizing it.')
65+
->assertExitCode(Command::SUCCESS);
66+
67+
$this->assertFileExists($filePath);
68+
69+
$appServiceProviderContent = $this->filesystem->get($appServiceProviderPath);
70+
$this->assertStringContainsString('use ApiPlatform\State\ProviderInterface;', $appServiceProviderContent);
71+
$this->assertStringContainsString("use App\State\\$providerName;", $appServiceProviderContent);
72+
$this->assertStringContainsString('$this->app->tag(MyStateProvider::class, ProviderInterface::class);', $appServiceProviderContent);
73+
74+
$this->filesystem->delete($filePath);
75+
}
76+
77+
public function testWhenStateProviderClassAlreadyExists(): void
78+
{
79+
$providerName = 'ExistingProvider';
80+
$existingFile = $this->pathResolver->generateStateFilename($providerName);
81+
$this->filesystem->put($existingFile, '<?php // Existing provider');
82+
83+
$expectedError = \sprintf('[ERROR] The file "%s" can\'t be generated because it already exists.', $existingFile);
84+
85+
$this->artisan(self::MAKE_STATE_PROVIDER_COMMAND)
86+
->expectsQuestion(self::STATE_PROVIDER_CLASS_NAME, $providerName)
87+
->expectsOutput($expectedError)
88+
->assertExitCode(Command::FAILURE);
89+
90+
$this->filesystem->delete($existingFile);
91+
}
92+
93+
public function testMakeStateProviderCommandWithoutGivenClassName(): void
94+
{
95+
$providerName = 'NoEmptyClassName';
96+
$filePath = $this->pathResolver->generateStateFilename($providerName);
97+
98+
$this->artisan(self::MAKE_STATE_PROVIDER_COMMAND)
99+
->expectsQuestion(self::STATE_PROVIDER_CLASS_NAME, '')
100+
->expectsOutput('[ERROR] This value cannot be blank.')
101+
->expectsQuestion(self::STATE_PROVIDER_CLASS_NAME, $providerName)
102+
->assertExitCode(Command::SUCCESS);
103+
104+
$this->assertFileExists($filePath);
105+
106+
$this->filesystem->delete($filePath);
107+
}
108+
109+
/**
110+
* @throws FileNotFoundException
111+
*/
112+
protected function tearDown(): void
113+
{
114+
parent::tearDown();
115+
116+
$this->appServiceFileGenerator->regenerateProviderFile();
117+
}
118+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the API Platform project.
5+
*
6+
* (c) Kévin Dunglas <dunglas@gmail.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
declare(strict_types=1);
13+
14+
namespace App\Providers;
15+
16+
use Illuminate\Support\ServiceProvider;
17+
18+
class AppServiceProvider extends ServiceProvider
19+
{
20+
public function boot(): void
21+
{
22+
}
23+
24+
public function register(): void
25+
{
26+
}
27+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the API Platform project.
5+
*
6+
* (c) Kévin Dunglas <dunglas@gmail.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
declare(strict_types=1);
13+
14+
namespace ApiPlatform\Laravel\Tests\Console\Maker\Utils;
15+
16+
use Illuminate\Contracts\Filesystem\FileNotFoundException;
17+
use Illuminate\Filesystem\Filesystem;
18+
19+
final readonly class AppServiceFileGenerator
20+
{
21+
public function __construct(private Filesystem $filesystem)
22+
{
23+
}
24+
25+
/**
26+
* @throws FileNotFoundException
27+
*/
28+
public function regenerateProviderFile(): void
29+
{
30+
$templatePath = \dirname(__DIR__).'/Resources/skeleton/AppServiceProvider.tpl.php';
31+
$targetPath = base_path('app/Providers/AppServiceProvider.php');
32+
33+
$this->regenerateFileFromTemplate($templatePath, $targetPath);
34+
}
35+
36+
/**
37+
* @throws FileNotFoundException
38+
*/
39+
private function regenerateFileFromTemplate(string $templatePath, string $targetPath): void
40+
{
41+
$content = $this->filesystem->get($templatePath);
42+
43+
$this->filesystem->put($targetPath, $content);
44+
}
45+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the API Platform project.
5+
*
6+
* (c) Kévin Dunglas <dunglas@gmail.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
declare(strict_types=1);
13+
14+
namespace ApiPlatform\Laravel\Tests\Console\Maker\Utils;
15+
16+
final readonly class PathResolver
17+
{
18+
public function getServiceProviderFilePath(): string
19+
{
20+
return base_path('app/Providers/AppServiceProvider.php');
21+
}
22+
23+
public function generateStateFilename(string $stateFilename): string
24+
{
25+
return $this->getStateDirectoryPath().$stateFilename.'.php';
26+
}
27+
28+
public function getStateDirectoryPath(): string
29+
{
30+
return base_path('src/State/');
31+
}
32+
}

‎src/Laravel/phpstan.neon.dist

+2-2
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@ parameters:
1313
- State
1414
- Test
1515
- Tests
16-
# ignoreErrors:
17-
# - '#PHPDoc tag @var#'
16+
ignoreErrors:
17+
- '#Cannot call method expectsQuestion#'
1818
#
1919
# excludePaths:
2020
# - ./*/*/FileToBeExcluded.php

0 commit comments

Comments
 (0)
Please sign in to comment.