Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Can't load entities from bundles using PSR-4 #282

Closed
arthens opened this issue Mar 25, 2014 · 30 comments
Closed

Can't load entities from bundles using PSR-4 #282

arthens opened this issue Mar 25, 2014 · 30 comments

Comments

@arthens
Copy link

arthens commented Mar 25, 2014

According to PSR-4, the namespace of a class doesn't have to be a direct mapping to the filesystem. See the first example of the specs

This doesn't look to be supported because of:
https://github.com/doctrine/DoctrineBundle/blob/master/Mapping/DisconnectedMetadataFactory.php#L143

This method tries to remove the namespace from the path, and fails because it can't find it.

e.g. of a bundle using PSR-4 and VendorName\BundleName as a prefix

$namespace = "VendorName\BundleName\Entity";
$path = "/site/vendor/vendorname/bundlename/Entity";

will fail because there's no direct mapping

@arthens
Copy link
Author

arthens commented Mar 25, 2014

This is happening when I run ./app/console doctrine:generate:entities [entity]

This is not the only problem with using PSR-4 and doctrine:generate:entities. I tried patching it manually, but then instead of updating my class it created a new class in the location it was expecting (e.g. /site/vendor/vendorname/bundlename/VendorName/BundleName/Entity)

@stof
Copy link
Member

stof commented Mar 25, 2014

is the problem happening when loading entities or when generating them ?

@arthens
Copy link
Author

arthens commented Mar 26, 2014

The problem is happening when generating them, because it fails when it tries to load the metadata.

Do you want me to create a simple bundle that highlight the problem?

@tmoitie
Copy link

tmoitie commented Apr 16, 2014

Having the same problem. If entity class doesn't exist, it creates the PSR-0 directory structure and generates it into there. If the entity does exist in the PSR-4 location, generator fails with this error:

$ app/console doctrine:generate:entities --path lib Tmoitie
Generating entities for namespace "Tmoitie"
  [RuntimeException]
  Can't find base path for "Tmoitie\Thingy\SchedulerBundle\Entity\PostSchedu
  le" (path: "/Users/tommoitie/Develop/thingy/lib/SchedulerBundle/Entity", d
  estination: "/Users/tommoitie/Develop/thingy/lib/SchedulerBundle/Entity").

Note, lib is mapped to PSR-4 autoloader with namespace Tmoitie\Thingy\, so those path/destinations are correct.

@tmoitie
Copy link

tmoitie commented Apr 23, 2014

Looks like the origin of the issue is in Doctrine itself, which has the PSR-0 naming structure ingrained into the writeEntityClass method: https://github.com/doctrine/doctrine2/blob/master/lib/Doctrine/ORM/Tools/EntityGenerator.php#L341

May be difficult to change this without breaking BC

@beberlei
Copy link
Member

PSR-4 is not supported in Doctrine.

@victorsmirnov
Copy link

This last comment sounds slightly strange. Please clarify what do you mean.

Why it is not supported?
Are there any plans to add PSR-4 support in Doctrine?

I think I can work on adding PSR-4 support to Doctrine. But first of all I should know if this is really needed. Or may be someone is already working on it. Do you think if this is possible?

Thank you for your help!

@johnpancoast
Copy link

As said earlier, it looks like doctrine directly relates class namespaces to filesystem paths (converting from \ to / for example) and psr-4 allows for autoloading of classes whose namespaces don't directly map to their paths.

E.g.,
https://github.com/doctrine/doctrine2/blob/master/lib/Doctrine/ORM/Tools/EntityGenerator.php#L363

I too wish I knew the plans for this for doctrine. I have to convert some code to psr 0 for some stuff due to this. Not too big of deal but...

@Ocramius
Copy link
Member

We don't plan to support psr-4.
On Sep 17, 2014 5:48 AM, "John Pancoast" notifications@github.com wrote:

