Invalid Type Error Occasionally in Symfony 2 Console - symfony

I have a Symfony 2 environment in which I am using a custom data type with Doctrine's MongoDB ODM mappings. This all works, except occasionally; when I go to clear the cache or install the assets I sometimes receive the following error:
[InvalidArgumentException]
Invalid type specified "..."
This seems to always happen with the next command I issue to the console after I have cleared the cache, later operations all succeed. Doctrine seems to have issues intermittently finding it, and I suspect it has to do with where I'm registering the type and when that occurs with relationship to when Doctrine processes the mappings.
The type is being added as part of the boot() method in another bundle which may not always be included.
What is happening here?
Can I somehow ensure that the type is loaded earlier, or provide it in a configuration file? As far as I can tell there is no way, at present, using the MongoDB configuration to specify custom types in a .yml file as described for the ORM here.

I found a good solution in this post.
The short answer is to add
\Doctrine\ODM\MongoDB\Mapping\Types\Type::registeredType('mytype', 'My\Type\Class');
in MyBundleClass::__consruct(). This will get the type registered before any warmup happens with the cache.
Using Type::registeredType() instead of Type::addType() will avoid checking to see if the type is already registered. In the case of Type::addType() will throw an exception if it has already been added.

To answer the second of my two questions above, I seem to have found a work-around for this, but I don't like it very much. It feels more like a hack than a proper solution.
In app/autoload.php after I register the annotation registry and driver, I call:
\Doctrine\ODM\MongoDB\Mapping\Types\Type::addType('mytype', 'My\Type\Class');
... and this appears to ensure that the type is registered when calling the console commands.

Related

How can I make sure an object is not in the database using Codeception?

I'm working on a Symfony application and writing some tests using CodeCeption.
I need to make sure some entities are created in the database, for which I need to make sure they don't exist previous to the execution of the method under test.
Is there something like:
$I->dontHaveInRepository($entity)
?
I've checked the docs but didn't find a way to do this.
Thanks!
Codeception assertion methods usually starts with see.
have methods do some setup work, like inserting record to database.
All see methods have dontSee counterparts.
So the method you had been looking for is dontSeeInRepository method of Doctrine2 module

Dump Documentation [NelmioApiDocBundle] v3.0

I'm using the NelmioApiDocBundle (v3.0) in my symfony 4 project and I want to dump the documentation of my Api project.
I see it's possible to do with older version of NelmioApiDocBundle with this command :
php bin/console api:swagger:dump destination_folder
but I got this error :
There are no commands defined in the "api:swagger" namespace
I don't know if it's still posible to dump the documentation with the new version of NelmioApiDocBundle
Seeing NelmioApiDocBundle makes me almost sure you are using FOSRestBundle, if you are I'd change to api-platform, you make ask why? First of all you get the API doc by default on route /api (no matter what format etc you always get full doc) second of all the bundle is easy to configure even if you need some custom funcionality like access to property per operation and even depending on role more here I've tried FOSRestBundle on Symfony 5.0 but it couldnt provide with the funcionality and configuration I desired and then I found out about the API platform. In case I missed your desired answer let me know in the comment and I'll provide the answer as good as I can

How can I get the Doctrine entity metadata before compiling Symfony container?

In one Symfony bundle I define a compiler pass to preprocess some configuration. Part of that config is based on Doctrine entities, so I need to get the full metadata information for all application entities.
The compiler pass is executed very late (PassConfig::TYPE_BEFORE_REMOVING). I'm using $container->get('doctrine') like this to get the entity metadata:
$em = $container->get('doctrine')->getManagerForClass($entityClass);
$entityMetadata = $em->getMetadataFactory()->getMetadataFor($entityClass);
However, this is causing random failures for some users because of the use of the doctrine service during the Symfony container compilation.
I'd recommend to change your entities addressing. Mainly - create your models with interfaces and make entities implementing them.
Using resolve_target_entities Doctrine will "convert" them to the particular classes.
An example code is here: https://github.com/Sylius/SyliusResourceBundle/blob/master/DependencyInjection/Compiler/DoctrineTargetEntitiesResolverPass.php
Just make sure your bundle is registered before DoctrineBundle is registered.
Then - in your whole app - instead of AppBundle::Entity addressing, use FQDN of interface bound to an entity earlier.
I've experimented a bit with compilers and services and it's a very bad idea to base on cross-bundle services under compiling container process... Why? It's not reliable - sometimes it will work as you want, sometimes it will fail as you described.
Thank you all for your comments and ideas. I post an answer to explain how I solved this problem.
Trying to use the Doctrine service in a compiler pass was creating more and more problems for our users (and it was creating other minor issues with other services such as Twig). So this was definitely a bad solution for our needs.
So at the end I decided to change everything. We no longer use a compiler pass to process the configuration and instead we use a regular PHP class called during runtime.
In the dev environment, the configuration is processed for each request. It's a bit slower than before, but we prevent any caching issue. In the prod environment we use Doctrine Cache to process the configuration once. Besides, we've create a cache warmer to create the cached configuration before the first request hits the application.

non-existant parameter "mcx" when using app/console

I am currently trying to go through the api-platform tutorial on https://api-platform.com/doc/1.0/getting-started/api but at the point where I use the console script (database creation), I just get the following error:
[Symfony\Component\DependencyInjection\Exception\ParameterNotFoundException]
You have requested a non-existent parameter "mcx".
They mention to use the [api-platform] tag here, but it apparently does not yet exist.
Anyone who runs into this kind of issue, check your parameters.yml file. I apparently chose too complex of a "secret" as it doesn't like percent (%) symbols in values and tries to parse them as separate parameters to be injected.

symfony deployment error: mapped superclass

When I deploy a symfony website including mapped superclass entities online, I get the following error:
AnnotationException: [Semantical Error] The annotation "#Doctrine\ORM\Mapping\MappedSuperClass" in class Acme\DemoBundle\Entity\Foo does not exist, or could not be auto-loaded.
Worst is, this error doesn't show if we use web/app.php (with debugging mode true), whereas it blocks the programm if you use web/app_dev.php.
I should add that, locally, this error does not show up while using either web/app.php or web/app_dev.php.
Does anyone have a clue about this dark mystery?
Thanks in advance for any hints.
Ok,
I will be answering to my own question, for the sake of future deployment processed by any fellow programmer.
the problem was in the doctrine annotation.
I put:
#MappedSuperClass
whereas it is:
#MappedSuperclass
REMEMBER:
on mac, it doesn't make a difference. But also on linux if in prod mode (with debug option at true). that is why it was working with web/app.php.
However, in dev mode (web/app_dev.php), it doesn't work on a linux environment, which makes a difference between capitalized and normal letters.
I hope it will save you the headaches it caused me ;)
Regards,
Wisebes
[issue solved]

Resources