Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Generate itemtypes without numbers; fixes #305 #306

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions hook.php
Original file line number Diff line number Diff line change
Expand Up @@ -61,9 +61,10 @@ function plugin_fields_install() {
echo "<td align='center'>";

//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");
Expand All @@ -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)) {
Expand Down
50 changes: 43 additions & 7 deletions inc/container.class.php
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down Expand Up @@ -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']]);
Expand Down
3 changes: 3 additions & 0 deletions inc/dropdown.class.php
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
9 changes: 7 additions & 2 deletions inc/field.class.php
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,9 @@ static function install(Migration $migration, $version) {
}
$migration->executeMigration();

$toolbox = new PluginFieldsToolbox();
$toolbox->fixFieldsNames($migration, ['NOT' => ['type' => 'dropdown']]);

return true;
}

Expand Down Expand Up @@ -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
Expand All @@ -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++;
}

Expand Down
148 changes: 148 additions & 0 deletions inc/toolbox.class.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
<?php

class PluginFieldsToolbox {

/**
* Get a clean system name from a label.
*
* @param string $label
*
* @return string
*/
public function getSystemNameFromLabel($label) {

$name = strtolower($label);

// 1. remove trailing "s" (plural forms)
$name = getSingular($name);

// 2. keep only alphanum
$name = preg_replace('/[^\da-z]/i', '', $name);

// 3. if empty, uses a random number
if (strlen($name) == 0) {
$name = rand();
}

// 4. replace numbers by letters
$name = $this->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']);
}
}
}
}
}
5 changes: 3 additions & 2 deletions tests/bootstrap.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,17 +13,18 @@

//install plugin
$plugin = new \Plugin();
$plugin->checkStates(true);
$plugin->getFromDBbyDir('fields');
//check from prerequisites as Plugin::install() does not!
if (!plugin_fields_check_prerequisites()) {
echo "\nPrerequisites are not met!";
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';
2 changes: 1 addition & 1 deletion tests/units/PluginFieldsContainer.php
Original file line number Diff line number Diff line change
Expand Up @@ -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() {
Expand Down