As said earlier, it looks like doctrine directly relates class namespaces
to filesystem paths (converting from \ to / for example) and psr-4 allows
for autoloading of classes whose namespaces don't directly map to their
paths.

E.g.,

https://github.com/doctrine/doctrine2/blob/master/lib/Doctrine/ORM/Tools/EntityGenerator.php#L363

I too wish I knew the plans for this for doctrine. I have to convert some
code to psr 0 for some stuff due to this. Not too big of deal but...


Reply to this email directly or view it on GitHub
#282 (comment)
.

@johnpancoast
Copy link

Good to know. Thanks.

@tmoitie
Copy link

tmoitie commented Sep 19, 2014

@Ocramius, If someone were to submit a pull request to introduce PSR-4 support in a non intrusive way, what's the likelyhood of it being merged?

@Ocramius
Copy link
Member

Very unlikely right now.
On Sep 19, 2014 5:45 PM, "Tom Moitié" notifications@github.com wrote:

@Ocramius https://github.com/Ocramius, If someone were to submit a pull
request to introduce PSR-4 in a non intrusive way, what's the likelyhood of
it being merged?


Reply to this email directly or view it on GitHub
#282 (comment)
.

@stof
Copy link
Member

stof commented Sep 19, 2014

@Ocramius why unlikely ? IMO, we should accept the support of generating classes in codebases using PSR-4 if we get a PR for it. Otherwise, lots of users won't be able to use it properly

@Ocramius
Copy link
Member

@stof we barely want support for code generation in the ORM right now...
On Sep 19, 2014 11:47 PM, "Christophe Coevoet" notifications@github.com
wrote:

@Ocramius https://github.com/Ocramius why unlikely ? IMO, we should
accept the support of generating classes in codebases using PSR-4 if we get
a PR for it. Otherwise, lots of users won't be able to use it properly


Reply to this email directly or view it on GitHub
#282 (comment)
.

@johnpancoast
Copy link

@Ocramius I can say that the code gen has been helpful. Perhaps it shouldn't live where it does but I hope it lives on.

@Ocramius
Copy link
Member

@shideon yes, but we don't see real value in people running the generator over and over again. The generator is meant to be used to import legacy schemas, NOT to generate getters/setters and overwrite existing classes.

I realize that this is a crusade against a functionality that is useful to some people, but we really only had a lot of bugs and misuses coming from it, and that for customizations that should be applied post code-generation by the developer that is working on the project.

One of these customizations is the location of the generated files.

@alex-ception
Copy link

Up on this feature, as it would be very useful. Is this planned ?

Misread what Ocramius said, ok. That's funny because in Sf doc the doctrine:generate:entities is completly misused.

@xabbuh
Copy link
Member

xabbuh commented Mar 10, 2015

Misread what Ocramius said, ok. That's funny because in Sf doc the doctrine:generate:entities is completly misused.

@alex-ception Can you open an issue on the Symfony documentation repository if you think that it can be improved?

@QuentinCurtet
Copy link

Hi,

I can't generate crud because of the base path
Is it due to PSR-4?

Thx

@fpiccinali
Copy link

I understand why doctrine's team does not wan't psr-4 and generator, but some of us need to regenerate getter often. Especially when our silly brains are not able to anticipate all ideas of our customers and creates the perfect model from scratch.

Here is a dirty-hack to enable doctrine:generate:entities with psr-4.

In Mapping/DisconnectedMetadataFactory.php, line 144 :

    private function getBasePathForClass($name, $namespace, $path) {
        $reflector = new \ReflectionClass($name);
        $destination = dirname($reflector->getFileName());
        return $destination;

/*
        $namespace = str_replace('\\', '/', $namespace);
        $search = str_replace('\\', '/', $path);
        $destination = str_replace('/' . $namespace, '', $search, $c);
        if ($c != 1) {
            throw new \RuntimeException(sprintf('Can\'t find base path for "%s" (path: "%s", destination: "%s").', $name, $path, $destination));
        }

        return $destination;
*/
    }

