Skip to content

Instantly share code, notes, and snippets.

@igormukhingmailcom
Last active February 6, 2024 08:25
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save igormukhingmailcom/3196a8cdf87a5c2ac18bac8287034880 to your computer and use it in GitHub Desktop.
Save igormukhingmailcom/3196a8cdf87a5c2ac18bac8287034880 to your computer and use it in GitHub Desktop.
Symfony/Sylius stupid issues that hard to debug and which may waste too many hours

Symfony/Sylius stupid issues that hard to debug and which may waste too many hours

1. [Doctrine\Common\Persistence\Mapping\MappingException] Class 'Your\SyliusPlugin\Entity\YourEntity' does not exist

When your plugin is AbstractResourceBundle and all your entities should be and actually placed at Model directory, you have that exception (notice ...\Entity\... at exception rather than ..\Model\...) for your Your\SyliusPlugin\Model\YourEntity.php that is weird.

This happens when you accidentally have your mapping file at src/Resources/config/doctrine/YourEntity.orm.xml (without ../model/.. part) rather than src/Resources/config/doctrine/model/YourEntity.orm.xml.

This issue may happen when you convert some of your application code (which use Entity directory) to plugin (which use Model directory). And copy-paste your entities and configurations from application to plugin.

2. Argument 1 passed to Sylius\Bundle\CoreBundle\Fixture\OptionsResolver\LazyOption::randomOneOrNull() must implement interface Sylius\Component\Resource\Repository\RepositoryInterface, null given

You should call trait constructors before parent constructor as parent constructor calls $this->configureOptions which sending not initialized repository to LazyOption::*.

Wrong:

parent::__construct($shopUserFactory, $customerFactory, $customerGroupRepository);
$this->__shopUserExampleFactoryTraitConstruct($channelRepository);

Good:

// Important: Traits constructors should be before parent constructor call
$this->__shopUserExampleFactoryTraitConstruct($channelRepository);

parent::__construct($shopUserFactory, $customerFactory, $customerGroupRepository);

3. Unable to find template "" (looked into: ...)

When you add new API root (for example, /shop-api/...)

You should specify that new root path at rules:

# config/packages/fos_rest.yaml
fos_rest:
    # ...
    format_listener:
        rules:
            # ...
            - { path: '^/shop-api/.*', priorities: ['json', 'xml'], fallback_format: json, prefer_extension: false }

When you haven't zone specified

Make sure all api roots specified at zone configuration. Otherwise, you will have this issue on some exceptions (example: Setono/SyliusGiftCardPlugin#63) which is very confusing.

# config/packages/fos_rest.yaml
fos_rest:
    # ...
    zone:
        - { path: '^/api/.*' }
        - { path: '^/shop-api/.*' }

Related: Sylius/Sylius-Standard#389, FriendsOfSymfony/FOSRestBundle#1853

4. New grid filter

Exception: An exception has been thrown during the rendering of a template ("An error has occurred resolving the options of the form "Symfony\Component\Form\Extension\Core\Type\TextType": The option "class" does not exist. Defined options are: " after adding new grid filter.

You just forgot to include your service file with grid filter definition (tagged by sylius.grid_filter).

5. Custom factory

Exception: Argument 1 passed to Factory\SomeFactory::__construct() must implement interface Sylius\Component\Resource\Factory\FactoryInterface, string given, called in /var/cache/dev/ContainerMtxuxQL/getXXX_Factory_XXXService.php on line 16

That happens when you specify custom factory at definition: ->scalarNode('factory')->defaultValue(SomeFactory::class)->cannotBeEmpty()->end()

And then trying to override:

<service id="app.custom_factory.some"
         class="App\Factory\SomeFactory"
         decorates="app.factory.some"
         decoration-priority="256">
    <argument type="service" id="app.custom_factory.some.inner" />
</service>

How to fix

Specify default factory instead of custom at: ->scalarNode('factory')->defaultValue(Factory::class)->cannotBeEmpty()->end()

6. Repository in custom directory

Issue/Exception: Cannot autowire service "App\Product\Import\Repository\ImportLineRepository": argument "$class" of method "Doctrine\ORM\EntityRepository::__construct()" references class "Doctrine\ORM\Mapping\ClassMetadata" but no su ch service exists.

That happens when you put repository at custom directory - lets say App\Product\Import\Repository\ImportLineRepository instead of App\Repository\ImportLineRepository or App\Repository\Product\ImportLineRepository.

Answer is at Sylius\Bundle\ResourceBundle\DependencyInjection\Driver\Doctrine\DoctrineORMDriver, who register aliases via registerAliasForArgument and uses only $metadata->getHumanizedName() . ' repository' as a name for alias.

If you inject your custom repository like this: __construct(ImportLineRepository $something) or even __construct(ImportLineRepository $repository) - it will not match that alias and autowire will be trying to get repo by instantiating repository. The key is the name of repository parameter in constructor. Instead of using $something or $repository - you should use name like this:

  • For app.product_import_line - $productImportLineRepository (but not $importLineRepository, $repository, $something)

  • For app.bla_bla_bla - $blaBlaBlaRepository (but not $blaBlaRepository, $blaRepository, $repository, $something)

Todo: Understand why we have this issue (and have to keep in mind thats trict naming for correct autowiring) only when repository file/class is outside src/Repository directory.

7. Return value of SM\Callback\Callback::filterCallable() must be callable, array returned

You renamed some service or service method and not renamed it at your state machine callback config. So callable became array, as method not recognized as something that exists and can be called.

@palttamas
Copy link

This is gold!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment