Skip to content

Commit

Permalink
Adding columns defined in actAs-templates to the docblock of the gene…
Browse files Browse the repository at this point in the history
…rated model class.
  • Loading branch information
thirsch committed Jan 23, 2024
1 parent 33bebf2 commit 69fefea
Show file tree
Hide file tree
Showing 2 changed files with 104 additions and 18 deletions.
91 changes: 73 additions & 18 deletions lib/Doctrine/Import/Builder.php
Original file line number Diff line number Diff line change
Expand Up @@ -396,12 +396,11 @@ public function buildTableDefinition(array $definition)
/**
* buildSetUp
*
* @param array $options
* @param array $columns
* @param array $relations
* @param array $definition
* @param array $actAsColumns
* @return string
*/
public function buildSetUp(array $definition)
public function buildSetUp(array $definition, array &$actAsColumns = array())
{
$ret = array();
$i = 0;
Expand Down Expand Up @@ -483,7 +482,7 @@ public function buildSetUp(array $definition)
}

if (isset($definition['actAs']) && is_array($definition['actAs']) && !empty($definition['actAs'])) {
$ret[$i] = $this->buildActAs($definition['actAs']);
$ret[$i] = $this->buildActAs($definition['actAs'], $actAsColumns);
$i++;
}

Expand Down Expand Up @@ -640,8 +639,9 @@ public function buildAccessors(array $definition)
* Build the phpDoc for a class definition
*
* @param array $definition
* @param array $actAsColumns
*/
public function buildPhpDocs(array $definition)
public function buildPhpDocs(array $definition, array $actAsColumns = array())
{
$ret = array();
$ret[] = $definition['className'];
Expand All @@ -654,7 +654,7 @@ public function buildPhpDocs(array $definition)
$setters = array();

if ((isset($definition['is_base_class']) && $definition['is_base_class']) || ! $this->generateBaseClasses()) {
foreach ($definition['columns'] as $name => $column) {
foreach (array_merge($definition['columns'], $actAsColumns) as $name => $column) {
$name = isset($column['name']) ? $column['name']:$name;
// extract column name & field name
if (stripos($name, ' as '))
Expand Down Expand Up @@ -865,7 +865,7 @@ public function buildPhpDocs(array $definition)
* @param string $option
* @return string assignation code
*/
private function emitAssign($level, $name, $option)
private function emitAssign($level, $name, $option, &$classname)
{
// find class matching $name
$classname = $name;
Expand Down Expand Up @@ -904,11 +904,12 @@ private function emitActAs($level, $name)
/**
* buildActAs: builds a complete actAs code. It supports hierarchy of plugins
* @param array $actAs array of plugin definitions and options
* @param array $actAsColumns contains on output an array of columns defined by actAs behaviors
*/
public function buildActAs($actAs)
public function buildActAs($actAs, array &$actAsColumns = array())
{
$emittedActAs = array();
$build = $this->innerBuildActAs($actAs, 0, null, $emittedActAs);
$build = $this->innerBuildActAs($actAs, 0, null, $emittedActAs, $actAsColumns);
foreach($emittedActAs as $str) {
$build .= $str;
}
Expand All @@ -922,9 +923,10 @@ public function buildActAs($actAs)
* @param int $level current indentation level
* @param string $parent name of the parent template/plugin
* @param array $emittedActAs contains on output an array of actAs command to be appended to output
* @param array $actAsColumns contains on output an array of columns defined by actAs behaviors
* @return string actAs full definition
*/
private function innerBuildActAs($actAs, $level = 0, $parent = null, array &$emittedActAs = array())
private function innerBuildActAs($actAs, $level = 0, $parent = null, array &$emittedActAs = array(), array &$actAsColumns = array())
{
// rewrite special case of actAs: [Behavior] which gave [0] => Behavior
if (is_array($actAs) && isset($actAs[0]) && !is_array($actAs[0])) {
Expand All @@ -945,7 +947,7 @@ private function innerBuildActAs($actAs, $level = 0, $parent = null, array &$emi
foreach($actAs as $template => $options) {
if ($template == 'actAs') {
// found another actAs
$build .= $this->innerBuildActAs($options, $level + 1, $parent, $emittedActAs);
$build .= $this->innerBuildActAs($options, $level + 1, $parent, $emittedActAs, $actAsColumns);
} else if (is_array($options)) {
// remove actAs from options
$realOptions = array();
Expand All @@ -959,17 +961,19 @@ private function innerBuildActAs($actAs, $level = 0, $parent = null, array &$emi
}

$optionPHP = $this->varExport($realOptions);
$build .= $this->emitAssign($level, $template, $optionPHP);
$build .= $this->emitAssign($level, $template, $optionPHP, $className);
$this->addActAsColumnsToDefinition($className, $realOptions, $actAsColumns);
if ($level == 0) {
$emittedActAs[] = $this->emitActAs($level, $template);
} else {
$build .= $this->emitAddChild($level, $currentParent, $template);
}
// descend for the remainings actAs
$parent = $template;
$build .= $this->innerBuildActAs($leftActAs, $level, $template, $emittedActAs);
$build .= $this->innerBuildActAs($leftActAs, $level, $template, $emittedActAs, $actAsColumns);
} else {
$build .= $this->emitAssign($level, $template, null);
$build .= $this->emitAssign($level, $template, null, $className);
$this->addActAsColumnsToDefinition($className, array($options), $actAsColumns);
if ($level == 0) {
$emittedActAs[] = $this->emitActAs($level, $template);
} else {
Expand All @@ -979,7 +983,8 @@ private function innerBuildActAs($actAs, $level = 0, $parent = null, array &$emi
}
}
} else {
$build .= $this->emitAssign($level, $actAs, null);
$build .= $this->emitAssign($level, $actAs, null, $className);
$this->addActAsColumnsToDefinition($className, array(), $actAsColumns);
if ($level == 0) {
$emittedActAs[] = $this->emitActAs($level, $actAs);
} else {
Expand All @@ -990,6 +995,55 @@ private function innerBuildActAs($actAs, $level = 0, $parent = null, array &$emi
return $build;
}

/**
* Adds the columns of the used actAs behaviors to the comment block.
*
* @param string $className
* @param array $instanceOptions
* @param array $actAsColumns
*
* @throws Doctrine_Import_Builder_Exception
*/
private function addActAsColumnsToDefinition($className, $instanceOptions, &$actAsColumns)
{
if ($className && class_exists($className)) {
$actAsInstance = new $className($instanceOptions);
$options = $actAsInstance->getOptions();

if (count($options) == 0) {
return;
}

// Some behaviors do not contain an array of columns, e.g. SoftDelete.
if (!is_array(reset($options))) {
$options = [$options];
}

foreach ($options as $name => $column) {
if (!is_array($column) || !array_key_exists('name', $column) || !array_key_exists('type', $column)) {
// 'name' or 'type' not found. Unfortunately there is no logger. What is the best way to abort here?
continue;
}

if (array_key_exists('disabled', $column) && $column['disabled']) {
// Column has been disabled.
continue;
}

// Add field, if it does not exist already.
if (
!array_key_exists($name, $actAsColumns)
&& !array_key_exists($column['name'], $actAsColumns)
) {
$actAsColumns[$name] = $column;
}
}
} else {
throw new Doctrine_Import_Builder_Exception('Missing class for actAs ' . $className . '.');
}
}


/**
* Build php code for adding record listeners
*
Expand Down Expand Up @@ -1122,9 +1176,10 @@ public function buildDefinition(array $definition)
$className = $definition['className'];
$extends = isset($definition['inheritance']['extends']) ? $definition['inheritance']['extends']:$this->_baseClassName;

$actAsColumns = array();
if ( ! (isset($definition['no_definition']) && $definition['no_definition'] === true)) {
$tableDefinitionCode = $this->buildTableDefinition($definition);
$setUpCode = $this->buildSetUp($definition);
$setUpCode = $this->buildSetUp($definition, $actAsColumns);
} else {
$tableDefinitionCode = null;
$setUpCode = null;
Expand All @@ -1136,7 +1191,7 @@ public function buildDefinition(array $definition)

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

$docs = PHP_EOL . $this->buildPhpDocs($definition);
$docs = PHP_EOL . $this->buildPhpDocs($definition, $actAsColumns);

$content = sprintf(self::$_tpl, $docs, $abstract,
$className,
Expand Down
31 changes: 31 additions & 0 deletions tests/Ticket/gh110TestCase.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<?php

class Doctrine_Ticket_gh110_TestCase extends Doctrine_UnitTestCase
{
public function testAddActAsColumnsToDocBlock()
{
$builder = new Doctrine_Import_Builder();
$class = $builder->buildDefinition(
array(
'className' => 'Ticket_gh110_TestRecord',
'topLevelClassName' => 'Ticket_gh110_TestRecord',
'is_base_class' => true,
'columns' => array(
'id' => array(
'type' => 'integer',
'length' => 4,
)
),
'actAs' => array(
'SoftDelete' => array(),
'Timestampable' => array(),
)
)
);

$this->assertTrue(preg_match('/@property int\s*\$id/', $class));
$this->assertTrue(preg_match('/@property string\s*\$deleted_at/', $class));
$this->assertTrue(preg_match('/@property string\s*\$created_at/', $class));
$this->assertTrue(preg_match('/@property string\s*\$updated_at/', $class));
}
}

0 comments on commit 69fefea

Please sign in to comment.