In Doctrine\ORM\Tools\EntityGenerator.php

    public function writeEntityClass(ClassMetadataInfo $metadata, $outputDirectory)
    {
        // hack fazae for psr-4
        $names= explode("\\", $metadata->name);
        $name=  array_pop($names);
        $path = $outputDirectory . '/' . $name . $this->extension;
//        $path = $outputDirectory . '/' . str_replace('\\', DIRECTORY_SEPARATOR, $metadata->name) . $this->extension;
        // end of hack
        $dir = dirname($path);
       ...

In Doctrine\ORM\Tools\EntityRepositoryGenerator.php

    public function writeEntityRepositoryClass($fullClassName, $outputDirectory)
    {
        $code = $this->generateEntityRepositoryClass($fullClassName);

        // hack fazae for psr-4
        $names= explode("\\", $fullClassName);
        $name=  array_pop($names);
        $path = $outputDirectory . DIRECTORY_SEPARATOR  . str_replace('\\', \DIRECTORY_SEPARATOR, $name) . '.php';
//        $path = $outputDirectory . DIRECTORY_SEPARATOR
//              . str_replace('\\', \DIRECTORY_SEPARATOR, $fullClassName) . '.php';
        // end of hack

It works with psr-4 and i can do "app/console doctrine:generate:entities myBundle:myEntity"
Warning: entities are in folder: mybundle/Entity/myEntity.php

@fpiccinali
Copy link

What about customize doctrine:generate:entities ?

Instead of rebuild all doctrine with psr-4 support - witch seems complicated -, what about adding an argument to the command in order to activate folders mode :

  • mode with "namespaced folders"
  • mode with "direct folders"

This way each one can select the way it prefer ?

@janvennemann
Copy link

Here is a fix for PSR-4 compatibility which acts as an optional lookup before the default PSR-1 path generation. It uses the composer autoloader to check for registered PSR-4 prefix paths. If for some reason no composer autoloader is present it continues to generate base paths the old way. It's therefore fully backwards compatible.

https://gist.github.com/janvennemann/46b2626eee2a4808ed75

The entity and crud controller generators work out of the box with this fix. The path passed to the entity repository generator is still wrong and needs to be fixed, but i don't need that at the moment so i haven't done that yet.

@kirkmadera
Copy link

Thanks @Ocramius for the clarity on why this isn't a priority. The entity generation is great, but you need to generate them elsewhere and copy them over either way (even with PSR-4 support) to avoid overwriting existing entity files which may have additional logic in them. Adding PSR-4 support might lead people to use this over and over again to keep their entities up to date, which could be problematic.

@multifinger
Copy link

Voting for PSR-4 support.
I'm developing several bundles and PSR-4 is the best choice to simplify bundle dirrectory structure
But without PSR-4 support in Doctrine I cant update my entites (and repositories classes as well), so instead of running 1 quick command (that takes no time at all) I need to create class manually, copy all new fields and methods, create repository class. For 10-fields entity it could take up to 1 hour!
So I think this feature is realy must have.
Please support it ...

@Ocramius
Copy link
Member

I cant update my entites

STOP_RE_GENERATING_ENTITIES_BASED_ON_DB_CHANGES

@multifinger
Copy link

I'm generating entities based on *.orm.yml schema.
yml provides more readable view of entity structure rather than php doc

@multifinger
Copy link

adding repositoryClass for example in yml requires to create that class, generate-task can do it for me, but without PSR-4 support i can't do that

@Ocramius
Copy link
Member

Same stuff: you write the entity classes. The code generation was never meant to be used as a "refresh" mechanism, and this scenario is actively considered feature abuse by doctrine core, so we don't support it.

@multifinger
Copy link

OK, what about creating new entities? Generation command is supported feature, so it should work in common cases. PSR-4 has the same rights to work as PSR-0

@Ocramius
Copy link
Member

Ocramius commented Aug 11, 2017 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests