From f99eae901a7dc5724db57add138c0d395f5dc5ea Mon Sep 17 00:00:00 2001 From: aB0t Date: Wed, 24 Apr 2024 21:10:42 +0200 Subject: [PATCH] Release of v3.2.1-beta3 Fix version_update column size. Improved the Schema Table update engine. --- CHANGELOG.md | 5 + README.md | 10 +- admin/README.txt | 10 +- admin/sql/install.mysql.utf8.sql | 6 +- admin/sql/updates/mysql/3.2.1-beta1.sql | 14 +- admin/sql/updates/mysql/3.2.1-beta2.sql | 3 + componentbuilder.xml | 6 +- componentbuilder_update_server.xml | 18 + .../VDM.Joomla/src/Abstraction/BaseTable.php | 4 +- .../VDM.Joomla/src/Abstraction/Schema.php | 441 +++++++++++++----- .../Compiler/Adminview/Data.php | 16 + .../Compiler/Component/Data.php | 6 + .../Compiler/Customview/Data.php | 6 + .../VDM.Joomla/src/Componentbuilder/Table.php | 6 +- script.php | 15 +- 15 files changed, 403 insertions(+), 163 deletions(-) create mode 100644 admin/sql/updates/mysql/3.2.1-beta2.sql diff --git a/CHANGELOG.md b/CHANGELOG.md index dac774d53..f9cb19948 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,8 @@ +# v3.2.1-beta3 + +- Fix version_update column size. +- Improved the Schema Table update engine. + # v3.2.1-beta2 - Fix the media field size limitation. #1109 diff --git a/README.md b/README.md index 102529ced..1162ef525 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ The Component Builder for [Joomla](https://extensions.joomla.org/extension/compo Whether you're a seasoned [Joomla](https://extensions.joomla.org/extension/component-builder/) developer, or have just started, Component Builder will save you lots of time and money. A real must have! -You can install it quite easily and with no limitations. On [gitea](https://git.vdm.dev/joomla/Component-Builder/tags) is the latest release (3.2.1-beta2) with **ALL** its features and **ALL** concepts totally open-source and free! +You can install it quite easily and with no limitations. On [gitea](https://git.vdm.dev/joomla/Component-Builder/tags) is the latest release (3.2.1-beta3) with **ALL** its features and **ALL** concepts totally open-source and free! > Watch Quick Build of a Hello World component in [JCB on Youtube](https://www.youtube.com/watch?v=IQfsLYIeblk&list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&index=45) @@ -144,13 +144,13 @@ TODO + *Author*: [Llewellyn van der Merwe](mailto:joomla@vdm.io) + *Name*: [Component Builder](https://git.vdm.dev/joomla/Component-Builder) + *First Build*: 30th April, 2015 -+ *Last Build*: 22nd April, 2024 -+ *Version*: 3.2.1-beta2 ++ *Last Build*: 24th April, 2024 ++ *Version*: 3.2.1-beta3 + *Copyright*: Copyright (C) 2015 Vast Development Method. All rights reserved. + *License*: GNU General Public License version 2 or later; see LICENSE.txt -+ *Line count*: **764243** ++ *Line count*: **764955** + *Field count*: **2097** -+ *File count*: **5381** ++ *File count*: **5382** + *Folder count*: **471** > This **component** was build with a [Joomla](https://extensions.joomla.org/extension/component-builder/) [Automated Component Builder](https://www.joomlacomponentbuilder.com). diff --git a/admin/README.txt b/admin/README.txt index 102529ced..1162ef525 100644 --- a/admin/README.txt +++ b/admin/README.txt @@ -9,7 +9,7 @@ The Component Builder for [Joomla](https://extensions.joomla.org/extension/compo Whether you're a seasoned [Joomla](https://extensions.joomla.org/extension/component-builder/) developer, or have just started, Component Builder will save you lots of time and money. A real must have! -You can install it quite easily and with no limitations. On [gitea](https://git.vdm.dev/joomla/Component-Builder/tags) is the latest release (3.2.1-beta2) with **ALL** its features and **ALL** concepts totally open-source and free! +You can install it quite easily and with no limitations. On [gitea](https://git.vdm.dev/joomla/Component-Builder/tags) is the latest release (3.2.1-beta3) with **ALL** its features and **ALL** concepts totally open-source and free! > Watch Quick Build of a Hello World component in [JCB on Youtube](https://www.youtube.com/watch?v=IQfsLYIeblk&list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&index=45) @@ -144,13 +144,13 @@ TODO + *Author*: [Llewellyn van der Merwe](mailto:joomla@vdm.io) + *Name*: [Component Builder](https://git.vdm.dev/joomla/Component-Builder) + *First Build*: 30th April, 2015 -+ *Last Build*: 22nd April, 2024 -+ *Version*: 3.2.1-beta2 ++ *Last Build*: 24th April, 2024 ++ *Version*: 3.2.1-beta3 + *Copyright*: Copyright (C) 2015 Vast Development Method. All rights reserved. + *License*: GNU General Public License version 2 or later; see LICENSE.txt -+ *Line count*: **764243** ++ *Line count*: **764955** + *Field count*: **2097** -+ *File count*: **5381** ++ *File count*: **5382** + *Folder count*: **471** > This **component** was build with a [Joomla](https://extensions.joomla.org/extension/component-builder/) [Automated Component Builder](https://www.joomlacomponentbuilder.com). diff --git a/admin/sql/install.mysql.utf8.sql b/admin/sql/install.mysql.utf8.sql index fb4346be7..079faf6f5 100644 --- a/admin/sql/install.mysql.utf8.sql +++ b/admin/sql/install.mysql.utf8.sql @@ -1525,7 +1525,7 @@ CREATE TABLE IF NOT EXISTS `#__componentbuilder_component_updates` ( `id` INT(11) NOT NULL AUTO_INCREMENT, `asset_id` INT(10) unsigned NOT NULL DEFAULT 0 COMMENT 'FK to the #__assets table.', `joomla_component` INT(11) NOT NULL DEFAULT 0, - `version_update` TEXT NOT NULL, + `version_update` MEDIUMTEXT NOT NULL, `params` TEXT NULL, `published` TINYINT(3) NOT NULL DEFAULT 1, `created_by` INT(10) unsigned NOT NULL DEFAULT 0, @@ -1905,7 +1905,7 @@ CREATE TABLE IF NOT EXISTS `#__componentbuilder_joomla_module_updates` ( `id` INT(11) NOT NULL AUTO_INCREMENT, `asset_id` INT(10) unsigned NOT NULL DEFAULT 0 COMMENT 'FK to the #__assets table.', `joomla_module` INT(11) NOT NULL DEFAULT 0, - `version_update` TEXT NOT NULL, + `version_update` MEDIUMTEXT NOT NULL, `params` TEXT NULL, `published` TINYINT(3) NOT NULL DEFAULT 1, `created_by` INT(10) unsigned NOT NULL DEFAULT 0, @@ -1988,7 +1988,7 @@ CREATE TABLE IF NOT EXISTS `#__componentbuilder_joomla_plugin_updates` ( `id` INT(11) NOT NULL AUTO_INCREMENT, `asset_id` INT(10) unsigned NOT NULL DEFAULT 0 COMMENT 'FK to the #__assets table.', `joomla_plugin` INT(11) NOT NULL DEFAULT 0, - `version_update` TEXT NOT NULL, + `version_update` MEDIUMTEXT NOT NULL, `params` TEXT NULL, `published` TINYINT(3) NOT NULL DEFAULT 1, `created_by` INT(10) unsigned NOT NULL DEFAULT 0, diff --git a/admin/sql/updates/mysql/3.2.1-beta1.sql b/admin/sql/updates/mysql/3.2.1-beta1.sql index ef45481f2..5bcf8654f 100644 --- a/admin/sql/updates/mysql/3.2.1-beta1.sql +++ b/admin/sql/updates/mysql/3.2.1-beta1.sql @@ -1,13 +1,15 @@ +UPDATE `#__componentbuilder_admin_view` +SET `alias_builder_type` = 0 +WHERE `alias_builder_type` = ''; + +UPDATE `#__componentbuilder_dynamic_get` +SET `addcalculation` = 0 +WHERE `addcalculation` = ''; + ALTER TABLE `#__componentbuilder_joomla_component` CHANGE `image` `image` VARCHAR(255) NOT NULL DEFAULT ''; - ALTER TABLE `#__componentbuilder_admin_view` CHANGE `alias_builder_type` `alias_builder_type` TINYINT(1) NOT NULL DEFAULT 0; - ALTER TABLE `#__componentbuilder_admin_view` CHANGE `icon` `icon` VARCHAR(255) NOT NULL DEFAULT ''; - ALTER TABLE `#__componentbuilder_admin_view` CHANGE `icon_add` `icon_add` VARCHAR(255) NOT NULL DEFAULT ''; - ALTER TABLE `#__componentbuilder_admin_view` CHANGE `icon_category` `icon_category` VARCHAR(255) NOT NULL DEFAULT ''; - ALTER TABLE `#__componentbuilder_custom_admin_view` CHANGE `icon` `icon` VARCHAR(255) NOT NULL DEFAULT ''; - ALTER TABLE `#__componentbuilder_dynamic_get` CHANGE `addcalculation` `addcalculation` TINYINT(1) NOT NULL DEFAULT 0; diff --git a/admin/sql/updates/mysql/3.2.1-beta2.sql b/admin/sql/updates/mysql/3.2.1-beta2.sql new file mode 100644 index 000000000..9c9830468 --- /dev/null +++ b/admin/sql/updates/mysql/3.2.1-beta2.sql @@ -0,0 +1,3 @@ +ALTER TABLE `#__componentbuilder_component_updates` CHANGE `version_update` `version_update` MEDIUMTEXT NOT NULL; +ALTER TABLE `#__componentbuilder_joomla_module_updates` CHANGE `version_update` `version_update` MEDIUMTEXT NOT NULL; +ALTER TABLE `#__componentbuilder_joomla_plugin_updates` CHANGE `version_update` `version_update` MEDIUMTEXT NOT NULL; diff --git a/componentbuilder.xml b/componentbuilder.xml index c160e3c2c..ab0da3e10 100644 --- a/componentbuilder.xml +++ b/componentbuilder.xml @@ -1,15 +1,15 @@ COM_COMPONENTBUILDER - 22nd April, 2024 + 24th April, 2024 Llewellyn van der Merwe joomla@vdm.io https://dev.vdm.io Copyright (C) 2015 Vast Development Method. All rights reserved. GNU General Public License version 2 or later; see LICENSE.txt - 3.2.1-beta2 + 3.2.1-beta3 Component Builder (v.3.2.1-beta2) +

