From d2672ca020c13f5d4686658d336a6e8848a7d852 Mon Sep 17 00:00:00 2001 From: "deb.monish" Date: Tue, 13 Feb 2018 19:35:06 +0530 Subject: [PATCH 01/22] Simplify SQL and translation pipeline changes --- plugins/common/LogEvents.civi-setup.php | 1 + plugins/init/Drupal.civi-setup.php | 2 +- .../GenerateSchema.civi-setup.php | 40 +++++++++++++++++++ src/Setup.php | 11 +++++ src/Setup/Event/GenerateSchemaEvent.php | 10 +++++ 5 files changed, 63 insertions(+), 1 deletion(-) create mode 100644 plugins/installDatabase/GenerateSchema.civi-setup.php create mode 100644 src/Setup/Event/GenerateSchemaEvent.php diff --git a/plugins/common/LogEvents.civi-setup.php b/plugins/common/LogEvents.civi-setup.php index ad2c393..310d380 100644 --- a/plugins/common/LogEvents.civi-setup.php +++ b/plugins/common/LogEvents.civi-setup.php @@ -18,6 +18,7 @@ 'civi.setup.checkRequirements', 'civi.setup.checkInstalled', 'civi.setup.installFiles', + 'civi.setup.generateSchema', 'civi.setup.installDatabase', 'civi.setup.uninstallDatabase', 'civi.setup.uninstallFiles', diff --git a/plugins/init/Drupal.civi-setup.php b/plugins/init/Drupal.civi-setup.php index cbf509f..75e7c5a 100644 --- a/plugins/init/Drupal.civi-setup.php +++ b/plugins/init/Drupal.civi-setup.php @@ -12,7 +12,7 @@ \Civi\Setup::dispatcher() ->addListener('civi.setup.checkAuthorized', function (\Civi\Setup\Event\CheckAuthorizedEvent $e) { $model = $e->getModel(); - if ($model->cms !== 'Drupal') { + if ($model->cms !== 'Drupal' || !function_exists('user_access')) { return; } diff --git a/plugins/installDatabase/GenerateSchema.civi-setup.php b/plugins/installDatabase/GenerateSchema.civi-setup.php new file mode 100644 index 0000000..87925b8 --- /dev/null +++ b/plugins/installDatabase/GenerateSchema.civi-setup.php @@ -0,0 +1,40 @@ +addListener('civi.setup.checkRequirements', function (\Civi\Setup\Event\CheckRequirementsEvent $e) { + \Civi\Setup::log()->info(sprintf('[%s] Handle %s', basename(__FILE__), 'checkRequirements')); + + if (!is_writable($e->getModel()->srcPath)) { + $e->addError('system', 'accessDenied', "Do not premission to create and write schema files."); + return; + } + }); + + \Civi\Setup::dispatcher() + ->addListener('civi.setup.generateSchema', function (\Civi\Setup\Event\GenerateSchemaEvent $e) { + $model = $e->getModel(); + + \Civi\Setup::log()->info(sprintf('[%s] Generate database schema', basename(__FILE__))); + + $genCode = new \CRM_Core_CodeGen_Main( + implode(DIRECTORY_SEPARATOR, array($model->srcPath, 'CRM', 'Core', 'DAO')) . DIRECTORY_SEPARATOR, // $CoreDAOCodePath + implode(DIRECTORY_SEPARATOR, array($model->srcPath, 'sql')), // $sqlCodePath + $model->srcPath, // $phpCodePath + implode(DIRECTORY_SEPARATOR, array($model->srcPath, 'templates')) . DIRECTORY_SEPARATOR, // $tplCodePath + NULL, // IGNORE + $model->cms, // cms + NULL, // db version + implode(DIRECTORY_SEPARATOR, array($model->srcPath, 'schema', 'Schema.xml')) // schema file + ); + $genCode->main(); + + }); diff --git a/src/Setup.php b/src/Setup.php index ffb1a29..784d39d 100644 --- a/src/Setup.php +++ b/src/Setup.php @@ -6,6 +6,7 @@ use Civi\Setup\Event\CheckInstalledEvent; use Civi\Setup\UI\Event\UIConstructEvent; use Civi\Setup\Event\InitEvent; +use Civi\Setup\Event\GenerateSchemaEvent; use Civi\Setup\Event\InstallDatabaseEvent; use Civi\Setup\Event\InstallFilesEvent; use Civi\Setup\Event\UninstallDatabaseEvent; @@ -194,6 +195,16 @@ public function installFiles() { return $this->getDispatcher()->dispatch('civi.setup.installFiles', $event); } + /** + * Generate the schema files. + * + * @return \Civi\Setup\Event\GenerateSchemaEvent + */ + public function generateSchema() { + $event = new GenerateSchemaEvent($this->getModel()); + return $this->getDispatcher()->dispatch('civi.setup.generateSchema', $event); + } + /** * Create the database schema. * diff --git a/src/Setup/Event/GenerateSchemaEvent.php b/src/Setup/Event/GenerateSchemaEvent.php new file mode 100644 index 0000000..5ee7b8a --- /dev/null +++ b/src/Setup/Event/GenerateSchemaEvent.php @@ -0,0 +1,10 @@ + Date: Thu, 15 Feb 2018 16:29:37 +0530 Subject: [PATCH 02/22] Add CRM_Core_CodeGen_Schema code to InstallSchema.civi-setup.php --- plugins/common/LogEvents.civi-setup.php | 1 - plugins/init/AvailableTables.civi-setup.php | 35 ++++++++++++++++ .../GenerateSchema.civi-setup.php | 40 ------------------- .../InstallSchema.civi-setup.php | 11 +++++ src/Setup.php | 11 ----- src/Setup/DbUtil.php | 31 ++++++++++++++ src/Setup/Event/GenerateSchemaEvent.php | 10 ----- src/Setup/FileUtil.php | 24 +++++++++++ src/Setup/Model.php | 6 +++ src/Setup/SmartyUtil.php | 30 ++++++++++++++ src/Setup/Template.php | 30 ++++++++++++++ 11 files changed, 167 insertions(+), 62 deletions(-) create mode 100644 plugins/init/AvailableTables.civi-setup.php delete mode 100644 plugins/installDatabase/GenerateSchema.civi-setup.php delete mode 100644 src/Setup/Event/GenerateSchemaEvent.php create mode 100644 src/Setup/SmartyUtil.php create mode 100644 src/Setup/Template.php diff --git a/plugins/common/LogEvents.civi-setup.php b/plugins/common/LogEvents.civi-setup.php index 310d380..ad2c393 100644 --- a/plugins/common/LogEvents.civi-setup.php +++ b/plugins/common/LogEvents.civi-setup.php @@ -18,7 +18,6 @@ 'civi.setup.checkRequirements', 'civi.setup.checkInstalled', 'civi.setup.installFiles', - 'civi.setup.generateSchema', 'civi.setup.installDatabase', 'civi.setup.uninstallDatabase', 'civi.setup.uninstallFiles', diff --git a/plugins/init/AvailableTables.civi-setup.php b/plugins/init/AvailableTables.civi-setup.php new file mode 100644 index 0000000..95484aa --- /dev/null +++ b/plugins/init/AvailableTables.civi-setup.php @@ -0,0 +1,35 @@ +addListener('civi.setup.init', function (\Civi\Setup\Event\InitEvent $e) { + \Civi\Setup::log()->info(sprintf('[%s] Handle %s', basename(__FILE__), 'init')); + + $m = $e->getModel(); + + $tables = NULL; + $schemaFile = implode(DIRECTORY_SEPARATOR, [$m->srcPath, 'xml', 'schema', 'Schema.xml']); + if (file_exists($schemaFile)) { + $versionFile = implode(DIRECTORY_SEPARATOR, [$m->srcPath, 'xml', 'version.xml']); + $xmlBuilt = \CRM_Core_CodeGen_Util_Xml::parse($versionFile); + $buildVersion = preg_replace('/^(\d{1,2}\.\d{1,2})\.(\d{1,2}|\w{4,7})$/i', '$1', $xmlBuilt->version_no); + $specification = new \CRM_Core_CodeGen_Specification(); + $specification->parse($schemaFile, $buildVersion); + $tables = $specification->tables; + } + else { + $e->addError('system', 'schemaMissing', "Schema file is missing: \"$schemaFile\""); + return; + } + + $m->setField('tables', 'options', $tables); + + }, \Civi\Setup::PRIORITY_PREPARE); diff --git a/plugins/installDatabase/GenerateSchema.civi-setup.php b/plugins/installDatabase/GenerateSchema.civi-setup.php deleted file mode 100644 index 87925b8..0000000 --- a/plugins/installDatabase/GenerateSchema.civi-setup.php +++ /dev/null @@ -1,40 +0,0 @@ -addListener('civi.setup.checkRequirements', function (\Civi\Setup\Event\CheckRequirementsEvent $e) { - \Civi\Setup::log()->info(sprintf('[%s] Handle %s', basename(__FILE__), 'checkRequirements')); - - if (!is_writable($e->getModel()->srcPath)) { - $e->addError('system', 'accessDenied', "Do not premission to create and write schema files."); - return; - } - }); - - \Civi\Setup::dispatcher() - ->addListener('civi.setup.generateSchema', function (\Civi\Setup\Event\GenerateSchemaEvent $e) { - $model = $e->getModel(); - - \Civi\Setup::log()->info(sprintf('[%s] Generate database schema', basename(__FILE__))); - - $genCode = new \CRM_Core_CodeGen_Main( - implode(DIRECTORY_SEPARATOR, array($model->srcPath, 'CRM', 'Core', 'DAO')) . DIRECTORY_SEPARATOR, // $CoreDAOCodePath - implode(DIRECTORY_SEPARATOR, array($model->srcPath, 'sql')), // $sqlCodePath - $model->srcPath, // $phpCodePath - implode(DIRECTORY_SEPARATOR, array($model->srcPath, 'templates')) . DIRECTORY_SEPARATOR, // $tplCodePath - NULL, // IGNORE - $model->cms, // cms - NULL, // db version - implode(DIRECTORY_SEPARATOR, array($model->srcPath, 'schema', 'Schema.xml')) // schema file - ); - $genCode->main(); - - }); diff --git a/plugins/installDatabase/InstallSchema.civi-setup.php b/plugins/installDatabase/InstallSchema.civi-setup.php index 79c798c..6ff3ade 100644 --- a/plugins/installDatabase/InstallSchema.civi-setup.php +++ b/plugins/installDatabase/InstallSchema.civi-setup.php @@ -47,6 +47,17 @@ $model = $e->getModel(); $sqlPath = $model->srcPath . DIRECTORY_SEPARATOR . 'sql'; + $tables = $model->tables; + + if (!file_exists($sqlPath)) { + Civi\Setup::log()->info('[InstallSchema.civi-setup.php] mkdir "{path}"', ['path' => $sqlPath]); + mkdir($sqlPath, 0777, TRUE); + \Civi\Setup\FileUtil::makeWebWriteable($sqlPath); + } + + \Civi\Setup\DbUtil::generateCreateSql($srcPath, $model->db['database'], $model->tables); + \Civi\Setup\DbUtil::generateNavigation($sqlPath); + \Civi\Setup\DbUtil::generateSample($sqlPath); \Civi\Setup\DbUtil::sourceSQL($model->db, $sqlPath . DIRECTORY_SEPARATOR . 'civicrm.mysql'); diff --git a/src/Setup.php b/src/Setup.php index 784d39d..ffb1a29 100644 --- a/src/Setup.php +++ b/src/Setup.php @@ -6,7 +6,6 @@ use Civi\Setup\Event\CheckInstalledEvent; use Civi\Setup\UI\Event\UIConstructEvent; use Civi\Setup\Event\InitEvent; -use Civi\Setup\Event\GenerateSchemaEvent; use Civi\Setup\Event\InstallDatabaseEvent; use Civi\Setup\Event\InstallFilesEvent; use Civi\Setup\Event\UninstallDatabaseEvent; @@ -195,16 +194,6 @@ public function installFiles() { return $this->getDispatcher()->dispatch('civi.setup.installFiles', $event); } - /** - * Generate the schema files. - * - * @return \Civi\Setup\Event\GenerateSchemaEvent - */ - public function generateSchema() { - $event = new GenerateSchemaEvent($this->getModel()); - return $this->getDispatcher()->dispatch('civi.setup.generateSchema', $event); - } - /** * Create the database schema. * diff --git a/src/Setup/DbUtil.php b/src/Setup/DbUtil.php index 15c8a3e..860a0a1 100644 --- a/src/Setup/DbUtil.php +++ b/src/Setup/DbUtil.php @@ -2,6 +2,7 @@ namespace Civi\Setup; use Civi\Setup\Exception\SqlException; +use Civi\Setup\Template; class DbUtil { @@ -238,4 +239,34 @@ public static function findTables($conn, $databaseName) { }, self::fetchAll($conn, $sql)); } + /** + * @param string $fileName + */ + public function generateCreateSql($srcPath, $databaseName, $tables, $fileName = 'civicrm.mysql') { + \Civi\Setup::log()->info("Generating sql file\n"); + $template = new Template($srcPath, 'sql'); + + $template->assign('database', $databaseName); + $template->assign('tables', $tables); + $dropOrder = array_reverse(array_keys($tables)); + $template->assign('dropOrder', $dropOrder); + $template->assign('mysql', 'modern'); + + $SQLfilePath = implode(DIRECTORY_SEPARATOR, [$srcPath, 'sql', $fileName]); + $template->run('schema.tpl', $SQLfilePath); + } + + public function generateNavigation($sqlPath) { + echo "Generating navigation file\n"; + \Civi\Setup::log()->info("Generating navigation file\n"); + $template = new Template('sql'); + $template->run('civicrm_navigation.tpl', $sqlPath . DIRECTORY_SEPARATOR . 'civicrm_navigation.mysql'); + } + + public function generateSample($sqlPath) { + $template = new Template('sql'); + $sections = ['civicrm_sample.tpl', 'civicrm_acl.tpl']; + $template->runConcat($sections, $sqlPath . DIRECTORY_SEPARATOR . 'civicrm_sample.mysql'); + $template->run('case_sample.tpl', $sqlPath . DIRECTORY_SEPARATOR . 'case_sample.mysql'); + } } diff --git a/src/Setup/Event/GenerateSchemaEvent.php b/src/Setup/Event/GenerateSchemaEvent.php deleted file mode 100644 index 5ee7b8a..0000000 --- a/src/Setup/Event/GenerateSchemaEvent.php +++ /dev/null @@ -1,10 +0,0 @@ - 'array', 'value' => array(), )); + $this->addField(array( + 'description' => 'CiviCRM Tables', + 'name' => 'tables', + 'type' => 'string', + 'options' => array(), + )); } /** diff --git a/src/Setup/SmartyUtil.php b/src/Setup/SmartyUtil.php new file mode 100644 index 0000000..b70365d --- /dev/null +++ b/src/Setup/SmartyUtil.php @@ -0,0 +1,30 @@ +template_dir = implode(DIRECTORY_SEPARATOR, [$srcPath, 'xml', 'templates']); + $smarty->plugins_dir = [ + implode(DIRECTORY_SEPARATOR, [$packagePath, 'Smarty', 'plugins']), + implode(DIRECTORY_SEPARATOR, [$srcPath, 'CRM', 'Core', 'Smarty', 'plugins']), + ]; + $smarty->compile_dir = \Civi\Setup\FileUtil::createTempDir('templates_c'); + $smarty->clear_all_cache(); + + // CRM-5308 / CRM-3507 - we need {localize} to work in the templates + require_once implode(DIRECTORY_SEPARATOR, [$srcPath, 'CRM', 'Core', 'Smarty', 'plugins', 'block.localize.php']); + $smarty->register_block('localize', 'smarty_block_localize'); + + return $smarty; + } +} diff --git a/src/Setup/Template.php b/src/Setup/Template.php new file mode 100644 index 0000000..2b8d7d7 --- /dev/null +++ b/src/Setup/Template.php @@ -0,0 +1,30 @@ +filetype = $filetype; + + $this->smarty = \Civi\Setup\SmartyUtil::createSmarty($srcPath); + + $this->assign('generated', "DO NOT EDIT. Generated by Installer"); + + if ($this->filetype === 'php') { + require_once 'PHP/Beautifier.php'; + // create an instance + $this->beautifier = new PHP_Beautifier(); + $this->beautifier->addFilter('ArrayNested'); + // add one or more filters + $this->beautifier->setIndentChar(' '); + $this->beautifier->setIndentNumber(2); + $this->beautifier->setNewLine("\n"); + } + } + +} From 1b022b1a14cd91539edc295b4d7cf10fbc396c8a Mon Sep 17 00:00:00 2001 From: "deb.monish" Date: Thu, 15 Feb 2018 18:48:34 +0530 Subject: [PATCH 03/22] use SQL content rather then filename to populate mysql data --- .../InstallSchema.civi-setup.php | 24 ++++------ src/Setup/DbUtil.php | 26 +++++----- src/Setup/Model.php | 4 ++ src/Setup/Template.php | 47 ++++++++++++++++++- 4 files changed, 70 insertions(+), 31 deletions(-) diff --git a/plugins/installDatabase/InstallSchema.civi-setup.php b/plugins/installDatabase/InstallSchema.civi-setup.php index 6ff3ade..c1e936e 100644 --- a/plugins/installDatabase/InstallSchema.civi-setup.php +++ b/plugins/installDatabase/InstallSchema.civi-setup.php @@ -47,32 +47,24 @@ $model = $e->getModel(); $sqlPath = $model->srcPath . DIRECTORY_SEPARATOR . 'sql'; - $tables = $model->tables; - if (!file_exists($sqlPath)) { - Civi\Setup::log()->info('[InstallSchema.civi-setup.php] mkdir "{path}"', ['path' => $sqlPath]); - mkdir($sqlPath, 0777, TRUE); - \Civi\Setup\FileUtil::makeWebWriteable($sqlPath); - } - - \Civi\Setup\DbUtil::generateCreateSql($srcPath, $model->db['database'], $model->tables); - \Civi\Setup\DbUtil::generateNavigation($sqlPath); - \Civi\Setup\DbUtil::generateSample($sqlPath); + \Civi\Setup\DbUtil::sourceSQL($model->db, \Civi\Setup\DbUtil::generateCreateSql($srcPath, $model->db['database'], $model->tables)); - \Civi\Setup\DbUtil::sourceSQL($model->db, $sqlPath . DIRECTORY_SEPARATOR . 'civicrm.mysql'); + \Civi\Setup\DbUtil::sourceSQL($model->db, \Civi\Setup\DbUtil::generateNavigation($sqlPath)); if (!empty($model->loadGenerated)) { - \Civi\Setup\DbUtil::sourceSQL($model->db, $sqlPath . DIRECTORY_SEPARATOR . 'civicrm_generated.mysql', TRUE); + \Civi\Setup\DbUtil::sourceSQL($model->db, \Civi\Setup\DbUtil::generateSample($sqlPath)); } else { $seedLanguage = $model->lang; + // @TODO need to generate and fetch seedLanguage mysql data if ($seedLanguage && $seedLanguage !== 'en_US') { - \Civi\Setup\DbUtil::sourceSQL($model->db, $sqlPath . DIRECTORY_SEPARATOR . "civicrm_data.{$seedLanguage}.mysql"); - \Civi\Setup\DbUtil::sourceSQL($model->db, $sqlPath . DIRECTORY_SEPARATOR . "civicrm_acl.{$seedLanguage}.mysql"); + \Civi\Setup\DbUtil::sourceSQL($model->db, file_get_contents($sqlPath . DIRECTORY_SEPARATOR . "civicrm_data.{$seedLanguage}.mysql")); + \Civi\Setup\DbUtil::sourceSQL($model->db, file_get_contents($sqlPath . DIRECTORY_SEPARATOR . "civicrm_acl.{$seedLanguage}.mysql")); } else { - \Civi\Setup\DbUtil::sourceSQL($model->db, $sqlPath . DIRECTORY_SEPARATOR . 'civicrm_data.mysql'); - \Civi\Setup\DbUtil::sourceSQL($model->db, $sqlPath . DIRECTORY_SEPARATOR . 'civicrm_acl.mysql'); + \Civi\Setup\DbUtil::sourceSQL($model->db, file_get_contents($sqlPath . DIRECTORY_SEPARATOR . 'civicrm_data.mysql')); + \Civi\Setup\DbUtil::sourceSQL($model->db, file_get_contents($sqlPath . DIRECTORY_SEPARATOR . 'civicrm_acl.mysql')); } } diff --git a/src/Setup/DbUtil.php b/src/Setup/DbUtil.php index 860a0a1..00ba035 100644 --- a/src/Setup/DbUtil.php +++ b/src/Setup/DbUtil.php @@ -97,17 +97,17 @@ public static function encodeHostPort($host, $port) { /** * @param array $db - * @param string $fileName + * @param string $SQLcontent * @param bool $lineMode * What does this mean? Seems weird. */ - public static function sourceSQL($db, $fileName, $lineMode = FALSE) { + public static function sourceSQL($db, $SQLcontent, $lineMode = FALSE) { $conn = self::connect($db); $conn->query('SET NAMES utf8'); if (!$lineMode) { - $string = file_get_contents($fileName); + $string = $SQLcontent; // change \r\n to fix windows issues $string = str_replace("\r\n", "\n", $string); @@ -133,7 +133,7 @@ public static function sourceSQL($db, $fileName, $lineMode = FALSE) { } } else { - $fd = fopen($fileName, "r"); + $fd = fopen($SQLcontent, "r"); while ($string = fgets($fd)) { $string = preg_replace("/^#[^\n]*$/m", "\n", $string); $string = preg_replace("/^(--[^-]).*/m", "\n", $string); @@ -242,7 +242,7 @@ public static function findTables($conn, $databaseName) { /** * @param string $fileName */ - public function generateCreateSql($srcPath, $databaseName, $tables, $fileName = 'civicrm.mysql') { + public function generateCreateSql($srcPath, $databaseName, $tables) { \Civi\Setup::log()->info("Generating sql file\n"); $template = new Template($srcPath, 'sql'); @@ -252,21 +252,19 @@ public function generateCreateSql($srcPath, $databaseName, $tables, $fileName = $template->assign('dropOrder', $dropOrder); $template->assign('mysql', 'modern'); - $SQLfilePath = implode(DIRECTORY_SEPARATOR, [$srcPath, 'sql', $fileName]); - $template->run('schema.tpl', $SQLfilePath); + return $template->getContent('schema.tpl'); } public function generateNavigation($sqlPath) { echo "Generating navigation file\n"; - \Civi\Setup::log()->info("Generating navigation file\n"); - $template = new Template('sql'); - $template->run('civicrm_navigation.tpl', $sqlPath . DIRECTORY_SEPARATOR . 'civicrm_navigation.mysql'); + \Civi\Setup::log()->info("Generating navigation SQL content\n"); + $template = new Template($sqlPath, 'sql'); + return $template->getContent('civicrm_navigation.tpl'); } public function generateSample($sqlPath) { - $template = new Template('sql'); - $sections = ['civicrm_sample.tpl', 'civicrm_acl.tpl']; - $template->runConcat($sections, $sqlPath . DIRECTORY_SEPARATOR . 'civicrm_sample.mysql'); - $template->run('case_sample.tpl', $sqlPath . DIRECTORY_SEPARATOR . 'case_sample.mysql'); + $template = new Template($sqlPath, 'sql'); + $sections = ['civicrm_sample.tpl', 'civicrm_acl.tpl', 'case_sample.tpl']; + return $template->getConcatContent($sections); } } diff --git a/src/Setup/Model.php b/src/Setup/Model.php index d1d59e7..93aa5e9 100644 --- a/src/Setup/Model.php +++ b/src/Setup/Model.php @@ -56,6 +56,10 @@ * Keys should be prefixed based on which plugin manages the field. * Values must only be scalars (bool/int/string) and arrays. * Ex: ['opt-in.version-check' => TRUE]. + * @property array $tables + * List of CiviCRM tables extracted from xml schema files. + * Values must only be array. + * Ex: ['civicrm_contact', 'civicrm_group']. */ class Model { diff --git a/src/Setup/Template.php b/src/Setup/Template.php index 2b8d7d7..c8ea41e 100644 --- a/src/Setup/Template.php +++ b/src/Setup/Template.php @@ -16,7 +16,7 @@ public function __construct($srcPath, $fileType) { $this->assign('generated', "DO NOT EDIT. Generated by Installer"); if ($this->filetype === 'php') { - require_once 'PHP/Beautifier.php'; + require_once implode(DIRECTORY_SEPARATOR, [$srcPath, 'packages', 'PHP', 'Beautifier.php']); // create an instance $this->beautifier = new PHP_Beautifier(); $this->beautifier->addFilter('ArrayNested'); @@ -27,4 +27,49 @@ public function __construct($srcPath, $fileType) { } } + /** + * Run template generator. + * + * @param string $infile + * Filename of the template, without a path. + * @param string $outpath + * Full path to the desired output file. + */ + public function getContent($infile, $outpath) { + $contents = $this->smarty->fetch($infile); + + if ($this->filetype === 'php') { + $this->beautifier->setInputString($contents); + $this->beautifier->process(); + $contents = $this->beautifier->get(); + // The beautifier isn't as beautiful as one would hope. Here's some extra string fudging. + $replacements = [ + ') ,' => '),', + "\n }\n}\n" => "\n }\n\n}\n", + '=> true,' => '=> TRUE,', + '=> false,' => '=> FALSE,', + ]; + $contents = str_replace(array_keys($replacements), array_values($replacements), $contents); + $contents = preg_replace('#(\s*)\\/\\*\\*#', "\n\$1/**", $contents); + // Convert old array syntax to new square brackets + $contents = CRM_Core_CodeGen_Util_ArraySyntaxConverter::convert($contents); + } + + return $contents; + } + + /** + * @param array $inputs + * Template filenames. + */ + public function getConcatContent($inputs) { + $content = ''; + foreach ($inputs as $infile) { + // FIXME: does not beautify. Document. + $content .= $this->smarty->fetch($infile) . "\n"; + } + + return $content; + } + } From f347d6d6f2ede1e3ee36e4b8418df04b02ddde55 Mon Sep 17 00:00:00 2001 From: Tim Otten Date: Thu, 15 Feb 2018 15:14:06 -0800 Subject: [PATCH 04/22] AvailableTables - Quiet --- plugins/init/AvailableTables.civi-setup.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/init/AvailableTables.civi-setup.php b/plugins/init/AvailableTables.civi-setup.php index 95484aa..0a4c5a5 100644 --- a/plugins/init/AvailableTables.civi-setup.php +++ b/plugins/init/AvailableTables.civi-setup.php @@ -22,7 +22,7 @@ $xmlBuilt = \CRM_Core_CodeGen_Util_Xml::parse($versionFile); $buildVersion = preg_replace('/^(\d{1,2}\.\d{1,2})\.(\d{1,2}|\w{4,7})$/i', '$1', $xmlBuilt->version_no); $specification = new \CRM_Core_CodeGen_Specification(); - $specification->parse($schemaFile, $buildVersion); + $specification->parse($schemaFile, $buildVersion, FALSE); $tables = $specification->tables; } else { From eff38f67a96b972b584bdf7111e045445d459c9d Mon Sep 17 00:00:00 2001 From: Tim Otten Date: Thu, 15 Feb 2018 15:14:30 -0800 Subject: [PATCH 05/22] InstallSchema - Fix path reference. Display more fine-grained messages. --- plugins/installDatabase/InstallSchema.civi-setup.php | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/plugins/installDatabase/InstallSchema.civi-setup.php b/plugins/installDatabase/InstallSchema.civi-setup.php index c1e936e..136b008 100644 --- a/plugins/installDatabase/InstallSchema.civi-setup.php +++ b/plugins/installDatabase/InstallSchema.civi-setup.php @@ -48,12 +48,15 @@ $sqlPath = $model->srcPath . DIRECTORY_SEPARATOR . 'sql'; - \Civi\Setup\DbUtil::sourceSQL($model->db, \Civi\Setup\DbUtil::generateCreateSql($srcPath, $model->db['database'], $model->tables)); + \Civi\Setup::log()->info(sprintf('[%s] generateCreateSql', basename(__FILE__))); + \Civi\Setup\DbUtil::sourceSQL($model->db, \Civi\Setup\DbUtil::generateCreateSql($model->srcPath, $model->db['database'], $model->tables)); - \Civi\Setup\DbUtil::sourceSQL($model->db, \Civi\Setup\DbUtil::generateNavigation($sqlPath)); + \Civi\Setup::log()->info(sprintf('[%s] generateNavigation', basename(__FILE__))); + \Civi\Setup\DbUtil::sourceSQL($model->db, \Civi\Setup\DbUtil::generateNavigation($model->srcPath)); if (!empty($model->loadGenerated)) { - \Civi\Setup\DbUtil::sourceSQL($model->db, \Civi\Setup\DbUtil::generateSample($sqlPath)); + \Civi\Setup::log()->info(sprintf('[%s] generateSample', basename(__FILE__))); + \Civi\Setup\DbUtil::sourceSQL($model->db, \Civi\Setup\DbUtil::generateSample($model->srcPath)); } else { $seedLanguage = $model->lang; From 552d0aa183309b4a209f09ca85153847fb9f86de Mon Sep 17 00:00:00 2001 From: Tim Otten Date: Thu, 15 Feb 2018 15:15:27 -0800 Subject: [PATCH 06/22] FileUtil - Fix createTempDir() --- src/Setup/FileUtil.php | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) diff --git a/src/Setup/FileUtil.php b/src/Setup/FileUtil.php index f81cf06..54a86bf 100644 --- a/src/Setup/FileUtil.php +++ b/src/Setup/FileUtil.php @@ -30,18 +30,6 @@ public static function isDeletable($path) { return is_writable(dirname($path)); } - /** - * @param string $dir - * @param int $perm - * - * @return string - */ - public static function createDir($dir, $perm = 0755) { - if (!self::isCreateable($dir)) { - mkdir($dir, $perm, TRUE); - } - } - /** * @param $prefix * @@ -49,7 +37,7 @@ public static function createDir($dir, $perm = 0755) { */ public static function createTempDir($prefix) { $newTempDir = tempnam(sys_get_temp_dir(), $prefix) . '.d'; - self::createDir($newTempDir); + mkdir($newTempDir, 0755, TRUE); return $newTempDir; } From e75c2bce73f573a1d6b32568f7fe1804d2f49826 Mon Sep 17 00:00:00 2001 From: Tim Otten Date: Thu, 15 Feb 2018 15:15:51 -0800 Subject: [PATCH 07/22] Template.php - Multiple fixes 1. Typo in variable name ($fileType) 2. Add `assign()`, because a few other spots seem to expect it 3. Remove unused param ($outputath) --- src/Setup/Template.php | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/Setup/Template.php b/src/Setup/Template.php index c8ea41e..90162af 100644 --- a/src/Setup/Template.php +++ b/src/Setup/Template.php @@ -9,7 +9,7 @@ class Template { protected $beautifier; public function __construct($srcPath, $fileType) { - $this->filetype = $filetype; + $this->filetype = $fileType; $this->smarty = \Civi\Setup\SmartyUtil::createSmarty($srcPath); @@ -27,15 +27,18 @@ public function __construct($srcPath, $fileType) { } } + public function assign($tpl_var, $value = NULL) { + return $this->smarty->assign($tpl_var, $value); + } + /** * Run template generator. * * @param string $infile * Filename of the template, without a path. - * @param string $outpath - * Full path to the desired output file. + * @return string */ - public function getContent($infile, $outpath) { + public function getContent($infile) { $contents = $this->smarty->fetch($infile); if ($this->filetype === 'php') { From bf76ef639bea30a5709a7bf75416e1ffc3695416 Mon Sep 17 00:00:00 2001 From: Tim Otten Date: Thu, 15 Feb 2018 15:17:29 -0800 Subject: [PATCH 08/22] DbUtil - Fix misnamed param. Throw error when running unsupported mode. --- src/Setup/DbUtil.php | 48 +++++++++++++++++++++----------------------- 1 file changed, 23 insertions(+), 25 deletions(-) diff --git a/src/Setup/DbUtil.php b/src/Setup/DbUtil.php index 00ba035..9777420 100644 --- a/src/Setup/DbUtil.php +++ b/src/Setup/DbUtil.php @@ -133,23 +133,24 @@ public static function sourceSQL($db, $SQLcontent, $lineMode = FALSE) { } } else { - $fd = fopen($SQLcontent, "r"); - while ($string = fgets($fd)) { - $string = preg_replace("/^#[^\n]*$/m", "\n", $string); - $string = preg_replace("/^(--[^-]).*/m", "\n", $string); - - $string = trim($string); - if (!empty($string)) { - if ($result = $conn->query($string)) { - if (is_object($result)) { - mysqli_free_result($result); - } - } - else { - throw new SqlException("Cannot execute $string: " . mysqli_error($conn)); - } - } - } + throw new \RuntimeException("Not implemented: lineMode"); + // $fd = fopen($SQLcontent, "r"); + // while ($string = fgets($fd)) { + // $string = preg_replace("/^#[^\n]*$/m", "\n", $string); + // $string = preg_replace("/^(--[^-]).*/m", "\n", $string); + // + // $string = trim($string); + // if (!empty($string)) { + // if ($result = $conn->query($string)) { + // if (is_object($result)) { + // mysqli_free_result($result); + // } + // } + // else { + // throw new SqlException("Cannot execute $string: " . mysqli_error($conn)); + // } + // } + // } } } @@ -239,9 +240,6 @@ public static function findTables($conn, $databaseName) { }, self::fetchAll($conn, $sql)); } - /** - * @param string $fileName - */ public function generateCreateSql($srcPath, $databaseName, $tables) { \Civi\Setup::log()->info("Generating sql file\n"); $template = new Template($srcPath, 'sql'); @@ -255,16 +253,16 @@ public function generateCreateSql($srcPath, $databaseName, $tables) { return $template->getContent('schema.tpl'); } - public function generateNavigation($sqlPath) { - echo "Generating navigation file\n"; + public function generateNavigation($srcPath) { \Civi\Setup::log()->info("Generating navigation SQL content\n"); - $template = new Template($sqlPath, 'sql'); + $template = new Template($srcPath, 'sql'); return $template->getContent('civicrm_navigation.tpl'); } - public function generateSample($sqlPath) { - $template = new Template($sqlPath, 'sql'); + public function generateSample($srcPath) { + $template = new Template($srcPath, 'sql'); $sections = ['civicrm_sample.tpl', 'civicrm_acl.tpl', 'case_sample.tpl']; return $template->getConcatContent($sections); } + } From 463b73081e75d4e6071ffd15f8bf90fc7d71adfc Mon Sep 17 00:00:00 2001 From: Tim Otten Date: Fri, 16 Feb 2018 05:04:19 -0800 Subject: [PATCH 09/22] SmartyUtil - Ensure that {ts}/ts() is available --- src/Setup/SmartyUtil.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/Setup/SmartyUtil.php b/src/Setup/SmartyUtil.php index b70365d..19c2441 100644 --- a/src/Setup/SmartyUtil.php +++ b/src/Setup/SmartyUtil.php @@ -9,8 +9,10 @@ class SmartyUtil { * @return \Smarty */ public static function createSmarty($srcPath) { + require_once 'CRM/Core/I18n.php'; + $packagePath = implode(DIRECTORY_SEPARATOR, [$srcPath, 'packages']); - require_once $packagePath . DIRECTORY_SEPARATOR . 'Smarty'. DIRECTORY_SEPARATOR . 'Smarty.class.php'; + require_once $packagePath . DIRECTORY_SEPARATOR . 'Smarty' . DIRECTORY_SEPARATOR . 'Smarty.class.php'; $smarty = new \Smarty(); $smarty->template_dir = implode(DIRECTORY_SEPARATOR, [$srcPath, 'xml', 'templates']); @@ -27,4 +29,5 @@ public static function createSmarty($srcPath) { return $smarty; } + } From fa0824b6a323f8fdc6fcf9d44af13e6d2a68fbf5 Mon Sep 17 00:00:00 2001 From: Tim Otten Date: Fri, 16 Feb 2018 05:04:52 -0800 Subject: [PATCH 10/22] UninstallSettingsFile - Tweak error message --- plugins/uninstallFiles/UninstallSettingsFile.civi-setup.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/uninstallFiles/UninstallSettingsFile.civi-setup.php b/plugins/uninstallFiles/UninstallSettingsFile.civi-setup.php index aec95b0..b10ab4b 100644 --- a/plugins/uninstallFiles/UninstallSettingsFile.civi-setup.php +++ b/plugins/uninstallFiles/UninstallSettingsFile.civi-setup.php @@ -16,7 +16,7 @@ $file = $e->getModel()->settingsPath; if (file_exists($file)) { if (!\Civi\Setup\FileUtil::isDeletable($file)) { - throw new \Exception("Cannot remove $file"); + throw new \Exception("Cannot remove \"$file\". Please check permissions on the file and directory."); } unlink($file); } From 7bd6d165faebebf2c071123cbfdc1f8a058a8dd7 Mon Sep 17 00:00:00 2001 From: Tim Otten Date: Fri, 16 Feb 2018 05:05:32 -0800 Subject: [PATCH 11/22] DbUtil - Remove extra newlines from log --- src/Setup/DbUtil.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Setup/DbUtil.php b/src/Setup/DbUtil.php index 9777420..d731543 100644 --- a/src/Setup/DbUtil.php +++ b/src/Setup/DbUtil.php @@ -241,7 +241,7 @@ public static function findTables($conn, $databaseName) { } public function generateCreateSql($srcPath, $databaseName, $tables) { - \Civi\Setup::log()->info("Generating sql file\n"); + \Civi\Setup::log()->info("Generating sql file"); $template = new Template($srcPath, 'sql'); $template->assign('database', $databaseName); @@ -254,7 +254,7 @@ public function generateCreateSql($srcPath, $databaseName, $tables) { } public function generateNavigation($srcPath) { - \Civi\Setup::log()->info("Generating navigation SQL content\n"); + \Civi\Setup::log()->info("Generating navigation SQL content"); $template = new Template($srcPath, 'sql'); return $template->getContent('civicrm_navigation.tpl'); } From b5734ec39cd685c85c3650f746f827b0ec3f3e8e Mon Sep 17 00:00:00 2001 From: Tim Otten Date: Fri, 16 Feb 2018 05:19:47 -0800 Subject: [PATCH 12/22] Combine InstallSchema, AvailableTables The main issue here is that `schema.tpl` is getting the wrong data. It was getting the DB name ```php generateCreateSql($model->srcPath, $model->db['database'], $model->tables) ``` But it should actually the full, parsed schema specification: ``` generateCreateSql($model->srcPath, $spec->database, $spec->tables) ``` So basically... `InstallSchema` needs access to the full `$specification` (which was only available in `AvailableTables`). And I don't currently see a use-case that requires exposing the schema as part of the installer model, so I think it's simpler to merge `AvailableTables` into `InstallSchema`. --- plugins/init/AvailableTables.civi-setup.php | 35 ------------------- .../InstallSchema.civi-setup.php | 33 ++++++++++++++++- src/Setup/Model.php | 10 ------ 3 files changed, 32 insertions(+), 46 deletions(-) delete mode 100644 plugins/init/AvailableTables.civi-setup.php diff --git a/plugins/init/AvailableTables.civi-setup.php b/plugins/init/AvailableTables.civi-setup.php deleted file mode 100644 index 0a4c5a5..0000000 --- a/plugins/init/AvailableTables.civi-setup.php +++ /dev/null @@ -1,35 +0,0 @@ -addListener('civi.setup.init', function (\Civi\Setup\Event\InitEvent $e) { - \Civi\Setup::log()->info(sprintf('[%s] Handle %s', basename(__FILE__), 'init')); - - $m = $e->getModel(); - - $tables = NULL; - $schemaFile = implode(DIRECTORY_SEPARATOR, [$m->srcPath, 'xml', 'schema', 'Schema.xml']); - if (file_exists($schemaFile)) { - $versionFile = implode(DIRECTORY_SEPARATOR, [$m->srcPath, 'xml', 'version.xml']); - $xmlBuilt = \CRM_Core_CodeGen_Util_Xml::parse($versionFile); - $buildVersion = preg_replace('/^(\d{1,2}\.\d{1,2})\.(\d{1,2}|\w{4,7})$/i', '$1', $xmlBuilt->version_no); - $specification = new \CRM_Core_CodeGen_Specification(); - $specification->parse($schemaFile, $buildVersion, FALSE); - $tables = $specification->tables; - } - else { - $e->addError('system', 'schemaMissing', "Schema file is missing: \"$schemaFile\""); - return; - } - - $m->setField('tables', 'options', $tables); - - }, \Civi\Setup::PRIORITY_PREPARE); diff --git a/plugins/installDatabase/InstallSchema.civi-setup.php b/plugins/installDatabase/InstallSchema.civi-setup.php index 136b008..c82527f 100644 --- a/plugins/installDatabase/InstallSchema.civi-setup.php +++ b/plugins/installDatabase/InstallSchema.civi-setup.php @@ -9,6 +9,22 @@ exit("Installation plugins must only be loaded by the installer.\n"); } +\Civi\Setup::dispatcher() + ->addListener('civi.setup.checkRequirements', function (\Civi\Setup\Event\CheckRequirementsEvent $e) { + $m = $e->getModel(); + $files = array( + 'xmlMissing' => implode(DIRECTORY_SEPARATOR, [$m->srcPath, 'xml']), + 'xmlSchemaMissing' => implode(DIRECTORY_SEPARATOR, [$m->srcPath, 'xml', 'schema', 'Schema.xml']), + 'xmlVersionMissing' => implode(DIRECTORY_SEPARATOR, [$m->srcPath, 'xml', 'version.xml']), + ); + + foreach ($files as $key => $file) { + if (!file_exists($file)) { + $e->addError('system', $key, "Schema file is missing: \"$file\""); + } + } + }); + \Civi\Setup::dispatcher() ->addListener('civi.setup.checkRequirements', function (\Civi\Setup\Event\CheckRequirementsEvent $e) { \Civi\Setup::log()->info(sprintf('[%s] Handle %s', basename(__FILE__), 'checkRequirements')); @@ -47,9 +63,10 @@ $model = $e->getModel(); $sqlPath = $model->srcPath . DIRECTORY_SEPARATOR . 'sql'; + $spec = _installschema_getSpec($model->srcPath); \Civi\Setup::log()->info(sprintf('[%s] generateCreateSql', basename(__FILE__))); - \Civi\Setup\DbUtil::sourceSQL($model->db, \Civi\Setup\DbUtil::generateCreateSql($model->srcPath, $model->db['database'], $model->tables)); + \Civi\Setup\DbUtil::sourceSQL($model->db, \Civi\Setup\DbUtil::generateCreateSql($model->srcPath, $spec->database, $spec->tables)); \Civi\Setup::log()->info(sprintf('[%s] generateNavigation', basename(__FILE__))); \Civi\Setup\DbUtil::sourceSQL($model->db, \Civi\Setup\DbUtil::generateNavigation($model->srcPath)); @@ -72,3 +89,17 @@ } }); + +/** + * @param string $srcPath + * @return \CRM_Core_CodeGen_Specification + */ +function _installschema_getSpec($srcPath) { + $schemaFile = implode(DIRECTORY_SEPARATOR, [$srcPath, 'xml', 'schema', 'Schema.xml']); + $versionFile = implode(DIRECTORY_SEPARATOR, [$srcPath, 'xml', 'version.xml']); + $xmlBuilt = \CRM_Core_CodeGen_Util_Xml::parse($versionFile); + $buildVersion = preg_replace('/^(\d{1,2}\.\d{1,2})\.(\d{1,2}|\w{4,7})$/i', '$1', $xmlBuilt->version_no); + $specification = new \CRM_Core_CodeGen_Specification(); + $specification->parse($schemaFile, $buildVersion, FALSE); + return $specification; +} diff --git a/src/Setup/Model.php b/src/Setup/Model.php index 93aa5e9..abacfb0 100644 --- a/src/Setup/Model.php +++ b/src/Setup/Model.php @@ -56,10 +56,6 @@ * Keys should be prefixed based on which plugin manages the field. * Values must only be scalars (bool/int/string) and arrays. * Ex: ['opt-in.version-check' => TRUE]. - * @property array $tables - * List of CiviCRM tables extracted from xml schema files. - * Values must only be array. - * Ex: ['civicrm_contact', 'civicrm_group']. */ class Model { @@ -154,12 +150,6 @@ public function __construct() { 'type' => 'array', 'value' => array(), )); - $this->addField(array( - 'description' => 'CiviCRM Tables', - 'name' => 'tables', - 'type' => 'string', - 'options' => array(), - )); } /** From f64d492b614b5ad7d946293521c45cc738c6c244 Mon Sep 17 00:00:00 2001 From: Tim Otten Date: Fri, 16 Feb 2018 06:10:06 -0800 Subject: [PATCH 13/22] InstallSchema - Convert from "listener" (closure) to "subscriber" (OOP) notation --- .../InstallSchema.civi-setup.php | 60 ++++++++++++------- 1 file changed, 37 insertions(+), 23 deletions(-) diff --git a/plugins/installDatabase/InstallSchema.civi-setup.php b/plugins/installDatabase/InstallSchema.civi-setup.php index c82527f..3b1f015 100644 --- a/plugins/installDatabase/InstallSchema.civi-setup.php +++ b/plugins/installDatabase/InstallSchema.civi-setup.php @@ -9,8 +9,21 @@ exit("Installation plugins must only be loaded by the installer.\n"); } -\Civi\Setup::dispatcher() - ->addListener('civi.setup.checkRequirements', function (\Civi\Setup\Event\CheckRequirementsEvent $e) { +class InstallSchemaPlugin implements \Symfony\Component\EventDispatcher\EventSubscriberInterface { + + public static function getSubscribedEvents() { + return [ + 'civi.setup.checkRequirements' => [ + ['checkXmlFiles', 0], + ['checkSqlFiles', 0], + ], + 'civi.setup.installDatabase' => [ + ['installDatabase', 0] + ], + ]; + } + + public function checkXmlFiles(\Civi\Setup\Event\CheckRequirementsEvent $e) { $m = $e->getModel(); $files = array( 'xmlMissing' => implode(DIRECTORY_SEPARATOR, [$m->srcPath, 'xml']), @@ -23,10 +36,9 @@ $e->addError('system', $key, "Schema file is missing: \"$file\""); } } - }); + } -\Civi\Setup::dispatcher() - ->addListener('civi.setup.checkRequirements', function (\Civi\Setup\Event\CheckRequirementsEvent $e) { + public function checkSqlFiles(\Civi\Setup\Event\CheckRequirementsEvent $e) { \Civi\Setup::log()->info(sprintf('[%s] Handle %s', basename(__FILE__), 'checkRequirements')); $seedLanguage = $e->getModel()->lang; $sqlPath = $e->getModel()->srcPath . DIRECTORY_SEPARATOR . 'sql'; @@ -54,16 +66,15 @@ } $e->addInfo('system', 'lang', "Language $seedLanguage is allowed."); - }); + } -\Civi\Setup::dispatcher() - ->addListener('civi.setup.installDatabase', function (\Civi\Setup\Event\InstallDatabaseEvent $e) { + public function installDatabase(\Civi\Setup\Event\InstallDatabaseEvent $e) { \Civi\Setup::log()->info(sprintf('[%s] Install database schema', basename(__FILE__))); $model = $e->getModel(); $sqlPath = $model->srcPath . DIRECTORY_SEPARATOR . 'sql'; - $spec = _installschema_getSpec($model->srcPath); + $spec = $this->loadSpecification($model->srcPath); \Civi\Setup::log()->info(sprintf('[%s] generateCreateSql', basename(__FILE__))); \Civi\Setup\DbUtil::sourceSQL($model->db, \Civi\Setup\DbUtil::generateCreateSql($model->srcPath, $spec->database, $spec->tables)); @@ -87,19 +98,22 @@ \Civi\Setup\DbUtil::sourceSQL($model->db, file_get_contents($sqlPath . DIRECTORY_SEPARATOR . 'civicrm_acl.mysql')); } } + } + + /** + * @param string $srcPath + * @return \CRM_Core_CodeGen_Specification + */ + protected function loadSpecification($srcPath) { + $schemaFile = implode(DIRECTORY_SEPARATOR, [$srcPath, 'xml', 'schema', 'Schema.xml']); + $versionFile = implode(DIRECTORY_SEPARATOR, [$srcPath, 'xml', 'version.xml']); + $xmlBuilt = \CRM_Core_CodeGen_Util_Xml::parse($versionFile); + $buildVersion = preg_replace('/^(\d{1,2}\.\d{1,2})\.(\d{1,2}|\w{4,7})$/i', '$1', $xmlBuilt->version_no); + $specification = new \CRM_Core_CodeGen_Specification(); + $specification->parse($schemaFile, $buildVersion, FALSE); + return $specification; + } - }); - -/** - * @param string $srcPath - * @return \CRM_Core_CodeGen_Specification - */ -function _installschema_getSpec($srcPath) { - $schemaFile = implode(DIRECTORY_SEPARATOR, [$srcPath, 'xml', 'schema', 'Schema.xml']); - $versionFile = implode(DIRECTORY_SEPARATOR, [$srcPath, 'xml', 'version.xml']); - $xmlBuilt = \CRM_Core_CodeGen_Util_Xml::parse($versionFile); - $buildVersion = preg_replace('/^(\d{1,2}\.\d{1,2})\.(\d{1,2}|\w{4,7})$/i', '$1', $xmlBuilt->version_no); - $specification = new \CRM_Core_CodeGen_Specification(); - $specification->parse($schemaFile, $buildVersion, FALSE); - return $specification; } + +\Civi\Setup::dispatcher()->addSubscriber(new InstallSchemaPlugin()); From 87e3bf6b99de0dcb1187f159508bc03befa60222 Mon Sep 17 00:00:00 2001 From: "deb.monish" Date: Mon, 19 Feb 2018 11:13:07 +0530 Subject: [PATCH 14/22] reorder install plugins and other minor fixes --- .../InstallSchema.civi-setup.php | 14 ++++++++---- src/Setup.php | 22 ++++++++++++++----- src/Setup/DbUtil.php | 2 +- 3 files changed, 28 insertions(+), 10 deletions(-) diff --git a/plugins/installDatabase/InstallSchema.civi-setup.php b/plugins/installDatabase/InstallSchema.civi-setup.php index 3b1f015..6aae6c7 100644 --- a/plugins/installDatabase/InstallSchema.civi-setup.php +++ b/plugins/installDatabase/InstallSchema.civi-setup.php @@ -65,6 +65,10 @@ public function checkSqlFiles(\Civi\Setup\Event\CheckRequirementsEvent $e) { } } + if (!file_exists($e->getModel()->settingsPath)) { + $e->addError('system', 'settingsPath', sprintf('The CiviCRM setting file is missing.')); + } + $e->addInfo('system', 'lang', "Language $seedLanguage is allowed."); } @@ -76,11 +80,10 @@ public function installDatabase(\Civi\Setup\Event\InstallDatabaseEvent $e) { $sqlPath = $model->srcPath . DIRECTORY_SEPARATOR . 'sql'; $spec = $this->loadSpecification($model->srcPath); - \Civi\Setup::log()->info(sprintf('[%s] generateCreateSql', basename(__FILE__))); - \Civi\Setup\DbUtil::sourceSQL($model->db, \Civi\Setup\DbUtil::generateCreateSql($model->srcPath, $spec->database, $spec->tables)); + require_once $model->settingsPath; - \Civi\Setup::log()->info(sprintf('[%s] generateNavigation', basename(__FILE__))); - \Civi\Setup\DbUtil::sourceSQL($model->db, \Civi\Setup\DbUtil::generateNavigation($model->srcPath)); + \Civi\Setup::log()->info(sprintf('[%s] generateCreateSql', basename(__FILE__))); + \Civi\Setup\DbUtil::sourceSQL($model->db, \Civi\Setup\DbUtil::generateCreateSql($model->srcPath, $model->db['database'], $spec->tables)); if (!empty($model->loadGenerated)) { \Civi\Setup::log()->info(sprintf('[%s] generateSample', basename(__FILE__))); @@ -98,6 +101,9 @@ public function installDatabase(\Civi\Setup\Event\InstallDatabaseEvent $e) { \Civi\Setup\DbUtil::sourceSQL($model->db, file_get_contents($sqlPath . DIRECTORY_SEPARATOR . 'civicrm_acl.mysql')); } } + + \Civi\Setup::log()->info(sprintf('[%s] generateNavigation', basename(__FILE__))); + \Civi\Setup\DbUtil::sourceSQL($model->db, \Civi\Setup\DbUtil::generateNavigation($model->srcPath)); } /** diff --git a/src/Setup.php b/src/Setup.php index ffb1a29..2bc5448 100644 --- a/src/Setup.php +++ b/src/Setup.php @@ -71,11 +71,23 @@ public static function init($modelValues = array(), $pluginCallback = NULL, $log $pluginDir = dirname(__DIR__) . '/plugins'; $pluginFiles = array(); - foreach (['*.civi-setup.php', '*/*.civi-setup.php'] as $pattern) { - foreach ((array) glob("$pluginDir/$pattern") as $file) { - $key = substr($file, strlen($pluginDir) + 1); - $key = preg_replace('/\.civi-setup\.php$/', '', $key); - $pluginFiles[$key] = $file; + $pluginFileDirs = [ + 'blocks', + 'checkInstalled', + 'checkRequirements', + 'common', + 'createForm', + 'init', + 'installFiles', + 'installDatabase', + ]; + // Don't include uninstall plugin files, as this need to be called on demand and shoudn't be part of Civi installtion setup + foreach ($pluginFileDirs as $pattern) { + foreach ((array) glob("$pluginDir/$pattern/*") as $file) { + if (strstr($file, '.civi-setup.php')) { + $key = preg_replace('/\.civi-setup\.php$/', '', $file); + $pluginFiles[$key] = $file; + } } } ksort($pluginFiles); diff --git a/src/Setup/DbUtil.php b/src/Setup/DbUtil.php index d731543..1e35248 100644 --- a/src/Setup/DbUtil.php +++ b/src/Setup/DbUtil.php @@ -30,7 +30,7 @@ public static function encodeDsn($db) { return sprintf('mysql://%s:%s@%s/%s', $db['username'], $db['password'], - self::encodeHostPort($db['host'], $db['port']), + $db['server']?: self::encodeHostPort($db['host'], $db['port']), $db['database'] ); } From 09106d6386a4c5edddd21576df92a7410a168ae2 Mon Sep 17 00:00:00 2001 From: "deb.monish" Date: Tue, 20 Feb 2018 07:44:29 +0530 Subject: [PATCH 15/22] additional fixes --- .../InstallSchema.civi-setup.php | 6 +- src/Setup.php | 22 ++----- src/Setup/DbUtil.php | 27 +-------- src/Setup/SchemaGenerator.php | 57 +++++++++++++++++++ 4 files changed, 66 insertions(+), 46 deletions(-) create mode 100644 src/Setup/SchemaGenerator.php diff --git a/plugins/installDatabase/InstallSchema.civi-setup.php b/plugins/installDatabase/InstallSchema.civi-setup.php index 6aae6c7..9566a28 100644 --- a/plugins/installDatabase/InstallSchema.civi-setup.php +++ b/plugins/installDatabase/InstallSchema.civi-setup.php @@ -83,11 +83,11 @@ public function installDatabase(\Civi\Setup\Event\InstallDatabaseEvent $e) { require_once $model->settingsPath; \Civi\Setup::log()->info(sprintf('[%s] generateCreateSql', basename(__FILE__))); - \Civi\Setup\DbUtil::sourceSQL($model->db, \Civi\Setup\DbUtil::generateCreateSql($model->srcPath, $model->db['database'], $spec->tables)); + \Civi\Setup\DbUtil::sourceSQL($model->db, \Civi\Setup\SchemaGenerator::generateCreateSql($model->srcPath, $spec->database, $spec->tables)); if (!empty($model->loadGenerated)) { \Civi\Setup::log()->info(sprintf('[%s] generateSample', basename(__FILE__))); - \Civi\Setup\DbUtil::sourceSQL($model->db, \Civi\Setup\DbUtil::generateSample($model->srcPath)); + \Civi\Setup\DbUtil::sourceSQL($model->db, \Civi\Setup\SchemaGenerator::generateSample($model->srcPath)); } else { $seedLanguage = $model->lang; @@ -103,7 +103,7 @@ public function installDatabase(\Civi\Setup\Event\InstallDatabaseEvent $e) { } \Civi\Setup::log()->info(sprintf('[%s] generateNavigation', basename(__FILE__))); - \Civi\Setup\DbUtil::sourceSQL($model->db, \Civi\Setup\DbUtil::generateNavigation($model->srcPath)); + \Civi\Setup\DbUtil::sourceSQL($model->db, \Civi\Setup\SchemaGenerator::generateNavigation($model->srcPath)); } /** diff --git a/src/Setup.php b/src/Setup.php index 2bc5448..ffb1a29 100644 --- a/src/Setup.php +++ b/src/Setup.php @@ -71,23 +71,11 @@ public static function init($modelValues = array(), $pluginCallback = NULL, $log $pluginDir = dirname(__DIR__) . '/plugins'; $pluginFiles = array(); - $pluginFileDirs = [ - 'blocks', - 'checkInstalled', - 'checkRequirements', - 'common', - 'createForm', - 'init', - 'installFiles', - 'installDatabase', - ]; - // Don't include uninstall plugin files, as this need to be called on demand and shoudn't be part of Civi installtion setup - foreach ($pluginFileDirs as $pattern) { - foreach ((array) glob("$pluginDir/$pattern/*") as $file) { - if (strstr($file, '.civi-setup.php')) { - $key = preg_replace('/\.civi-setup\.php$/', '', $file); - $pluginFiles[$key] = $file; - } + foreach (['*.civi-setup.php', '*/*.civi-setup.php'] as $pattern) { + foreach ((array) glob("$pluginDir/$pattern") as $file) { + $key = substr($file, strlen($pluginDir) + 1); + $key = preg_replace('/\.civi-setup\.php$/', '', $key); + $pluginFiles[$key] = $file; } } ksort($pluginFiles); diff --git a/src/Setup/DbUtil.php b/src/Setup/DbUtil.php index 1e35248..6b67121 100644 --- a/src/Setup/DbUtil.php +++ b/src/Setup/DbUtil.php @@ -30,7 +30,7 @@ public static function encodeDsn($db) { return sprintf('mysql://%s:%s@%s/%s', $db['username'], $db['password'], - $db['server']?: self::encodeHostPort($db['host'], $db['port']), + $db['server'], $db['database'] ); } @@ -240,29 +240,4 @@ public static function findTables($conn, $databaseName) { }, self::fetchAll($conn, $sql)); } - public function generateCreateSql($srcPath, $databaseName, $tables) { - \Civi\Setup::log()->info("Generating sql file"); - $template = new Template($srcPath, 'sql'); - - $template->assign('database', $databaseName); - $template->assign('tables', $tables); - $dropOrder = array_reverse(array_keys($tables)); - $template->assign('dropOrder', $dropOrder); - $template->assign('mysql', 'modern'); - - return $template->getContent('schema.tpl'); - } - - public function generateNavigation($srcPath) { - \Civi\Setup::log()->info("Generating navigation SQL content"); - $template = new Template($srcPath, 'sql'); - return $template->getContent('civicrm_navigation.tpl'); - } - - public function generateSample($srcPath) { - $template = new Template($srcPath, 'sql'); - $sections = ['civicrm_sample.tpl', 'civicrm_acl.tpl', 'case_sample.tpl']; - return $template->getConcatContent($sections); - } - } diff --git a/src/Setup/SchemaGenerator.php b/src/Setup/SchemaGenerator.php new file mode 100644 index 0000000..5e99bec --- /dev/null +++ b/src/Setup/SchemaGenerator.php @@ -0,0 +1,57 @@ +info("Generating sql file"); + $template = new Template($srcPath, 'sql'); + + $template->assign('database', $database); + $template->assign('tables', $tables); + $dropOrder = array_reverse(array_keys($tables)); + $template->assign('dropOrder', $dropOrder); + $template->assign('mysql', 'modern'); + + return $template->getContent('schema.tpl'); + } + + /** + * Return translated SQL content using tpl, mainly contain SQL codes to populate navigation links + * + * @param string $srcPath + * + * @return string + */ + public static function generateNavigation($srcPath) { + \Civi\Setup::log()->info("Generating navigation SQL content"); + $template = new Template($srcPath, 'sql'); + return $template->getContent('civicrm_navigation.tpl'); + } + + /** + * Return translated SQL content using tpl, mainly contain SQL codes to populate essential CiviCRM data + * + * @param string $srcPath + * + * @return string + */ + public static function generateSample($srcPath) { + $template = new Template($srcPath, 'sql'); + $sections = ['civicrm_sample.tpl', 'civicrm_acl.tpl', 'case_sample.tpl']; + return $template->getConcatContent($sections); + } + +} From 6ed179fc320be52554e41ff9a6ea891d12eab771 Mon Sep 17 00:00:00 2001 From: Tim Otten Date: Tue, 20 Feb 2018 14:28:54 -0800 Subject: [PATCH 16/22] SchemaGenerator, InstallSchema - More consistent log output --- plugins/installDatabase/InstallSchema.civi-setup.php | 8 +++++--- src/Setup/SchemaGenerator.php | 6 +----- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/plugins/installDatabase/InstallSchema.civi-setup.php b/plugins/installDatabase/InstallSchema.civi-setup.php index 9566a28..a826159 100644 --- a/plugins/installDatabase/InstallSchema.civi-setup.php +++ b/plugins/installDatabase/InstallSchema.civi-setup.php @@ -82,27 +82,29 @@ public function installDatabase(\Civi\Setup\Event\InstallDatabaseEvent $e) { require_once $model->settingsPath; - \Civi\Setup::log()->info(sprintf('[%s] generateCreateSql', basename(__FILE__))); + \Civi\Setup::log()->info(sprintf('[%s] Load basic tables', basename(__FILE__))); \Civi\Setup\DbUtil::sourceSQL($model->db, \Civi\Setup\SchemaGenerator::generateCreateSql($model->srcPath, $spec->database, $spec->tables)); if (!empty($model->loadGenerated)) { - \Civi\Setup::log()->info(sprintf('[%s] generateSample', basename(__FILE__))); + \Civi\Setup::log()->info(sprintf('[%s] Load sample data', basename(__FILE__))); \Civi\Setup\DbUtil::sourceSQL($model->db, \Civi\Setup\SchemaGenerator::generateSample($model->srcPath)); } else { $seedLanguage = $model->lang; // @TODO need to generate and fetch seedLanguage mysql data if ($seedLanguage && $seedLanguage !== 'en_US') { + \Civi\Setup::log()->info(sprintf('[%s] Load localized data', basename(__FILE__))); \Civi\Setup\DbUtil::sourceSQL($model->db, file_get_contents($sqlPath . DIRECTORY_SEPARATOR . "civicrm_data.{$seedLanguage}.mysql")); \Civi\Setup\DbUtil::sourceSQL($model->db, file_get_contents($sqlPath . DIRECTORY_SEPARATOR . "civicrm_acl.{$seedLanguage}.mysql")); } else { + \Civi\Setup::log()->info(sprintf('[%s] Load default data', basename(__FILE__))); \Civi\Setup\DbUtil::sourceSQL($model->db, file_get_contents($sqlPath . DIRECTORY_SEPARATOR . 'civicrm_data.mysql')); \Civi\Setup\DbUtil::sourceSQL($model->db, file_get_contents($sqlPath . DIRECTORY_SEPARATOR . 'civicrm_acl.mysql')); } } - \Civi\Setup::log()->info(sprintf('[%s] generateNavigation', basename(__FILE__))); + \Civi\Setup::log()->info(sprintf('[%s] Load navigation data', basename(__FILE__))); \Civi\Setup\DbUtil::sourceSQL($model->db, \Civi\Setup\SchemaGenerator::generateNavigation($model->srcPath)); } diff --git a/src/Setup/SchemaGenerator.php b/src/Setup/SchemaGenerator.php index 5e99bec..8b9df8e 100644 --- a/src/Setup/SchemaGenerator.php +++ b/src/Setup/SchemaGenerator.php @@ -10,13 +10,10 @@ class SchemaGenerator { * * @param string $srcPath * @param array $database - * @return array $tables - * Ex: ['civicrm_view1', 'civicrm_view2'] - * + * @param array $tables * @return string */ public static function generateCreateSql($srcPath, $database, $tables) { - \Civi\Setup::log()->info("Generating sql file"); $template = new Template($srcPath, 'sql'); $template->assign('database', $database); @@ -36,7 +33,6 @@ public static function generateCreateSql($srcPath, $database, $tables) { * @return string */ public static function generateNavigation($srcPath) { - \Civi\Setup::log()->info("Generating navigation SQL content"); $template = new Template($srcPath, 'sql'); return $template->getContent('civicrm_navigation.tpl'); } From 0d8c11981b5663b41f23ae2fbb9055cf43932560 Mon Sep 17 00:00:00 2001 From: Tim Otten Date: Tue, 20 Feb 2018 15:09:01 -0800 Subject: [PATCH 17/22] InstallSchema - Allow `ts()` to work without booting `CRM_Core_DAO` Depends: https://github.com/civicrm/civicrm-core/pull/11699 --- plugins/installDatabase/InstallSchema.civi-setup.php | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/plugins/installDatabase/InstallSchema.civi-setup.php b/plugins/installDatabase/InstallSchema.civi-setup.php index a826159..a53edd8 100644 --- a/plugins/installDatabase/InstallSchema.civi-setup.php +++ b/plugins/installDatabase/InstallSchema.civi-setup.php @@ -80,7 +80,10 @@ public function installDatabase(\Civi\Setup\Event\InstallDatabaseEvent $e) { $sqlPath = $model->srcPath . DIRECTORY_SEPARATOR . 'sql'; $spec = $this->loadSpecification($model->srcPath); - require_once $model->settingsPath; + $conn = \Civi\Setup\DbUtil::connect($model->db); + \CRM_Core_I18n::$SQL_ESCAPER = function($text) use ($conn) { + return $conn->escape_string($text); + }; \Civi\Setup::log()->info(sprintf('[%s] Load basic tables', basename(__FILE__))); \Civi\Setup\DbUtil::sourceSQL($model->db, \Civi\Setup\SchemaGenerator::generateCreateSql($model->srcPath, $spec->database, $spec->tables)); @@ -106,6 +109,8 @@ public function installDatabase(\Civi\Setup\Event\InstallDatabaseEvent $e) { \Civi\Setup::log()->info(sprintf('[%s] Load navigation data', basename(__FILE__))); \Civi\Setup\DbUtil::sourceSQL($model->db, \Civi\Setup\SchemaGenerator::generateNavigation($model->srcPath)); + + \CRM_Core_I18n::$SQL_ESCAPER = NULL; } /** From 66da8e85e41838a97d93845196e14c9183ff9004 Mon Sep 17 00:00:00 2001 From: "deb.monish" Date: Fri, 23 Feb 2018 19:46:45 +0530 Subject: [PATCH 18/22] multilingual fix --- .../installDatabase/InstallSchema.civi-setup.php | 14 ++++++-------- src/Setup/SchemaGenerator.php | 3 ++- 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/plugins/installDatabase/InstallSchema.civi-setup.php b/plugins/installDatabase/InstallSchema.civi-setup.php index a53edd8..7d44a02 100644 --- a/plugins/installDatabase/InstallSchema.civi-setup.php +++ b/plugins/installDatabase/InstallSchema.civi-setup.php @@ -88,23 +88,21 @@ public function installDatabase(\Civi\Setup\Event\InstallDatabaseEvent $e) { \Civi\Setup::log()->info(sprintf('[%s] Load basic tables', basename(__FILE__))); \Civi\Setup\DbUtil::sourceSQL($model->db, \Civi\Setup\SchemaGenerator::generateCreateSql($model->srcPath, $spec->database, $spec->tables)); + $seedLanguage = $model->lang; if (!empty($model->loadGenerated)) { \Civi\Setup::log()->info(sprintf('[%s] Load sample data', basename(__FILE__))); \Civi\Setup\DbUtil::sourceSQL($model->db, \Civi\Setup\SchemaGenerator::generateSample($model->srcPath)); } - else { - $seedLanguage = $model->lang; - // @TODO need to generate and fetch seedLanguage mysql data - if ($seedLanguage && $seedLanguage !== 'en_US') { + elseif ($seedLanguage) { + global $tsLocale; + $tsLocale = $seedLanguage; + if ($seedLanguage !== 'en_US') { \Civi\Setup::log()->info(sprintf('[%s] Load localized data', basename(__FILE__))); - \Civi\Setup\DbUtil::sourceSQL($model->db, file_get_contents($sqlPath . DIRECTORY_SEPARATOR . "civicrm_data.{$seedLanguage}.mysql")); - \Civi\Setup\DbUtil::sourceSQL($model->db, file_get_contents($sqlPath . DIRECTORY_SEPARATOR . "civicrm_acl.{$seedLanguage}.mysql")); } else { \Civi\Setup::log()->info(sprintf('[%s] Load default data', basename(__FILE__))); - \Civi\Setup\DbUtil::sourceSQL($model->db, file_get_contents($sqlPath . DIRECTORY_SEPARATOR . 'civicrm_data.mysql')); - \Civi\Setup\DbUtil::sourceSQL($model->db, file_get_contents($sqlPath . DIRECTORY_SEPARATOR . 'civicrm_acl.mysql')); } + \Civi\Setup\DbUtil::sourceSQL($model->db, \Civi\Setup\SchemaGenerator::generateSample($model->srcPath, $seedLanguage)); } \Civi\Setup::log()->info(sprintf('[%s] Load navigation data', basename(__FILE__))); diff --git a/src/Setup/SchemaGenerator.php b/src/Setup/SchemaGenerator.php index 8b9df8e..7304664 100644 --- a/src/Setup/SchemaGenerator.php +++ b/src/Setup/SchemaGenerator.php @@ -46,7 +46,8 @@ public static function generateNavigation($srcPath) { */ public static function generateSample($srcPath) { $template = new Template($srcPath, 'sql'); - $sections = ['civicrm_sample.tpl', 'civicrm_acl.tpl', 'case_sample.tpl']; + + $sections = ['civicrm_country.tpl', 'civicrm_state_province.tpl', 'civicrm_data.tpl', 'civicrm_acl.tpl', 'case_sample.tpl']; return $template->getConcatContent($sections); } From 4f0315a21d23b420a694bff17540df296ee0389a Mon Sep 17 00:00:00 2001 From: "deb.monish" Date: Thu, 26 Apr 2018 00:03:20 +0530 Subject: [PATCH 19/22] additional fixes --- .../InstallSchema.civi-setup.php | 27 ++++++++----------- src/Setup/SchemaGenerator.php | 14 ++++++++-- 2 files changed, 23 insertions(+), 18 deletions(-) diff --git a/plugins/installDatabase/InstallSchema.civi-setup.php b/plugins/installDatabase/InstallSchema.civi-setup.php index 7d44a02..cad9077 100644 --- a/plugins/installDatabase/InstallSchema.civi-setup.php +++ b/plugins/installDatabase/InstallSchema.civi-setup.php @@ -53,18 +53,6 @@ public function checkSqlFiles(\Civi\Setup\Event\CheckRequirementsEvent $e) { return; } - $files = array( - $sqlPath . DIRECTORY_SEPARATOR . "civicrm_data.{$seedLanguage}.mysql", - $sqlPath . DIRECTORY_SEPARATOR . "civicrm_acl.{$seedLanguage}.mysql", - ); - - foreach ($files as $file) { - if (!file_exists($file)) { - $e->addError('system', 'langMissing', "Language schema file is missing: \"$file\""); - return; - } - } - if (!file_exists($e->getModel()->settingsPath)) { $e->addError('system', 'settingsPath', sprintf('The CiviCRM setting file is missing.')); } @@ -91,7 +79,7 @@ public function installDatabase(\Civi\Setup\Event\InstallDatabaseEvent $e) { $seedLanguage = $model->lang; if (!empty($model->loadGenerated)) { \Civi\Setup::log()->info(sprintf('[%s] Load sample data', basename(__FILE__))); - \Civi\Setup\DbUtil::sourceSQL($model->db, \Civi\Setup\SchemaGenerator::generateSample($model->srcPath)); + \Civi\Setup\DbUtil::sourceSQL($model->db, file_get_contents($sqlPath . DIRECTORY_SEPARATOR . 'civicrm_generated.mysql')); } elseif ($seedLanguage) { global $tsLocale; @@ -102,11 +90,18 @@ public function installDatabase(\Civi\Setup\Event\InstallDatabaseEvent $e) { else { \Civi\Setup::log()->info(sprintf('[%s] Load default data', basename(__FILE__))); } - \Civi\Setup\DbUtil::sourceSQL($model->db, \Civi\Setup\SchemaGenerator::generateSample($model->srcPath, $seedLanguage)); + \Civi\Setup\DbUtil::sourceSQL($model->db, \Civi\Setup\SchemaGenerator::generateSample($model->srcPath, $spec->buildVersion)); + + \Civi\Setup::log()->info(sprintf('[%s] Load navigation data', basename(__FILE__))); + \Civi\Setup\DbUtil::sourceSQL($model->db, \Civi\Setup\SchemaGenerator::generateNavigation($model->srcPath)); + + \Civi\Setup::log()->info(sprintf('[%s] Load zipcode data', basename(__FILE__))); + $conn->query("DROP TABLE IF EXISTS zipcodes"); + \Civi\Setup\DbUtil::sourceSQL($model->db, file_get_contents($sqlPath . DIRECTORY_SEPARATOR . 'zipcodes.mysql')); } - \Civi\Setup::log()->info(sprintf('[%s] Load navigation data', basename(__FILE__))); - \Civi\Setup\DbUtil::sourceSQL($model->db, \Civi\Setup\SchemaGenerator::generateNavigation($model->srcPath)); + require_once $model->settingsPath; + \Civi\Core\Container::boot(TRUE); \CRM_Core_I18n::$SQL_ESCAPER = NULL; } diff --git a/src/Setup/SchemaGenerator.php b/src/Setup/SchemaGenerator.php index 7304664..9d946f4 100644 --- a/src/Setup/SchemaGenerator.php +++ b/src/Setup/SchemaGenerator.php @@ -44,10 +44,20 @@ public static function generateNavigation($srcPath) { * * @return string */ - public static function generateSample($srcPath) { + public static function generateSample($srcPath, $dbVersion) { $template = new Template($srcPath, 'sql'); + $template->assign('db_version', $dbVersion); - $sections = ['civicrm_country.tpl', 'civicrm_state_province.tpl', 'civicrm_data.tpl', 'civicrm_acl.tpl', 'case_sample.tpl']; + $sections = [ + 'civicrm_country.tpl', + 'civicrm_state_province.tpl', + 'civicrm_currency.tpl', + 'civicrm_data.tpl', + 'civicrm_acl.tpl', + 'civicrm_sample.tpl', + 'case_sample.tpl', + 'civicrm_version_sql.tpl', + ]; return $template->getConcatContent($sections); } From c3bed334c9364065101dcf724038ce86467e225b Mon Sep 17 00:00:00 2001 From: Tim Otten Date: Mon, 14 May 2018 23:39:54 -0700 Subject: [PATCH 20/22] SchemaGenerator::generateSample - Use the full version This version number winds up in the database (`civicrm_domain.version`); it needs to be the fully formed number so that future upgrades work correctly. --- plugins/installDatabase/InstallSchema.civi-setup.php | 2 +- src/Setup/SchemaGenerator.php | 7 +++++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/plugins/installDatabase/InstallSchema.civi-setup.php b/plugins/installDatabase/InstallSchema.civi-setup.php index cad9077..28e085f 100644 --- a/plugins/installDatabase/InstallSchema.civi-setup.php +++ b/plugins/installDatabase/InstallSchema.civi-setup.php @@ -90,7 +90,7 @@ public function installDatabase(\Civi\Setup\Event\InstallDatabaseEvent $e) { else { \Civi\Setup::log()->info(sprintf('[%s] Load default data', basename(__FILE__))); } - \Civi\Setup\DbUtil::sourceSQL($model->db, \Civi\Setup\SchemaGenerator::generateSample($model->srcPath, $spec->buildVersion)); + \Civi\Setup\DbUtil::sourceSQL($model->db, \Civi\Setup\SchemaGenerator::generateSample($model->srcPath)); \Civi\Setup::log()->info(sprintf('[%s] Load navigation data', basename(__FILE__))); \Civi\Setup\DbUtil::sourceSQL($model->db, \Civi\Setup\SchemaGenerator::generateNavigation($model->srcPath)); diff --git a/src/Setup/SchemaGenerator.php b/src/Setup/SchemaGenerator.php index 9d946f4..1ca1156 100644 --- a/src/Setup/SchemaGenerator.php +++ b/src/Setup/SchemaGenerator.php @@ -44,9 +44,12 @@ public static function generateNavigation($srcPath) { * * @return string */ - public static function generateSample($srcPath, $dbVersion) { + public static function generateSample($srcPath) { + $versionFile = implode(DIRECTORY_SEPARATOR, [$srcPath, 'xml', 'version.xml']); + $xml = \CRM_Core_CodeGen_Util_Xml::parse($versionFile); + $template = new Template($srcPath, 'sql'); - $template->assign('db_version', $dbVersion); + $template->assign('db_version', $xml->version_no); $sections = [ 'civicrm_country.tpl', From 839da8f324a618eebc40b09b0465905a2b730876 Mon Sep 17 00:00:00 2001 From: Tim Otten Date: Tue, 15 May 2018 00:38:16 -0700 Subject: [PATCH 21/22] InstallSchema - Split `generateSample()`. Preserve old behavior. The behavior (prior to this commit) is not equivalent to published behavior because the normal/minimalist installation includes a smattering of sample records (e.g. sample case-types). This revision helps us do the old behavior by distinguishing between: * `generateBasicData()` is just the baseline data (countries, option-groups, etc). This is equivalent to the old behavior. * `generateSampleData()` includes the baseline data as well as some hypothetical/org-specific data (case-types, etc). This is similar in spirit to `civicrm_generated.mysql`, but it's not complete. --- .../InstallSchema.civi-setup.php | 15 ++----- src/Setup/SchemaGenerator.php | 39 ++++++++++++++++++- 2 files changed, 41 insertions(+), 13 deletions(-) diff --git a/plugins/installDatabase/InstallSchema.civi-setup.php b/plugins/installDatabase/InstallSchema.civi-setup.php index 28e085f..f8a2b90 100644 --- a/plugins/installDatabase/InstallSchema.civi-setup.php +++ b/plugins/installDatabase/InstallSchema.civi-setup.php @@ -79,25 +79,18 @@ public function installDatabase(\Civi\Setup\Event\InstallDatabaseEvent $e) { $seedLanguage = $model->lang; if (!empty($model->loadGenerated)) { \Civi\Setup::log()->info(sprintf('[%s] Load sample data', basename(__FILE__))); + // At time of writing, `generateSampleData()` is not yet a full replacement for `civicrm_generated.mysql`. \Civi\Setup\DbUtil::sourceSQL($model->db, file_get_contents($sqlPath . DIRECTORY_SEPARATOR . 'civicrm_generated.mysql')); + // \Civi\Setup\DbUtil::sourceSQL($model->db, \Civi\Setup\SchemaGenerator::generateSampleData($model->srcPath)); } elseif ($seedLanguage) { global $tsLocale; $tsLocale = $seedLanguage; - if ($seedLanguage !== 'en_US') { - \Civi\Setup::log()->info(sprintf('[%s] Load localized data', basename(__FILE__))); - } - else { - \Civi\Setup::log()->info(sprintf('[%s] Load default data', basename(__FILE__))); - } - \Civi\Setup\DbUtil::sourceSQL($model->db, \Civi\Setup\SchemaGenerator::generateSample($model->srcPath)); + \Civi\Setup::log()->info(sprintf('[%s] Load basic data', basename(__FILE__))); + \Civi\Setup\DbUtil::sourceSQL($model->db, \Civi\Setup\SchemaGenerator::generateBasicData($model->srcPath)); \Civi\Setup::log()->info(sprintf('[%s] Load navigation data', basename(__FILE__))); \Civi\Setup\DbUtil::sourceSQL($model->db, \Civi\Setup\SchemaGenerator::generateNavigation($model->srcPath)); - - \Civi\Setup::log()->info(sprintf('[%s] Load zipcode data', basename(__FILE__))); - $conn->query("DROP TABLE IF EXISTS zipcodes"); - \Civi\Setup\DbUtil::sourceSQL($model->db, file_get_contents($sqlPath . DIRECTORY_SEPARATOR . 'zipcodes.mysql')); } require_once $model->settingsPath; diff --git a/src/Setup/SchemaGenerator.php b/src/Setup/SchemaGenerator.php index 1ca1156..ebbc7af 100644 --- a/src/Setup/SchemaGenerator.php +++ b/src/Setup/SchemaGenerator.php @@ -38,19 +38,24 @@ public static function generateNavigation($srcPath) { } /** - * Return translated SQL content using tpl, mainly contain SQL codes to populate essential CiviCRM data + * Generate an example set of data, including the basic data as well + * as some example records/entities (e.g. case-types, membership types). * * @param string $srcPath * * @return string */ - public static function generateSample($srcPath) { + public static function generateSampleData($srcPath) { $versionFile = implode(DIRECTORY_SEPARATOR, [$srcPath, 'xml', 'version.xml']); $xml = \CRM_Core_CodeGen_Util_Xml::parse($versionFile); $template = new Template($srcPath, 'sql'); $template->assign('db_version', $xml->version_no); + // If you're going to use the full data generator... + // "DROP TABLE IF EXISTS zipcodes" + // .... file_get_contents($sqlPath . DIRECTORY_SEPARATOR . 'zipcodes.mysql')... + $sections = [ 'civicrm_country.tpl', 'civicrm_state_province.tpl', @@ -61,6 +66,36 @@ public static function generateSample($srcPath) { 'case_sample.tpl', 'civicrm_version_sql.tpl', ]; + + // DROP TABLE IF EXISTS zipcodes; + + return $template->getConcatContent($sections); + } + + /** + * Generate a minimalist set of basic data, such as + * common option-values and countries. + * + * @param string $srcPath + * + * @return string + * SQL + */ + public static function generateBasicData($srcPath) { + $versionFile = implode(DIRECTORY_SEPARATOR, [$srcPath, 'xml', 'version.xml']); + $xml = \CRM_Core_CodeGen_Util_Xml::parse($versionFile); + + $template = new Template($srcPath, 'sql'); + $template->assign('db_version', $xml->version_no); + + $sections = [ + 'civicrm_country.tpl', + 'civicrm_state_province.tpl', + 'civicrm_currency.tpl', + 'civicrm_data.tpl', + 'civicrm_acl.tpl', + 'civicrm_version_sql.tpl', + ]; return $template->getConcatContent($sections); } From a109dda1c9fc469328effcdfba2d56d298a4f13c Mon Sep 17 00:00:00 2001 From: Tim Otten Date: Tue, 15 May 2018 00:46:00 -0700 Subject: [PATCH 22/22] SchemaGenerator - Simplify code-style for calling civicrm_navigation.tpl There are a bunch of `*.tpl` files which are incorporated into the baseline dataset. Most of these are listed in an array in `generateBasicData()`, but `civicrm_navigation.tpl` was treated differently (with its own `generateNavigation()`). This cuts down several SLOC. It appears to be equivalent based on reading and based on testing DB snapshots (before/after). --- .../installDatabase/InstallSchema.civi-setup.php | 3 --- src/Setup/SchemaGenerator.php | 14 ++------------ 2 files changed, 2 insertions(+), 15 deletions(-) diff --git a/plugins/installDatabase/InstallSchema.civi-setup.php b/plugins/installDatabase/InstallSchema.civi-setup.php index f8a2b90..f8752e3 100644 --- a/plugins/installDatabase/InstallSchema.civi-setup.php +++ b/plugins/installDatabase/InstallSchema.civi-setup.php @@ -88,9 +88,6 @@ public function installDatabase(\Civi\Setup\Event\InstallDatabaseEvent $e) { $tsLocale = $seedLanguage; \Civi\Setup::log()->info(sprintf('[%s] Load basic data', basename(__FILE__))); \Civi\Setup\DbUtil::sourceSQL($model->db, \Civi\Setup\SchemaGenerator::generateBasicData($model->srcPath)); - - \Civi\Setup::log()->info(sprintf('[%s] Load navigation data', basename(__FILE__))); - \Civi\Setup\DbUtil::sourceSQL($model->db, \Civi\Setup\SchemaGenerator::generateNavigation($model->srcPath)); } require_once $model->settingsPath; diff --git a/src/Setup/SchemaGenerator.php b/src/Setup/SchemaGenerator.php index ebbc7af..b093c4f 100644 --- a/src/Setup/SchemaGenerator.php +++ b/src/Setup/SchemaGenerator.php @@ -25,18 +25,6 @@ public static function generateCreateSql($srcPath, $database, $tables) { return $template->getContent('schema.tpl'); } - /** - * Return translated SQL content using tpl, mainly contain SQL codes to populate navigation links - * - * @param string $srcPath - * - * @return string - */ - public static function generateNavigation($srcPath) { - $template = new Template($srcPath, 'sql'); - return $template->getContent('civicrm_navigation.tpl'); - } - /** * Generate an example set of data, including the basic data as well * as some example records/entities (e.g. case-types, membership types). @@ -65,6 +53,7 @@ public static function generateSampleData($srcPath) { 'civicrm_sample.tpl', 'case_sample.tpl', 'civicrm_version_sql.tpl', + 'civicrm_navigation.tpl', ]; // DROP TABLE IF EXISTS zipcodes; @@ -95,6 +84,7 @@ public static function generateBasicData($srcPath) { 'civicrm_data.tpl', 'civicrm_acl.tpl', 'civicrm_version_sql.tpl', + 'civicrm_navigation.tpl', ]; return $template->getConcatContent($sections); }