Go to the documentation of this file.00001 <?php
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00015 class MetaClassProperty
00016 {
00017 private $class = null;
00018
00019 private $name = null;
00020 private $columnName = null;
00021
00022 private $type = null;
00023 private $size = null;
00024
00025 private $required = false;
00026 private $identifier = false;
00027
00028 private $relation = null;
00029
00030 private $strategy = null;
00031
00032 public function __construct(
00033 $name,
00034 BasePropertyType $type,
00035 MetaClass $class
00036 )
00037 {
00038 $this->name = $name;
00039
00040 $this->type = $type;
00041
00042 $this->class = $class;
00043 }
00044
00045 public function equals(MetaClassProperty $property)
00046 {
00047 return (
00048 ($property->getName() == $this->getName())
00049 && ($property->getColumnName() == $this->getColumnName())
00050 && ($property->getType() == $this->getType())
00051 && ($property->getSize() == $this->getSize())
00052 && ($property->getRelation() == $this->getRelation())
00053 && ($property->isRequired() == $this->isRequired())
00054 && ($property->isIdentifier() == $this->isIdentifier())
00055 );
00056 }
00057
00061 public function getClass()
00062 {
00063 return $this->class;
00064 }
00065
00066 public function getName()
00067 {
00068 return $this->name;
00069 }
00070
00074 public function setName($name)
00075 {
00076 $this->name = $name;
00077
00078 return $this;
00079 }
00080
00081 public function getColumnName()
00082 {
00083 return $this->columnName;
00084 }
00085
00089 public function setColumnName($name)
00090 {
00091 $this->columnName = $name;
00092
00093 return $this;
00094 }
00095
00099 public function getConvertedName()
00100 {
00101 return strtolower(
00102 preg_replace(':([A-Z]):', '_\1', $this->name)
00103 );
00104 }
00105
00109 public function getType()
00110 {
00111 return $this->type;
00112 }
00113
00114 public function getSize()
00115 {
00116 return $this->size;
00117 }
00118
00123 public function setSize($size)
00124 {
00125 if ($this->type instanceof NumericType) {
00126 if (strpos($size, ',') !== false) {
00127 list($size, $precision) = explode(',', $size, 2);
00128
00129 $this->type->setPrecision($precision);
00130 }
00131 }
00132
00133 Assert::isInteger(
00134 $size,
00135 'only integers allowed in size parameter'
00136 );
00137
00138 if ($this->type->isMeasurable()) {
00139 $this->size = $size;
00140 } else
00141 throw new WrongArgumentException(
00142 "size not allowed for '"
00143 .$this->getName().'::'.get_class($this->type)
00144 ."' type"
00145 );
00146
00147 return $this;
00148 }
00149
00150 public function isRequired()
00151 {
00152 return $this->required;
00153 }
00154
00155 public function isOptional()
00156 {
00157 return !$this->required;
00158 }
00159
00163 public function required()
00164 {
00165 $this->required = true;
00166
00167 return $this;
00168 }
00169
00173 public function optional()
00174 {
00175 $this->required = false;
00176
00177 return $this;
00178 }
00179
00180 public function isIdentifier()
00181 {
00182 return $this->identifier;
00183 }
00184
00188 public function setIdentifier($really = false)
00189 {
00190 $this->identifier = ($really === true);
00191
00192 return $this;
00193 }
00194
00198 public function getRelation()
00199 {
00200 return $this->relation;
00201 }
00202
00203 public function getRelationId()
00204 {
00205 if ($this->relation)
00206 return $this->relation->getId();
00207
00208 return null;
00209 }
00210
00214 public function setRelation(MetaRelation $relation)
00215 {
00216 $this->relation = $relation;
00217
00218 return $this;
00219 }
00220
00224 public function setFetchStrategy(FetchStrategy $strategy)
00225 {
00226 $this->strategy = $strategy;
00227
00228 return $this;
00229 }
00230
00234 public function getFetchStrategy()
00235 {
00236 return $this->strategy;
00237 }
00238
00239 public function getFetchStrategyId()
00240 {
00241 if ($this->strategy)
00242 return $this->strategy->getId();
00243 elseif (
00244 $this->getClass()->getFetchStrategyId()
00245 && ($this->getRelationId() == MetaRelation::ONE_TO_ONE)
00246 && ($this->getType() instanceof ObjectType)
00247 && (!$this->getType()->isGeneric())
00248 )
00249 return $this->getClass()->getFetchStrategyId();
00250
00251 return null;
00252 }
00253
00254 public function toMethods(
00255 MetaClass $class,
00256 MetaClassProperty $holder = null
00257 )
00258 {
00259 return $this->type->toMethods($class, $this, $holder);
00260 }
00261
00262 public function getRelationColumnName()
00263 {
00264 if ($this->type instanceof ObjectType && !$this->type->isGeneric()) {
00265 if ($this->relation->getId() == MetaRelation::MANY_TO_MANY)
00266 $columnName = $this->type->getClass()->getTableName().'_id';
00267 else
00268 $columnName = $this->getColumnName();
00269 } elseif ($this->type instanceof InternalType) {
00270 $out = array();
00271 foreach ($this->type->getSuffixList() as $suffix) {
00272 $out[] = $this->getColumnName().'_'.$suffix;
00273 }
00274 return $out;
00275 } else
00276 $columnName = $this->getColumnName();
00277
00278 return $columnName;
00279 }
00280
00281 public function toColumn()
00282 {
00283 if (
00284 $this->getType() instanceof ObjectType
00285 && (
00286 ($this->getType() instanceof InternalType)
00287 || (
00288 !$this->getType()->isGeneric()
00289 && (
00290 $this->getType()->getClass()->getPattern()
00291 instanceof ValueObjectPattern
00292 )
00293 )
00294 )
00295 ) {
00296 $columns = array();
00297
00298 $prefix =
00299 $this->getType() instanceof InternalType
00300 ? $this->getColumnName().'_'
00301 : null;
00302
00303 $remote = $this->getType()->getClass();
00304
00305 foreach ($remote->getAllProperties() as $property) {
00306 $columns[] = $property->buildColumn(
00307 $prefix.$property->getRelationColumnName()
00308 );
00309 }
00310
00311 return $columns;
00312 }
00313
00314 return $this->buildColumn($this->getRelationColumnName());
00315 }
00316
00317 public function toLightProperty(MetaClass $holder)
00318 {
00319 $className = null;
00320
00321 if (
00322 ($this->getRelationId() == MetaRelation::ONE_TO_MANY)
00323 || ($this->getRelationId() == MetaRelation::MANY_TO_MANY)
00324 ) {
00325
00326 $primitiveName = 'identifierList';
00327 } elseif ($this->isIdentifier()) {
00328 if ($this->getType() instanceof IntegerType) {
00329 $primitiveName = 'integerIdentifier';
00330 $className = $holder->getName();
00331 } elseif ($this->getType() instanceof StringType) {
00332 $primitiveName = 'scalarIdentifier';
00333 $className = $holder->getName();
00334 } else
00335 $primitiveName = $this->getType()->getPrimitiveName();
00336 } elseif (
00337 !$this->isIdentifier()
00338 && !$this->getType()->isGeneric()
00339 && ($this->getType() instanceof ObjectType)
00340 ) {
00341 $pattern = $this->getType()->getClass()->getPattern();
00342
00343 if ($pattern instanceof EnumerationClassPattern) {
00344 $primitiveName = 'enumeration';
00345 } elseif (
00346 $pattern instanceof DictionaryClassPattern
00347 && ($identifier = $this->getType()->getClass()->getIdentifier())
00348 ) {
00349 if ($identifier->getType() instanceof IntegerType) {
00350 $primitiveName = 'integerIdentifier';
00351 } elseif ($identifier->getType() instanceof StringType) {
00352 $primitiveName = 'scalarIdentifier';
00353 } else
00354 $primitiveName = $this->getType()->getPrimitiveName();
00355 } else
00356 $primitiveName = $this->getType()->getPrimitiveName();
00357 } else
00358 $primitiveName = $this->getType()->getPrimitiveName();
00359
00360 $inner = false;
00361
00362 if ($this->getType() instanceof ObjectType) {
00363 $className = $this->getType()->getClassName();
00364
00365 if (!$this->getType()->isGeneric()) {
00366 $class = $this->getType()->getClass();
00367 $pattern = $class->getPattern();
00368
00369 if ($pattern instanceof InternalClassPattern)
00370 $className = $holder->getName();
00371
00372 if (
00373 (
00374 ($pattern instanceof InternalClassPattern)
00375 || ($pattern instanceof ValueObjectPattern)
00376 ) && (
00377 $className <> $holder->getName()
00378 )
00379 ) {
00380 $inner = true;
00381 }
00382 }
00383 }
00384
00385 $propertyClassName = (
00386 $inner
00387 ? 'InnerMetaProperty'
00388 : 'LightMetaProperty'
00389 );
00390
00391 if (
00392 ($this->getType() instanceof IntegerType)
00393 ) {
00394 $size = $this->getType()->getSize();
00395 } elseif (
00396 ($this->getType() instanceof ObjectType)
00397 && ($this->getRelationId() == MetaRelation::ONE_TO_ONE)
00398 && ($identifier = $this->getType()->getClass()->getIdentifier())
00399 && ($this->getType()->isMeasurable())
00400 ) {
00401 $size = $identifier->getType()->getSize();
00402 } elseif ($this->getType()->isMeasurable()) {
00403 $size = $this->size;
00404 } else {
00405 $size = null;
00406 }
00407
00408 return
00409 call_user_func_array(
00410 array($propertyClassName, 'fill'),
00411 array(
00412 new $propertyClassName,
00413 $this->getName(),
00414 $this->getName() <> $this->getRelationColumnName()
00415 ? $this->getRelationColumnName()
00416 : null,
00417 $primitiveName,
00418 $className,
00419 $size,
00420 $this->isRequired(),
00421 $this->getType()->isGeneric(),
00422 $inner,
00423 $this->getRelationId(),
00424 $this->getFetchStrategyId()
00425 )
00426 );
00427 }
00428
00429 private function buildColumn($columnName)
00430 {
00431 if (is_array($columnName)) {
00432 $out = array();
00433
00434 foreach ($columnName as $name) {
00435 $out[] = $this->buildColumn($name);
00436 }
00437
00438 return $out;
00439 }
00440
00441 $column = <<<EOT
00442 addColumn(
00443 DBColumn::create(
00444 {$this->type->toColumnType($this->size)}
00445 EOT;
00446
00447 if ($this->required) {
00448 $column .= <<<EOT
00449 ->
00450 setNull(false)
00451 EOT;
00452 }
00453
00454 if ($this->size) {
00455 $column .= <<<EOT
00456 ->
00457 setSize({$this->size})
00458 EOT;
00459 }
00460
00461 if ($this->type instanceof NumericType) {
00462 $column .= <<<EOT
00463 ->
00464 setPrecision({$this->type->getPrecision()})
00465 EOT;
00466 }
00467
00468 $column .= <<<EOT
00469 ,
00470 '{$columnName}'
00471 )
00472 EOT;
00473
00474 if ($this->identifier) {
00475 $column .= <<<EOT
00476 ->
00477 setPrimaryKey(true)
00478 EOT;
00479
00480 if ($this->getType() instanceof IntegerType) {
00481 $column .= <<<EOT
00482 ->
00483 setAutoincrement(true)
00484 EOT;
00485 }
00486 }
00487
00488 if ($this->type->hasDefault()) {
00489 $default = $this->type->getDefault();
00490
00491 if ($this->type instanceof BooleanType) {
00492 if ($default)
00493 $default = 'true';
00494 else
00495 $default = 'false';
00496 } elseif ($this->type instanceof StringType) {
00497 $default = "'{$default}'";
00498 }
00499
00500 $column .= <<<EOT
00501 ->
00502 setDefault({$default})
00503 EOT;
00504 }
00505
00506 $column .= <<<EOT
00507
00508 )
00509 EOT;
00510
00511 return $column;
00512 }
00513
00514 private function toVarName($name)
00515 {
00516 return strtolower($name[0]).substr($name, 1);
00517 }
00518 }
00519 ?>