Skip to content

Commit 3de830a

Browse files
committed
Adding columns defined in actAs-templates to the docblock of the generated model class.
1 parent 1d68711 commit 3de830a

File tree

2 files changed

+118
-12
lines changed

2 files changed

+118
-12
lines changed

lib/Doctrine/Import/Builder.php

Lines changed: 87 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,14 @@ class Doctrine_Import_Builder extends Doctrine_Builder
179179
*/
180180
protected $_phpDocEmail = '##EMAIL##';
181181

182+
183+
/**
184+
* Contains the actAs columns after running buildSetUp
185+
*
186+
* @var array
187+
*/
188+
private $_actAsColumns = array();
189+
182190
/**
183191
* _tpl
184192
*
@@ -396,9 +404,7 @@ public function buildTableDefinition(array $definition)
396404
/**
397405
* buildSetUp
398406
*
399-
* @param array $options
400-
* @param array $columns
401-
* @param array $relations
407+
* @param array $definition
402408
* @return string
403409
*/
404410
public function buildSetUp(array $definition)
@@ -857,21 +863,33 @@ public function buildPhpDocs(array $definition)
857863
return $ret;
858864
}
859865

866+
/**
867+
* find class matching $name
868+
*
869+
* @param $name
870+
* @return string
871+
*/
872+
private function findTemplateClassMatchingName($name)
873+
{
874+
$classname = $name;
875+
if (class_exists("Doctrine_Template_$name", true)) {
876+
$classname = "Doctrine_Template_$name";
877+
}
878+
879+
return $classname;
880+
}
881+
860882
/**
861883
* emit a behavior assign
862884
*
863885
* @param int $level
864886
* @param string $name
865887
* @param string $option
888+
* @param string $classname
866889
* @return string assignation code
867890
*/
868-
private function emitAssign($level, $name, $option)
891+
private function emitAssign($level, $name, $option, $classname)
869892
{
870-
// find class matching $name
871-
$classname = $name;
872-
if (class_exists("Doctrine_Template_$name", true)) {
873-
$classname = "Doctrine_Template_$name";
874-
}
875893
return " \$" . strtolower($name) . "$level = new $classname($option);". PHP_EOL;
876894
}
877895

