@@ -179,6 +179,25 @@ class Doctrine_Import_Builder extends Doctrine_Builder
179
179
*/
180
180
protected $ _phpDocEmail = '##EMAIL## ' ;
181
181
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
+
182
201
/**
183
202
* _tpl
184
203
*
@@ -396,9 +415,7 @@ public function buildTableDefinition(array $definition)
396
415
/**
397
416
* buildSetUp
398
417
*
399
- * @param array $options
400
- * @param array $columns
401
- * @param array $relations
418
+ * @param array $definition
402
419
* @return string
403
420
*/
404
421
public function buildSetUp (array $ definition )
@@ -857,21 +874,33 @@ public function buildPhpDocs(array $definition)
857
874
return $ ret ;
858
875
}
859
876
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
+
860
893
/**
861
894
* emit a behavior assign
862
895
*
863
896
* @param int $level
864
897
* @param string $name
865
898
* @param string $option
899
+ * @param class-string $classname
866
900
* @return string assignation code
867
901
*/
868
- private function emitAssign ($ level , $ name , $ option )
902
+ private function emitAssign ($ level , $ name , $ option, $ classname )
869
903
{
870
- // find class matching $name
871
- $ classname = $ name ;
872
- if (class_exists ("Doctrine_Template_ $ name " , true )) {
873
- $ classname = "Doctrine_Template_ $ name " ;
874
- }
875
904
return " \$" . strtolower ($ name ) . "$ level = new $ classname( $ option); " . PHP_EOL ;
876
905
}
877
906
@@ -943,6 +972,7 @@ private function innerBuildActAs($actAs, $level = 0, $parent = null, array &$emi
943
972
$ currentParent = $ parent ;
944
973
if (is_array ($ actAs )) {
945
974
foreach ($ actAs as $ template => $ options ) {
975
+ $ className = $ this ->findTemplateClassMatchingName ($ template );
946
976
if ($ template == 'actAs ' ) {
947
977
// found another actAs
948
978
$ build .= $ this ->innerBuildActAs ($ options , $ level + 1 , $ parent , $ emittedActAs );
@@ -959,7 +989,8 @@ private function innerBuildActAs($actAs, $level = 0, $parent = null, array &$emi
959
989
}
960
990
961
991
$ optionPHP = $ this ->varExport ($ realOptions );
962
- $ build .= $ this ->emitAssign ($ level , $ template , $ optionPHP );
992
+ $ build .= $ this ->emitAssign ($ level , $ template , $ optionPHP , $ className );
993
+ $ this ->determineActAsColumns ($ className , $ realOptions );
963
994
if ($ level == 0 ) {
964
995
$ emittedActAs [] = $ this ->emitActAs ($ level , $ template );
965
996
} else {
@@ -969,7 +1000,8 @@ private function innerBuildActAs($actAs, $level = 0, $parent = null, array &$emi
969
1000
$ parent = $ template ;
970
1001
$ build .= $ this ->innerBuildActAs ($ leftActAs , $ level , $ template , $ emittedActAs );
971
1002
} else {
972
- $ build .= $ this ->emitAssign ($ level , $ template , null );
1003
+ $ build .= $ this ->emitAssign ($ level , $ template , null , $ className );
1004
+ $ this ->determineActAsColumns ($ className , array ($ options ));
973
1005
if ($ level == 0 ) {
974
1006
$ emittedActAs [] = $ this ->emitActAs ($ level , $ template );
975
1007
} else {
@@ -979,7 +1011,9 @@ private function innerBuildActAs($actAs, $level = 0, $parent = null, array &$emi
979
1011
}
980
1012
}
981
1013
} 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 ());
983
1017
if ($ level == 0 ) {
984
1018
$ emittedActAs [] = $ this ->emitActAs ($ level , $ actAs );
985
1019
} else {
@@ -990,6 +1024,87 @@ private function innerBuildActAs($actAs, $level = 0, $parent = null, array &$emi
990
1024
return $ build ;
991
1025
}
992
1026
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
+
993
1108
/**
994
1109
* Build php code for adding record listeners
995
1110
*
@@ -1122,6 +1237,8 @@ public function buildDefinition(array $definition)
1122
1237
$ className = $ definition ['className ' ];
1123
1238
$ extends = isset ($ definition ['inheritance ' ]['extends ' ]) ? $ definition ['inheritance ' ]['extends ' ]:$ this ->_baseClassName ;
1124
1239
1240
+ // Clear actAsColumns
1241
+ $ this ->actAsColumns = array ();
1125
1242
if ( ! (isset ($ definition ['no_definition ' ]) && $ definition ['no_definition ' ] === true )) {
1126
1243
$ tableDefinitionCode = $ this ->buildTableDefinition ($ definition );
1127
1244
$ setUpCode = $ this ->buildSetUp ($ definition );
@@ -1136,6 +1253,7 @@ public function buildDefinition(array $definition)
1136
1253
1137
1254
$ setUpCode .= $ this ->buildToString ($ definition );
1138
1255
1256
+ $ definition ['columns ' ] = $ this ->mergeDefinitionAndActAsColumns ($ definition ['columns ' ], $ this ->actAsColumns );
1139
1257
$ docs = PHP_EOL . $ this ->buildPhpDocs ($ definition );
1140
1258
1141
1259
$ content = sprintf (self ::$ _tpl , $ docs , $ abstract ,
0 commit comments