Skip to content

Commit 32f56b3

Browse files
authored
Merge pull request #144 from seamuslee001/dao-FKs
generate foreign keys in DAOs
2 parents cf6cefc + fc73a1f commit 32f56b3

File tree

1 file changed

+69
-17
lines changed

1 file changed

+69
-17
lines changed

src/CRM/CivixBundle/Command/AddEntityBoilerplateCommand.php

Lines changed: 69 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)