@@ -943,6 +961,7 @@ private function innerBuildActAs($actAs, $level = 0, $parent = null, array &$emi
943961
$currentParent = $parent;
944962
if (is_array($actAs)) {
945963
foreach($actAs as $template => $options) {
964+
$className = $this->findTemplateClassMatchingName($template);
946965
if ($template == 'actAs') {
947966
// found another actAs
948967
$build .= $this->innerBuildActAs($options, $level + 1, $parent, $emittedActAs);
@@ -959,7 +978,8 @@ private function innerBuildActAs($actAs, $level = 0, $parent = null, array &$emi
959978
}
960979

961980
$optionPHP = $this->varExport($realOptions);
962-
$build .= $this->emitAssign($level, $template, $optionPHP);
981+
$build .= $this->emitAssign($level, $template, $optionPHP, $className);
982+
$this->determineActAsColumns($className, $realOptions);
963983
if ($level == 0) {
964984
$emittedActAs[] = $this->emitActAs($level, $template);
965985
} else {
@@ -969,7 +989,8 @@ private function innerBuildActAs($actAs, $level = 0, $parent = null, array &$emi
969989
$parent = $template;
970990
$build .= $this->innerBuildActAs($leftActAs, $level, $template, $emittedActAs);
971991
} else {
972-
$build .= $this->emitAssign($level, $template, null);
992+
$build .= $this->emitAssign($level, $template, null, $className);
993+
$this->determineActAsColumns($className, array($options));
973994
if ($level == 0) {
974995
$emittedActAs[] = $this->emitActAs($level, $template);
975996
} else {
@@ -979,7 +1000,9 @@ private function innerBuildActAs($actAs, $level = 0, $parent = null, array &$emi
9791000
}
9801001
}
9811002
} else {
982-
$build .= $this->emitAssign($level, $actAs, null);
1003+
$className = $this->findTemplateClassMatchingName($actAs);
1004+
$build .= $this->emitAssign($level, $actAs, null, $className);
1005+
$this->determineActAsColumns($className, array());
9831006
if ($level == 0) {
9841007
$emittedActAs[] = $this->emitActAs($level, $actAs);
9851008
} else {
@@ -990,6 +1013,55 @@ private function innerBuildActAs($actAs, $level = 0, $parent = null, array &$emi
9901013
return $build;
9911014
}
9921015

1016+
/**
1017+
* Adds the columns of the used actAs behaviors to the comment block.
1018+
*
1019+
* @param string $className
1020+
* @param array $instanceOptions
1021+
*
1022+
* @throws Doctrine_Import_Builder_Exception
1023+
*/
1024+
private function determineActAsColumns($className, $instanceOptions)
1025+
{
1026+
// No class specified or class does not exist.
1027+
if (!$className || !class_exists($className)) {
1028+
return;
1029+
}
1030+
1031+
$actAsInstance = new $className($instanceOptions);
1032+
$options = $actAsInstance->getOptions();
1033+
1034+
if (count($options) == 0) {
1035+
return;
1036+
}
1037+
1038+
// Some behaviors do not contain an array of columns, e.g. SoftDelete.
1039+
if (!is_array(reset($options))) {
1040+
$options = array($options);
1041+
}
1042+
1043+
foreach ($options as $name => $column) {
1044+
if (!is_array($column) || !array_key_exists('name', $column) || !array_key_exists('type', $column)) {
1045+
// 'name' or 'type' not found. Unfortunately there is no logger. What is the best way to abort here?
1046+
continue;
1047+
}
1048+
1049+
if (array_key_exists('disabled', $column) && $column['disabled']) {
1050+
// Column has been disabled.
1051+
continue;
1052+
}
1053+
1054+
// Add field, if it does not exist already.
1055+
if (
1056+
!array_key_exists($name, $this->_actAsColumns)
1057+
&& !array_key_exists($column['name'], $this->_actAsColumns)
1058+
) {
1059+
$this->_actAsColumns[$name] = $column;
1060+
}
1061+
}
1062+
}
1063+
1064+
9931065
/**
9941066
* Build php code for adding record listeners
9951067
*
@@ -1122,6 +1194,8 @@ public function buildDefinition(array $definition)
11221194
$className = $definition['className'];
11231195
$extends = isset($definition['inheritance']['extends']) ? $definition['inheritance']['extends']:$this->_baseClassName;
11241196

1197+
// Clear actAsColumns
1198+
$this->_actAsColumns = array();
11251199
if ( ! (isset($definition['no_definition']) && $definition['no_definition'] === true)) {
11261200
$tableDefinitionCode = $this->buildTableDefinition($definition);
11271201
$setUpCode = $this->buildSetUp($definition);
@@ -1136,6 +1210,7 @@ public function buildDefinition(array $definition)
11361210

11371211
$setUpCode.= $this->buildToString($definition);
11381212

1213+
$definition['columns'] = array_merge($definition['columns'], $this->_actAsColumns);
11391214
$docs = PHP_EOL . $this->buildPhpDocs($definition);
11401215

11411216
$content = sprintf(self::$_tpl, $docs, $abstract,

tests/Ticket/gh110TestCase.php

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
<?php
2+
3+
class Doctrine_Ticket_gh110_TestCase extends Doctrine_UnitTestCase
4+
{
5+
public function testAddActAsColumnsToDocBlock()
6+
{
7+
$builder = new Doctrine_Import_Builder();
8+
$class = $builder->buildDefinition(
9+
array(
10+
'className' => 'Ticket_gh110_TestRecord',
11+
'topLevelClassName' => 'Ticket_gh110_TestRecord',
12+
'is_base_class' => true,
13+
'columns' => array(
14+
'id' => array(
15+
'type' => 'integer',
16+
'length' => 4,
17+
)
18+
),
19+
'actAs' => array(
20+
'SoftDelete' => array(),
21+
'Timestampable' => array(),
22+
)
23+
)
24+
);
25+
26+
$this->assertTrue(preg_match('/@property int\s*\$id/', $class));
27+
$this->assertTrue(preg_match('/@property string\s*\$deleted_at/', $class));
28+
$this->assertTrue(preg_match('/@property string\s*\$created_at/', $class));
29+
$this->assertTrue(preg_match('/@property string\s*\$updated_at/', $class));
30+
}
31+
}

0 commit comments

Comments
 (0)