@@ -179,6 +179,25 @@ 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<string, array{
187+ * name: string,
188+ * type: string,
189+ * disabled?: bool,
190+ * alias?: string,
191+ * length?: int,
192+ * unique?: bool,
193+ * fixed?: bool,
194+ * primary?: bool,
195+ * notblank?: bool,
196+ * default?: mixed,
197+ * }>
198+ */
199+ private $ actAsColumns = array ();
200+
182201 /**
183202 * _tpl
184203 *
@@ -396,9 +415,7 @@ public function buildTableDefinition(array $definition)
396415 /**
397416 * buildSetUp
398417 *
399- * @param array $options
400- * @param array $columns
401- * @param array $relations
418+ * @param array $definition
402419 * @return string
403420 */
404421 public function buildSetUp (array $ definition )
@@ -857,21 +874,33 @@ public function buildPhpDocs(array $definition)
857874 return $ ret ;
858875 }
859876
877+ /**
878+ * find class matching $name
879+ *
880+ * @param $name
881+ * @return class-string<Doctrine_Template>
882+ */
883+ private function findTemplateClassMatchingName ($ name )
884+ {
885+ $ classname = $ name ;
886+ if (class_exists ("Doctrine_Template_ $ name " , true )) {
887+ $ classname = "Doctrine_Template_ $ name " ;
888+ }
889+
890+ return $ classname ;
891+ }
892+
860893 /**
861894 * emit a behavior assign
862895 *
863896 * @param int $level
864897 * @param string $name
865898 * @param string $option
899+ * @param class-string $classname
866900 * @return string assignation code
867901 */
868- private function emitAssign ($ level , $ name , $ option )
902+ private function emitAssign ($ level , $ name , $ option, $ classname )
869903 {
870- // find class matching $name
871- $ classname = $ name ;
872- if (class_exists ("Doctrine_Template_ $ name " , true )) {
873- $ classname = "Doctrine_Template_ $ name " ;
874- }
875904 return " \$" . strtolower ($ name ) . "$ level = new $ classname( $ option); " . PHP_EOL ;
876905 }
877906
@@ -943,6 +972,7 @@ private function innerBuildActAs($actAs, $level = 0, $parent = null, array &$emi
943972 $ currentParent = $ parent ;
944973 if (is_array ($ actAs )) {
945974 foreach ($ actAs as $ template => $ options ) {
975+ $ className = $ this ->findTemplateClassMatchingName ($ template );
946976 if ($ template == 'actAs ' ) {
947977 // found another actAs
948978 $ build .= $ this ->innerBuildActAs ($ options , $ level + 1 , $ parent , $ emittedActAs );
@@ -959,7 +989,8 @@ private function innerBuildActAs($actAs, $level = 0, $parent = null, array &$emi
959989 }
960990
961991 $ optionPHP = $ this ->varExport ($ realOptions );
962- $ build .= $ this ->emitAssign ($ level , $ template , $ optionPHP );
992+ $ build .= $ this ->emitAssign ($ level , $ template , $ optionPHP , $ className );
993+ $ this ->determineActAsColumns ($ className , $ realOptions );
963994 if ($ level == 0 ) {
964995 $ emittedActAs [] = $ this ->emitActAs ($ level , $ template );
965996 } else {
@@ -969,7 +1000,8 @@ private function innerBuildActAs($actAs, $level = 0, $parent = null, array &$emi
9691000 $ parent = $ template ;
9701001 $ build .= $ this ->innerBuildActAs ($ leftActAs , $ level , $ template , $ emittedActAs );
9711002 } else {
972- $ build .= $ this ->emitAssign ($ level , $ template , null );
1003+ $ build .= $ this ->emitAssign ($ level , $ template , null , $ className );
1004+ $ this ->determineActAsColumns ($ className , array ($ options ));
9731005 if ($ level == 0 ) {
9741006 $ emittedActAs [] = $ this ->emitActAs ($ level , $ template );
9751007 } else {
@@ -979,7 +1011,9 @@ private function innerBuildActAs($actAs, $level = 0, $parent = null, array &$emi
9791011 }
9801012 }
9811013 } else {
982- $ build .= $ this ->emitAssign ($ level , $ actAs , null );
1014+ $ className = $ this ->findTemplateClassMatchingName ($ actAs );
1015+ $ build .= $ this ->emitAssign ($ level , $ actAs , null , $ className );
1016+ $ this ->determineActAsColumns ($ className , array ());
9831017 if ($ level == 0 ) {
9841018 $ emittedActAs [] = $ this ->emitActAs ($ level , $ actAs );
9851019 } else {
@@ -990,6 +1024,87 @@ private function innerBuildActAs($actAs, $level = 0, $parent = null, array &$emi
9901024 return $ build ;
9911025 }
9921026
1027+ /**
1028+ * Adds the columns of the used actAs behaviors to the comment block.
1029+ *
1030+ * @param class-string $className
1031+ * @param array $instanceOptions
1032+ *
1033+ * @throws Doctrine_Import_Builder_Exception
1034+ */
1035+ private function determineActAsColumns ($ className , $ instanceOptions )
1036+ {
1037+ // No class specified or class does not exist.
1038+ if (!$ className || !class_exists ($ className )) {
1039+ return ;
1040+ }
1041+
1042+ // PHP >= 7.4 is planned as a minimum version for the upcoming release of doctrine1,
1043+ // therefore we simply skip the generation of actAs columns if run below 7.0, as
1044+ // instantiation exceptions are not supported before PHP 7
1045+ if (PHP_VERSION_ID <= 70000 ) {
1046+ return ;
1047+ }
1048+
1049+ try {
1050+ $ actAsInstance = new $ className ($ instanceOptions );
1051+ } catch (Error $ e ) {
1052+ // The class can't be instantiated, skipping it
1053+ return ;
1054+ }
1055+
1056+ if (!$ actAsInstance || !method_exists ($ actAsInstance , 'getOptions ' )) {
1057+ return ;
1058+ }
1059+
1060+ $ options = $ actAsInstance ->getOptions ();
1061+
1062+ // Some behaviors do not contain an array of columns, e.g. SoftDelete.
1063+ if (!is_array (reset ($ options ))) {
1064+ $ options = array ($ options );
1065+ }
1066+
1067+ foreach ($ options as $ name => $ column ) {
1068+ if (!is_array ($ column ) || !array_key_exists ('name ' , $ column ) || !array_key_exists ('type ' , $ column )) {
1069+ // 'name' or 'type' not found.
1070+ continue ;
1071+ }
1072+
1073+ if (array_key_exists ('disabled ' , $ column ) && $ column ['disabled ' ]) {
1074+ // Column has been disabled.
1075+ continue ;
1076+ }
1077+
1078+ // Add field, if it does not exist already.
1079+ if (array_key_exists ($ name , $ this ->actAsColumns )) {
1080+ continue ;
1081+ }
1082+
1083+ $ this ->actAsColumns [$ name ] = $ column ;
1084+ }
1085+ }
1086+
1087+ private function mergeDefinitionAndActAsColumns (array $ definitionColumns , array $ actAsColumns )
1088+ {
1089+ $ result = $ definitionColumns ;
1090+
1091+ foreach ($ actAsColumns as $ actAsOptionName => $ actAsColumn ) {
1092+ $ actAsColumnName = isset ($ actAsColumn ['name ' ]) ? $ actAsColumn ['name ' ] : $ actAsOptionName ;
1093+
1094+ foreach ($ result as $ optionName => $ column ) {
1095+ $ name = isset ($ column ['name ' ]) ? $ column ['name ' ] : $ optionName ;
1096+ if ($ name === $ actAsColumnName ) {
1097+ continue 2 ;
1098+ }
1099+ }
1100+
1101+ $ result [$ actAsOptionName ] = $ actAsColumn ;
1102+ }
1103+
1104+ return $ result ;
1105+ }
1106+
1107+
9931108 /**
9941109 * Build php code for adding record listeners
9951110 *
@@ -1122,6 +1237,8 @@ public function buildDefinition(array $definition)
11221237 $ className = $ definition ['className ' ];
11231238 $ extends = isset ($ definition ['inheritance ' ]['extends ' ]) ? $ definition ['inheritance ' ]['extends ' ]:$ this ->_baseClassName ;
11241239
1240+ // Clear actAsColumns
1241+ $ this ->actAsColumns = array ();
11251242 if ( ! (isset ($ definition ['no_definition ' ]) && $ definition ['no_definition ' ] === true )) {
11261243 $ tableDefinitionCode = $ this ->buildTableDefinition ($ definition );
11271244 $ setUpCode = $ this ->buildSetUp ($ definition );
@@ -1136,6 +1253,7 @@ public function buildDefinition(array $definition)
11361253
11371254 $ setUpCode .= $ this ->buildToString ($ definition );
11381255
1256+ $ definition ['columns ' ] = $ this ->mergeDefinitionAndActAsColumns ($ definition ['columns ' ], $ this ->actAsColumns );
11391257 $ docs = PHP_EOL . $ this ->buildPhpDocs ($ definition );
11401258
11411259 $ content = sprintf (self ::$ _tpl , $ docs , $ abstract ,
0 commit comments