diff --git a/hook.php b/hook.php
index ac0f7c98..45aaf360 100644
--- a/hook.php
+++ b/hook.php
@@ -61,9 +61,10 @@ function plugin_fields_install() {
echo "
";
//load all classes
+ $dir = GLPI_ROOT . "/plugins/fields/inc/";
+ include_once ("{$dir}toolbox.class.php");
foreach ($classesToInstall as $class) {
if ($plug = isPluginItemType($class)) {
- $dir = GLPI_ROOT . "/plugins/fields/inc/";
$item = strtolower($plug['class']);
if (file_exists("$dir$item.class.php")) {
include_once ("$dir$item.class.php");
@@ -74,7 +75,6 @@ function plugin_fields_install() {
//install
foreach ($classesToInstall as $class) {
if ($plug = isPluginItemType($class)) {
- $dir = GLPI_ROOT . "/plugins/fields/inc/";
$item =strtolower($plug['class']);
if (file_exists("$dir$item.class.php")) {
if (!call_user_func([$class,'install'], $migration, $version)) {
diff --git a/inc/container.class.php b/inc/container.class.php
index 921adf0b..0db30066 100644
--- a/inc/container.class.php
+++ b/inc/container.class.php
@@ -68,6 +68,47 @@ static function install(Migration $migration, $version) {
$migration->migrationOneTable($table);
}
+ // Fix containers names that were generated prior to Fields 1.9.2.
+ $glpi_version = preg_replace('/^((\d+\.?)+).*$/', '$1', GLPI_VERSION);
+ $bad_named_containers = $DB->request(
+ [
+ 'FROM' => self::getTable(),
+ 'WHERE' => [
+ 'name' => [
+ 'REGEXP',
+ // Regex will be escaped by PDO in GLPI 10+, but has to be escaped for GLPI < 10
+ version_compare($glpi_version, '10.0', '>=') ? '\d+' : $DB->escape('\d+')
+ ],
+ ],
+ ]
+ );
+
+ if ($bad_named_containers->count() > 0) {
+ $migration->displayMessage(__("Fix container names", "fields"));
+
+ foreach ($bad_named_containers as $container) {
+ $old_name = $container['name'];
+
+ // Update container name
+ $toolbox = new PluginFieldsToolbox();
+ $container['name'] = $toolbox->getSystemNameFromLabel($container['label']);
+ $container_obj = new PluginFieldsContainer();
+ $container_obj->update(
+ $container,
+ false
+ );
+
+ // Rename container tables
+ foreach (json_decode($container['itemtypes']) as $itemtype) {
+ $old_table = getTableForItemType(self::getClassname($itemtype, $old_name));
+ $new_table = getTableForItemType(self::getClassname($itemtype, $container['name']));
+ if ($DB->tableExists($old_table)) {
+ $migration->renameTable($old_table, $new_table);
+ }
+ }
+ }
+ }
+
//Computer OS tab is no longer part of computer object. Moving to main
$ostab = self::findContainer(Computer::getType(), 'domtab', Computer::getType() . '$1');
if ($ostab) {
@@ -355,13 +396,8 @@ function prepareInputForAdd($input) {
}
}
- // construct field name by processing label
- // (remove non alphanumeric char and any trailing spaces)
- $input['name'] = strtolower(preg_replace("/[^\da-z]/i", "", preg_replace('/s*$/', '', $input['label'])));
- // if empty, uses a random number
- if (strlen($input['name']) == 0) {
- $input['name'] = rand();
- }
+ $toolbox = new PluginFieldsToolbox();
+ $input['name'] = $toolbox->getSystemNameFromLabel($input['label']);
//check for already existing container with same name
$found = $this->find(['name' => $input['name']]);
diff --git a/inc/dropdown.class.php b/inc/dropdown.class.php
index e149ec64..edb8f311 100644
--- a/inc/dropdown.class.php
+++ b/inc/dropdown.class.php
@@ -13,6 +13,9 @@ class PluginFieldsDropdown {
* @return void
*/
static function install(Migration $migration, $version) {
+ $toolbox = new PluginFieldsToolbox();
+ $toolbox->fixFieldsNames($migration, ['type' => 'dropdown']);
+
$migration->displayMessage(__("Updating generated dropdown files", "fields"));
// -> 0.90-1.3: generated class moved
// OLD path: GLPI_ROOT."/plugins/fields/inc/$class_filename"
diff --git a/inc/field.class.php b/inc/field.class.php
index 1683fd58..8b5da257 100644
--- a/inc/field.class.php
+++ b/inc/field.class.php
@@ -57,6 +57,9 @@ static function install(Migration $migration, $version) {
}
$migration->executeMigration();
+ $toolbox = new PluginFieldsToolbox();
+ $toolbox->fixFieldsNames($migration, ['NOT' => ['type' => 'dropdown']]);
+
return true;
}
@@ -182,9 +185,11 @@ function post_purgeItem() {
* @return string the parsed name
*/
function prepareName($input) {
+ $toolbox = new PluginFieldsToolbox();
+
//contruct field name by processing label (remove non alphanumeric char)
if (empty($input['name'])) {
- $input['name'] = strtolower(preg_replace("/[^\da-z]/i", "", $input['label']))."field";
+ $input['name'] = $toolbox->getSystemNameFromLabel($input['label']) . 'field';
}
//for dropdown, if already exist, link to it
@@ -203,7 +208,7 @@ function prepareName($input) {
$field_name = $input['name'];
$i = 2;
while (count($field->find(['name' => $field_name])) > 0) {
- $field_name = $input['name'].$i;
+ $field_name = $toolbox->getIncrementedSystemName($input['name'], $i);
$i++;
}
diff --git a/inc/toolbox.class.php b/inc/toolbox.class.php
new file mode 100644
index 00000000..7b4abc47
--- /dev/null
+++ b/inc/toolbox.class.php
@@ -0,0 +1,148 @@
+replaceIntByLetters($name);
+
+ return $name;
+ }
+
+ /**
+ * Return system name incremented by given increment.
+ *
+ * @param string $name
+ * @param integer $increment
+ *
+ * @return string
+ */
+ public function getIncrementedSystemName($name, $increment) {
+ return $name . $this->replaceIntByLetters((string)$increment);
+ }
+
+ /**
+ * Replace integers by corresponding letters inside given string.
+ *
+ * @param string $str
+ *
+ * @return mixed
+ */
+ private function replaceIntByLetters($str) {
+ return str_replace(
+ ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9'],
+ ['zero', 'one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine'],
+ $str
+ );
+ }
+
+ /**
+ * Fix dropdown names that were generated prior to Fields 1.9.2.
+ *
+ * @param Migration $migration
+ * @param mixed $condition
+ *
+ * @return void
+ */
+ public function fixFieldsNames(Migration $migration, $condition) {
+ global $DB;
+
+ $glpi_version = preg_replace('/^((\d+\.?)+).*$/', '$1', GLPI_VERSION);
+ $bad_named_fields = $DB->request(
+ [
+ 'FROM' => PluginFieldsField::getTable(),
+ 'WHERE' => [
+ 'name' => [
+ 'REGEXP',
+ // Regex will be escaped by PDO in GLPI 10+, but has to be escaped for GLPI < 10
+ version_compare($glpi_version, '10.0', '>=') ? '\d+' : $DB->escape('\d+')
+ ],
+ $condition,
+ ],
+ ]
+ );
+
+ if ($bad_named_fields->count() === 0) {
+ return;
+ }
+
+ $migration->displayMessage(__("Fix fields names", "fields"));
+
+ foreach ($bad_named_fields as $field) {
+ $old_name = $field['name'];
+
+ // Update field name
+ $field_obj = new PluginFieldsField();
+ $field['name'] = null;
+ $field['name'] = $field_obj->prepareName($field);
+ $field_obj->update(
+ $field,
+ false
+ );
+
+ $sql_fields_to_rename = [
+ $old_name => $field['name'],
+ ];
+
+ if ('dropdown' === $field['type']) {
+ // Rename dropdown table
+ $old_table = getTableForItemType(PluginFieldsDropdown::getClassname($old_name));
+ $new_table = getTableForItemType(PluginFieldsDropdown::getClassname($field['name']));
+ if ($DB->tableExists($old_table)) {
+ $migration->renameTable($old_table, $new_table);
+ }
+
+ // Rename foreign keys in containers tables
+ $old_fk = getForeignKeyFieldForTable($old_table);
+ $new_fk = getForeignKeyFieldForTable($new_table);
+ $sql_fields_to_rename[$old_fk] = $new_fk;
+ }
+
+ // Rename columns in plugin tables
+ foreach ($sql_fields_to_rename as $old_field_name => $new_field_name) {
+ $tables_to_update = $DB->request(
+ [
+ 'SELECT DISTINCT' => 'TABLE_NAME',
+ 'FROM' => 'INFORMATION_SCHEMA.COLUMNS',
+ 'WHERE' => [
+ 'TABLE_NAME' => ['LIKE', 'glpi_plugin_fields_%'],
+ 'COLUMN_NAME' => $old_field_name
+ ],
+ ]
+ );
+
+ foreach ($tables_to_update as $table_to_update) {
+ $sql_type = PluginFieldsMigration::getSQLType($field['type']);
+ $migration->changeField(
+ $table_to_update['TABLE_NAME'],
+ $old_field_name,
+ $new_field_name,
+ $sql_type
+ );
+ $migration->migrationOneTable($table_to_update['TABLE_NAME']);
+ }
+ }
+ }
+ }
+}
diff --git a/tests/bootstrap.php b/tests/bootstrap.php
index 177dde78..74bed30e 100644
--- a/tests/bootstrap.php
+++ b/tests/bootstrap.php
@@ -13,6 +13,7 @@
//install plugin
$plugin = new \Plugin();
+$plugin->checkStates(true);
$plugin->getFromDBbyDir('fields');
//check from prerequisites as Plugin::install() does not!
if (!plugin_fields_check_prerequisites()) {
@@ -20,10 +21,10 @@
die(1);
}
if (!$plugin->isInstalled('fields')) {
- call_user_func([$plugin, 'install'], $plugin->getID());
+ $plugin->install($plugin->getID());
}
if (!$plugin->isActivated('fields')) {
- call_user_func([$plugin, 'activate'], $plugin->getID());
+ $plugin->activate($plugin->getID());
}
include_once __DIR__ . '/FieldsDbTestCase.php';
diff --git a/tests/units/PluginFieldsContainer.php b/tests/units/PluginFieldsContainer.php
index e624f242..dae95802 100644
--- a/tests/units/PluginFieldsContainer.php
+++ b/tests/units/PluginFieldsContainer.php
@@ -30,7 +30,7 @@ public function testNewContainer() {
$newid = $container->add($data);
$this->integer($newid)->isGreaterThan(0);
- $this->boolean(class_exists('PluginFieldsComputercontainerlabel1'))->isTrue();
+ $this->boolean(class_exists('PluginFieldsComputercontainerlabelOne'))->isTrue();
}
public function testGetTypes() {
|