Doctrine is affected by PHP bug #62577. simplexml_load_file is not
able to load files if libxml_disable_entity_loader(true) has been
called. simplexml_load_file fails with the message:
I/O warning : failed to load external entity "/my/mappings/my_entity.dcm.xml"
in /path-to/lib/Doctrine/ORM/Mapping/Driver/XmlDriver.php on line 711
This error occurs even if there are no external entities in the XML file.
Waiting for the PHP bug to be resolved is infeasible, because it is
unresolved since years. Therefore Doctrine needs to circumvent the bug
by replacing simplexml_load_file with simplexml_load_string while getting
the file contents itself. simplexml_load_string is not affected by the
PHP bug.
The `ClassMetadataInfo` was always using the "current class" to
fetch the reflection of a property even when a field is declared
on the parent class (which causes `ReflectionProperty` to throw
an exception).
ConvertMappingCommand and GenerateEntitiesCommand both use the DisconnectedClassMetadataFactory, which allows metadata manipulation without loading the associated classes. Commit a36bea broke these two commands by adding a bailout condition in ClassMetadataFactory::populateDiscriminatorValue which checks $metadata->reflClass->isAbstract(). If the DisconnectedClassMetadataFactory is being used, $metadata->reflClass will always be null, causing a fatal error, "Fatal error: Call to a member function isAbstract() on null".
This commit adds a check to see if $metadata->reflClass is set before checking isAbstract.
initialize() is called sometimes, even when the following code doesn't need
the targetPlatform property. Specifically, in AbstractClassMetadataFactory::getAllMetadata().
But as of DBAL 2.5.0, calling Connection::getDatabasePlatform() will make a
connection to the database, which means that sometimes it may fail (e.g. you
haven't configured your database yet). As a result, calling a method like
AbstractClassMetadataFactory::getAllMetadata() - which does not need the
targetPlatform - will fail, because determining the targetPlatform requires
a connection, which fails.
This avoids that - we only get the targetPlatform *when* we need it, which
are cases where we're doing things that do indeed need a connection.