. */ /** * This is the base class for any builder class that is using the data model. * * This could be extended by classes that build SQL DDL, PHP classes, configuration * files, input forms, etc. * * This class has a static method to return the correct builder subclass identified by * a given key. Note that in order for this factory method to work, the properties have to have * been loaded first. Usage should look something like this (from within a AbstractProelDataModelTask subclass): * * * DataModelBuilder::setBuildProperties($this->getPropelProperties()); * $builder = DataModelBuilder::builderFactory($table, 'peer'); * // $builder (by default) instanceof PHP5ComplexPeerBuilder * * * @author Hans Lellelid * @package propel.engine.builder */ abstract class DataModelBuilder { // -------------------------------------------------------------- // Static properties & methods // -------------------------------------------------------------- /** * Build properties (after they've been transformed from "propel.some.name" => "someName"). * @var array string[] */ private static $buildProperties = array(); /** * Sets the [name transformed] build properties to use. * @param array Property values keyed by [transformed] prop names. */ public static function setBuildProperties($props) { self::$buildProperties = $props; } /** * Get a specific [name transformed] build property. * @param string $name * @return string */ public static function getBuildProperty($name) { return isset(self::$buildProperties[$name]) ? self::$buildProperties[$name] : null; } /** * Imports and returns the classname of the builder class for specified 'type'. * @param $type The "key" for class to load. * @return string The unqualified classname. */ public static function getBuilderClass($type) { if (empty(self::$buildProperties)) { throw new BuildException("Cannot determine builder class when no build properties have been loaded (hint: Did you call DataModelBuilder::setBuildProperties(\$props) first?)"); } $propname = 'builder' . ucfirst(strtolower($type)) . 'Class'; $classpath = self::getBuildProperty($propname); if (empty($classpath)) { throw new BuildException("Unable to find class path for '$propname' property."); } // This is a slight hack to workaround camel case inconsistencies for the DDL classes. // Basically, we want to turn ?.?.?.sqliteDDLBuilder into ?.?.?.SqliteDDLBuilder $lastdotpos = strrpos($classpath, '.'); if ($lastdotpos) $classpath[$lastdotpos+1] = strtoupper($classpath[$lastdotpos+1]); else ucfirst($classpath); return Phing::import($classpath); } /** * Factory method to load a new builder instance based on specified type. * @param Table $table * @param $type The "key" for class to load. * @throws BuildException if specified class cannot be found / loaded. */ public static function builderFactory(Table $table, $type) { $classname = self::getBuilderClass($type); return new $classname($table); } /** * Utility function to build a path for use in include()/require() statement. * * Supports two function signatures: * (1) getFilePath($dotPathClass); * (2) getFilePath($dotPathPrefix, $className); * * @param string $path dot-path to class or to package prefix. * @param string $classname class name * @return string */ public static function getFilePath($path, $classname = null, $extension = '.php') { $path = strtr(ltrim($path, '.'), '.', '/'); if ($classname !== null) { if ($path !== "") { $path .= '/'; } return $path . $classname . $extension; } else { return $path . $extension; } } // -------------------------------------------------------------- // Non-static properties & methods inherited by subclasses // -------------------------------------------------------------- /** * The current table. * @var Table */ private $table; /** * An array of warning messages that can be retrieved for display (e.g. as part of phing build process). * @var array string[] */ private $warnings = array(); /** * Creates new instance of DataModelBuilder subclass. * @param Table $table The Table which we are using to build [OM, DDL, etc.]. */ public function __construct(Table $table) { $this->table = $table; } /** * Returns the Platform class for this table (database). * @return Platform */ protected function getPlatform() { return $this->getTable()->getDatabase()->getPlatform(); } /** * Returns the database for current table. * @return Database */ protected function getDatabase() { return $this->getTable()->getDatabase(); } /** * Returns the current Table object. * @return Table */ protected function getTable() { return $this->table; } /** * Pushes a message onto the stack of warnings. * @param string $msg The warning message. */ protected function warn($msg) { $this->warnings[] = $msg; } /** * Gets array of warning messages. * @return array string[] */ public function getWarnings() { return $this->warnings; } /** * Wraps call to Platform->quoteIdentifier() with a check to see whether quoting is enabled. * * All subclasses should call this quoteIdentifier() method rather than calling the Platform * method directly. This method is used by both DataSQLBuilder and DDLBuilder, and potentially * in the OM builders also, which is why it is defined in this class. * * @param string $text The text to quote. * @return string Quoted text. */ public function quoteIdentifier($text) { if (!self::getBuildProperty('disableIdentifierQuoting')) { return $this->getPlatform()->quoteIdentifier($text); } return $text; } }