@@ -396,12 +396,11 @@ public function buildTableDefinition(array $definition)
396396    /** 
397397     * buildSetUp 
398398     * 
399-      * @param  array $options 
400-      * @param  array $columns 
401-      * @param  array $relations 
399+      * @param  array $definition 
400+      * @param  array $actAsColumns 
402401     * @return string 
403402     */ 
404-     public  function  buildSetUp (array  $ definition )
403+     public  function  buildSetUp (array  $ definition,  array  & $ actAsColumns  =  array () )
405404    {
406405        $ ret  = array ();
407406        $ i  = 0 ;
@@ -483,7 +482,7 @@ public function buildSetUp(array $definition)
483482        }
484483
485484        if  (isset ($ definition ['actAs ' ]) && is_array ($ definition ['actAs ' ]) && !empty ($ definition ['actAs ' ])) {
486-             $ ret [$ i ] = $ this  ->buildActAs ($ definition ['actAs ' ]);
485+             $ ret [$ i ] = $ this  ->buildActAs ($ definition ['actAs ' ],  $ actAsColumns  );
487486            $ i ++;
488487        }
489488
@@ -640,8 +639,9 @@ public function buildAccessors(array $definition)
640639     * Build the phpDoc for a class definition 
641640     * 
642641     * @param  array  $definition 
642+      * @param  array  $actAsColumns 
643643     */ 
644-     public  function  buildPhpDocs (array  $ definition )
644+     public  function  buildPhpDocs (array  $ definition,  array   $ actAsColumns  =  array () )
645645    {
646646        $ ret  = array ();
647647        $ ret [] = $ definition ['className ' ];
@@ -654,7 +654,7 @@ public function buildPhpDocs(array $definition)
654654        $ setters   = array ();
655655
656656        if  ((isset ($ definition ['is_base_class ' ]) && $ definition ['is_base_class ' ]) || ! $ this  ->generateBaseClasses ()) {
657-             foreach  ($ definition ['columns ' ] as  $ name  => $ column ) {
657+             foreach  (array_merge ( $ definition ['columns ' ],  $ actAsColumns )  as  $ name  => $ column ) {
658658                $ name  = isset ($ column ['name ' ]) ? $ column ['name ' ]:$ name ;
659659                // extract column name & field name 
660660                if  (stripos ($ name , ' as  ' ))
@@ -857,21 +857,33 @@ public function buildPhpDocs(array $definition)
857857        return  $ ret ;
858858    }
859859
860+     /** 
861+      * find class matching $name 
862+      * 
863+      * @param $name 
864+      * @return string 
865+      */ 
866+     private  function  findTemplateClassMatchingName ($ name )
867+     {
868+         $ classname  = $ name ;
869+         if  (class_exists ("Doctrine_Template_ $ name " , true )) {
870+             $ classname  = "Doctrine_Template_ $ name " ;
871+         }
872+ 
873+         return  $ classname ;
874+     }
875+ 
860876    /** 
861877     * emit a behavior assign 
862878     * 
863879     * @param int $level 
864880     * @param string $name 
865881     * @param string $option 
882+      * @param string $classname 
866883     * @return string assignation code 
867884     */ 
868-     private  function  emitAssign ($ level , $ name , $ option )
885+     private  function  emitAssign ($ level , $ name , $ option,  $ classname  )
869886    {
870-         // find class matching $name 
871-         $ classname  = $ name ;
872-         if  (class_exists ("Doctrine_Template_ $ name " , true )) {
873-             $ classname  = "Doctrine_Template_ $ name " ;
874-         }
875887        return  "         \$"  . strtolower ($ name ) . "$ level = new  $ classname( $ option); " . PHP_EOL ;
876888    }
877889
@@ -904,11 +916,12 @@ private function emitActAs($level, $name)
904916    /** 
905917     * buildActAs: builds a complete actAs code. It supports hierarchy of plugins 
906918     * @param array $actAs array of plugin definitions and options 
919+      * @param array $actAsColumns contains on output an array of columns defined by actAs behaviors 
907920     */ 
908-     public  function  buildActAs ($ actAs )
921+     public  function  buildActAs ($ actAs,  array  & $ actAsColumns  =  array () )
909922    {
910923        $ emittedActAs  = array ();
911-         $ build  = $ this  ->innerBuildActAs ($ actAs , 0 , null , $ emittedActAs );
924+         $ build  = $ this  ->innerBuildActAs ($ actAs , 0 , null , $ emittedActAs,  $ actAsColumns  );
912925        foreach ($ emittedActAs  as  $ str ) {
913926            $ build  .= $ str ;
914927        }
@@ -922,9 +935,10 @@ public function buildActAs($actAs)
922935     * @param int    $level current indentation level 
923936     * @param string $parent name of the parent template/plugin 
924937     * @param array  $emittedActAs contains on output an array of actAs command to be appended to output 
938+      * @param array  $actAsColumns contains on output an array of columns defined by actAs behaviors 
925939     * @return string actAs full definition 
926940     */ 
927-     private  function  innerBuildActAs ($ actAs , $ level  = 0 , $ parent  = null , array  &$ emittedActAs  = array ())
941+     private  function  innerBuildActAs ($ actAs , $ level  = 0 , $ parent  = null , array  &$ emittedActAs  = array (),  array  & $ actAsColumns  =  array () )
928942    {
929943        // rewrite special case of actAs: [Behavior] which gave [0] => Behavior 
930944        if  (is_array ($ actAs ) && isset ($ actAs [0 ]) && !is_array ($ actAs [0 ])) {
@@ -943,9 +957,10 @@ private function innerBuildActAs($actAs, $level = 0, $parent = null, array &$emi
943957        $ currentParent  = $ parent ;
944958        if  (is_array ($ actAs )) {
945959            foreach ($ actAs  as  $ template  => $ options ) {
960+                 $ className  = $ this  ->findTemplateClassMatchingName ($ template );
946961                if  ($ template  == 'actAs ' ) {
947962                    // found another actAs 
948-                     $ build  .= $ this  ->innerBuildActAs ($ options , $ level  + 1 , $ parent , $ emittedActAs );
963+                     $ build  .= $ this  ->innerBuildActAs ($ options , $ level  + 1 , $ parent , $ emittedActAs,  $ actAsColumns  );
949964                } else  if  (is_array ($ options )) {
950965                    // remove actAs from options 
951966                    $ realOptions  = array ();
@@ -959,17 +974,19 @@ private function innerBuildActAs($actAs, $level = 0, $parent = null, array &$emi
959974                    }
960975
961976                    $ optionPHP  = $ this  ->varExport ($ realOptions );
962-                     $ build  .= $ this  ->emitAssign ($ level , $ template , $ optionPHP );
977+                     $ build  .= $ this  ->emitAssign ($ level , $ template , $ optionPHP , $ className );
978+                     $ this  ->addActAsColumnsToDefinition ($ className , $ realOptions , $ actAsColumns );
963979                    if  ($ level  == 0 ) {
964980                        $ emittedActAs [] = $ this  ->emitActAs ($ level , $ template );
965981                    } else  {
966982                        $ build  .= $ this  ->emitAddChild ($ level , $ currentParent , $ template );
967983                    }
968984                    // descend for the remainings actAs 
969985                    $ parent  = $ template ;
970-                     $ build  .= $ this  ->innerBuildActAs ($ leftActAs , $ level , $ template , $ emittedActAs );
986+                     $ build  .= $ this  ->innerBuildActAs ($ leftActAs , $ level , $ template , $ emittedActAs,  $ actAsColumns  );
971987                } else  {
972-                     $ build  .= $ this  ->emitAssign ($ level , $ template , null );
988+                     $ build  .= $ this  ->emitAssign ($ level , $ template , null , $ className );
989+                     $ this  ->addActAsColumnsToDefinition ($ className , array ($ options ), $ actAsColumns );
973990                    if  ($ level  == 0 ) {
974991                        $ emittedActAs [] = $ this  ->emitActAs ($ level , $ template );
975992                    } else  {
@@ -979,7 +996,9 @@ private function innerBuildActAs($actAs, $level = 0, $parent = null, array &$emi
979996                }
980997            }
981998        } else  {
982-             $ build  .= $ this  ->emitAssign ($ level , $ actAs , null );
999+             $ className  = $ this  ->findTemplateClassMatchingName ($ actAs );
1000+             $ build  .= $ this  ->emitAssign ($ level , $ actAs , null , $ className );
1001+             $ this  ->addActAsColumnsToDefinition ($ className , array (), $ actAsColumns );
9831002            if  ($ level  == 0 ) {
9841003                $ emittedActAs [] = $ this  ->emitActAs ($ level , $ actAs );
9851004            } else  {
@@ -990,6 +1009,56 @@ private function innerBuildActAs($actAs, $level = 0, $parent = null, array &$emi
9901009        return  $ build ;
9911010    }
9921011
1012+     /** 
1013+      * Adds the columns of the used actAs behaviors to the comment block. 
1014+      * 
1015+      * @param string $className 
1016+      * @param array $instanceOptions 
1017+      * @param array $actAsColumns 
1018+      * 
1019+      * @throws Doctrine_Import_Builder_Exception 
1020+      */ 
1021+     private  function  addActAsColumnsToDefinition ($ className , $ instanceOptions , &$ actAsColumns )
1022+     {
1023+         // No class specified or class does not exist. 
1024+         if  (!$ className  || !class_exists ($ className )) {
1025+             return ;
1026+         }
1027+ 
1028+         $ actAsInstance  = new  $ className ($ instanceOptions );
1029+         $ options  = $ actAsInstance ->getOptions ();
1030+ 
1031+         if  (count ($ options ) == 0 ) {
1032+             return ;
1033+         }
1034+ 
1035+         // Some behaviors do not contain an array of columns, e.g. SoftDelete. 
1036+         if  (!is_array (reset ($ options ))) {
1037+             $ options  = array ($ options );
1038+         }
1039+ 
1040+         foreach  ($ options  as  $ name  => $ column ) {
1041+             if  (!is_array ($ column ) || !array_key_exists ('name ' , $ column ) || !array_key_exists ('type ' , $ column )) {
1042+                 // 'name' or 'type' not found. Unfortunately there is no logger. What is the best way to abort here? 
1043+                  continue ;
1044+             }
1045+ 
1046+             if  (array_key_exists ('disabled ' , $ column ) && $ column ['disabled ' ]) {
1047+                 // Column has been disabled. 
1048+                 continue ;
1049+             }
1050+ 
1051+             // Add field, if it does not exist already. 
1052+             if  (
1053+                 !array_key_exists ($ name , $ actAsColumns )
1054+                 && !array_key_exists ($ column ['name ' ], $ actAsColumns )
1055+             ) {
1056+                 $ actAsColumns [$ name ] = $ column ;
1057+             }
1058+         }
1059+     }
1060+ 
1061+ 
9931062    /** 
9941063     * Build php code for adding record listeners 
9951064     * 
@@ -1122,9 +1191,10 @@ public function buildDefinition(array $definition)
11221191        $ className  = $ definition ['className ' ];
11231192        $ extends  = isset ($ definition ['inheritance ' ]['extends ' ]) ? $ definition ['inheritance ' ]['extends ' ]:$ this  ->_baseClassName ;
11241193
1194+         $ actAsColumns  = array ();
11251195        if  ( ! (isset ($ definition ['no_definition ' ]) && $ definition ['no_definition ' ] === true )) {
11261196            $ tableDefinitionCode  = $ this  ->buildTableDefinition ($ definition );
1127-             $ setUpCode  = $ this  ->buildSetUp ($ definition );
1197+             $ setUpCode  = $ this  ->buildSetUp ($ definition,  $ actAsColumns  );
11281198        } else  {
11291199            $ tableDefinitionCode  = null ;
11301200            $ setUpCode  = null ;
@@ -1136,7 +1206,7 @@ public function buildDefinition(array $definition)
11361206
11371207        $ setUpCode .= $ this  ->buildToString ($ definition );
11381208
1139-         $ docs  = PHP_EOL  . $ this  ->buildPhpDocs ($ definition );
1209+         $ docs  = PHP_EOL  . $ this  ->buildPhpDocs ($ definition,  $ actAsColumns  );
11401210
11411211        $ content  = sprintf (self ::$ _tpl , $ docs , $ abstract ,
11421212            $ className ,
0 commit comments