@@ -25,10 +25,17 @@ protected function configure() {
2525 );
2626 }
2727
28+
29+ /**
30+ * Note: this function replicates a fair amount of the functionality of
31+ * CRM_Core_CodeGen_Specification (which is a bit messy and hard to interact
32+ * with). It's tempting to completely rewrite / rethink entity generation. Until
33+ * then...
34+ */
2835 protected function execute (InputInterface $ input , OutputInterface $ output ) {
29- // load Civi to get access to civicrm_api_get_function_name
3036 Services::boot (['output ' => $ output ]);
3137 $ civicrm_api3 = Services::api3 ();
38+
3239 if (!$ civicrm_api3 || !$ civicrm_api3 ->local ) {
3340 $ output ->writeln ("<error>Require access to local CiviCRM source tree. Configure civicrm_api3_conf_path.</error> " );
3441 return 1 ;
@@ -42,33 +49,30 @@ protected function execute(InputInterface $input, OutputInterface $output) {
4249 $ ctx ['type ' ] = 'module ' ;
4350 $ ctx ['basedir ' ] = \CRM \CivixBundle \Application::findExtDir ();
4451 $ basedir = new Path ($ ctx ['basedir ' ]);
45-
4652 $ info = new Info ($ basedir ->string ('info.xml ' ));
4753 $ info ->load ($ ctx );
4854 $ attrs = $ info ->get ()->attributes ();
55+
4956 if ($ attrs ['type ' ] != 'module ' ) {
5057 $ output ->writeln ('<error>Wrong extension type: ' . $ attrs ['type ' ] . '</error> ' );
5158 return ;
5259 }
5360
5461 $ xmlSchemaGlob = "xml/schema/ {$ ctx ['namespace ' ]}/*.xml " ;
5562 $ absXmlSchemaGlob = $ basedir ->string ($ xmlSchemaGlob );
56- // var_dump(($absXmlSchemaGlob));
5763 $ xmlSchemas = glob ($ absXmlSchemaGlob );
5864
59- if (!count ($ xmlSchemas )){
65+ if (!count ($ xmlSchemas )) {
6066 throw new Exception ("Could not find files matching ' $ xmlSchemaGlob'. You may want to run `civix generate:entity` before running this command. " );
6167 }
6268
63- $ specification = new \CRM_Core_CodeGen_Specification ;
69+ $ specification = new \CRM_Core_CodeGen_Specification () ;
6470 $ specification ->buildVersion = \CRM_Utils_System::majorVersion ();
65-
66- $ config = new \stdClass ;
71+ $ config = new \stdClass ();
6772 $ config ->phpCodePath = $ basedir ->string ('' );
6873 $ config ->sqlCodePath = $ basedir ->string ('sql/ ' );
6974
70- foreach ($ xmlSchemas as $ xmlSchema ){
71-
75+ foreach ($ xmlSchemas as $ xmlSchema ) {
7276 $ dom = new \DomDocument ();
7377 $ xmlString = file_get_contents ($ xmlSchema );
7478 $ dom ->loadXML ($ xmlString );
@@ -78,15 +82,23 @@ protected function execute(InputInterface $input, OutputInterface $output) {
7882 continue ;
7983 }
8084 $ specification ->getTable ($ xml , $ database , $ tables );
85+ $ name = (string ) $ xml ->name ;
86+ $ tables [$ name ]['name ' ] = $ name ;
87+ $ tables [$ name ]['sourceFile ' ] = $ xmlSchema ;
88+ }
8189
82- $ tables [(string ) $ xml ->name ]['sourceFile ' ] = $ xmlSchema ;
83- $ config ->tables = $ tables ;
84- $ _namespace = ' ' . preg_replace (':/: ' , '_ ' , $ ctx ['namespace ' ]);
85- $ dao = new \CRM_Core_CodeGen_DAO ($ config , (string ) $ xml ->name , "{$ _namespace }_ExtensionUtil::ts " );
90+ $ config ->tables = $ tables ;
91+ $ _namespace = ' ' . preg_replace (':/: ' , '_ ' , $ ctx ['namespace ' ]);
92+ $ this ->orderTables ($ tables );
93+ $ this ->resolveForeignKeys ($ tables );
94+ $ config ->tables = $ tables ;
95+
96+ foreach ($ tables as $ table ) {
97+ $ dao = new \CRM_Core_CodeGen_DAO ($ config , (string ) $ table ['name ' ], "{$ _namespace }_ExtensionUtil::ts " );
8698 ob_start (); // Don't display gencode's output
8799 $ dao ->run ();
88100 ob_end_clean (); // Don't display gencode's output
89- $ daoFileName = $ basedir ->string ("{$ xml -> base } /DAO/ { $ xml -> class } .php " );
101+ $ daoFileName = $ basedir ->string ("{$ table [ ' base ' ]}{ $ table [ ' fileName ' ]} " );
90102 $ output ->writeln ("<info>Write $ daoFileName</info> " );
91103 }
92104
@@ -100,16 +112,56 @@ protected function execute(InputInterface $input, OutputInterface $output) {
100112 $ schema ->generateDropSql ('auto_uninstall.sql ' );
101113 $ output ->writeln ("<info>Write {$ basedir ->string ('sql/auto_uninstall.sql ' )}</info> " );
102114 ob_end_clean (); // Don't display gencode's output
103-
104115 $ module = new Module (Services::templating ());
105116 $ module ->loadInit ($ ctx );
106117 $ module ->save ($ ctx , $ output );
118+ $ upgraderClass = str_replace ('/ ' , '_ ' , $ ctx ['namespace ' ]) . '_Upgrader ' ;
107119
108- $ upgraderClass = str_replace ('/ ' , '_ ' , $ ctx ['namespace ' ]).'_Upgrader ' ;
109- if (!class_exists ($ upgraderClass )){
120+ if (!class_exists ($ upgraderClass )) {
110121 $ output ->writeln ('<comment>You are missing an upgrader class. Your generated SQL files will not be executed on enable and uninstall. Fix this by running `civix generate:upgrader`.</comment> ' );
111122 }
112123
113124 }
114125
126+ private function orderTables (&$ tables ) {
127+
128+ $ ordered = [];
129+
130+ while (count ($ tables )) {
131+ foreach ($ tables as $ k => $ table ) {
132+ if (!isset ($ table ['foreignKey ' ])) {
133+ $ ordered [$ k ] = $ table ;
134+ unset($ tables [$ k ]);
135+ }
136+ foreach ($ table ['foreignKey ' ] as $ fKey ) {
137+ if (in_array ($ fKey ['table ' ], array_keys ($ tables ))) {
138+ continue ;
139+ }
140+ $ ordered [$ k ] = $ table ;
141+ unset($ tables [$ k ]);
142+ }
143+ }
144+ }
145+ $ tables = $ ordered ;
146+ }
147+
148+ private function resolveForeignKeys (&$ tables ) {
149+ foreach ($ tables as &$ table ) {
150+ if (isset ($ table ['foreignKey ' ])) {
151+ foreach ($ table ['foreignKey ' ] as &$ key ) {
152+ if (isset ($ tables [$ key ['table ' ]])) {
153+ $ key ['className ' ] = $ tables [$ key ['table ' ]]['className ' ];
154+ $ key ['fileName ' ] = $ tables [$ key ['table ' ]]['fileName ' ];
155+ $ table ['fields ' ][$ key ['name ' ]]['FKClassName ' ] = $ key ['className ' ];
156+ }
157+ else {
158+ $ key ['className ' ] = \CRM_Core_DAO_AllCoreTables::getClassForTable ($ key ['table ' ]);
159+ $ key ['fileName ' ] = $ key ['className ' ] . '.php ' ;
160+ $ table ['fields ' ][$ key ['name ' ]]['FKClassName ' ] = $ key ['className ' ];
161+ }
162+ }
163+ }
164+ }
165+ }
166+
115167}
0 commit comments