diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index e305134..6d0a12e 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -1,16 +1,16 @@ -name: BuildPlugin +name: Build extension on: - push: - branches: - - '0.3' + workflow_dispatch: + push: + branches: + - main jobs: - build: - uses: FriendsOfShopware/actions/.github/workflows/store.yml@main - with: - extensionName: ${{ github.event.repository.name }} - shopwareVersion: '6.4.0' - secrets: - accountUser: ${{ secrets.ACCOUNT_USER }} - accountPassword: ${{ secrets.ACCOUNT_PASSWORD }} - ghToken: ${{ secrets.GITHUB_TOKEN }} + build: + uses: FriendsOfShopware/actions/.github/workflows/store-shopware-cli.yml@main + with: + extensionName: ${{ github.event.repository.name }} + secrets: + accountUser: ${{ secrets.ACCOUNT_USER }} + accountPassword: ${{ secrets.ACCOUNT_PASSWORD }} + ghToken: ${{ secrets.GITHUB_TOKEN }} diff --git a/.gitpod.Dockerfile b/.gitpod.Dockerfile deleted file mode 100644 index 04895a0..0000000 --- a/.gitpod.Dockerfile +++ /dev/null @@ -1,29 +0,0 @@ -FROM gitpod/workspace-base:latest - -COPY --from=composer/composer:2-bin /composer /usr/bin/composer -COPY --from=ghcr.io/friendsofshopware/shopware-cli /usr/local/bin/shopware-cli /usr/bin/shopware-cli - -RUN sudo add-apt-repository ppa:ondrej/php -y && \ - curl -fsSL https://deb.nodesource.com/setup_16.x | sudo bash - && \ - wget https://get.symfony.com/cli/installer -O - | sudo bash -s -- --install-dir=/usr/bin && \ - sudo apt-get install -y \ - php8.1-fpm php8.1-mysql php8.1-curl php8.1-gd php8.1-xml php8.1-zip php8.1-opcache php8.1-mbstring php8.1-intl php8.1-cli \ - rsync \ - mysql-client-8.0 \ - nodejs && \ - shopware-cli completion bash | sudo tee /etc/bash_completion.d/shopware-cli && \ - shopware-cli completion zsh | sudo tee /usr/local/share/zsh/site-functions/_shopware-cli && \ - shopware-cli completion fish | sudo tee /usr/share/fish/completions/shopware-cli.fish && \ - sudo apt-get upgrade -y && \ - echo "memory_limit=512M" > php.ini && \ - echo "assert.active=0" >> php.ini && \ - echo "opcache.interned_strings_buffer=20" >> php.ini && \ - echo "zend.detect_unicode=0" >> php.ini && \ - echo "realpath_cache_ttl=3600" >> php.ini && \ - sudo cp php.ini /etc/php/8.1/cli/conf.d/99-overrides.ini && \ - sudo cp php.ini /etc/php/8.1/fpm/conf.d/99-overrides.ini && \ - rm php.ini && \ - echo "[client]" > ~/.my.cnf && \ - echo "host=127.0.0.1" >> ~/.my.cnf && \ - echo "user=root" >> ~/.my.cnf && \ - echo "password=root" >> ~/.my.cnf diff --git a/.gitpod.yml b/.gitpod.yml deleted file mode 100644 index 6cd50d7..0000000 --- a/.gitpod.yml +++ /dev/null @@ -1,111 +0,0 @@ -image: - file: .gitpod.Dockerfile - -tasks: - - name: Shopware - before: | - echo 'alias admin-watch="LOAD_DOTENV=0 APP_URL=http://localhost:8000 ./bin/watch-administration.sh"' >> ~/.bashrc - init: | - EXTENSION_NAME=$(basename $PWD) - TMP_DIR=$(mktemp -d) - - mv * .* "$TMP_DIR" || true - - # Run MySQL - docker run --restart always -d --name=mysql -p 127.0.0.1:3306:3306 -e MYSQL_ROOT_PASSWORD=root mysql:8 - docker run --restart always -d --name=adminer --link mysql:mysql -p 5000:8080 -e ADMINER_DESIGN=pepa-linha -e ADMINER_DEFAULT_SERVER=mysql -e ADMINER_PLUGINS="tables-filter table-structure json-column version-noverify" ghcr.io/shyim/shopware-docker/adminer - - composer config --global github-oauth.github.com $(printf '%s\n' host=github.com | gp credential-helper get | sort | head -2 | tail -1 | sed 's;password=;;') - - composer create-project shopware/production:dev-flex . -n - composer req --dev profiler fakerphp/faker mbezhanov/faker-provider-collection maltyxx/images-generator - # Configure Shopware - sed -i -e 's;DATABASE_URL=.*$;DATABASE_URL=mysql://root:root@127.0.0.1:3306/shopware;' .env - sed -i -e "s;APP_URL=.*$;APP_URL=$(gp url 8000);" .env - echo "TRUSTED_PROXIES=192.168.0.0/16" >> .env - - ./bin/console system:install --basic-setup --create-database --drop-database - - ./bin/console system:config:set core.frw.completedAt '2019-10-07T10:46:23+00:00' - - ./bin/console framework:demodata --products 300 - ./bin/console dal:refresh:index - rm -rf var/cache/* - # Set by default to dev - sed -i -e "s;APP_ENV=.*$;APP_URL=dev;" .env - - # Move actual repository - mv "$TMP_DIR" "custom/plugins/$EXTENSION_NAME" - cp "custom/plugins/$EXTENSION_NAME/.gitpod.yml" . - - shopware-cli extension prepare "custom/plugins/$EXTENSION_NAME" - shopware-cli extension build "custom/plugins/$EXTENSION_NAME" - command: | - # Gitpod registers the ports on first docker command - docker ps - - # Wait for port open - gp ports await 3306 - - # Wait until MySQL is reachable - until mysqladmin ping; do - sleep 1 - done - - # Update domain url - ./bin/console sales-channel:update:domain $(gp url 8000 | awk -F[/:] '{print $4}') - - # Start Webserver - symfony server:start --port 8000 -d - - name: Getting Started - command: | - echo 'Hey!. Your environment is starting soon. You can see the progress in the Shopware Terminal' - echo 'If you want to run the Admin Watch, just use the Terminal alias: admin-watch' - echo 'Happy Coding!' - echo "Shop URL: $(gp url 8000)" - echo "Admin-Watcher URL: $(gp url 8080)" - echo "Adminer URL: $(gp url 5000)" -ports: - - port: 8000 - visibility: private - description: Shopware - onOpen: open-browser - - port: 5000 - visibility: private - description: Adminer - onOpen: notify - - name: Admin-Watcher - port: 8080 - onOpen: notify - description: "Use Forward Proxy to localhost to access this service" - -jetbrains: - plugins: - - com.jetbrains.php - - com.intellij.php.tools.quality.phpstan - - com.intellij.php.psalm - - org.jetbrains.plugins.yaml - - com.jetbrains.twig - - fr.adrienbrault.idea.symfony2plugin - - de.shyim.shopware6 - - de.shyim.ideaphpstantoolbox - - de.espend.idea.php.annotation - phpstorm: - vmoptions: "-Xmx4g" - prebuilds: - version: stable - -vscode: - extensions: - - bmewburn.vscode-intelephense-client - - redhat.vscode-yaml - -github: - prebuilds: - master: true - branches: true - pullRequests: true - pullRequestsFromForks: true - addCheck: false - addComment: false - addBadge: true \ No newline at end of file diff --git a/CHANGELOG_en-GB.md b/CHANGELOG.md similarity index 92% rename from CHANGELOG_en-GB.md rename to CHANGELOG.md index 3fa13ee..35c212e 100644 --- a/CHANGELOG_en-GB.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +# 1.0.0 + +- Shopware 6.5 compatibility + # 0.3.6 - Updated psysh package diff --git a/CHANGELOG_de-DE.md b/CHANGELOG_de-DE.md deleted file mode 100644 index ce4d524..0000000 --- a/CHANGELOG_de-DE.md +++ /dev/null @@ -1,38 +0,0 @@ -# 0.3.6 - -- Updated psysh package -- Block blacklist is now configureable using Symfony Config - -# 0.3.5 - -- Updated block blacklist - -# 0.3.4 - -- Updated block blacklist - -# 0.3.3 - -- Fixed problems with mail sending - -# 0.3.2 - -- Fixed serialization issue with profiler - -# 0.3.1 - -- Fixed installation using composer - -# 0.3.0 - -- Shopware 6.4 Kompatibilität - - -# 0.2.2 - -- Behebung von Autoloading-Problemen des Composers -- Fix Kernel-Debug-Erkennung - -# 0.2.1 - -- Shopware 6.3 Kompatibilität diff --git a/composer.json b/composer.json index 2524c48..d654bc8 100644 --- a/composer.json +++ b/composer.json @@ -1,6 +1,6 @@ { "name": "frosh/development-helper", - "version": "0.3.6", + "version": "1.0.0", "description": "Development Helper", "type": "shopware-platform-plugin", "license": "MIT", @@ -16,16 +16,11 @@ } }, "require": { - "shopware/core": "~6.4.11", + "shopware/core": "~6.5.0", "nikic/php-parser": "*", "friendsofphp/php-cs-fixer": "*", "psy/psysh": "^0.11.9" }, - "config": { - "platform": { - "php": "7.4.3" - } - }, "extra": { "shopware-plugin-class": "Frosh\\DevelopmentHelper\\FroshDevelopmentHelper", "copyright": "FriendsOfShopware", diff --git a/src/Command/ExtendTemplate.php b/src/Command/ExtendTemplate.php index 5aa23a9..b4bcd46 100644 --- a/src/Command/ExtendTemplate.php +++ b/src/Command/ExtendTemplate.php @@ -2,6 +2,7 @@ namespace Frosh\DevelopmentHelper\Command; +use Symfony\Component\Console\Attribute\AsCommand; use Frosh\DevelopmentHelper\Component\Twig\BlockCollector; use Shopware\Core\Framework\Adapter\Cache\CacheClearer; use Symfony\Component\Console\Command\Command; @@ -13,25 +14,20 @@ use Symfony\Component\Console\Style\SymfonyStyle; use Symfony\Component\Filesystem\Filesystem; +#[AsCommand('frosh:extend:template', description: 'Generates the template extension for you')] class ExtendTemplate extends Command { - public static $defaultName = 'frosh:extend:template'; - private BlockCollector $blockCollector; - private array $pluginInfos; - private CacheClearer $cacheClearer; + private readonly CacheClearer $cacheClearer; - public function __construct(BlockCollector $blockCollector, array $pluginInfos, CacheClearer $cacheClearer) + public function __construct(private readonly BlockCollector $blockCollector, private readonly array $pluginInfos, CacheClearer $cacheClearer) { parent::__construct(); - $this->blockCollector = $blockCollector; - $this->pluginInfos = $pluginInfos; $this->cacheClearer = $cacheClearer; } protected function configure() { $this - ->setDescription('Generates the template extension for you') ->addArgument('pluginName', InputArgument::REQUIRED, 'Plugin Name'); } diff --git a/src/Command/MakeDefinition.php b/src/Command/MakeDefinition.php index b65284b..09fc228 100644 --- a/src/Command/MakeDefinition.php +++ b/src/Command/MakeDefinition.php @@ -2,6 +2,7 @@ namespace Frosh\DevelopmentHelper\Command; +use Symfony\Component\Console\Attribute\AsCommand; use Frosh\DevelopmentHelper\Component\Generator\Definition\CollectionGenerator; use Frosh\DevelopmentHelper\Component\Generator\Definition\EntityConsoleQuestion; use Frosh\DevelopmentHelper\Component\Generator\Definition\DefinitionGenerator; @@ -14,60 +15,23 @@ use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\Console\Style\SymfonyStyle; +#[AsCommand('frosh:make:definition', description: 'Generates an entity')] class MakeDefinition extends Command { - public static $defaultName = 'frosh:make:definition'; - - /** - * @var EntityLoader - */ - private $entityLoader; - - /** - * @var EntityConsoleQuestion - */ - private $entityConsoleQuestion; - - /** - * @var DefinitionGenerator - */ - private $definitionGenerator; - - /** - * @var EntityGenerator - */ - private $entityGenerator; - - /** - * @var CollectionGenerator - */ - private $collectionGenerator; - - /** - * @var FixCodeStyle - */ - private $fixCodeStyle; - public function __construct( - EntityLoader $entityLoader, - EntityConsoleQuestion $entityConsoleQuestion, - DefinitionGenerator $definitionGenerator, - EntityGenerator $entityGenerator, - CollectionGenerator $collectionGenerator, - FixCodeStyle $fixCodeStyle + private readonly EntityLoader $entityLoader, + private readonly EntityConsoleQuestion $entityConsoleQuestion, + private readonly DefinitionGenerator $definitionGenerator, + private readonly EntityGenerator $entityGenerator, + private readonly CollectionGenerator $collectionGenerator, + private readonly FixCodeStyle $fixCodeStyle ) { parent::__construct(); - $this->entityLoader = $entityLoader; - $this->entityConsoleQuestion = $entityConsoleQuestion; - $this->definitionGenerator = $definitionGenerator; - $this->entityGenerator = $entityGenerator; - $this->collectionGenerator = $collectionGenerator; - $this->fixCodeStyle = $fixCodeStyle; } protected function configure(): void { - $this->setDescription('Generates an entity') + $this ->addArgument('namespace', InputArgument::REQUIRED, 'Namespace (FroshTest\\Content\\Store)'); } diff --git a/src/Command/MakeMigration.php b/src/Command/MakeMigration.php index 6c2c12f..b733baf 100644 --- a/src/Command/MakeMigration.php +++ b/src/Command/MakeMigration.php @@ -2,6 +2,7 @@ namespace Frosh\DevelopmentHelper\Command; +use Symfony\Component\Console\Attribute\AsCommand; use Doctrine\DBAL\Connection; use Doctrine\DBAL\Schema\Comparator; use Doctrine\DBAL\Schema\Schema; @@ -14,28 +15,20 @@ use Symfony\Component\Console\Style\SymfonyStyle; use Symfony\Component\Filesystem\Filesystem; +#[AsCommand('frosh:make:migration', description: 'Generates a migration')] class MakeMigration extends Command { - public static $defaultName = 'frosh:make:migration'; - - private string $projectDir; - private DefinitionInstanceRegistry $definitionInstanceRegistry; - private MigrationSchemaBuilder $migrationSchemaBuilder; - private Connection $connection; - private array $pluginInfos; + private readonly DefinitionInstanceRegistry $definitionInstanceRegistry; + private readonly Connection $connection; public function __construct( - string $kernelRootDir, - array $pluginInfos, + private readonly array $pluginInfos, DefinitionInstanceRegistry $definitionInstanceRegistry, - MigrationSchemaBuilder $migrationSchemaBuilder, + private readonly MigrationSchemaBuilder $migrationSchemaBuilder, Connection $connection ) { parent::__construct(); - $this->projectDir = $kernelRootDir; $this->definitionInstanceRegistry = $definitionInstanceRegistry; - $this->migrationSchemaBuilder = $migrationSchemaBuilder; - $this->pluginInfos = $pluginInfos; $this->connection = $connection; } @@ -46,22 +39,20 @@ protected function configure(): void ->addArgument('definition', InputArgument::IS_ARRAY, 'Definition name'); } - protected function execute(InputInterface $input, OutputInterface $output) + protected function execute(InputInterface $input, OutputInterface $output): int { $io = new SymfonyStyle($input, $output); - $plugin = $this->projectDir . '/custom/plugins/' . $input->getArgument('plugin'); - $toSchema = new Schema(); foreach ($input->getArgument('definition') as $name) { $definition = $this->definitionInstanceRegistry->getByEntityName($name); $this->migrationSchemaBuilder->buildSchemaOfDefinition($toSchema, $definition); } - $fromSchema = $this->connection->getSchemaManager()->createSchema(); + $fromSchema = $this->connection->createSchemaManager()->introspectSchema(); $comparator = new Comparator(); - $updateQueries = $comparator->compare($fromSchema, $toSchema)->toSaveSql($this->connection->getDatabasePlatform()); + $updateQueries = $comparator->compareSchemas($fromSchema, $toSchema)->toSaveSql($this->connection->getDatabasePlatform()); if (\count($updateQueries) === 0) { $io->success('Schema is already up to date'); @@ -102,7 +93,7 @@ public function updateDestructive(Connection \$connection): void $dbalExec = ''; foreach ($updateQueries as $sql) { - $dbalExec .= sprintf(' $connection->executeUpdate(\'%s\');' . PHP_EOL, addslashes($sql)); + $dbalExec .= sprintf(' $connection->executeUpdate(\'%s\');' . PHP_EOL, addslashes((string) $sql)); } $content = str_replace( diff --git a/src/Command/MakePlugin.php b/src/Command/MakePlugin.php index ac07d70..3d6b5b9 100644 --- a/src/Command/MakePlugin.php +++ b/src/Command/MakePlugin.php @@ -2,6 +2,7 @@ namespace Frosh\DevelopmentHelper\Command; +use Symfony\Component\Console\Attribute\AsCommand; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputInterface; @@ -10,9 +11,10 @@ use Symfony\Component\Console\Style\SymfonyStyle; use Symfony\Component\Filesystem\Filesystem; +#[AsCommand('frosh:make:plugin', description: 'Generates a plugin')] class MakePlugin extends Command { - private string $pluginFolderDir; + private readonly string $pluginFolderDir; public function __construct(string $kernelRootDir) { @@ -20,8 +22,6 @@ public function __construct(string $kernelRootDir) $this->pluginFolderDir = $kernelRootDir . '/custom/plugins/'; } - public static $defaultName = 'frosh:make:plugin'; - public function configure(): void { $this @@ -116,19 +116,12 @@ class #class# extends Plugin private function makeChangelogFiles(Filesystem $fs, string $pluginPath): void { - $deChangelog = <<dumpFile($pluginPath . '/CHANGELOG_de-DE.md', $deChangelog); - $fs->dumpFile($pluginPath . '/CHANGELOG_en-GB.md', $enChangelog); + $fs->dumpFile($pluginPath . '/CHANGELOG.md', $enChangelog); } private function makeDefaultServicesXml(Filesystem $fs, string $pluginPath): void diff --git a/src/Command/SchemaDiff.php b/src/Command/SchemaDiff.php index 651f015..f343e71 100644 --- a/src/Command/SchemaDiff.php +++ b/src/Command/SchemaDiff.php @@ -2,6 +2,7 @@ namespace Frosh\DevelopmentHelper\Command; +use Symfony\Component\Console\Attribute\AsCommand; use Doctrine\DBAL\Connection; use Doctrine\DBAL\Schema\Comparator; use Frosh\DevelopmentHelper\Component\Generator\Migration\MigrationSchemaBuilder; @@ -9,32 +10,24 @@ use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; +#[AsCommand('frosh:schema:diff', description: 'Diffs the database structure with the known definitions')] class SchemaDiff extends Command { - private MigrationSchemaBuilder $builder; - private Connection $connection; + private readonly Connection $connection; - public function __construct(MigrationSchemaBuilder $builder, Connection $connection) + public function __construct(private readonly MigrationSchemaBuilder $builder, Connection $connection) { parent::__construct(); - $this->builder = $builder; $this->connection = $connection; } - protected static $defaultName = 'frosh:schema:diff'; - - public function configure(): void - { - $this->setDescription('Diffs the database structure with the known definitions'); - } - protected function execute(InputInterface $input, OutputInterface $output): int { $localSchema = $this->builder->build(); - $remoteSchema = $this->connection->getSchemaManager()->createSchema(); + $remoteSchema = $this->connection->createSchemaManager()->introspectSchema(); $comparator = new Comparator(); - $sqls = $comparator->compare($remoteSchema, $localSchema)->toSaveSql($this->connection->getDatabasePlatform()); + $sqls = $comparator->compareSchemas($remoteSchema, $localSchema)->toSaveSql($this->connection->getDatabasePlatform()); $output->writeln($sqls); diff --git a/src/Command/Tinker.php b/src/Command/Tinker.php index c5c0f75..e925467 100644 --- a/src/Command/Tinker.php +++ b/src/Command/Tinker.php @@ -2,6 +2,7 @@ namespace Frosh\DevelopmentHelper\Command; +use Symfony\Component\Console\Attribute\AsCommand; use Psy\Configuration; use Psy\Shell; use Symfony\Component\Console\Command\Command; @@ -9,16 +10,15 @@ use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; +#[AsCommand('tinker', description: 'Starts a tinker session')] class Tinker extends Command { - protected static $defaultName = 'tinker'; - - protected function configure() + protected function configure(): void { $this->addArgument('include', InputArgument::IS_ARRAY, 'Include file(s) before starting tinker'); } - protected function execute(InputInterface $input, OutputInterface $output) + protected function execute(InputInterface $input, OutputInterface $output): int { $this->getApplication()->setCatchExceptions(false); diff --git a/src/Component/Generator/Definition/CollectionGenerator.php b/src/Component/Generator/Definition/CollectionGenerator.php index 65901df..aa0d266 100644 --- a/src/Component/Generator/Definition/CollectionGenerator.php +++ b/src/Component/Generator/Definition/CollectionGenerator.php @@ -23,17 +23,9 @@ public function generate(Definition $loaderResult): void } $phpDoc = '/** - * @method void add(%className% $entity) - * @method void set(string $key, %className% $entity) - * @method %className%[] getIterator() - * @method %className%[] getElements() - * @method %className%|null get(string $key) - * @method %className%|null first() - * @method %className%|null last() + * @extends EntityCollection<%className%> */'; - - $node = $builder ->namespace($loaderResult->namespace) ->addStmt($builder->use(EntityCollection::class)) diff --git a/src/Component/Generator/Definition/DefinitionGenerator.php b/src/Component/Generator/Definition/DefinitionGenerator.php index 21c8b50..72c8212 100644 --- a/src/Component/Generator/Definition/DefinitionGenerator.php +++ b/src/Component/Generator/Definition/DefinitionGenerator.php @@ -52,9 +52,7 @@ public function generate(Definition $definition): void $nodeFinder = new NodeFinder(); /** @var ClassMethod $method */ - $method = $nodeFinder->findFirst([$namespace], static function (Node $node) { - return $node instanceof ClassMethod && $node->name->name === 'defineFields'; - }); + $method = $nodeFinder->findFirst([$namespace], static fn(Node $node) => $node instanceof ClassMethod && $node->name->name === 'defineFields'); $method->stmts = [new Return_(new New_( new Name('FieldCollection'), diff --git a/src/Component/Generator/Definition/EntityConsoleQuestion.php b/src/Component/Generator/Definition/EntityConsoleQuestion.php index d2f3f51..cce954e 100644 --- a/src/Component/Generator/Definition/EntityConsoleQuestion.php +++ b/src/Component/Generator/Definition/EntityConsoleQuestion.php @@ -20,14 +20,11 @@ class EntityConsoleQuestion { /** - * @var QuestionHandlerInterface[] + * @param QuestionHandlerInterface[] $questionHelpers */ - private $questionHelpers; - - public function __construct(iterable $questionHelpers) + public function __construct(private readonly iterable $questionHelpers) { $this->fieldsTypes = TypeMapping::getCompletionTypes(); - $this->questionHelpers = $questionHelpers; } /** @@ -123,9 +120,7 @@ private function hasField(array $fieldCollection, string $field): bool private function getCurrentFields(array $fieldCollection): array { - return array_map(static function (Field $field) { - return $field->getPropertyName(); - }, $fieldCollection); + return array_map(static fn(Field $field) => $field->getPropertyName(), $fieldCollection); } private function addMissingFkFields(array $fieldCollection): array diff --git a/src/Component/Generator/Definition/EntityGenerator.php b/src/Component/Generator/Definition/EntityGenerator.php index 8e60930..6b9613e 100644 --- a/src/Component/Generator/Definition/EntityGenerator.php +++ b/src/Component/Generator/Definition/EntityGenerator.php @@ -66,47 +66,22 @@ public function generate(Definition $definition): void continue; } - $type = TypeMapping::mapToPhpType($field, true, $definition); - - $class->stmts[] = $builder->property($field->getPropertyName())->makeProtected()->setDocComment('/** @var ' . $type . ' */')->getNode(); - } - - /** @var Field $field */ - foreach ($definition->fields as $field) { - if ($field->name === IdField::class) { - continue; - } - - $setterMethodName = 'set' . ucfirst($field->getPropertyName()); - $getterMethodName = 'get' . ucfirst($field->getPropertyName()); - - if ($this->hasMethod($classMethods, $setterMethodName) || $this->hasMethod($classMethods, $getterMethodName)) { - continue; - } - $type = TypeMapping::mapToPhpType($field, false, $definition); - if ($field->isNullable()) { $type = '?' . $type; } - $method = new ClassMethod(new Identifier($setterMethodName)); - $method->flags = Class_::MODIFIER_PUBLIC; - $method->returnType = new Identifier('void'); - $method->params = [new Param(new Name('$value'), null, new Name($type))]; - - $var = new PropertyFetch(new Variable('this'), new Name($field->getPropertyName())); - $method->stmts[] = new Expression(new Assign($var, new Variable('value'))); + $node = $builder + ->property($field->getPropertyName()) + ->setType($type) + ->makePublic(); - $class->stmts[] = $method; - - $method = new ClassMethod(new Identifier($getterMethodName)); - $method->flags = Class_::MODIFIER_PUBLIC; - $method->returnType = new Identifier($type); - - $method->stmts[] = new Return_($var); + if ($field->isNullable()) { + $node = $node->setDefault(null); + } - $class->stmts[] = $method; + $class->stmts[] = $node + ->getNode(); } $printer = new Standard(); diff --git a/src/Component/Generator/Definition/EntityLoader.php b/src/Component/Generator/Definition/EntityLoader.php index b90f754..72368ba 100644 --- a/src/Component/Generator/Definition/EntityLoader.php +++ b/src/Component/Generator/Definition/EntityLoader.php @@ -2,6 +2,13 @@ namespace Frosh\DevelopmentHelper\Component\Generator\Definition; +use PhpParser\Node\Stmt\Use_; +use PhpParser\Node\Expr\New_; +use PhpParser\Node\Expr\MethodCall; +use PhpParser\Node\Scalar\String_; +use PhpParser\Node\Scalar\LNumber; +use PhpParser\Node\Expr\ClassConstFetch; +use PhpParser\Node\Expr\ConstFetch; use Frosh\DevelopmentHelper\Component\Generator\Struct\Definition; use Frosh\DevelopmentHelper\Component\Generator\Struct\Field; use Frosh\DevelopmentHelper\Component\Generator\Struct\Flag; @@ -11,6 +18,7 @@ use PhpParser\NodeFinder; use PhpParser\ParserFactory; use Shopware\Core\Framework\DataAbstractionLayer\DefinitionInstanceRegistry; +use Shopware\Core\Kernel; use Symfony\Component\Console\Style\SymfonyStyle; use Symfony\Component\Filesystem\Filesystem; @@ -19,15 +27,10 @@ class EntityLoader /** * @var Node\Stmt\Use_[] */ - private $useFlags; - /** - * @var DefinitionInstanceRegistry - */ - private $instanceRegistry; + private ?array $useFlags = null; - public function __construct(DefinitionInstanceRegistry $instanceRegistry) + public function __construct(private readonly DefinitionInstanceRegistry $instanceRegistry, private readonly Kernel $kernel) { - $this->instanceRegistry = $instanceRegistry; } public function load(string $class, SymfonyStyle $io): Definition @@ -81,20 +84,16 @@ private function parseFile(string $entityFile): array $nodeFinder = new NodeFinder(); - $this->useFlags = $nodeFinder->findInstanceOf($ast, Node\Stmt\Use_::class); + $this->useFlags = $nodeFinder->findInstanceOf($ast, Use_::class); - $method = $nodeFinder->findFirst($ast, function (Node $node) { - return $node instanceof ClassMethod && $node->name->name === 'defineFields'; - }); + $method = $nodeFinder->findFirst($ast, fn(Node $node) => $node instanceof ClassMethod && $node->name->name === 'defineFields'); if (! $method instanceof ClassMethod) { throw new \RuntimeException('Class does not implement defineFields'); } /** @var Node\Expr\New_ $fieldCollection */ - $fieldCollection = $nodeFinder->findFirst([$method], function (Node $node) { - return $node instanceof Node\Expr\New_ && (string) $node->class === 'FieldCollection'; - }); + $fieldCollection = $nodeFinder->findFirst([$method], fn(Node $node) => $node instanceof New_ && (string) $node->class === 'FieldCollection'); /** @var Node\Expr\Array_ $array */ $array = $fieldCollection->args[0]->value; @@ -104,7 +103,7 @@ private function parseFile(string $entityFile): array $flags = []; /** @var Node\Expr\New_ $exprNew */ $exprNew = null; - if ($item->value instanceof Node\Expr\MethodCall) { + if ($item->value instanceof MethodCall) { foreach ($item->value->args as $arg) { $flags[] = new Flag($this->getFQCN((string) $arg->value->class), $this->parserArgumentsToPhp($arg->value->args)); } @@ -128,16 +127,16 @@ private function parserArgumentsToPhp($element): array /** @var Node\Arg $arg */ foreach ($element as $arg) { switch (true) { - case $arg->value instanceof Node\Scalar\String_: + case $arg->value instanceof String_: $args[] = (string) $arg->value->value; break; - case $arg->value instanceof Node\Scalar\LNumber: + case $arg->value instanceof LNumber: $args[] = (int) $arg->value->value; break; - case $arg->value instanceof Node\Expr\ClassConstFetch: + case $arg->value instanceof ClassConstFetch: $args[] = $this->getFQCN($arg->value->class) . '::' . $arg->value->name; break; - case $arg->value instanceof Node\Expr\ConstFetch: + case $arg->value instanceof ConstFetch: $value = (string) $arg->value->name; if ($value === 'null') { $value = null; @@ -150,7 +149,7 @@ private function parserArgumentsToPhp($element): array $args[] = $value; break; default: - throw new \RuntimeException('Type not supported: ' . get_class($arg->value)); + throw new \RuntimeException('Type not supported: ' . $arg->value::class); } } @@ -162,7 +161,7 @@ public function getFQCN(string $name): string foreach ($this->useFlags as $useFlag) { /** @var Node\Stmt\UseUse $item */ foreach ($useFlag->uses as $item) { - if (strpos((string) $item->name, '\\' . $name) !== false) { + if (str_contains((string) $item->name, '\\' . $name)) { return $item->name; } } @@ -194,8 +193,7 @@ private function normalizeName(string $class): string private function getNewEntityFolder(string $namespace): string { - global $classLoader; - $prefixes = $classLoader->getPrefixesPsr4(); + $prefixes = $this->kernel->getPluginLoader()->getClassLoader()->getPrefixesPsr4(); $namespaceSplit = explode('\\', $namespace); unset($namespaceSplit[count($namespaceSplit) -1 ]); @@ -206,7 +204,7 @@ private function getNewEntityFolder(string $namespace): string $loopNamespace = implode('\\', $namespaceSplit) . '\\'; if (isset($prefixes[$loopNamespace])) { - return rtrim(rtrim($prefixes[$loopNamespace][0],'/').'/' . implode('/', array_reverse($suffix)), '/') . '/'; + return rtrim(rtrim((string) $prefixes[$loopNamespace][0],'/').'/' . implode('/', array_reverse($suffix)), '/') . '/'; } $index = count($namespaceSplit) -1; diff --git a/src/Component/Generator/Definition/ExtensionGenerator.php b/src/Component/Generator/Definition/ExtensionGenerator.php index 419df0c..d0fa8fe 100644 --- a/src/Component/Generator/Definition/ExtensionGenerator.php +++ b/src/Component/Generator/Definition/ExtensionGenerator.php @@ -2,6 +2,7 @@ namespace Frosh\DevelopmentHelper\Component\Generator\Definition; +use PhpParser\Node\Stmt\Expression; use Frosh\DevelopmentHelper\Component\Generator\Struct\Definition; use Frosh\DevelopmentHelper\Component\Generator\Struct\Field; use Frosh\DevelopmentHelper\Component\Generator\UseHelper; @@ -46,12 +47,10 @@ public function generate(Definition $definition, Definition $reference, Field $f $builder = new BuilderFactory(); /** @var ClassMethod $method */ - $method = $nodeFinder->findFirst([$namespace], static function (Node $node) { - return $node instanceof ClassMethod && $node->name->name === 'extendFields'; - }); + $method = $nodeFinder->findFirst([$namespace], static fn(Node $node) => $node instanceof ClassMethod && $node->name->name === 'extendFields'); $useHelper->addUse($field->name); - $method->stmts[] = new Node\Stmt\Expression($builder->methodCall($builder->var('collection'), new Identifier('add'), [$this->buildField($field, $useHelper)])); + $method->stmts[] = new Expression($builder->methodCall($builder->var('collection'), new Identifier('add'), [$this->buildField($field, $useHelper)])); $namespace->stmts = array_merge($useHelper->getStms(), $namespace->stmts); diff --git a/src/Component/Generator/Definition/ParserBuilderTrait.php b/src/Component/Generator/Definition/ParserBuilderTrait.php index b715969..5b274af 100644 --- a/src/Component/Generator/Definition/ParserBuilderTrait.php +++ b/src/Component/Generator/Definition/ParserBuilderTrait.php @@ -2,6 +2,7 @@ namespace Frosh\DevelopmentHelper\Component\Generator\Definition; +use PhpParser\Node\Expr\Array_; use Frosh\DevelopmentHelper\Component\Generator\Struct\Field; use Frosh\DevelopmentHelper\Component\Generator\UseHelper; use PhpParser\Node\Arg; @@ -42,9 +43,9 @@ private function buildArgsForParser(array $elementArgs): array foreach ($elementArgs as $arg) { switch (gettype($arg)) { case 'string': - if (strpos($arg, '::class') !== false) { + if (str_contains($arg, '::class')) { $args[] = new Arg(new ClassConstFetch(new Name('\\' . substr($arg, 0, -7)), new Identifier('class'))); - } elseif (strpos($arg, '::') !== false) { + } elseif (str_contains($arg, '::')) { [$firstPart, $secondPart] = explode('::', $arg, 2); $args[] = new Arg(new ClassConstFetch(new Name('\\' . $firstPart), new Identifier($secondPart))); } else { @@ -62,7 +63,7 @@ private function buildArgsForParser(array $elementArgs): array $args[] = new Arg(new ConstFetch(new Name($arg ? 'true' : 'false'))); break; case 'array': - $args[] = new Arg(new Expr\Array_()); + $args[] = new Arg(new Array_()); break; default: throw new \RuntimeException('Invalid type ' . gettype($arg)); diff --git a/src/Component/Generator/Definition/TypeMapping.php b/src/Component/Generator/Definition/TypeMapping.php index c17432f..b9e2f86 100644 --- a/src/Component/Generator/Definition/TypeMapping.php +++ b/src/Component/Generator/Definition/TypeMapping.php @@ -81,7 +81,6 @@ class TypeMapping TreePathField::class => 'string', UpdatedAtField::class => '\DateTime', VersionField::class => 'string', - WhitelistRuleField::class => 'array', PasswordField::class => 'string', NumberRangeField::class => 'string', ManyToManyIdField::class => 'array', @@ -110,7 +109,7 @@ public static function mapToPhpType(Field $field, bool $respectNull, Definition if ($type === 'associationField') { $type = substr($field->getReferenceClass(), 0, -7); - if (strpos($type, '\\') !== false) { + if (str_contains($type, '\\')) { $type = '\\' . $type; } } diff --git a/src/Component/Generator/FixCodeStyle.php b/src/Component/Generator/FixCodeStyle.php index 918bdd6..95d2ac6 100644 --- a/src/Component/Generator/FixCodeStyle.php +++ b/src/Component/Generator/FixCodeStyle.php @@ -30,7 +30,10 @@ public function fix(Definition $loaderResult): void $resolver = new ConfigurationResolver( $config, - [], + [ + 'dry-run' => false, + 'stop-on-violation' => false, + ], getcwd(), new ToolInfo() ); diff --git a/src/Component/Generator/Migration/MigrationSchemaBuilder.php b/src/Component/Generator/Migration/MigrationSchemaBuilder.php index a1afc8b..89d8449 100644 --- a/src/Component/Generator/Migration/MigrationSchemaBuilder.php +++ b/src/Component/Generator/Migration/MigrationSchemaBuilder.php @@ -49,7 +49,7 @@ class MigrationSchemaBuilder { - private DefinitionInstanceRegistry $instanceRegistry; + private readonly DefinitionInstanceRegistry $instanceRegistry; public function __construct(DefinitionInstanceRegistry $instanceRegistry) { @@ -93,7 +93,7 @@ public function buildSchemaOfDefinition(Schema $schema, EntityDefinition $defini $table->addColumn($field->getStorageName(), $type, $options); } - $table->setPrimaryKey(array_map(function (StorageAware $field) {return $field->getStorageName();}, $definition->getPrimaryKeys()->getElements())); + $table->setPrimaryKey(array_map(fn(StorageAware $field) => $field->getStorageName(), $definition->getPrimaryKeys()->getElements())); $this->addForeignKeys($table, $definition); } @@ -191,7 +191,7 @@ private function getFieldDefinition(Field $field): array break; default: - throw new \RuntimeException(sprintf('Unknown field %s', \get_class($field))); + throw new \RuntimeException(sprintf('Unknown field %s', $field::class)); } return [ diff --git a/src/Component/Generator/QuestionHandler/GenericHandler.php b/src/Component/Generator/QuestionHandler/GenericHandler.php index 7923111..2e00010 100644 --- a/src/Component/Generator/QuestionHandler/GenericHandler.php +++ b/src/Component/Generator/QuestionHandler/GenericHandler.php @@ -18,18 +18,8 @@ class GenericHandler implements QuestionHandlerInterface { - /** - * @var array - */ - private $entityDefinitions; - private ExtensionGenerator $extensionGenerator; - private EntityLoader $entityLoader; - - public function __construct(array $entityDefinitions, ExtensionGenerator $extensionGenerator, EntityLoader $entityLoader) + public function __construct(private readonly array $entityDefinitions, private readonly ExtensionGenerator $extensionGenerator, private readonly EntityLoader $entityLoader) { - $this->entityDefinitions = $entityDefinitions; - $this->extensionGenerator = $extensionGenerator; - $this->entityLoader = $entityLoader; } public function supports(string $field): bool @@ -93,7 +83,7 @@ public function handle(Definition $definition, SymfonyStyle $io, string $name, s } else if($answer === 'false') { $answer = false; } else if(strlen((string) $answer) && $parameter->hasType()) { - $parameterType = (string) $parameter->getType(); + $parameterType = (string) ($parameter->getType() ? $parameter->getType()->getName() : null); if ($parameterType === 'int') { $answer = (int) $answer; diff --git a/src/Component/Generator/QuestionHandler/ManyToManyHandler.php b/src/Component/Generator/QuestionHandler/ManyToManyHandler.php index 35a254e..5c2e5f7 100644 --- a/src/Component/Generator/QuestionHandler/ManyToManyHandler.php +++ b/src/Component/Generator/QuestionHandler/ManyToManyHandler.php @@ -22,43 +22,14 @@ class ManyToManyHandler implements QuestionHandlerInterface { - /** - * @var array - */ - private $entityDefinitions; - - /** - * @var EntityLoader - */ - private $loader; - - /** - * @var DefinitionGenerator - */ - private $definitionGenerator; - - /** - * @var EntityGenerator - */ - private $entityGenerator; - - /** - * @var ExtensionGenerator - */ - private $extensionGenerator; - public function __construct( - array $entityDefinitions, - EntityLoader $loader, - DefinitionGenerator $definitionGenerator, - EntityGenerator $entityGenerator, - ExtensionGenerator $extensionGenerator - ) { - $this->entityDefinitions = $entityDefinitions; - $this->loader = $loader; - $this->definitionGenerator = $definitionGenerator; - $this->entityGenerator = $entityGenerator; - $this->extensionGenerator = $extensionGenerator; + private readonly array $entityDefinitions, + private readonly EntityLoader $loader, + private readonly DefinitionGenerator $definitionGenerator, + private readonly EntityGenerator $entityGenerator, + private readonly ExtensionGenerator $extensionGenerator + ) + { } public function supports(string $field): bool diff --git a/src/Component/Generator/UseHelper.php b/src/Component/Generator/UseHelper.php index 776d82b..5cb5509 100644 --- a/src/Component/Generator/UseHelper.php +++ b/src/Component/Generator/UseHelper.php @@ -8,8 +8,8 @@ class UseHelper { - private $alreadyAddedUses = []; - private $printUses = []; + private array $alreadyAddedUses = []; + private array $printUses = []; public function addUsage(string $use): void { @@ -31,9 +31,7 @@ public function addUse(string $use): void */ public function getStms(): array { - return array_map(static function (string $use) { - return new Use_([new UseUse(new Name($use))]); - }, $this->printUses); + return array_map(static fn(string $use) => new Use_([new UseUse(new Name($use))]), $this->printUses); } public function getShortName(string $name): string diff --git a/src/Component/Profiler/TwigDataCollector.php b/src/Component/Profiler/TwigDataCollector.php index ea06451..d5c19d4 100644 --- a/src/Component/Profiler/TwigDataCollector.php +++ b/src/Component/Profiler/TwigDataCollector.php @@ -8,14 +8,8 @@ class TwigDataCollector extends BaseTwigDataCollector { - /** - * @var TwigDecorator - */ - private $twig; - - public function __construct(Profile $profile, Environment $twig = null) + public function __construct(Profile $profile, private readonly Environment $twig) { - $this->twig = $twig; parent::__construct($profile, $twig); } @@ -24,10 +18,10 @@ public function getTemplateData(): array return $this->data['renders']; } - public function lateCollect() + public function lateCollect(): void { $this->data['renders'] = json_decode(json_encode($this->twig->getTemplateData()), true); - return parent::lateCollect(); + parent::lateCollect(); } } diff --git a/src/Component/Profiler/TwigDecorator.php b/src/Component/Profiler/TwigDecorator.php index abbd6f3..0adb21f 100644 --- a/src/Component/Profiler/TwigDecorator.php +++ b/src/Component/Profiler/TwigDecorator.php @@ -7,7 +7,7 @@ class TwigDecorator extends Environment { - private $renders = []; + private array $renders = []; public function render($name, array $context = []): string { @@ -17,7 +17,7 @@ public function render($name, array $context = []): string $name = $name->getTemplateName(); } - if (strpos($name, 'WebProfiler') === false) { + if (!str_contains((string) $name, 'WebProfiler')) { $this->renders[$name] = $context; } diff --git a/src/Component/Twig/Extension/BlockCommentExtension.php b/src/Component/Twig/Extension/BlockCommentExtension.php index efbf336..2db301d 100644 --- a/src/Component/Twig/Extension/BlockCommentExtension.php +++ b/src/Component/Twig/Extension/BlockCommentExtension.php @@ -9,20 +9,14 @@ class BlockCommentExtension extends AbstractExtension { - /** - * @var string - */ - private $kernelRootDir; - - private array $twigExcludeKeywords; - - public function __construct(string $kernelRootDir, array $twigExcludeKeywords) + public function __construct(private readonly string $kernelRootDir, private readonly array $twigExcludeKeywords) { - $this->kernelRootDir = $kernelRootDir; - $this->twigExcludeKeywords = $twigExcludeKeywords; } - public function getNodeVisitors() + /** + * @return BlogCommentNodeVisitor[] + */ + public function getNodeVisitors(): array { return [new BlogCommentNodeVisitor($this->kernelRootDir, $this->twigExcludeKeywords)]; } diff --git a/src/Component/Twig/NodeVisitor/BlogCommentNodeVisitor.php b/src/Component/Twig/NodeVisitor/BlogCommentNodeVisitor.php index 71dcba3..1defc66 100644 --- a/src/Component/Twig/NodeVisitor/BlogCommentNodeVisitor.php +++ b/src/Component/Twig/NodeVisitor/BlogCommentNodeVisitor.php @@ -14,17 +14,8 @@ class BlogCommentNodeVisitor extends AbstractNodeVisitor { - /** - * @var string - */ - private $kernelRootDir; - - private array $twigExcludeKeywords; - - public function __construct(string $kernelRootDir, array $twigExcludeKeywords) + public function __construct(private readonly string $kernelRootDir, private readonly array $twigExcludeKeywords) { - $this->kernelRootDir = $kernelRootDir; - $this->twigExcludeKeywords = $twigExcludeKeywords; } @@ -57,7 +48,7 @@ protected function doLeaveNode(Node $node, Environment $env): Node $path = $node->getTemplateName(); if ($node->getSourceContext() instanceof Source) { - $path = ltrim(str_replace($this->kernelRootDir, '', $node->getSourceContext()->getPath()), '/'); + $path = ltrim(str_replace($this->kernelRootDir, '', (string) $node->getSourceContext()->getPath()), '/'); } if ($this->shouldSkip($node)) { @@ -91,6 +82,10 @@ private function shouldSkip(Node $node): bool { $name = $node->getTemplateName(); + if ($node->getSourceContext() && str_contains((string) $node->getSourceContext()->getPath(), 'symfony/web-profiler')) { + return true; + } + if ($node instanceof BlockNode) { $name = $node->getAttribute('name'); } @@ -100,7 +95,7 @@ private function shouldSkip(Node $node): bool } foreach ($this->twigExcludeKeywords as $key) { - if (strpos($name, $key) !== false) { + if (str_contains((string) $name, (string) $key)) { return true; } } diff --git a/src/FroshDevelopmentHelper.php b/src/FroshDevelopmentHelper.php index 59bedbe..30c6a07 100644 --- a/src/FroshDevelopmentHelper.php +++ b/src/FroshDevelopmentHelper.php @@ -15,10 +15,6 @@ use Symfony\Component\DependencyInjection\Loader\YamlFileLoader; use Symfony\Component\DependencyInjection\ContainerBuilder; -if (file_exists(__DIR__ . '/../vendor/autoload.php')) { - require_once __DIR__ . '/../vendor/autoload.php'; -} - class FroshDevelopmentHelper extends Plugin { public function build(ContainerBuilder $container): void @@ -52,4 +48,9 @@ private function buildConfig(ContainerBuilder $container): void $configLoader->load($confDir . '/{packages}/*' . Kernel::CONFIG_EXTS, 'glob'); } + + public function executeComposerCommands(): bool + { + return true; + } } diff --git a/src/Resources/config/services.xml b/src/Resources/config/services.xml index 3d883ee..73b1abf 100644 --- a/src/Resources/config/services.xml +++ b/src/Resources/config/services.xml @@ -12,8 +12,8 @@ %frosh_development_helper.twig.exclude_keywords% - - + + diff --git a/src/Resources/views/Collector/twig.html.twig b/src/Resources/views/Collector/twig.html.twig index 2bb5c92..7553b2c 100644 --- a/src/Resources/views/Collector/twig.html.twig +++ b/src/Resources/views/Collector/twig.html.twig @@ -1,9 +1,45 @@ {% extends '@WebProfiler/Profiler/layout.html.twig' %} +{% block head %} + {{ parent() }} + + +{% endblock %} + {% block toolbar %} {% set time = collector.templatecount ? '%0.0f'|format(collector.time) : 'n/a' %} {% set icon %} - {{ include('@WebProfiler/Icon/twig.svg') }} + {{ source('@WebProfiler/Icon/twig.svg') }} {{ time }} ms {% endset %} @@ -32,7 +68,7 @@ {% block menu %} - {{ include('@WebProfiler/Icon/twig.svg') }} + {{ source('@WebProfiler/Icon/twig.svg') }} Twig {% endblock %} @@ -41,7 +77,7 @@ {% if collector.templatecount == 0 %}

