Skip to content

Commit

Permalink
use config to create final webhook classes
Browse files Browse the repository at this point in the history
  • Loading branch information
MrYamous committed Jan 1, 2025
1 parent 0624f13 commit 9e0e042
Show file tree
Hide file tree
Showing 4 changed files with 71 additions and 41 deletions.
68 changes: 35 additions & 33 deletions src/Maker/MakeWebhook.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,7 @@
use Symfony\Bundle\MakerBundle\InputAwareMakerInterface;
use Symfony\Bundle\MakerBundle\InputConfiguration;
use Symfony\Bundle\MakerBundle\Maker\Common\InstallDependencyTrait;
use Symfony\Bundle\MakerBundle\Str;
use Symfony\Bundle\MakerBundle\Util\ClassNameDetails;
use Symfony\Bundle\MakerBundle\Util\UseStatementGenerator;
use Symfony\Bundle\MakerBundle\Util\ClassSource\Model\ClassData;
use Symfony\Bundle\MakerBundle\Util\YamlSourceManipulator;
use Symfony\Bundle\MakerBundle\Validator;
use Symfony\Component\Console\Command\Command;
Expand Down Expand Up @@ -146,21 +144,37 @@ public function interact(InputInterface $input, ConsoleStyle $io, Command $comma

public function generate(InputInterface $input, ConsoleStyle $io, Generator $generator): void
{
$requestParserDetails = $this->generator->createClassNameDetails(
Str::asClassName($this->name.'RequestParser'),
'Webhook\\'
$requestParserClassData = ClassData::create(
class: \sprintf('Webhook\\%s', $input->getArgument('name')),
suffix: 'RequestParser',
extendsClass: AbstractRequestParser::class,
useStatements: [
JsonException::class,
Request::class,
Response::class,
RemoteEvent::class,
AbstractRequestParser::class,
RejectWebhookException::class,
RequestMatcherInterface::class,
],
);
$remoteEventConsumerDetails = $this->generator->createClassNameDetails(
Str::asClassName($this->name.'WebhookConsumer'),
'RemoteEvent\\'

$remoteEventClassData = ClassData::create(
class: \sprintf('RemoteEvent\\%s', $input->getArgument('name')),
suffix: 'WebhookConsumer',
useStatements: [
AsRemoteEventConsumer::class,

Check failure on line 166 in src/Maker/MakeWebhook.php

View workflow job for this annotation

GitHub Actions / PHPStan

Class Symfony\Bundle\MakerBundle\Maker\AsRemoteEventConsumer not found.
ConsumerInterface::class,

Check failure on line 167 in src/Maker/MakeWebhook.php

View workflow job for this annotation

GitHub Actions / PHPStan

Class Symfony\Bundle\MakerBundle\Maker\ConsumerInterface not found.
RemoteEvent::class,
],
);

$this->addToYamlConfig($this->name, $requestParserDetails);
$this->addToYamlConfig($this->name, $requestParserClassData);

$this->generateRequestParser(requestParserDetails: $requestParserDetails);
$this->generateRequestParser($requestParserClassData);

$this->generator->generateClass(
$remoteEventConsumerDetails->getFullName(),
$this->generator->generateClassFromClassData(
$remoteEventClassData,
'webhook/WebhookConsumer.tpl.php',
[
'webhook_name' => $this->name,
Expand All @@ -178,7 +192,7 @@ private function verifyWebhookName(string $entityName): bool
return preg_match(self::WEBHOOK_NAME_PATTERN, $entityName);
}

private function addToYamlConfig(string $webhookName, ClassNameDetails $requestParserDetails): void
private function addToYamlConfig(string $webhookName, ClassData $requestParserClassData): void
{
$yamlConfig = Yaml::dump(['framework' => ['webhook' => ['routing' => []]]], 4, 2);
if ($this->fileManager->fileExists(self::WEBHOOK_CONFIG_PATH)) {
Expand All @@ -193,7 +207,7 @@ private function addToYamlConfig(string $webhookName, ClassNameDetails $requestP
}

$arrayConfig['framework']['webhook']['routing'][$webhookName] = [
'service' => $requestParserDetails->getFullName(),
'service' => $requestParserClassData->getFullClassName(),
'secret' => 'your_secret_here',
];
$this->ysm->setData(
Expand All @@ -204,43 +218,31 @@ private function addToYamlConfig(string $webhookName, ClassNameDetails $requestP
/**
* @throws \Exception
*/
private function generateRequestParser(ClassNameDetails $requestParserDetails): void
private function generateRequestParser(ClassData $requestParserClassData): void
{
$useStatements = new UseStatementGenerator([
JsonException::class,
Request::class,
Response::class,
RemoteEvent::class,
AbstractRequestParser::class,
RejectWebhookException::class,
RequestMatcherInterface::class,
]);

// Use a ChainRequestMatcher if multiple matchers have been added OR if none (will be printed with an empty array)
$useChainRequestsMatcher = false;

if (1 !== \count($this->requestMatchers)) {
$useChainRequestsMatcher = true;
$useStatements->addUseStatement(ChainRequestMatcher::class);
$requestParserClassData->addUseStatement(ChainRequestMatcher::class);
}

$requestMatcherArguments = [];

foreach ($this->requestMatchers as $requestMatcherClass) {
$useStatements->addUseStatement($requestMatcherClass);
$requestParserClassData->addUseStatement($requestMatcherClass);
$requestMatcherArguments[$requestMatcherClass] = $this->getRequestMatcherArguments(requestMatcherClass: $requestMatcherClass);

if (ExpressionRequestMatcher::class === $requestMatcherClass) {
$useStatements->addUseStatement(Expression::class);
$useStatements->addUseStatement(ExpressionLanguage::class);
$requestParserClassData->addUseStatement([Expression::class, ExpressionLanguage::class]);
}
}

$this->generator->generateClass(
$requestParserDetails->getFullName(),
$this->generator->generateClassFromClassData(
$requestParserClassData,
'webhook/RequestParser.tpl.php',
[
'use_statements' => $useStatements,
'use_chained_requests_matcher' => $useChainRequestsMatcher,
'request_matchers' => $this->requestMatchers,
'request_matcher_arguments' => $requestMatcherArguments,
Expand Down
6 changes: 3 additions & 3 deletions templates/webhook/RequestParser.tpl.php
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
<?= "<?php\n" ?>

namespace <?= $namespace; ?>;
namespace <?= $class_data->getNamespace(); ?>;

<?= $use_statements; ?>
<?= $class_data->getUseStatements(); ?>

final class <?= $class_name ?> extends AbstractRequestParser
<?= $class_data->getClassDeclaration(); ?>
{
protected function getRequestMatcher(): RequestMatcherInterface
{
Expand Down
8 changes: 3 additions & 5 deletions templates/webhook/WebhookConsumer.tpl.php
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
<?= "<?php\n" ?>

namespace <?= $namespace; ?>;
namespace <?= $class_data->getNamespace(); ?>;

use Symfony\Component\RemoteEvent\Attribute\AsRemoteEventConsumer;
use Symfony\Component\RemoteEvent\Consumer\ConsumerInterface;
use Symfony\Component\RemoteEvent\RemoteEvent;
<?= $class_data->getUseStatements(); ?>

#[AsRemoteEventConsumer('<?= $webhook_name ?>')]
final class <?= $class_name ?> implements ConsumerInterface
<?= $class_data->getClassDeclaration(); ?> implements ConsumerInterface
{
public function __construct()
{
Expand Down
30 changes: 30 additions & 0 deletions tests/Maker/MakeWebhookTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
use Symfony\Bundle\MakerBundle\Maker\MakeWebhook;
use Symfony\Bundle\MakerBundle\Test\MakerTestCase;
use Symfony\Bundle\MakerBundle\Test\MakerTestRunner;
use Symfony\Component\Yaml\Yaml;

class MakeWebhookTest extends MakerTestCase
{
Expand Down Expand Up @@ -270,5 +271,34 @@ public function getTestDetails(): \Generator
);
}),
];

yield 'it_makes_webhook_not_final' => [$this->createMakerTest()
->run(function (MakerTestRunner $runner) {
$runner->writeFile(
'config/packages/dev/maker.yaml',
Yaml::dump(['when@dev' => ['maker' => ['generate_final_classes' => false]]])
);

$runner->runMaker(
[
'remote_service',
'',
]
);

$outputExpectations = [
'src/Webhook/RemoteServiceRequestParser.php' => 'class RemoteServiceRequestParser extends AbstractRequestParser;',
'src/RemoteEvent/RemoteServiceWebhookConsumer.php' => 'class RemoteServiceWebhookConsumer implements ConsumerInterface',
];

foreach ($outputExpectations as $expectedFileName => $expectedContent) {
$path = $runner->getPath($expectedFileName);

$this->assertFileExists($runner->getPath($expectedFileName));

Check failure on line 297 in tests/Maker/MakeWebhookTest.php

View workflow job for this annotation

GitHub Actions / PHP 8.3 + @6.4.x-dev highest deps

Failed asserting that file "/home/runner/work/maker-bundle/maker-bundle/tests/tmp/cache/maker_app_d2ff772a5829a5303f7159b51283f4d9_6.4.x-dev/src/Webhook/RemoteServiceRequestParser.php" exists.

Check failure on line 297 in tests/Maker/MakeWebhookTest.php

View workflow job for this annotation

GitHub Actions / PHP 8.3 + @7.0.x-dev highest deps

Failed asserting that file "/home/runner/work/maker-bundle/maker-bundle/tests/tmp/cache/maker_app_d2ff772a5829a5303f7159b51283f4d9_7.0.x-dev/src/Webhook/RemoteServiceRequestParser.php" exists.

Check failure on line 297 in tests/Maker/MakeWebhookTest.php

View workflow job for this annotation

GitHub Actions / PHP 8.3 + @7.1.x-dev highest deps

Failed asserting that file "/home/runner/work/maker-bundle/maker-bundle/tests/tmp/cache/maker_app_d2ff772a5829a5303f7159b51283f4d9_7.1.x-dev/src/Webhook/RemoteServiceRequestParser.php" exists.

Check failure on line 297 in tests/Maker/MakeWebhookTest.php

View workflow job for this annotation

GitHub Actions / PHP 8.1 + @6.4.* lowest deps

Failed asserting that file "/home/runner/work/maker-bundle/maker-bundle/tests/tmp/cache/maker_app_d2ff772a5829a5303f7159b51283f4d9_6.4/src/Webhook/RemoteServiceRequestParser.php" exists.

Check failure on line 297 in tests/Maker/MakeWebhookTest.php

View workflow job for this annotation

GitHub Actions / PHP 8.1 + @6.4.* highest deps

Failed asserting that file "/home/runner/work/maker-bundle/maker-bundle/tests/tmp/cache/maker_app_d2ff772a5829a5303f7159b51283f4d9_6.4/src/Webhook/RemoteServiceRequestParser.php" exists.
$this->assertStringNotContainsString('final', file_get_contents($path));
$this->assertStringContainsString($expectedContent, file_get_contents($path));
}
}),
];
}
}

0 comments on commit 9e0e042

Please sign in to comment.