@@ -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 class-string<Doctrine_Template>
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 class-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,87 @@ 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 class-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+ // PHP >= 7.4 is planned as a minimum version for the upcoming release of doctrine1,
1032+ // therefore we simply skip the generation of actAs columns if run below 7.0, as
1033+ // instantiation exceptions are not supported before PHP 7
1034+ if (PHP_VERSION_ID <= 70000 ) {
1035+ return ;
1036+ }
1037+
1038+ try {
1039+ $ actAsInstance = new $ className ($ instanceOptions );
1040+ } catch (Error $ e ) {
1041+ // The class can't be instantiated, skipping it
1042+ return ;
1043+ }
1044+
1045+ if (!$ actAsInstance || !method_exists ($ actAsInstance , 'getOptions ' )) {
1046+ return ;
1047+ }
1048+
1049+ $ options = $ actAsInstance ->getOptions ();
1050+
1051+ // Some behaviors do not contain an array of columns, e.g. SoftDelete.
1052+ if (!is_array (reset ($ options ))) {
1053+ $ options = array ($ options );
1054+ }
1055+
1056+ foreach ($ options as $ name => $ column ) {
1057+ if (!is_array ($ column ) || !array_key_exists ('name ' , $ column ) || !array_key_exists ('type ' , $ column )) {
1058+ // 'name' or 'type' not found. Unfortunately there is no logger. What is the best way to abort here?
1059+ continue ;
1060+ }
1061+
1062+ if (array_key_exists ('disabled ' , $ column ) && $ column ['disabled ' ]) {
1063+ // Column has been disabled.
1064+ continue ;
1065+ }
1066+
1067+ // Add field, if it does not exist already.
1068+ if (array_key_exists ($ name , $ this ->actAsColumns )) {
1069+ continue ;
1070+ }
1071+
1072+ $ this ->actAsColumns [$ name ] = $ column ;
1073+ }
1074+ }
1075+
1076+ private function mergeDefinitionAndActAsColumns (array $ definitionColumns , array $ actAsColumns )
1077+ {
1078+ $ result = $ definitionColumns ;
1079+
1080+ foreach ($ actAsColumns as $ actAsOptionName => $ actAsColumn ) {
1081+ $ actAsColumnName = isset ($ actAsColumn ['name ' ]) ? $ actAsColumn ['name ' ] : $ actAsOptionName ;
1082+
1083+ foreach ($ result as $ optionName => $ column ) {
1084+ $ name = isset ($ column ['name ' ]) ? $ column ['name ' ] : $ optionName ;
1085+ if ($ name === $ actAsColumnName ) {
1086+ continue 2 ;
1087+ }
1088+ }
1089+
1090+ $ result [$ actAsOptionName ] = $ actAsColumn ;
1091+ }
1092+
1093+ return $ result ;
1094+ }
1095+
1096+
9931097 /**
9941098 * Build php code for adding record listeners
9951099 *
@@ -1122,6 +1226,8 @@ public function buildDefinition(array $definition)
11221226 $ className = $ definition ['className ' ];
11231227 $ extends = isset ($ definition ['inheritance ' ]['extends ' ]) ? $ definition ['inheritance ' ]['extends ' ]:$ this ->_baseClassName ;
11241228
1229+ // Clear actAsColumns
1230+ $ this ->actAsColumns = array ();
11251231 if ( ! (isset ($ definition ['no_definition ' ]) && $ definition ['no_definition ' ] === true )) {
11261232 $ tableDefinitionCode = $ this ->buildTableDefinition ($ definition );
11271233 $ setUpCode = $ this ->buildSetUp ($ definition );
@@ -1136,6 +1242,7 @@ public function buildDefinition(array $definition)
11361242
11371243 $ setUpCode .= $ this ->buildToString ($ definition );
11381244
1245+ $ definition ['columns ' ] = $ this ->mergeDefinitionAndActAsColumns ($ definition ['columns ' ], $ this ->actAsColumns );
11391246 $ docs = PHP_EOL . $ this ->buildPhpDocs ($ definition );
11401247
11411248 $ content = sprintf (self ::$ _tpl , $ docs , $ abstract ,
0 commit comments