Twig

-
+

No Twig templates were rendered for this request.

{% else %} @@ -53,19 +89,23 @@ Render time
-
- {{ collector.templatecount }} - Template calls -
+
-
- {{ collector.blockcount }} - Block calls -
+
+
+ {{ collector.templatecount }} + Template calls +
-
- {{ collector.macrocount }} - Macro calls +
+ {{ collector.blockcount }} + Block calls +
+ +
+ {{ collector.macrocount }} + Macro calls +
@@ -93,17 +133,14 @@ {% for template, count in collector.templates %} - {%- set file = collector.templatePaths[template]|default(false) -%} - {%- set link = file ? file|file_link(1) : false -%} - - {{ include('@WebProfiler/Icon/twig.svg') }} + {% set file = collector.templatePaths[template]|default(false) %} + {% set link = file ? file|file_link(1) : false %} + {% if link %} - {{ template }} - + + {{ template }} + {{ file|file_relative|default(file) }} + {% else %} {{ template }} {% endif %} diff --git a/src/Subscriber/DisableStorefrontErrorHandling.php b/src/Subscriber/DisableStorefrontErrorHandling.php index 0e4637d..06a6723 100644 --- a/src/Subscriber/DisableStorefrontErrorHandling.php +++ b/src/Subscriber/DisableStorefrontErrorHandling.php @@ -10,22 +10,18 @@ class DisableStorefrontErrorHandling implements EventSubscriberInterface { - /** @var ContainerBagInterface */ - private $containerBag; - - public function __construct(ContainerBagInterface $containerBag) + public function __construct(private readonly ContainerBagInterface $containerBag) { - $this->containerBag = $containerBag; } - public static function getSubscribedEvents() + public static function getSubscribedEvents(): array { return [ KernelEvents::EXCEPTION => ['disableFrontendErrorHandling', -95] ]; } - public function disableFrontendErrorHandling(ExceptionEvent $event) + public function disableFrontendErrorHandling(ExceptionEvent $event): void { //if we are in dev mode, we will see exceptions if ($this->containerBag->all()['kernel.debug']) {