Component Builder (v.3.2.1-beta3)

The Component Builder for [Joomla](https://extensions.joomla.org/extension/component-builder/) is highly advanced tool that is truly able to build extremely complex components in a fraction of the time. diff --git a/componentbuilder_update_server.xml b/componentbuilder_update_server.xml index ca80d4a78..3201f98ad 100644 --- a/componentbuilder_update_server.xml +++ b/componentbuilder_update_server.xml @@ -1667,4 +1667,22 @@ https://dev.vdm.io + + Component Builder + Builds Complex Joomla Components + pkg_component_builder + package + site + 3.2.1-beta3 + https://dev.vdm.io + + https://git.vdm.dev/api/v1/repos/joomla/pkg-component-builder/archive/v3.2.1-beta3.zip + + + beta + + Llewellyn van der Merwe + https://dev.vdm.io + + \ No newline at end of file diff --git a/libraries/vendor_jcb/VDM.Joomla/src/Abstraction/BaseTable.php b/libraries/vendor_jcb/VDM.Joomla/src/Abstraction/BaseTable.php index ee9043d9e..46227edca 100644 --- a/libraries/vendor_jcb/VDM.Joomla/src/Abstraction/BaseTable.php +++ b/libraries/vendor_jcb/VDM.Joomla/src/Abstraction/BaseTable.php @@ -48,7 +48,7 @@ abstract class BaseTable implements Tableinterface 'tab_name' => NULL, 'db' => [ 'type' => 'INT(11)', - 'default' => '', + 'default' => 'EMPTY', 'auto_increment' => true, 'primary_key' => true, 'null_switch' => 'NOT NULL' @@ -227,7 +227,7 @@ abstract class BaseTable implements Tableinterface 'tab_name' => NULL, 'db' => [ 'type' => 'TEXT', - 'default' => '', + 'default' => 'EMPTY', 'null_switch' => 'NULL' ] ] diff --git a/libraries/vendor_jcb/VDM.Joomla/src/Abstraction/Schema.php b/libraries/vendor_jcb/VDM.Joomla/src/Abstraction/Schema.php index 764b7d5e6..53c05915a 100644 --- a/libraries/vendor_jcb/VDM.Joomla/src/Abstraction/Schema.php +++ b/libraries/vendor_jcb/VDM.Joomla/src/Abstraction/Schema.php @@ -12,7 +12,8 @@ namespace VDM\Joomla\Abstraction; -use Joomla\CMS\Factory; +use Joomla\CMS\Factory; +use Joomla\CMS\Version; use VDM\Joomla\Interfaces\Tableinterface as Table; use VDM\Joomla\Interfaces\SchemaInterface; @@ -87,6 +88,14 @@ abstract class Schema implements SchemaInterface */ private array $success; + /** + * Current Joomla Version We are IN + * + * @var int + * @since 3.2.1 + **/ + protected $currentVersion; + /** * Constructor. * @@ -108,8 +117,11 @@ abstract class Schema implements SchemaInterface // set the component table $this->prefix = $this->db->getPrefix() . $this->getCode(); + + // set the current version + $this->currentVersion = Version::MAJOR_VERSION; } catch (\Exception $e) { - throw new \Exception("Error: failed to initialize schema class due to a database error.", 0, $e); + throw new \Exception("Error: failed to initialize schema class due to a database error."); } } @@ -141,7 +153,7 @@ abstract class Schema implements SchemaInterface } } } catch (\Exception $e) { - throw new \Exception("Error: updating database schema.", 0, $e); + throw new \Exception("Error: updating database schema. " . $e->getMessage()); } if (count($this->success) == 1) @@ -156,6 +168,63 @@ abstract class Schema implements SchemaInterface return $this->success; } + /** + * Get the targeted component code + * + * @return string + * @since 3.2.1 + */ + abstract protected function getCode(): string; + + /** + * Check if a table exists in the database. + * + * @param string $table The name of the table to check. + * + * @return bool True if table exists, False otherwise. + * @since 3.2.1 + */ + protected function tableExists(string $table): bool + { + return in_array($this->getTable($table), $this->tables); + } + + /** + * Update the schema of an existing table. + * + * @param string $table The table to update. + * + * @return void + * @since 3.2.1 + * @throws \Exception If there is an error while updating the schema. + */ + public function updateSchema(string $table): void + { + try { + $existingColumns = $this->getExistingColumns($table); + $expectedColumns = $this->table->fields($table, true); + + $missingColumns = array_diff($expectedColumns, $existingColumns); + + if (!empty($missingColumns)) + { + $this->addMissingColumns($table, $missingColumns); + } + + $this->checkColumnsDataType($table, $expectedColumns); + + } catch (\Exception $e) { + throw new \Exception("Error: updating schema for $table table. " . $e->getMessage()); + } + + if (!empty($missingColumns)) + { + $column_s = (count($missingColumns) == 1) ? 'column' : 'columns'; + $missingColumns = implode(', ', $missingColumns); + $this->success[] = "Success: added missing ($missingColumns) $column_s to $table table."; + } + } + /** * Create a table with all necessary fields. * @@ -189,56 +258,27 @@ abstract class Schema implements SchemaInterface $this->db->setQuery($createTableSql); $this->db->execute(); } catch (\Exception $e) { - throw new \Exception("Error: failed to create missing $table table.", 0, $e); + throw new \Exception("Error: failed to create missing $table table. " . $e->getMessage()); } $this->success[] = "Success: created missing $table table."; } /** - * Update the schema of an existing table. + * Fetch existing columns from a database table. * - * @param string $table The table to update. + * @param string $table The name of the table. * - * @return void + * @return array An array of column names. * @since 3.2.1 - * @throws \Exception If there is an error while updating the schema. */ - public function updateSchema(string $table): void + protected function getExistingColumns(string $table): array { - try { - $existingColumns = $this->getExistingColumns($table); - $expectedColumns = $this->table->fields($table, true); + $this->columns = $this->db->getTableColumns($this->getTable($table), false); - $missingColumns = array_diff($expectedColumns, $existingColumns); - - if (!empty($missingColumns)) - { - $this->addMissingColumns($table, $missingColumns); - } - - $this->checkColumnsDataType($table, $expectedColumns); - - } catch (\Exception $e) { - throw new \Exception("Error: updating schema for $table table.", 0, $e); - } - - if (!empty($missingColumns)) - { - $column_s = (count($missingColumns) == 1) ? 'column' : 'columns'; - $missingColumns = implode(', ', $missingColumns); - $this->success[] = "Success: added missing ($missingColumns) $column_s to $table table."; - } + return array_keys($this->columns); } - /** - * Get the targeted component code - * - * @return string - * @since 3.2.1 - */ - abstract protected function getCode(): string; - /** * Add missing columns to a table. * @@ -270,7 +310,7 @@ abstract class Schema implements SchemaInterface } catch (\Exception $e) { $column_s = (count($columns) == 1) ? 'column' : 'columns'; $columns = implode(', ', $columns); - throw new \Exception("Error: failed to add ($columns) $column_s to $table table.", 0, $e); + throw new \Exception("Error: failed to add ($columns) $column_s to $table table. " . $e->getMessage()); } } @@ -291,18 +331,20 @@ abstract class Schema implements SchemaInterface $current = $this->columns[$column] ?? null; if ($current === null || ($expected = $this->table->get($table, $column, 'db')) === null) { - // this field is no longer part of the component and can be ignored continue; } // check if the data type and size match - if (strcasecmp($current->Type, $expected['type']) != 0) + if ($this->isDataTypeChangeSignificant($current->Type, $expected['type'])) { $requireUpdate[$column] = [ 'column' => $column, 'current' => $current->Type, 'expected' => $expected['type'] ]; + + // check if update of default values is needed + $this->checkDefault($table, $column); } } @@ -312,6 +354,89 @@ abstract class Schema implements SchemaInterface } } + /** + * Generates a SQL snippet for defining a table column, incorporating column type, + * default value, nullability, and auto-increment properties. + * + * @param string $table The table name to be used. + * @param string $field The field name in the table to generate SQL for. + * + * @return string|null The SQL snippet for the column definition. + * @since 3.2.1 + * @throws \Exception If the schema details cannot be retrieved or the SQL statement cannot be constructed properly. + */ + protected function getColumnDefinition(string $table, string $field): ?string + { + try { + // Retrieve the database schema details for the specified table and field + if (($db = $this->table->get($table, $field, 'db')) === null) + { + return null; + } + + // Prepare the column name + $column_name = $this->db->quoteName($field); + $db['name'] = $field; + + // Prepare the type and default value SQL statement + $type = $db['type'] ?? 'TEXT'; + $db_default = isset($db['default']) ? $db['default'] : null; + $default = $this->getDefaultValue($type, $db_default); + + // Prepare the null switch, and auto increment statement + $null_switch = !empty($db['null_switch']) ? " " . $db['null_switch'] : ''; + $auto_increment = !empty($db['auto_increment']) ? " AUTO_INCREMENT" : ''; + + $this->setKeys($db); + + // Assemble the SQL snippet for the column definition + return "{$column_name} {$type}{$null_switch}{$default}{$auto_increment}"; + } catch (\Exception $e) { + throw new \Exception("Error: failed to generate column definition for ($table.$field). " . $e->getMessage()); + } + } + + /** + * Check and Update the default values if needed, including existing data adjustments + * + * @param string $table The table to update. + * @param string $column The column/field to check. + * + * @return void + * @since 3.2.1 + */ + protected function checkDefault(string $table, string $column): void + { + // Retrieve the expected column configuration + $expected = $this->table->get($table, $column, 'db'); + + // Skip updates if the column is auto_increment + if (isset($expected['auto_increment']) && $expected['auto_increment']) + { + return; + } + + // Retrieve the current column configuration + $current = $this->columns[$column]; + + // Check if default should be empty and current default is null, skip processing + if (strtoupper($expected['default']) === 'EMPTY' && $current->Default === NULL) + { + return; + } + + // Determine the new default value based on the expected settings + $type = $expected['type'] ?? 'TEXT'; + $db_default = isset($expected['default']) ? $expected['default'] : null; + $newDefault = $this->getDefaultValue($type, $db_default, true); + + // First, adjust existing rows to conform to the new default if necessary + if (is_numeric($newDefault) && $this->adjustExistingDefaults($table, $column, $current->Default, $newDefault)) + { + $this->success[] = "Success: updated the ($column) defaults in $table table."; + } + } + /** * Update the data type of the given fields. * @@ -336,13 +461,120 @@ abstract class Schema implements SchemaInterface if ($this->updateColumnDataType($alterQuery, $table, $column)) { - $current = (string) $types['current'] ?? 'error'; - $expected = (string) $types['expected'] ?? 'error'; + $current = $types['current'] ?? 'error'; + $expected = $types['expected'] ?? 'error'; $this->success[] = "Success: updated ($column) column datatype $current to $expected in $table table."; } } } - + + /** + * Add the component name to get the full table name. + * + * @param string $table The table name. + * + * @return void + * @since 3.2.1 + */ + protected function getTable(string $table): string + { + return $this->prefix . '_' . $table; + } + + /** + * Determines if the change in data type between two definitions is significant. + * + * This function checks if there's a significant difference between the current + * data type and the expected data type that would require updating the database schema. + * It ignores size and other modifiers for certain data types where MySQL considers + * these attributes irrelevant for storage. + * + * @param string $currentType The current data type from the database schema. + * @param string $expectedType The expected data type to validate against. + * + * @return bool Returns true if the data type change is significant, otherwise false. + * @since 3.2.1 + */ + function isDataTypeChangeSignificant(string $currentType, string $expectedType): bool + { + // we only do this for Joomla 4+ + if ($this->currentVersion != 3) + { + // Normalize both input types to lowercase for case-insensitive comparison + $currentType = strtolower($currentType); + $expectedType = strtolower($expectedType); + + // Define types where size or other modifiers are irrelevant + $sizeIrrelevantTypes = [ + 'int', 'tinyint', 'smallint', 'mediumint', 'bigint', // Standard integer types + 'int unsigned', 'tinyint unsigned', 'smallint unsigned', 'mediumint unsigned', 'bigint unsigned', // Unsigned integer types + ]; + + // Check if the type involves size-irrelevant types + foreach ($sizeIrrelevantTypes as $type) + { + if (strpos($expectedType, $type) !== false) + { + // Remove any numeric sizes and modifiers for comparison + $pattern = '/\(\d+\)|unsigned|\s*/'; + $cleanCurrentType = preg_replace($pattern, '', $currentType); + $cleanExpectedType = preg_replace($pattern, '', $expectedType); + + // Compare the cleaned types + if ($cleanCurrentType === $cleanExpectedType) + { + return false; // No significant change + } + } + } + } + + // Perform a standard case-insensitive comparison for other types + if (strcasecmp($currentType, $expectedType) == 0) + { + return false; // No significant change + } + + return true; // Significant datatype change detected + } + + /** + * Updates existing rows in a column to a new default value + * + * @param string $table The table to update. + * @param string $column The column to update. + * @param mixed $currentDefault Current default value. + * @param mixed $newDefault The new default value to be set. + * + * @return void + * @since 3.2.1 + * @throws \Exception If there is an error updating column defaults. + */ + protected function adjustExistingDefaults(string $table, string $column, $currentDefault, $newDefault): bool + { + // Determine if adjustment is needed based on new and current defaults + if ($newDefault !== $currentDefault) + { + try { + // Format the new default for SQL use + $sqlDefault = $this->db->quote($newDefault); + + $updateTable = 'UPDATE ' . $this->db->quoteName($this->getTable($table)); + $dbField = $this->db->quoteName($column); + + // Update SQL to set new default on existing rows where the default is currently the old default + $sql = $updateTable . " SET $dbField = $sqlDefault WHERE $dbField IS NULL OR $dbField = ''"; + + // Execute the update + $this->db->setQuery($sql); + return $this->db->execute(); + } catch (\Exception $e) { + throw new \Exception("Error: failed to update ($column) column defaults in $table table. " . $e->getMessage()); + } + } + return false; + } + /** * Update the data type of the given field. * @@ -360,7 +592,7 @@ abstract class Schema implements SchemaInterface $this->db->setQuery($updateString); return $this->db->execute(); } catch (\Exception $e) { - throw new \Exception("Error: failed to update the datatype of ($field) column in $table table.", 0, $e); + throw new \Exception("Error: failed to update the datatype of ($field) column in $table table. " . $e->getMessage()); } } @@ -388,6 +620,20 @@ abstract class Schema implements SchemaInterface return implode(', ', $keys); } + /** + * Function to set the view keys + * + * @param string $column The field column database array values + * + * @return void + * @since 3.2.1 + */ + protected function setKeys(array $column): void + { + $this->setUniqueKey($column); + $this->setKey($column); + } + /** * Function to set the unique key * @@ -423,97 +669,34 @@ abstract class Schema implements SchemaInterface } /** - * Add the component name to get the full table name. + * Adjusts the default value SQL fragment for a database field based on its type and specific rules. * - * @param string $table The table name. + * If the field is of type DATETIME and the Joomla version is not 3, it sets the default to CURRENT_TIMESTAMP + * if not explicitly specified otherwise. For all other types, or when a 'EMPTY' default is specified, it handles + * defaults by either leaving them unset or applying the provided default, properly quoted for SQL safety. * - * @return void - * @since 3.2.1 - */ - protected function getTable(string $table): string - { - return $this->prefix . '_' . $table; - } - - /** - * Check if a table exists in the database. + * @param string $type The type of the database field (e.g., 'DATETIME'). + * @param string|null $defaultValue Optional default value for the field, null if not provided. + * @param bool $pure Optional to add the 'DEFAULT' string or not. * - * @param string $table The name of the table to check. - * - * @return bool True if table exists, False otherwise. - * @since 3.2.1 - */ - private function tableExists(string $table): bool - { - return in_array($this->getTable($table), $this->tables); - } - - /** - * Fetch existing columns from a database table. - * - * @param string $table The name of the table. - * - * @return array An array of column names. - * @since 3.2.1 - */ - private function getExistingColumns(string $table): array - { - $this->columns = $this->db->getTableColumns($this->getTable($table), false); - - return array_keys($this->columns); - } - - /** - * Generates a SQL snippet for defining a table column, incorporating column type, - * default value, nullability, and auto-increment properties. - * - * @param string $table The table name to be used. - * @param string $field The field name in the table to generate SQL for. - * - * @return string|null The SQL snippet for the column definition. + * @return string The SQL fragment to set the default value for a field. * @since 3.2.1 - * @throws \Exception If the schema details cannot be retrieved or the SQL statement cannot be constructed properly. */ - private function getColumnDefinition(string $table, string $field): ?string + protected function getDefaultValue(string $type, ?string $defaultValue, bool $pure = false): string { - try { - // Retrieve the database schema details for the specified table and field - if (($db = $this->table->get($table, $field, 'db')) === null) - { - return null; - } - - // Prepare the column name - $column_name = $this->db->quoteName($field); - $db['name'] = $field; - - // Prepare the default value SQL, null switch, and auto increment statement - $default = !empty($db['default']) ? " DEFAULT " . $this->db->quote($db['default']) : ''; - $null_switch = !empty($db['null_switch']) ? " " . $db['null_switch'] : ''; - $auto_increment = !empty($db['auto_increment']) ? " AUTO_INCREMENT" : ''; - $type = !empty($db['type']) ? $db['type'] : 'TEXT'; - - $this->setKeys($db); - - // Assemble the SQL snippet for the column definition - return "{$column_name} {$type}{$default}{$null_switch}{$auto_increment}"; - } catch (\Exception $e) { - throw new \Exception("Error: failed to generate column definition for $table.$field", 0, $e); + if ($defaultValue === null || strtoupper($defaultValue) === 'EMPTY') + { + return ''; } - } - /** - * Function to set the view keys - * - * @param string $column The field column database array values - * - * @return void - * @since 3.2.1 - */ - private function setKeys(array $column): void - { - $this->setUniqueKey($column); - $this->setKey($column); + // Set default for DATETIME fields in Joomla versions above 3 + if (strtoupper($type) === 'DATETIME' && $this->currentVersion != 3) + { + return $pure ? "CURRENT_TIMESTAMP" : " DEFAULT CURRENT_TIMESTAMP"; + } + + // Apply and quote the default value + return $pure ? $defaultValue : " DEFAULT " . $this->db->quote($defaultValue); } } diff --git a/libraries/vendor_jcb/VDM.Joomla/src/Componentbuilder/Compiler/Adminview/Data.php b/libraries/vendor_jcb/VDM.Joomla/src/Componentbuilder/Compiler/Adminview/Data.php index 3f82ff0b0..501266958 100644 --- a/libraries/vendor_jcb/VDM.Joomla/src/Componentbuilder/Compiler/Adminview/Data.php +++ b/libraries/vendor_jcb/VDM.Joomla/src/Componentbuilder/Compiler/Adminview/Data.php @@ -433,6 +433,22 @@ class Data } unset($view->addtables); + // Make sure the icon is only an icon path + if (strpos($view->icon, '#') !== false) + { + $view->icon = strstr($view->icon, '#', true); + } + // Make sure the icon_add is only an icon_add path + if (strpos($view->icon_add, '#') !== false) + { + $view->icon_add = strstr($view->icon_add, '#', true); + } + // Make sure the icon_add is only an icon_add path + if (strpos($view->icon_category, '#') !== false) + { + $view->icon_category = strstr($view->icon_category, '#', true); + } + // set custom tabs $this->customtabs->set($view); diff --git a/libraries/vendor_jcb/VDM.Joomla/src/Componentbuilder/Compiler/Component/Data.php b/libraries/vendor_jcb/VDM.Joomla/src/Componentbuilder/Compiler/Component/Data.php index 541af4c40..93ba3016c 100644 --- a/libraries/vendor_jcb/VDM.Joomla/src/Componentbuilder/Compiler/Component/Data.php +++ b/libraries/vendor_jcb/VDM.Joomla/src/Componentbuilder/Compiler/Component/Data.php @@ -404,6 +404,12 @@ final class Data ) ); + // Make sure the image is only an image path + if (strpos($component->image, '#') !== false) + { + $component->image = strstr($component->image, '#', true); + } + // set the website and autor for global use (default to VDM if not found) $this->config->set('project_website', $component->website ?? 'https://dev.vdm.io'); $this->config->set('project_author', $component->author ?? 'VDM'); diff --git a/libraries/vendor_jcb/VDM.Joomla/src/Componentbuilder/Compiler/Customview/Data.php b/libraries/vendor_jcb/VDM.Joomla/src/Componentbuilder/Compiler/Customview/Data.php index f3ac65786..de049af55 100644 --- a/libraries/vendor_jcb/VDM.Joomla/src/Componentbuilder/Compiler/Customview/Data.php +++ b/libraries/vendor_jcb/VDM.Joomla/src/Componentbuilder/Compiler/Customview/Data.php @@ -243,6 +243,12 @@ class Data 'jcb_ce_onBeforeModelCustomViewData', [&$item, &$id, &$table] ); + // Make sure the icon is only an icon path + if (strpos($item->icon, '#') !== false) + { + $item->icon = strstr($item->icon, '#', true); + } + // set GUI mapper $guiMapper = [ 'table' => $table, diff --git a/libraries/vendor_jcb/VDM.Joomla/src/Componentbuilder/Table.php b/libraries/vendor_jcb/VDM.Joomla/src/Componentbuilder/Table.php index 36f8d1e2c..92805b604 100644 --- a/libraries/vendor_jcb/VDM.Joomla/src/Componentbuilder/Table.php +++ b/libraries/vendor_jcb/VDM.Joomla/src/Componentbuilder/Table.php @@ -9598,7 +9598,7 @@ class Table extends BaseTable implements Tableinterface 'store' => 'json', 'tab_name' => 'Updates', 'db' => [ - 'type' => 'TEXT', + 'type' => 'MEDIUMTEXT', 'default' => 'EMPTY', 'null_switch' => 'NOT NULL', 'unique_key' => false, @@ -10526,7 +10526,7 @@ class Table extends BaseTable implements Tableinterface 'store' => 'json', 'tab_name' => 'Updates', 'db' => [ - 'type' => 'TEXT', + 'type' => 'MEDIUMTEXT', 'default' => 'EMPTY', 'null_switch' => 'NOT NULL', 'unique_key' => false, @@ -10734,7 +10734,7 @@ class Table extends BaseTable implements Tableinterface 'store' => 'json', 'tab_name' => 'Updates', 'db' => [ - 'type' => 'TEXT', + 'type' => 'MEDIUMTEXT', 'default' => 'EMPTY', 'null_switch' => 'NOT NULL', 'unique_key' => false, diff --git a/script.php b/script.php index 791b82233..5ab2edb00 100644 --- a/script.php +++ b/script.php @@ -9810,7 +9810,7 @@ class Com_ComponentbuilderInstallerScript echo '

-

Upgrade to Version 3.2.1-beta2 Was Successful! Let us know if anything is not working as expected.

'; +

Upgrade to Version 3.2.1-beta3 Was Successful! Let us know if anything is not working as expected.

'; // Set db if not set already. if (!isset($db)) @@ -11780,16 +11780,17 @@ class Com_ComponentbuilderInstallerScript /** * Ensures that a class in the namespace is available. - * If the class is not already loaded, it attempts to load it. + * If the class is not already loaded, it attempts to load it via the power autoloader. * - * @param mixed $className The class name to load. + * @param mixed $nameClass The name::class we are looking for. * * @return void * @since 3.2.1 + * @throws \Exception If the class could not be loaded. */ - protected function ensureClassExists($className): void + protected function ensureClassExists($nameClass): void { - if (!class_exists($className, true)) + if (!class_exists($nameClass, true)) { // The power autoloader for this project admin area. $power_autoloader = JPATH_ADMINISTRATOR . '/componenents/com_componentbuilder/helpers/powerload.php'; @@ -11799,9 +11800,9 @@ class Com_ComponentbuilderInstallerScript } // Check again if the class now exists after requiring it - if (!class_exists($className, true)) + if (!class_exists($nameClass, true)) { - throw new \Exception($errorMessage); + throw new \Exception("We failed to find/load the $nameClass"); } } }