-
Notifications
You must be signed in to change notification settings - Fork 2
Midgard Compatibility Notes
This library currently contains the following Midgard API functionality:
- Creating Doctrine ClassMetadata and
midgard_dbobjectbased Entity classes from MgdSchema XML files - Support for most of the
midgard_objectAPI (CRUD, parameters, attachments, parent/up relations, softdelete, etc.) - Query Support for
midgard_query_builder,midgard_collectorandmidgard_object_class - Metadata support, Repligard,
midgard_blob,midgard_user - Partial support for database creation/update (
midgard_storage) and reflection (midgard_reflection_property,midgard_reflector_object)
This is all that is needed to run openpsa. Both older Midgard features (like MultiLang or Sitegroups) and newer features (like Workspaces) are out of scope, but Pull Requests are of course welcome, so if anyone feels motivated to work on those areas, go right ahead!
Basically, the adapter consists of three parts: The XML reader, which transforms MgdSchema files into an intermediate representation, the class generator, which converts it into PHP classes that correspond to Midgard DB object classes (and that are used by Doctrine as entity classes) and lastly, the Metadata driver, which builds the ClassMetadata information Doctrine uses for querying and hydrating data.
Apart from that, there is a bunch of helper classes that provide special Midgard behaviors for Doctrine in the form of a Query Filter, an Event Subscriber and one special Type currently. And of course there are versions of (most of) Midgard's PHP classes, which provide the actual API emulation.
-
Entities in Doctrine can only share the same table if there is a discriminator column which tells them apart. Currently, midgard-portable works around this by only registering one of the colliding classes which collects all properties of all affected classes. The others are then converted into aliases. This means that if you have e.g.
midgard_personandorg_openpsa_personschemas, you only get one entity class containing the properties of both classes, and an a class alias for the second name. The classes are sorted alphabetically before merging, the first one will become the actual class and the rest will be aliases.For the collected properties, some limitations apply: For example, if two MgdSchema classes using the same DB table both define a property with the PHP name
myfield, but they both point to a differentdbfield, one of them will become unreachable. Also, if two MgdSchema classes define different field types for the same field (e.g.stringvs.texton a field namedextra), only one of these definitions will be used. The latter case may be implementable in the adapter, but it really is not a solid configuration to begin with (as it could theoretically lead to data loss), so this is not in the cards for now -
Links to non-PK fields are not supported in Doctrine. So GUID-based link functionality is implemented in the adapter, which entails a performance penalty. Also, some cases (like parent GUID links) are not supported yet
-
Metadata simulation is somewhat imperfect in the sense that the metadata columns are accessible through the object itself (e.g.
$topic->metadata_deleted). This will be changed once we start utilizing embedded objects (Embeddable) from Doctrine ORM 2.5.
-
It is not possible to run midgard-portable when the original Midgard (or Midgard2) extension is loaded. Even if we could work around the extensions' segfaults, it likely wouldn't do any good, since the extension registers all its classes on PHP startup, so that the midgard-portable's classes would never get loaded.
-
Doctrine is somewhat stricter when it comes to referential integrity. So some of the more quirky behaviors of Midgard (like being able to purge parents while deleted children are still in the database) are more or less impossible to implement with reasonable effort. Unfortunately, the exception thrown in those cases is rather cryptic, and normally says something like
A new entity was found through the relationship 'classname#link_property' that was not configured to cascade persist operations for entity
-
Doctrine does not support public properties on entity classes, so using
get_object_vars()will always return an empty result. Obviously,ReflectionExtension('midgard2')will also fail, so you can't use this to get a list of all registered MgdSchema classes. As a workaround, you can use midgard-introspection, which abstracts these differences away. -
Do not try to call
print_r(),var_dump()or similar functions on entities when using PHP 5.5 or earlier. This applies to all Doctrine entities and is not specific to midgard-portable, but it is worth remembering if you try to run code originally written for the Midgard extension. midgard-introspection contains aprint_r()method you can use instead.
-
Association fields (i.e. fields with
linkin the MgdSchema definition) must be marked as nullable in the database. It is impossible to get Doctrine to accept0as a value. So existing database tables must be updated. You can do so by running themidgard-portable schemacommand -
When converting a Midgard1 database directly to midgard-portable (with
openpsa/installer), the primary key of the repligard table will change. In some situations, Doctrine may not be able to do this automatically, if you get an exception during the conversion, you can work around it by removing the primary key directly from the database -
newer MySQL version will throw
SQLSTATE[22007]: Invalid datetime formaterrors on converted legacy databases, you can get around them by adding:
'driverOptions' => [
1002 => "SET SESSION sql_mode='ALLOW_INVALID_DATES'"
],to your $db_config