public static function generate(MetaClass $class) { if (!$class->doBuild()) { return null; } $out = ''; $out .= "class " . $class->getName(); $out .= " {\n"; foreach ($class->getProperties() as $property) { $out .= "+get" . ucfirst($property->getName()) . "()\n"; } $out .= "}\n"; if ($class->getParent()) { $out .= $class->getParent()->getName() . " <|-- " . $class->getName() . "\n"; } $out .= "\n"; return $out; }
public static function build(MetaClass $class) { $out = self::getHead(); $out .= "abstract class Auto{$class->getName()}"; $isNamed = false; if ($parent = $class->getParent()) { $out .= " extends {$parent->getName()}"; } elseif ($class->getPattern() instanceof DictionaryClassPattern && $class->hasProperty('name')) { $out .= " extends NamedObject"; $isNamed = true; } elseif (!$class->getPattern() instanceof ValueObjectPattern) { $out .= " extends IdentifiableObject"; } if ($interfaces = $class->getInterfaces()) { $out .= ' implements ' . implode(', ', $interfaces); } $out .= "\n{\n"; foreach ($class->getProperties() as $property) { if (!self::doPropertyBuild($class, $property, $isNamed)) { continue; } $out .= "protected \${$property->getName()} = " . "{$property->getType()->getDeclaration()};\n"; if ($property->getFetchStrategyId() == FetchStrategy::LAZY) { $out .= "protected \${$property->getName()}Id = null;\n"; } } $valueObjects = array(); foreach ($class->getProperties() as $property) { if ($property->getType() instanceof ObjectType && !$property->getType()->isGeneric() && $property->getType()->getClass()->getPattern() instanceof ValueObjectPattern) { $valueObjects[$property->getName()] = $property->getType()->getClassName(); } } if ($valueObjects) { $out .= <<<EOT public function __construct() { EOT; foreach ($valueObjects as $propertyName => $className) { $out .= "\$this->{$propertyName} = new {$className}();\n"; } $out .= "}\n"; } foreach ($class->getProperties() as $property) { if (!self::doPropertyBuild($class, $property, $isNamed)) { continue; } $out .= $property->toMethods($class); } $out .= "}\n"; $out .= self::getHeel(); return $out; }
public static function build(MetaClass $class) { $out = self::getHead(); $parent = $class->getParent(); if ($class->hasBuildableParent()) { $parentName = 'Proto' . $parent->getName(); } else { $parentName = 'AbstractProtoClass'; } $out .= <<<EOT abstract class AutoProto{$class->getName()} extends {$parentName} { EOT; $classDump = self::dumpMetaClass($class); $out .= <<<EOT {$classDump} } EOT; return $out . self::getHeel(); }
/** * @return MetaConfiguration **/ private function checkSanity(MetaClass $class) { if ((!$class->getParent() || $class->getFinalParent()->getPattern() instanceof InternalClassPattern) && !$class->getPattern() instanceof ValueObjectPattern && !$class->getPattern() instanceof InternalClassPattern) { Assert::isTrue($class->getIdentifier() !== null, 'only value objects can live without identifiers. ' . 'do not use them anyway (' . $class->getName() . ')'); } if ($class->getType() && $class->getTypeId() == MetaClassType::CLASS_SPOOKED) { Assert::isFalse(count($class->getProperties()) > 1, 'spooked classes must have only identifier: ' . $class->getName()); Assert::isTrue($class->getPattern() instanceof SpookedClassPattern || $class->getPattern() instanceof SpookedEnumerationPattern, 'spooked classes must use spooked patterns only: ' . $class->getName()); } foreach ($class->getProperties() as $property) { if (!$property->getType()->isGeneric() && $property->getType() instanceof ObjectType && $property->getType()->getClass()->getPattern() instanceof ValueObjectPattern) { Assert::isTrue($property->isRequired(), 'optional value object is not supported:' . $property->getName() . ' @ ' . $class->getName()); Assert::isTrue($property->getRelationId() == MetaRelation::ONE_TO_ONE, 'value objects must have OneToOne relation: ' . $property->getName() . ' @ ' . $class->getName()); } elseif ($property->getFetchStrategyId() == FetchStrategy::LAZY && $property->getType()->isGeneric()) { throw new WrongArgumentException('lazy one-to-one is supported only for ' . 'non-generic object types ' . '(' . $property->getName() . ' @ ' . $class->getName() . ')'); } } return $this; }
public static function buildRelations(MetaClass $class) { $out = null; $knownJunctions = array(); foreach ($class->getAllProperties() as $property) { if ($relation = $property->getRelation()) { $foreignClass = $property->getType()->getClass(); if ($relation->getId() == MetaRelation::ONE_TO_MANY || !$foreignClass->getPattern()->tableExists() || $class->getParent()) { continue; } elseif ($relation->getId() == MetaRelation::MANY_TO_MANY) { $tableName = $class->getTableName() . '_' . $foreignClass->getTableName(); if (isset($knownJunctions[$tableName])) { continue; } else { $knownJunctions[$tableName] = true; } $foreignPropery = clone $foreignClass->getIdentifier(); $name = $class->getName(); $name = strtolower($name[0]) . substr($name, 1); $name .= 'Id'; $foreignPropery->setName($name)->setColumnName($foreignPropery->getConvertedName())->setIdentifier(false); // we don't want any garbage in such tables $property = clone $property; $property->required(); // prevent name collisions if ($property->getRelationColumnName() == $foreignPropery->getColumnName()) { $foreignPropery->setColumnName($class->getTableName() . '_' . $property->getConvertedName() . '_id'); } $out .= <<<EOT \$schema-> \taddTable( \t\tDBTable::create('{$tableName}')-> \t\t{$property->toColumn()}-> \t\t{$foreignPropery->toColumn()}-> \t\taddUniques('{$property->getRelationColumnName()}', '{$foreignPropery->getColumnName()}') \t); EOT; } else { $sourceTable = $class->getTableName(); $sourceColumn = $property->getRelationColumnName(); $targetTable = $foreignClass->getTableName(); $targetColumn = $foreignClass->getIdentifier()->getColumnName(); $out .= <<<EOT // {$sourceTable}.{$sourceColumn} -> {$targetTable}.{$targetColumn} \$schema-> \tgetTableByName('{$sourceTable}')-> \t\tgetColumnByName('{$sourceColumn}')-> \t\t\tsetReference( \t\t\t\t\$schema-> \t\t\t\t\tgetTableByName('{$targetTable}')-> \t\t\t\t\tgetColumnByName('{$targetColumn}'), \t\t\t\tForeignChangeAction::restrict(), \t\t\t\tForeignChangeAction::cascade() \t\t\t); EOT; } } } return $out; }