How to add custom code to Doctrine’s Model Generator.

When I start a Flex/Doctrine project, I create the DB model using MySQL Workbench. From there, I’ll use the Doctrine MySQL Workbench plugin (slightly modified) to create my YAML file. I’ll then run the Doctrine::generateModelsFromYaml function to create my models.

After generating the model classes, the one thing I used to have to do manually is add the _explicitType property to my top level classes as such:

class User extends BaseUser{
	public function construct(){
		$this->mapValue("_explicitType","com.persistence.User");
	}
}

If you want to automate this step or add something completely different you can edit the “buildDefinition” function in Doctrine/Import/Builder.php. I simply added my edits to the $tableDefinitionCode variable.
NOTE: This particular hack only inserts your custom code in your top level class and not in your base classes.
Here’s what my modified version looks like to get the example above:

        public function buildDefinition(array $definition)
    {
        if ( ! isset($definition['className'])) {
            throw new Doctrine_Import_Builder_Exception('Missing class name.');
        }
        $abstract = isset($definition['abstract']) && $definition['abstract'] === true ? 'abstract ':null;
        $className = $definition['className'];
        $extends = isset($definition['inheritance']['extends']) ? $definition['inheritance']['extends']:$this->_baseClassName;
 
        if ( ! (isset($definition['no_definition']) && $definition['no_definition'] === true)) {
            $tableDefinitionCode = $this->buildTableDefinition($definition);
            $setUpCode = $this->buildSetUp($definition);
        } else {
        	//This is the top level class where we can do some custom coding.
			$tableDefinitionCode = PHP_EOL . 
'	public function construct(){
		$this->mapValue("_explicitType","com.persistence.' . $className . '");
	}';
 
			$setUpCode = null;
        }
 
        if ($tableDefinitionCode && $setUpCode) {
            $setUpCode = PHP_EOL . $setUpCode;
        }
 
 
        $docs = PHP_EOL . $this->buildPhpDocs($definition);
 
        $content = sprintf(self::$_tpl, $docs, $abstract,
                                       $className,
                                       $extends,
                                       $tableDefinitionCode,
                                       $setUpCode);
 
        return $content;
    }

Since I always have unique class names, I randomly picked “com.persistence” as my _explicitType package name because it’s strictly used for hydrating the object on the Flex side of AMF and doesn’t necessarily need to represent the actual location of the PHP class/service. So as long as my Flexa DTO/VO has the metadata [RemoteClass(alias=”com.persistence.User”)] set, it’ll come back to Flex correctly typed and not a generic object.