%PDF- %PDF-
Mini Shell

Mini Shell

Direktori : /var/www/projetos/suporte.iigd.com.br.old/install/migrations/
Upload File :
Create Path :
Current File : /var/www/projetos/suporte.iigd.com.br.old/install/migrations/update_0.83.x_to_0.84.0.php

<?php

/**
 * ---------------------------------------------------------------------
 *
 * GLPI - Gestionnaire Libre de Parc Informatique
 *
 * http://glpi-project.org
 *
 * @copyright 2015-2022 Teclib' and contributors.
 * @copyright 2003-2014 by the INDEPNET Development Team.
 * @licence   https://www.gnu.org/licenses/gpl-3.0.html
 *
 * ---------------------------------------------------------------------
 *
 * LICENSE
 *
 * This file is part of GLPI.
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 *
 * ---------------------------------------------------------------------
 */

/**
 * Update from 0.83.1 to 0.84
 *
 * @return bool for success (will die for most error)
 **/
function update083xto0840()
{
    global $DB, $migration;

    $updateresult     = true;
    $ADDTODISPLAYPREF = [];

   //TRANS: %s is the number of new version
    $migration->displayTitle(sprintf(__('Update to %s'), '0.84'));
    $migration->setVersion('0.84');

   // Add the internet field and copy rights from networking
    $migration->addField('glpi_profiles', 'internet', 'char', ['after'  => 'networking',
        'update' => '`networking`'
    ]);

    $backup_tables = false;
    $newtables     = ['glpi_contractcosts',
        'glpi_entities_rssfeeds', 'glpi_groups_rssfeeds',
        'glpi_problems_suppliers', 'glpi_profiles_rssfeeds',
        'glpi_rssfeeds_users', 'glpi_rssfeeds',
        'glpi_suppliers_tickets', 'glpi_ticketcosts'
    ];

    foreach ($newtables as $new_table) {
       // rename new tables if exists ?
        if ($DB->tableExists($new_table)) {
            $migration->dropTable("backup_$new_table");
            $migration->displayWarning("$new_table table already exists. " .
                                    "A backup have been done to backup_$new_table.");
            $backup_tables = true;
            $query         = $migration->renameTable("$new_table", "backup_$new_table");
        }
    }
    if ($backup_tables) {
        $migration->displayWarning(
            "You can delete backup tables if you have no need of them.",
            true
        );
    }

    updateNetworkFramework($ADDTODISPLAYPREF);

    $migration->addField('glpi_mailcollectors', 'accepted', 'string');
    $migration->addField('glpi_mailcollectors', 'refused', 'string');
    $migration->addField('glpi_mailcollectors', 'use_kerberos', 'bool', ['value' => 0]);
    $migration->addField("glpi_mailcollectors", 'errors', "integer");
    $migration->addField("glpi_mailcollectors", 'use_mail_date', "bool", ['value' => 0]);

   // Password security
    $migration->addField('glpi_configs', 'use_password_security', 'bool');
    $migration->addField('glpi_configs', 'password_min_length', 'integer', ['value' => 8]);
    $migration->addField('glpi_configs', 'password_need_number', 'bool', ['value' => 1]);
    $migration->addField('glpi_configs', 'password_need_letter', 'bool', ['value' => 1]);
    $migration->addField('glpi_configs', 'password_need_caps', 'bool', ['value' => 1]);
    $migration->addField('glpi_configs', 'password_need_symbol', 'bool', ['value' => 1]);

    $migration->addField('glpi_configs', 'use_check_pref', 'bool');

   // Ajax buffer time
    $migration->addField(
        'glpi_configs',
        'ajax_buffertime_load',
        'integer',
        ['value' => 0,
            'after' => 'ajax_min_textsearch_load'
        ]
    );

   // Clean display prefs
    $query = "UPDATE `glpi_displaypreferences`
             SET `num` = 160
             WHERE `itemtype` = 'Software'
                   AND `num` = 7";
    $DB->query($query);

   // Update bookmarks from States to AllAssets
    foreach ($DB->request("glpi_bookmarks", "`itemtype` = 'States'") as $data) {
        $query = str_replace('itemtype=States', 'itemtype=AllAssets', $data['query']);
        $query = "UPDATE `glpi_bookmarks`
                SET query = '" . addslashes($query) . "'
                WHERE `id` = '" . $data['id'] . "'";
        $DB->query($query);
    }
    $query = "UPDATE `glpi_bookmarks`
             SET `itemtype` = 'AllAssets', `path` = 'front/allassets.php'
             WHERE `itemtype` = 'States'";
    $DB->query($query);

    $query = "UPDATE `glpi_displaypreferences`
             SET `itemtype` = 'AllAssets'
             WHERE `itemtype` = 'States'";
    $DB->query($query);

    if ($DB->tableExists('glpi_networkportmigrations')) {
        $migration->displayWarning("You should have a look at the \"migration cleaner\" tool!", true);
        $migration->displayWarning(
            "With it, you should re-create the networks topologies and the links between the networks and the addresses",
            true
        );
    }

    $lang_to_update = ['ca_CA' => 'ca_ES',
        'dk_DK' => 'da_DK',
        'ee_ET' => 'et_EE',
        'el_EL' => 'el_GR',
        'he_HE' => 'he_IL',
        'no_NB' => 'nb_NO',
        'no_NN' => 'nn_NO',
        'ua_UA' => 'uk_UA',
    ];
    foreach ($lang_to_update as $old => $new) {
        $query = "UPDATE `glpi_configs`
               SET `language` = '$new'
               WHERE `language` = '$old';";
        $DB->queryOrDie($query, "0.84 language in config $old to $new");

        $query = "UPDATE `glpi_users`
               SET `language` = '$new'
               WHERE `language` = '$old';";
        $DB->queryOrDie($query, "0.84 language in users $old to $new");
    }

    $migration->displayMessage(sprintf(__('Data migration - %s'), 'tickets and problems status'));

    $status  = ['new'           => CommonITILObject::INCOMING,
        'assign'        => CommonITILObject::ASSIGNED,
        'plan'          => CommonITILObject::PLANNED,
        'waiting'       => CommonITILObject::WAITING,
        'solved'        => CommonITILObject::SOLVED,
        'closed'        => CommonITILObject::CLOSED,
        'accepted'      => CommonITILObject::ACCEPTED,
        'observe'       => CommonITILObject::OBSERVED,
        'evaluation'    => CommonITILObject::EVALUATION,
        'approbation'   => CommonITILObject::APPROVAL,
        'test'          => CommonITILObject::TEST,
        'qualification' => CommonITILObject::QUALIFICATION
    ];
    foreach (['glpi_tickets', 'glpi_problems'] as $table) {
       // Migrate datas
        foreach ($status as $old => $new) {
            $query = "UPDATE `$table`
                   SET `status` = '$new'
                   WHERE `status` = '$old'";
            $DB->queryOrDie($query, "0.84 status in $table $old to $new");
        }
        $migration->changeField(
            $table,
            'status',
            'status',
            'integer',
            ['value' => CommonITILObject::INCOMING]
        );
    }

   // Migrate templates
    $query = "SELECT `glpi_notificationtemplatetranslations`.*
             FROM `glpi_notificationtemplatetranslations`
             INNER JOIN `glpi_notificationtemplates`
                  ON (`glpi_notificationtemplates`.`id`
                        = `glpi_notificationtemplatetranslations`.`notificationtemplates_id`)
             WHERE `glpi_notificationtemplatetranslations`.`content_text` LIKE '%storestatus=%'
                   OR `glpi_notificationtemplatetranslations`.`content_html` LIKE '%storestatus=%'
                   OR `glpi_notificationtemplatetranslations`.`subject` LIKE '%storestatus=%'";

    if ($result = $DB->query($query)) {
        if ($DB->numrows($result)) {
            while ($data = $DB->fetchAssoc($result)) {
                $subject = $data['subject'];
                $text    = $data['content_text'];
                $html    = $data['content_html'];
                foreach ($status as $old => $new) {
                    $subject = str_replace("ticket.storestatus=$old", "ticket.storestatus=$new", $subject);
                    $text    = str_replace("ticket.storestatus=$old", "ticket.storestatus=$new", $text);
                    $html    = str_replace("ticket.storestatus=$old", "ticket.storestatus=$new", $html);
                    $subject = str_replace("problem.storestatus=$old", "problem.storestatus=$new", $subject);
                    $text    = str_replace("problem.storestatus=$old", "problem.storestatus=$new", $text);
                    $html    = str_replace("problem.storestatus=$old", "problem.storestatus=$new", $html);
                }
                $query = "UPDATE `glpi_notificationtemplatetranslations`
                      SET `subject` = '" . addslashes($subject) . "',
                          `content_text` = '" . addslashes($text) . "',
                          `content_html` = '" . addslashes($html) . "'
                      WHERE `id` = " . $data['id'] . "";
                $DB->queryOrDie($query, "0.84 fix tags usage for storestatus");
            }
        }
    }

   // Update Rules
    $changes                = [];
    $changes['RuleTicket']  = 'status';

    $DB->query("SET SESSION group_concat_max_len = 4194304;");
    foreach ($changes as $ruletype => $field) {
       // Get rules
        $query = "SELECT GROUP_CONCAT(`id`)
                FROM `glpi_rules`
                WHERE `sub_type` = '" . $ruletype . "'
                GROUP BY `sub_type`";
        if ($result = $DB->query($query)) {
            if ($DB->numrows($result) > 0) {
                // Get rule string
                $rules = $DB->result($result, 0, 0);

                // Update actions
                foreach ($status as $old => $new) {
                    $query = "UPDATE `glpi_ruleactions`
                         SET `value` = '$new'
                         WHERE `field` = '$field'
                               AND `value` = '$old'
                               AND `rules_id` IN ($rules)";

                    $DB->queryOrDie($query, "0.84 update datas for rules actions");
                }
            }
        }
    }

   // Update glpi_profiles : ticket_status
    foreach ($DB->request('glpi_profiles') as $data) {
        $fields_to_decode = ['ticket_status','problem_status'];
        foreach ($fields_to_decode as $field) {
            $tab = importArrayFromDB($data[$field]);
            if (is_array($tab)) {
                $newtab = [];
                foreach ($tab as $key => $values) {
                    foreach ($values as $key2 => $val2) {
                        $newtab[$status[$key]][$status[$key2]] = $val2;
                    }
                }

                $query  = "UPDATE `glpi_profiles`
                       SET `$field` = '" . addslashes(exportArrayToDB($newtab)) . "'
                       WHERE `id` = '" . $data['id'] . "'";
                $DB->queryOrDie($query, "0.84 migrate $field of glpi_profiles");
            }
        }
    }

    $migration->displayMessage(sprintf(
        __('Change of the database layout - %s'),
        'Merge entity and entitydatas'
    ));

    if ($DB->tableExists('glpi_entitydatas')) {
        $migration->changeField('glpi_entities', 'id', 'id', 'integer');
        $migration->migrationOneTable('glpi_entities');
       // pour que la procedure soit re-entrante
        if (countElementsInTable("glpi_entities", ['id' => 0]) < 1) {
           // Create root entity
            $query = "INSERT INTO `glpi_entities`
                          (`id`, `name`, `completename`, `entities_id`, `level`)
                   VALUES (0,'" . addslashes(__('Root entity')) . "',
                           '" . addslashes(__('Root entity')) . "', '-1', '1');";

            $DB->queryOrDie($query, '0.84 insert root entity into glpi_entities');
        }
       //       $newID = $DB->insertId();
       //       $query = "UPDATE `glpi_entities`
       //                 SET `id` = '0'
       //                 WHERE `id` = '$newID'";
       //       $DB->queryOrDie($query, '0.84 be sure that id of the root entity if 0 in glpi_entities');

        $migration->addField("glpi_entities", 'address', "text");
        $migration->addField("glpi_entities", 'postcode', "string");
        $migration->addField("glpi_entities", 'town', "string");
        $migration->addField("glpi_entities", 'state', "string");
        $migration->addField("glpi_entities", 'country', "string");
        $migration->addField("glpi_entities", 'website', "string");
        $migration->addField("glpi_entities", 'phonenumber', "string");
        $migration->addField("glpi_entities", 'fax', "string");
        $migration->addField("glpi_entities", 'email', "string");
        $migration->addField("glpi_entities", 'admin_email', "string");
        $migration->addField("glpi_entities", 'admin_email_name', "string");
        $migration->addField("glpi_entities", 'admin_reply', "string");
        $migration->addField("glpi_entities", 'admin_reply_name', "string");
        $migration->addField("glpi_entities", 'notification_subject_tag', "string");
        $migration->addField("glpi_entities", 'notepad', "longtext");
        $migration->addField("glpi_entities", 'ldap_dn', "string");
        $migration->addField("glpi_entities", 'tag', "string");
        $migration->addField("glpi_entities", 'authldaps_id', "integer");
        $migration->addField("glpi_entities", 'mail_domain', "string");
        $migration->addField("glpi_entities", 'entity_ldapfilter', "text");
        $migration->addField("glpi_entities", 'mailing_signature', "text");
        $migration->addField(
            "glpi_entities",
            'cartridges_alert_repeat',
            "integer",
            ['value' => -2]
        );
        $migration->addField(
            "glpi_entities",
            'consumables_alert_repeat',
            "integer",
            ['value' => -2]
        );
        $migration->addField("glpi_entities", 'use_licenses_alert', "integer", ['value' => -2]);
        $migration->addField(
            "glpi_entities",
            'use_contracts_alert',
            "integer",
            ['value' => -2]
        );
        $migration->addField("glpi_entities", 'use_infocoms_alert', "integer", ['value' => -2]);
        $migration->addField(
            "glpi_entities",
            'use_reservations_alert',
            "integer",
            ['value' => -2]
        );
        $migration->addField("glpi_entities", 'autoclose_delay', "integer", ['value' => -2]);
        $migration->addField("glpi_entities", 'notclosed_delay', "integer", ['value' => -2]);
        $migration->addField("glpi_entities", 'calendars_id', "integer", ['value' => -2]);
        $migration->addField("glpi_entities", 'auto_assign_mode', "integer", ['value' => -2]);
        $migration->addField("glpi_entities", 'tickettype', "integer", ['value' => -2]);
        $migration->addField("glpi_entities", 'max_closedate', "datetime");
        $migration->addField("glpi_entities", 'inquest_config', "integer", ['value' => -2]);
        $migration->addField("glpi_entities", 'inquest_rate', "integer");
        $migration->addField("glpi_entities", 'inquest_delay', "integer", ['value' => -10]);
        $migration->addField("glpi_entities", 'inquest_URL', "string");
        $migration->addField(
            "glpi_entities",
            'autofill_warranty_date',
            "string",
            ['value' => -2]
        );
        $migration->addField("glpi_entities", 'autofill_use_date', "string", ['value' => -2]);
        $migration->addField("glpi_entities", 'autofill_buy_date', "string", ['value' => -2]);
        $migration->addField(
            "glpi_entities",
            'autofill_delivery_date',
            "string",
            ['value' => -2]
        );
        $migration->addField("glpi_entities", 'autofill_order_date', "string", ['value' => -2]);
        $migration->addField("glpi_entities", 'tickettemplates_id', "integer", ['value' => -2]);
        $migration->addField(
            "glpi_entities",
            'entities_id_software',
            "integer",
            ['value' => -2]
        );
        $migration->addField(
            "glpi_entities",
            'default_contract_alert',
            "integer",
            ['value' => -2]
        );
        $migration->addField(
            "glpi_entities",
            'default_infocom_alert',
            "integer",
            ['value' => -2]
        );
        $migration->addField(
            "glpi_entities",
            'default_alarm_threshold',
            "integer",
            ['value' => -2]
        );
        $migration->migrationOneTable('glpi_entities');

        $fields = ['address', 'postcode', 'town', 'state', 'country', 'website',
            'phonenumber', 'fax', 'email', 'admin_email', 'admin_email_name',
            'admin_reply', 'admin_reply_name', 'notification_subject_tag',
            'notepad', 'ldap_dn', 'tag', 'authldaps_id', 'mail_domain',
            'entity_ldapfilter', 'mailing_signature', 'cartridges_alert_repeat',
            'consumables_alert_repeat', 'use_licenses_alert', 'use_contracts_alert',
            'use_infocoms_alert', 'use_reservations_alert', 'autoclose_delay',
            'notclosed_delay', 'calendars_id', 'auto_assign_mode', 'tickettype',
            'max_closedate', 'inquest_config', 'inquest_rate', 'inquest_delay',
            'inquest_URL', 'autofill_warranty_date', 'autofill_use_date',
            'autofill_buy_date', 'autofill_delivery_date', 'autofill_order_date',
            'tickettemplates_id', 'entities_id_software', 'default_contract_alert',
            'default_infocom_alert', 'default_alarm_threshold'
        ];
        $entity = new Entity();
        foreach ($DB->request('glpi_entitydatas') as $data) {
            if ($entity->getFromDB($data['entities_id'])) {
                $update_fields = [];
                foreach ($fields as $field) {
                    if (is_null($data[$field])) {
                        $update_fields[] = "`$field` = NULL";
                    } else {
                        $update_fields[] = "`$field` = '" . addslashes($data[$field]) . "'";
                    }
                }

                $query  = "UPDATE `glpi_entities`
                       SET " . implode(',', $update_fields) . "
                       WHERE `id` = '" . $data['entities_id'] . "'";
                $DB->queryOrDie($query, "0.84 transfer datas from glpi_entitydatas to glpi_entities");
            } else {
                $migration->displayMessage('Entity ID ' . $data['entities_id'] . ' does not exist');
            }
        }
        $migration->dropTable('glpi_entitydatas');
    }
    regenerateTreeCompleteName("glpi_entities");

    $migration->displayMessage(sprintf(
        __('Data migration - %s'),
        'copy entity information to computers_softwareversions'
    ));

    if ($migration->addField("glpi_computers_softwareversions", "entities_id", "integer")) {
        $migration->migrationOneTable('glpi_computers_softwareversions');

        $query3 = "UPDATE `glpi_computers_softwareversions`
                 LEFT JOIN `glpi_computers`
                    ON `computers_id`=`glpi_computers`.`id`
                 SET `glpi_computers_softwareversions`.`entities_id` = `glpi_computers`.`entities_id`";

        $DB->queryOrDie($query3, "0.84 update entities_id in glpi_computers_softwareversions");

       /// create index for search count on tab
        $migration->addKey(
            "glpi_computers_softwareversions",
            ['entities_id', 'is_template', 'is_deleted'],
            'computers_info'
        );
        $migration->addKey("glpi_computers_softwareversions", 'is_template');
        $migration->addKey("glpi_computers_softwareversions", 'is_deleted');
    }

   /// create new index for search
    $migration->addKey(
        "glpi_softwarelicenses",
        ['softwares_id', 'expire'],
        'softwares_id_expire'
    );
    $migration->dropKey("glpi_softwarelicenses", 'softwares_id');

    $migration->displayMessage(sprintf(
        __('Data migration - %s'),
        'create validation_answer notification'
    ));

   // Check if notifications already exists
    if (
        countElementsInTable(
            'glpi_notifications',
            ['itemtype' => 'Ticket',
                'event'    => 'validation_answer'
            ]
        ) == 0
    ) {
       // No notifications duplicate all

        $query = "SELECT *
                FROM `glpi_notifications`
                WHERE `itemtype` = 'Ticket'
                      AND `event` = 'validation'";
        foreach ($DB->request($query) as $notif) {
            $query = "INSERT INTO `glpi_notifications`
                          (`name`, `entities_id`, `itemtype`, `event`, `mode`,
                          `notificationtemplates_id`, `comment`, `is_recursive`, `is_active`,
                          `date_mod`)
                   VALUES ('" . addslashes($notif['name']) . " Answer',
                           '" . $notif['entities_id'] . "', 'Ticket',
                           'validation_answer', '" . $notif['mode'] . "',
                           '" . $notif['notificationtemplates_id'] . "',
                           '" . addslashes($notif['comment']) . "', '" . $notif['is_recursive'] . "',
                           '" . $notif['is_active'] . "', NOW());";
            $DB->queryOrDie($query, "0.84 insert validation_answer notification");
            $newID  = $DB->insertId();
            $query2 = "SELECT *
                    FROM `glpi_notificationtargets`
                    WHERE `notifications_id` = '" . $notif['id'] . "'";
            foreach ($DB->request($query2) as $target) {
                $query = "INSERT INTO `glpi_notificationtargets`
                             (`notifications_id`, `type`, `items_id`)
                      VALUES ($newID, '" . $target['type'] . "', '" . $target['items_id'] . "')";
                $DB->queryOrDie($query, "0.84 insert targets for validation_answer notification");
            }
        }
    }

    $migration->displayMessage(sprintf(
        __('Data migration - %s'),
        'create contracts notification'
    ));

    $from_to = ['end'    => 'periodicity',
        'notice' => 'periodicitynotice'
    ];
    foreach ($from_to as $from => $to) {
       // Check if notifications already exists
        if (
            countElementsInTable(
                'glpi_notifications',
                ['itemtype' => 'Contract', 'event' => $to]
            ) == 0
        ) {
           // No notifications duplicate all

            $query = "SELECT *
                   FROM `glpi_notifications`
                   WHERE `itemtype` = 'Contract'
                         AND `event` = '$from'";
            foreach ($DB->request($query) as $notif) {
                $query = "INSERT INTO `glpi_notifications`
                             (`name`, `entities_id`, `itemtype`, `event`, `mode`,
                              `notificationtemplates_id`, `comment`, `is_recursive`, `is_active`,
                              `date_mod`)
                      VALUES ('" . addslashes($notif['name']) . " Periodicity',
                              '" . $notif['entities_id'] . "', 'Contract', '$to', '" . $notif['mode'] . "',
                              '" . $notif['notificationtemplates_id'] . "',
                              '" . addslashes($notif['comment']) . "', '" . $notif['is_recursive'] . "',
                              '" . $notif['is_active'] . "', NOW());";
                $DB->queryOrDie($query, "0.84 insert contract " . $to . " notification");
                $newID  = $DB->insertId();
                $query2 = "SELECT *
                       FROM `glpi_notificationtargets`
                       WHERE `notifications_id` = '" . $notif['id'] . "'";
                foreach ($DB->request($query2) as $target) {
                    $query = "INSERT INTO `glpi_notificationtargets`
                                (`notifications_id`, `type`, `items_id`)
                         VALUES ('" . $newID . "', '" . $target['type'] . "', '" . $target['items_id'] . "')";
                    $DB->queryOrDie($query, "0.84 insert targets for ??ontract " . $to . " notification");
                }
            }
        }
    }

    $migration->displayMessage(sprintf(
        __('Change of the database layout - %s'),
        'contract and ticket costs'
    ));

    if (!$DB->tableExists('glpi_contractcosts')) {
        $query = "CREATE TABLE `glpi_contractcosts` (
                  `id` int NOT NULL AUTO_INCREMENT,
                  `contracts_id` int NOT NULL DEFAULT '0',
                  `name` varchar(255) DEFAULT NULL,
                  `comment` text COLLATE utf8_unicode_ci,
                  `begin_date` date DEFAULT NULL,
                  `end_date` date DEFAULT NULL,
                  `cost` decimal(20,4) NOT NULL DEFAULT '0.0000',
                  `budgets_id` int NOT NULL DEFAULT '0',
                  `entities_id` int NOT NULL DEFAULT '0',
                  `is_recursive` tinyint NOT NULL DEFAULT '0',
                  PRIMARY KEY (`id`),
                  KEY `name` (`name`),
                  KEY `contracts_id` (`contracts_id`),
                  KEY `begin_date` (`begin_date`),
                  KEY `end_date` (`end_date`),
                  KEY `entities_id` (`entities_id`),
                  KEY `is_recursive` (`is_recursive`),
                  KEY `budgets_id` (`budgets_id`)
                ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci";
        $DB->queryOrDie($query, "0.84 add table glpi_contractcosts");

        $migration->migrationOneTable('glpi_contractcosts');

        foreach ($DB->request('glpi_contracts', "`cost` > 0") as $data) {
            $begin_to_add = "NULL";
            $end_to_add   = "NULL";

            if (!is_null($data['begin_date'])) {
                $begin_to_add = "'" . $data['begin_date'] . "'";

                if ($data['duration']) {
                    $end_to_add = "'" . date("Y-m-d", strtotime($data['begin_date'] . "+" . $data['duration'] . " month")) . "'";
                } else {
                    $end_to_add = "'" . $data['begin_date'] . "'";
                }
            }
            $query = "INSERT INTO `glpi_contractcosts`
                          (`contracts_id`, `name`, `begin_date`, `end_date`,
                           `cost`,  `entities_id`,
                           `is_recursive`)
                   VALUES ('" . $data['id'] . "', 'Cost', $begin_to_add, $end_to_add,
                           '" . $data['cost'] . "', '" . $data['entities_id'] . "',
                           '" . $data['is_recursive'] . "')";
            $DB->queryOrDie($query, '0.84 move contracts costs');
        }
        $migration->dropField('glpi_contracts', 'cost');
    }

    if (!$DB->tableExists('glpi_ticketcosts')) {
        $query = "CREATE TABLE `glpi_ticketcosts` (
                  `id` int NOT NULL AUTO_INCREMENT,
                  `tickets_id` int NOT NULL DEFAULT '0',
                  `name` varchar(255) DEFAULT NULL,
                  `comment` text COLLATE utf8_unicode_ci,
                  `begin_date` date DEFAULT NULL,
                  `end_date` date DEFAULT NULL,
                  `actiontime` int NOT NULL DEFAULT '0',
                  `cost_time` decimal(20,4) NOT NULL DEFAULT '0.0000',
                  `cost_fixed` decimal(20,4) NOT NULL DEFAULT '0.0000',
                  `cost_material` decimal(20,4) NOT NULL DEFAULT '0.0000',
                  `budgets_id` int NOT NULL DEFAULT '0',
                  `entities_id` int NOT NULL DEFAULT '0',
                  PRIMARY KEY (`id`),
                  KEY `name` (`name`),
                  KEY `tickets_id` (`tickets_id`),
                  KEY `begin_date` (`begin_date`),
                  KEY `end_date` (`end_date`),
                  KEY `entities_id` (`entities_id`),
                  KEY `budgets_id` (`budgets_id`)
                ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci";
        $DB->queryOrDie($query, "0.84 add table glpi_ticketcosts");

        $migration->migrationOneTable('glpi_ticketcosts');

        foreach (
            $DB->request('glpi_tickets', "`cost_time` > 0
                            OR `cost_fixed` > 0
                            OR `cost_material` > 0") as $data
        ) {
            $begin_to_add = "NULL";
            $end_to_add   = "NULL";

            if (!is_null($data['date'])) {
                $begin_to_add = "'" . $data['date'] . "'";

                if (!is_null($data['solvedate'])) {
                    $end_to_add = "'" . $data['solvedate'] . "'";
                } else {
                    $end_to_add = "'" . $data['date'] . "'";
                }
            }
            $query = "INSERT INTO `glpi_ticketcosts`
                          (`tickets_id`, `name`, `begin_date`, `end_date`,
                           `cost_time`,`cost_fixed`,
                           `cost_material`, `entities_id`,
                           `actiontime`)
                   VALUES ('" . $data['id'] . "', 'Cost', $begin_to_add, $end_to_add,
                           '" . $data['cost_time'] . "','" . $data['cost_fixed'] . "',
                           '" . $data['cost_material'] . "', '" . $data['entities_id'] . "',
                           '" . $data['actiontime'] . "')";
            $DB->queryOrDie($query, '0.84 move tickets costs');
        }
        $migration->dropField('glpi_tickets', 'cost_time');
        $migration->dropField('glpi_tickets', 'cost_fixed');
        $migration->dropField('glpi_tickets', 'cost_material');
    }

    $migration->addField(
        "glpi_profiles",
        "ticketcost",
        "char",
        ['update'    => "'w'",
            'condition' => " WHERE `update_ticket` = 1"
        ]
    );
   // Set default to r as before
    $query = "UPDATE `glpi_profiles`
             SET `ticketcost` = 'r'
             WHERE `ticketcost` IS NULL";
    $DB->queryOrDie($query, "0.84 set ticketcost in glpi_profiles");

    $migration->displayMessage(sprintf(__('Change of the database layout - %s'), 'rss flows'));

    if (!$DB->tableExists('glpi_rssfeeds')) {
        $query = "CREATE TABLE `glpi_rssfeeds` (
                  `id` int NOT NULL AUTO_INCREMENT,
                  `name` varchar(255) DEFAULT NULL,
                  `users_id` int NOT NULL DEFAULT '0',
                  `comment` text COLLATE utf8_unicode_ci,
                  `url` text COLLATE utf8_unicode_ci,
                  `refresh_rate` int NOT NULL DEFAULT '86400',
                  `max_items` int NOT NULL DEFAULT '20',
                  `have_error` TINYINT NOT NULL DEFAULT 0,
                  `is_active` TINYINT NOT NULL DEFAULT 0,
                  `date_mod` DATETIME DEFAULT NULL,
                  PRIMARY KEY (`id`),
                  KEY `name` (`name`),
                  KEY `users_id` (`users_id`),
                  KEY `date_mod` (`date_mod`),
                  KEY `have_error` (`have_error`),
                  KEY `is_active` (`is_active`)
                ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci";
        $DB->queryOrDie($query, "0.84 add table glpi_rssfeeds");
        $ADDTODISPLAYPREF['RSSFeed'] = [2,4,5,19,6,7];
    }
    if (!$DB->tableExists('glpi_rssfeeds_users')) {
        $query = "CREATE TABLE `glpi_rssfeeds_users` (
                  `id` int NOT NULL AUTO_INCREMENT,
                  `rssfeeds_id` int NOT NULL DEFAULT '0',
                  `users_id` int NOT NULL DEFAULT '0',
                  PRIMARY KEY (`id`),
                  KEY `rssfeeds_id` (`rssfeeds_id`),
                  KEY `users_id` (`users_id`)
                ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci";

        $DB->queryOrDie($query, "0.84 add table glpi_rssfeeds_users");
    }

    if (!$DB->tableExists('glpi_groups_rssfeeds')) {
        $query = "CREATE TABLE `glpi_groups_rssfeeds` (
                  `id` int NOT NULL AUTO_INCREMENT,
                  `rssfeeds_id` int NOT NULL DEFAULT '0',
                  `groups_id` int NOT NULL DEFAULT '0',
                  `entities_id` int NOT NULL DEFAULT '-1',
                  `is_recursive` TINYINT NOT NULL DEFAULT 0,
                  PRIMARY KEY (`id`),
                  KEY `rssfeeds_id` (`rssfeeds_id`),
                  KEY `groups_id` (`groups_id`),
                  KEY `entities_id` (`entities_id`),
                  KEY `is_recursive` (`is_recursive`)

                ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci";

        $DB->queryOrDie($query, "0.84 add table glpi_groups_rssfeeds");
    }

    if (!$DB->tableExists('glpi_profiles_rssfeeds')) {
        $query = "CREATE TABLE `glpi_profiles_rssfeeds` (
                  `id` int NOT NULL AUTO_INCREMENT,
                  `rssfeeds_id` int NOT NULL DEFAULT '0',
                  `profiles_id` int NOT NULL DEFAULT '0',
                  `entities_id` int NOT NULL DEFAULT '-1',
                  `is_recursive` TINYINT NOT NULL DEFAULT 0,
                  PRIMARY KEY (`id`),
                  KEY `rssfeeds_id` (`rssfeeds_id`),
                  KEY `profiles_id` (`profiles_id`),
                  KEY `entities_id` (`entities_id`),
                  KEY `is_recursive` (`is_recursive`)
                ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci";

        $DB->queryOrDie($query, "0.84 add table glpi_profiles_rssfeeds");
    }

    if (!$DB->tableExists('glpi_entities_rssfeeds')) {
        $query = "CREATE TABLE `glpi_entities_rssfeeds` (
                  `id` int NOT NULL AUTO_INCREMENT,
                  `rssfeeds_id` int NOT NULL DEFAULT '0',
                  `entities_id` int NOT NULL DEFAULT '0',
                  `is_recursive` TINYINT NOT NULL DEFAULT 0,
                  PRIMARY KEY (`id`),
                  KEY `rssfeeds_id` (`rssfeeds_id`),
                  KEY `entities_id` (`entities_id`),
                  KEY `is_recursive` (`is_recursive`)
                ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci";

        $DB->queryOrDie($query, "0.84 add table glpi_entities_rssfeeds");
    }

    $migration->displayMessage(sprintf(__('Change of the database layout - %s'), 'planning recalls'));

    if (!$DB->tableExists('glpi_planningrecalls')) {
        $query = "CREATE TABLE `glpi_planningrecalls` (
                  `id` int NOT NULL AUTO_INCREMENT,
                  `items_id` int NOT NULL DEFAULT '0',
                  `itemtype` varchar(100) COLLATE utf8_unicode_ci NOT NULL,
                  `users_id` int NOT NULL DEFAULT '0',
                  `before_time` int NOT NULL DEFAULT '-10',
                  `when` datetime DEFAULT NULL,
                  PRIMARY KEY (`id`),
                  KEY `users_id` (`users_id`),
                  KEY `before_time` (`before_time`),
                  KEY `when` (`when`),
                  UNIQUE KEY `unicity` (`itemtype`,`items_id`, `users_id`)
                ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci";
        $DB->queryOrDie($query, "0.84 add table glpi_planningrecalls");
    }

    $query = "SELECT *
             FROM `glpi_notificationtemplates`
             WHERE `itemtype` = 'PlanningRecall'";

    if ($result = $DB->query($query)) {
        if ($DB->numrows($result) == 0) {
            $query = "INSERT INTO `glpi_notificationtemplates`
                          (`name`, `itemtype`, `date_mod`)
                   VALUES ('Planning recall', 'PlanningRecall', NOW())";
            $DB->queryOrDie($query, "0.84 add planning recall notification");
            $notid = $DB->insertId();

            $query = "INSERT INTO `glpi_notificationtemplatetranslations`
                          (`notificationtemplates_id`, `language`, `subject`,
                           `content_text`,
                           `content_html`)
                   VALUES ($notid, '', '##recall.action##: ##recall.item.name##',
                           '##recall.action##: ##recall.item.name##

##recall.item.content##

##lang.recall.planning.begin##: ##recall.planning.begin##
##lang.recall.planning.end##: ##recall.planning.end##
##lang.recall.planning.state##: ##recall.planning.state##
##lang.recall.item.private##: ##recall.item.private##',
'&lt;p&gt;##recall.action##: &lt;a href=\"##recall.item.url##\"&gt;##recall.item.name##&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;##recall.item.content##&lt;/p&gt;
&lt;p&gt;##lang.recall.planning.begin##: ##recall.planning.begin##&lt;br /&gt;##lang.recall.planning.end##: ##recall.planning.end##&lt;br /&gt;##lang.recall.planning.state##: ##recall.planning.state##&lt;br /&gt;##lang.recall.item.private##: ##recall.item.private##&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;')";
            $DB->queryOrDie($query, "0.84 add planning recall notification translation");

            $query = "INSERT INTO `glpi_notifications`
                          (`name`, `entities_id`, `itemtype`, `event`, `mode`,
                           `notificationtemplates_id`, `comment`, `is_recursive`, `is_active`,
                           `date_mod`)
                   VALUES ('Planning recall', 0, 'PlanningRecall', 'planningrecall', 'mail',
                             $notid, '', 1, 1, NOW())";
            $DB->queryOrDie($query, "0.84 add planning recall notification");
            $notifid = $DB->insertId();

            $query = "INSERT INTO `glpi_notificationtargets`
                          (`id`, `notifications_id`, `type`, `items_id`)
                   VALUES (NULL, $notifid, " . Notification::USER_TYPE . ", " . Notification::AUTHOR . ");";
            $DB->queryOrDie($query, "0.84 add planning recall notification target");
        }
    }

    if (
        !countElementsInTable(
            'glpi_crontasks',
            ['itemtype' => 'PlanningRecall', 'name' => 'planningrecall']
        )
    ) {
        $query = "INSERT INTO `glpi_crontasks`
                       (`itemtype`, `name`, `frequency`, `param`, `state`, `mode`, `allowmode`,
                        `hourmin`, `hourmax`, `logs_lifetime`, `lastrun`, `lastcode`, `comment`)
                VALUES ('PlanningRecall', 'planningrecall', 300, NULL, 1, 1, 3,
                        0, 24, 30, NULL, NULL, NULL)";
        $DB->queryOrDie($query, "0.84 populate glpi_crontasks for planningrecall");
    }

    $migration->displayMessage(sprintf(__('Change of the database layout - %s'), 'various fields'));

    $migration->changeField(
        'glpi_entities',
        'default_alarm_threshold',
        'default_cartridges_alarm_threshold',
        'integer',
        ['value' => -2]
    );
    $migration->migrationOneTable('glpi_entities');
    $migration->addField(
        "glpi_entities",
        'default_consumables_alarm_threshold',
        "integer",
        ['value'  => -2,
            'update' => 'default_cartridges_alarm_threshold'
        ]
    );
    $migration->migrationOneTable('glpi_entities');
   // move -1 to Entity::CONFIG_NEVER
    $query = 'UPDATE `glpi_entities`
             SET `default_consumables_alarm_threshold` = -10
             WHERE `default_consumables_alarm_threshold` = -1';
    $DB->query($query);
    $query = 'UPDATE `glpi_entities`
             SET `default_cartridges_alarm_threshold` = -10
             WHERE `default_cartridges_alarm_threshold` = -1';
    $DB->query($query);

    $migration->addField(
        "glpi_entities",
        'send_contracts_alert_before_delay',
        "integer",
        ['value'     => -2,
            'after'     => 'use_contracts_alert',
            'update'    => '0', // No delay for root entity
            'condition' => 'WHERE `id`=0'
        ]
    );
    $migration->addField(
        "glpi_entities",
        'send_infocoms_alert_before_delay',
        "integer",
        ['value'     => -2,
            'after'     => 'use_infocoms_alert',
            'update'    => '0', // No delay for root entity
            'condition' => 'WHERE `id`=0'
        ]
    );
    $migration->addField(
        "glpi_entities",
        'send_licenses_alert_before_delay',
        "integer",
        ['value'     => -2,
            'after'     => 'use_licenses_alert',
            'update'    => '0', // No delay for root entity
            'condition' => 'WHERE `id`=0'
        ]
    );

    $migration->addField("glpi_configs", "notification_to_myself", "bool", ['value' => 1]);
    $migration->addField("glpi_configs", 'duedateok_color', "string", ['value' => '#06ff00']);
    $migration->addField(
        "glpi_configs",
        'duedatewarning_color',
        "string",
        ['value' => '#ffb800']
    );
    $migration->addField(
        "glpi_configs",
        'duedatecritical_color',
        "string",
        ['value' => '#ff0000']
    );
    $migration->addField("glpi_configs", 'duedatewarning_less', "integer", ['value' => 20]);
    $migration->addField("glpi_configs", 'duedatecritical_less', "integer", ['value' => 5]);
    $migration->addField("glpi_configs", 'duedatewarning_unit', "string", ['value' => '%']);
    $migration->addField("glpi_configs", 'duedatecritical_unit', "string", ['value' => '%']);
    $migration->addField("glpi_configs", "realname_ssofield", "string");
    $migration->addField("glpi_configs", "firstname_ssofield", "string");
    $migration->addField("glpi_configs", "email1_ssofield", "string");
    $migration->addField("glpi_configs", "email2_ssofield", "string");
    $migration->addField("glpi_configs", "email3_ssofield", "string");
    $migration->addField("glpi_configs", "email4_ssofield", "string");
    $migration->addField("glpi_configs", "phone_ssofield", "string");
    $migration->addField("glpi_configs", "phone2_ssofield", "string");
    $migration->addField("glpi_configs", "mobile_ssofield", "string");
    $migration->addField("glpi_configs", "comment_ssofield", "string");
    $migration->addField("glpi_configs", "title_ssofield", "string");
    $migration->addField("glpi_configs", "category_ssofield", "string");
    $migration->addField("glpi_configs", "language_ssofield", "string");
    $migration->addField("glpi_configs", "entity_ssofield", "string");
    $migration->addField("glpi_configs", "registration_number_ssofield", "string");

    $migration->addField("glpi_users", "notification_to_myself", "tinyint DEFAULT NULL");
    $migration->addField("glpi_users", 'duedateok_color', "string");
    $migration->addField("glpi_users", 'duedatewarning_color', "string");
    $migration->addField("glpi_users", 'duedatecritical_color', "string");
    $migration->addField("glpi_users", 'duedatewarning_less', "int DEFAULT NULL");
    $migration->addField("glpi_users", 'duedatecritical_less', "int DEFAULT NULL");
    $migration->addField("glpi_users", 'duedatewarning_unit', "string");
    $migration->addField("glpi_users", 'duedatecritical_unit', "string");

    $migration->addField("glpi_users", 'display_options', "text");

    $migration->addField("glpi_reservationitems", "is_deleted", "bool");
    $migration->addKey("glpi_reservationitems", "is_deleted");

    $migration->addField("glpi_documentcategories", 'documentcategories_id', "integer");
    $migration->addField("glpi_documentcategories", 'completename', "text");
    $migration->addField("glpi_documentcategories", 'level', "integer");
    $migration->addField("glpi_documentcategories", 'ancestors_cache', "longtext");
    $migration->addField("glpi_documentcategories", 'sons_cache', "longtext");
    $migration->migrationOneTable('glpi_documentcategories');
    $migration->addKey("glpi_documentcategories", ['documentcategories_id','name'], 'unicity');
    regenerateTreeCompleteName("glpi_documentcategories");

    $migration->addField("glpi_contacts", 'usertitles_id', "integer");
    $migration->addKey("glpi_contacts", 'usertitles_id');

    $migration->addField("glpi_contacts", 'address', "text");
    $migration->addField("glpi_contacts", 'postcode', "string");
    $migration->addField("glpi_contacts", 'town', "string");
    $migration->addField("glpi_contacts", 'state', "string");
    $migration->addField("glpi_contacts", 'country', "string");

    $migration->addField(
        "glpi_configs",
        'x509_ou_restrict',
        "string",
        ['after' => 'x509_email_field']
    );
    $migration->addField(
        "glpi_configs",
        'x509_o_restrict',
        "string",
        ['after' => 'x509_email_field']
    );
    $migration->addField(
        "glpi_configs",
        'x509_cn_restrict',
        "string",
        ['after' => 'x509_email_field']
    );

    if (!$DB->tableExists('glpi_slalevelcriterias')) {
        $query = "CREATE TABLE `glpi_slalevelcriterias` (
                  `id` int NOT NULL AUTO_INCREMENT,
                  `slalevels_id` int NOT NULL DEFAULT '0',
                  `criteria` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
                  `condition` int NOT NULL DEFAULT '0'
                              COMMENT 'see define.php PATTERN_* and REGEX_* constant',
                  `pattern` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
                  PRIMARY KEY (`id`),
                  KEY `slalevels_id` (`slalevels_id`),
                  KEY `condition` (`condition`)
                ) ENGINE=MyISAM  DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci";
        $DB->queryOrDie($query, "0.84 create glpi_slalevelcriterias");
    }

    $migration->addField(
        "glpi_slalevels",
        'match',
        "CHAR(10) DEFAULT NULL COMMENT 'see define.php *_MATCHING constant'"
    );

    $query = "UPDATE `glpi_slalevelactions`
             SET `action_type` = 'append'
             WHERE `action_type` = 'assign'
                   AND `field` IN ('_users_id_requester',  '_groups_id_requester',
                                   '_users_id_assign',     '_groups_id_assign',
                                   '_suppliers_id_assign', '_users_id_observer',
                                   '_groups_id_observer');";
    $DB->queryOrDie($query, "0.84 update data for SLA actors add");

   // Clean observer as recipient of satisfaction survey
    $query = "DELETE FROM `glpi_notificationtargets`
             WHERE `glpi_notificationtargets`.`type` = '" . Notification::USER_TYPE . "'
                   AND `glpi_notificationtargets`.`items_id` = '" . Notification::OBSERVER . "'
                   AND `notifications_id` IN (SELECT `glpi_notifications`.`id`
                                              FROM `glpi_notifications`
                                              WHERE `glpi_notifications`.`itemtype` = 'Ticket'
                                                    AND `glpi_notifications`.`event` = 'satisfaction')";

    $DB->queryOrDie($query, "0.84 clean targets for satisfaction notification");

   // Clean user as recipient of item not unique
    $query = "DELETE FROM `glpi_notificationtargets`
             WHERE `glpi_notificationtargets`.`type` = '" . Notification::USER_TYPE . "'
                   AND `glpi_notificationtargets`.`items_id` = '" . Notification::USER . "'
                   AND `notifications_id` IN (SELECT `glpi_notifications`.`id`
                                              FROM `glpi_notifications`
                                              WHERE `glpi_notifications`.`itemtype` = 'FieldUnicity'
                                                    AND `glpi_notifications`.`event` = 'refuse')";

    $DB->queryOrDie($query, "0.84 clean targets for fieldunicity notification");

    if (!$DB->tableExists('glpi_blacklists')) {
        $query = "CREATE TABLE `glpi_blacklists` (
                  `id` int NOT NULL AUTO_INCREMENT,
                  `type` int NOT NULL DEFAULT '0',
                  `name` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
                  `value` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
                  `comment` text COLLATE utf8_unicode_ci,
                  PRIMARY KEY (`id`),
                  KEY `type` (`type`),
                  KEY `name` (`name`)
                ) ENGINE=MyISAM  DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci";
        $DB->queryOrDie($query, "0.84 create glpi_blacklists");

        $ADDTODISPLAYPREF['Blacklist'] = [12,11];

        $toinsert = [Blacklist::IP  => ['empty IP'  => '',
            'localhost' => '127.0.0.1',
            'zero IP'   => '0.0.0.0'
        ],
            Blacklist::MAC => ['empty MAC' => '']
        ];
        foreach ($toinsert as $type => $datas) {
            if (count($datas)) {
                foreach ($datas as $name => $value) {
                    $query = "INSERT INTO `glpi_blacklists`
                                (`type`,`name`,`value`)
                         VALUES ('$type','" . addslashes($name) . "','" . addslashes($value) . "')";
                    $DB->queryOrDie($query, "0.84 insert datas to glpi_blacklists");
                }
            }
        }
    }

    $query  = "SELECT `id`
              FROM `glpi_rulerightparameters`
              WHERE `name` = '(LDAP) MemberOf'";
    $result = $DB->query($query);
    if (!$DB->numrows($result)) {
        $query = "INSERT INTO `glpi_rulerightparameters`
                VALUES (NULL, '(LDAP) MemberOf', 'memberof', '')";
        $DB->queryOrDie($query, "0.84 insert (LDAP) MemberOf in glpi_rulerightparameters");
    }

    if (!$DB->tableExists('glpi_ssovariables')) {
        $query = "CREATE TABLE `glpi_ssovariables` (
                  `id` int NOT NULL AUTO_INCREMENT,
                  `name` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
                  `comment` text COLLATE utf8_unicode_ci NOT NULL,
                  PRIMARY KEY (`id`)
                ) ENGINE=MyISAM  DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci";
        $DB->queryOrDie($query, "0.84 create glpi_ssovariables");

        $query = "INSERT INTO `glpi_ssovariables`
                       (`id`, `name`, `comment`)
                VALUES (1, 'HTTP_AUTH_USER', ''),
                       (2, 'REMOTE_USER', ''),
                       (3, 'PHP_AUTH_USER', ''),
                       (4, 'USERNAME', ''),
                       (5, 'REDIRECT_REMOTE_USER', ''),
                       (6, 'HTTP_REMOTE_USER', '')";
        $DB->queryOrDie($query, "0.84 add values from  glpi_ssovariables");
    }

    if ($migration->addField('glpi_configs', 'ssovariables_id', 'integer')) {
        $migration->migrationOneTable('glpi_configs');
       //Get configuration
        $query = "SELECT `existing_auth_server_field`
                FROM `glpi_configs`";
        $result = $DB->query($query);

        $existing_auth_server_field = $DB->result($result, 0, "existing_auth_server_field");
        if ($existing_auth_server_field) {
           //Get dropdown value for existing_auth_server_field
            $query = "SELECT `id`
                   FROM `glpi_ssovariables`
                   WHERE `name` = '$existing_auth_server_field'";
            $result = $DB->query($query);
           //Update config
            if ($DB->numrows($result) > 0) {
                $query = "UPDATE `glpi_configs`
                      SET `ssovariables_id` = '" . $DB->result($result, 0, "id") . "'";
                $DB->queryOrDie($query, "0.84 update glpi_configs");
            }
           //Drop old field
        }
    }

    $migration->dropField('glpi_configs', 'existing_auth_server_field');
   //Remove field to specify an ldap server for SSO users : don't need it anymore
    $migration->dropField('glpi_configs', 'authldaps_id_extra');

   // Clean uneeded logs
    $cleancondition                = [];
    $cleancondition['reminder_kb'] = "`itemtype` IN ('Entity', 'User', 'Profile', 'Group')
                                       AND `itemtype_link` IN ('Reminder', 'Knowbase')";

    foreach ($cleancondition as $name => $condition) {
        $query = "DELETE
                FROM `glpi_logs`
                WHERE $condition";
        $DB->queryOrDie($query, "0.84 clean logs for $name");
    }

   //Remove OCS tables from GLPI's core
    $migration->renameTable('glpi_ocsadmininfoslinks', 'ocs_glpi_ocsadmininfoslinks');
    $migration->renameTable('glpi_ocslinks', 'ocs_glpi_ocslinks');
    $migration->renameTable('glpi_ocsservers', 'ocs_glpi_ocsservers');
    $migration->renameTable('glpi_registrykeys', 'ocs_glpi_registrykeys');

   // Migrate RuleOcs to RuleImportEntity
    $query = "UPDATE `glpi_rules`
             SET `sub_type` = 'RuleImportEntity'
             WHERE `sub_type` = 'RuleOcs'";
    $DB->queryOrDie($query, "0.84 update datas for old OCS rules");

    $migration->copyTable('glpi_rules', 'ocs_glpi_rules');
    $migration->copyTable('glpi_ruleactions', 'ocs_glpi_ruleactions');
    $migration->copyTable('glpi_rulecriterias', 'ocs_glpi_rulecriterias');

   // Delete OCS rules
    $DB->query("SET SESSION group_concat_max_len = 4194304;");
    $query = "SELECT GROUP_CONCAT(`id`)
             FROM `glpi_rules`
             WHERE `sub_type` = 'RuleImportEntity'
             GROUP BY `sub_type`";
    if ($result = $DB->query($query)) {
        if ($DB->numrows($result) > 0) {
           // Get rule string
            $rules = $DB->result($result, 0, 0);
            $query = "DELETE
                   FROM `glpi_ruleactions`
                   WHERE `rules_id` IN ($rules)";

            $DB->queryOrDie($query, "0.84 clean RuleImportEntity datas");

            $query = "DELETE
                   FROM `glpi_rulecriterias`
                   WHERE `rules_id` IN ($rules)";
            $DB->queryOrDie($query, "0.84 clean RuleImportEntity datas");

            $query = "DELETE
                   FROM `glpi_rules`
                   WHERE `id` IN ($rules)";
            $DB->queryOrDie($query, "0.84 clean RuleImportEntity datas");
        }
    }

   // copy table to keep value of fields deleted after
    $migration->copyTable('glpi_profiles', 'ocs_glpi_profiles');

    $migration->dropField('glpi_profiles', 'ocsng');
    $migration->dropField('glpi_profiles', 'sync_ocsng');
    $migration->dropField('glpi_profiles', 'view_ocsng');
    $migration->dropField('glpi_profiles', 'clean_ocsng');

    $migration->changeField('glpi_profiles', 'rule_ocs', 'rule_import', 'char');

    $migration->changeField('glpi_rulecacheprinters', 'ignore_ocs_import', 'ignore_import', 'char');
    $migration->changeField('glpi_rulecachesoftwares', 'ignore_ocs_import', 'ignore_import', 'char');

    $migration->dropField('glpi_configs', 'use_ocs_mode');

   // clean crontask
    $migration->copyTable('glpi_crontasks', 'ocs_glpi_crontasks');
    $query = "DELETE
             FROM `glpi_crontasks`
             WHERE `itemtype` = 'OcsServer'";
    $DB->queryOrDie($query, "0.84 delete OcsServer in crontasks");

   // clean displaypreferences
    $migration->copyTable('glpi_displaypreferences', 'ocs_glpi_displaypreferences');
    $query = "DELETE
             FROM `glpi_displaypreferences`
             WHERE `itemtype` = 'OcsServer'";
    $DB->queryOrDie($query, "0.84 delete OcsServer in displaypreferences");

   // Give history entries to plugin
    $query = "UPDATE `glpi_logs`
             SET `linked_action` = `linked_action`+1000,
                 `itemtype_link` = 'PluginOcsinventoryngOcslink'
             WHERE `linked_action` IN (8,9,10,11)";
    $DB->queryOrDie($query, "0.84 update OCS links in history");

    $migration->displayWarning(
        "You can delete ocs_* tables if you use OCS mode ONLY AFTER ocsinventoryng plugin installation.",
        true
    );
    $migration->displayWarning(
        "You can delete ocs_* tables if you do not use OCS synchronisation.",
        true
    );

    $migration->addField('glpi_authldaps', 'pagesize', 'integer');
    $migration->addField('glpi_authldaps', 'ldap_maxlimit', 'integer');
    $migration->addField('glpi_authldaps', 'can_support_pagesize', 'bool');

   // Add delete ticket notification
    if (
        countElementsInTable(
            "glpi_notifications",
            ['itemtype' => 'Ticket', 'event' => 'delete']
        ) == 0
    ) {
       // Get first template for tickets :
        $notid = 0;
        $query = "SELECT MIN(id) AS id
                FROM `glpi_notificationtemplates`
                WHERE `itemtype` = 'Ticket'";
        if ($result = $DB->query($query)) {
            if ($DB->numrows($result) == 1) {
                $notid = $DB->result($result, 0, 0);
            }
        }
        if ($notid > 0) {
            $notifications = ['delete' => [Notification::GLOBAL_ADMINISTRATOR]];

            $notif_names   = ['delete' => 'Delete Ticket'];

            foreach ($notifications as $type => $targets) {
                $query = "INSERT INTO `glpi_notifications`
                              (`name`, `entities_id`, `itemtype`, `event`, `mode`,
                               `notificationtemplates_id`, `comment`, `is_recursive`, `is_active`,
                               `date_mod`)
                       VALUES ('" . $notif_names[$type] . "', 0, 'Ticket', '$type', 'mail',
                               $notid, '', 1, 1, NOW())";
                $DB->queryOrDie($query, "0.83 add problem $type notification");
                $notifid = $DB->insertId();

                foreach ($targets as $target) {
                    $query = "INSERT INTO `glpi_notificationtargets`
                                (`id`, `notifications_id`, `type`, `items_id`)
                         VALUES (NULL, $notifid, " . Notification::USER_TYPE . ", $target);";
                    $DB->queryOrDie($query, "0.83 add problem $type notification target");
                }
            }
        }
    }

   // Add multiple suppliers for itil objects
    if (!$DB->tableExists('glpi_problems_suppliers')) {
        $query = "CREATE TABLE `glpi_problems_suppliers` (
                  `id` int NOT NULL AUTO_INCREMENT,
                  `problems_id` int NOT NULL DEFAULT '0',
                  `suppliers_id` int NOT NULL DEFAULT '0',
                  `type` int NOT NULL DEFAULT '1',
                  PRIMARY KEY (`id`),
                  UNIQUE KEY `unicity` (`problems_id`,`type`,`suppliers_id`),
                  KEY `group` (`suppliers_id`,`type`)
                ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci";
        $DB->queryOrDie($query, "0.84 add table glpi_problems_suppliers");

        $migration->migrationOneTable('glpi_problems_suppliers');
        foreach ($DB->request('glpi_problems', "`suppliers_id_assign` > 0") as $data) {
            $query = "INSERT INTO `glpi_problems_suppliers`
                          (`suppliers_id`, `type`, `problems_id`)
                   VALUES ('" . $data['suppliers_id_assign'] . "', '" . CommonITILActor::ASSIGN . "',
                           '" . $data['id'] . "')";
            $DB->query($query);
        }
        $migration->dropField('glpi_problems', 'suppliers_id_assign');
    }

    if (!$DB->tableExists('glpi_suppliers_tickets')) {
        $query = "CREATE TABLE `glpi_suppliers_tickets` (
                  `id` int NOT NULL AUTO_INCREMENT,
                  `tickets_id` int NOT NULL DEFAULT '0',
                  `suppliers_id` int NOT NULL DEFAULT '0',
                  `type` int NOT NULL DEFAULT '1',
                  PRIMARY KEY (`id`),
                  UNIQUE KEY `unicity` (`tickets_id`,`type`,`suppliers_id`),
                  KEY `group` (`suppliers_id`,`type`)
                ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci";
        $DB->queryOrDie($query, "0.84 add table glpi_suppliers_tickets");

        $migration->migrationOneTable('glpi_suppliers_tickets');
        foreach ($DB->request('glpi_tickets', "`suppliers_id_assign` > 0") as $data) {
            $query = "INSERT INTO `glpi_suppliers_tickets`
                          (`suppliers_id`, `type`, `tickets_id`)
                   VALUES ('" . $data['suppliers_id_assign'] . "', '" . CommonITILActor::ASSIGN . "',
                           '" . $data['id'] . "')";
            $DB->query($query);
        }
        $migration->dropField('glpi_tickets', 'suppliers_id_assign');
    }

    $migration->addField('glpi_tickets', 'locations_id', 'integer');
    $migration->addKey('glpi_tickets', 'locations_id');

    $migration->displayMessage(sprintf(__('Data migration - %s'), 'RuleTicket'));

    $changes                            = [];
    $changes['RuleTicket']              = ['suppliers_id_assign' => '_suppliers_id_assign'];
    $changes['RuleDictionnarySoftware'] = ['_ignore_ocs_import' => '_ignore_import'];
    $changes['RuleImportEntity']        = ['_ignore_ocs_import' => '_ignore_import'];
    $changes['RuleDictionnaryPrinter']  = ['_ignore_ocs_import' => '_ignore_import'];

    $DB->query("SET SESSION group_concat_max_len = 4194304;");
    foreach ($changes as $ruletype => $tab) {
       // Get rules
        $query = "SELECT GROUP_CONCAT(`id`)
                FROM `glpi_rules`
                WHERE `sub_type` = '" . $ruletype . "'
                GROUP BY `sub_type`";
        if ($result = $DB->query($query)) {
            if ($DB->numrows($result) > 0) {
                // Get rule string
                $rules = $DB->result($result, 0, 0);
                // Update actions
                foreach ($tab as $old => $new) {
                    $query = "UPDATE `glpi_ruleactions`
                         SET `field` = '$new'
                         WHERE `field` = '$old'
                               AND `rules_id` IN ($rules)";

                    $DB->queryOrDie($query, "0.84 update datas for rules actions");
                }
                // Update criteria
                foreach ($tab as $old => $new) {
                    $query = "UPDATE `glpi_rulecriterias`
                         SET `criteria` = '$new'
                         WHERE `criteria` = '$old'
                               AND `rules_id` IN ($rules)";
                    $DB->queryOrDie($query, "0.84 update datas for rules criteria");
                }
            }
        }
    }

   // change ruleaction for manufacturer (id to name)
    $query = "SELECT  `glpi_ruleactions` .`id` AS id,
                     `sub_type`,
                     `glpi_manufacturers`.`name` AS newvalue
             FROM `glpi_rules`
             INNER JOIN `glpi_ruleactions`
                  ON (`glpi_rules`.`id` = `glpi_ruleactions`.`rules_id`
                      AND `field` = 'Manufacturer')
             LEFT JOIN `glpi_manufacturers`
                  ON `glpi_manufacturers`.`id` = `glpi_ruleactions`.`value`
             WHERE `sub_type` = 'RuleDictionnarySoftware'";

    if ($result = $DB->query($query)) {
        if ($DB->numrows($result) > 0) {
            while ($data = $DB->fetchAssoc($result)) {
                // Update manufacturer
                $query = "UPDATE `glpi_ruleactions`
                      SET `value` = '" . $data['newvalue'] . "'
                      WHERE `id` = " . $data['id'];

                 $DB->queryOrDie($query, "0.84 update value of manufacturer for rules actions");
            }
        }
    }

   // Move ticketrecurrent values to correct ones
    $migration->changeField('glpi_ticketrecurrents', 'periodicity', 'periodicity', 'string');
    $migration->addField('glpi_ticketrecurrents', 'calendars_id', 'integer');
    $migration->addField('glpi_ticketrecurrents', 'end_date', 'datetime');

    $migration->migrationOneTable('glpi_ticketrecurrents');
    foreach ($DB->request('glpi_ticketrecurrents', "`periodicity` >= " . MONTH_TIMESTAMP) as $data) {
        $periodicity = $data['periodicity'];
        if (is_numeric($periodicity)) {
            if ($periodicity >= 365 * DAY_TIMESTAMP) {
                $periodicity = round($periodicity / (365 * DAY_TIMESTAMP)) . 'YEAR';
            } else {
                $periodicity = round($periodicity / (MONTH_TIMESTAMP)) . 'MONTH';
            }
            $query = "UPDATE `glpi_ticketrecurrents`
                   SET `periodicity` = '$periodicity'
                   WHERE `id` = '" . $data['id'] . "'";
            $DB->query($query);
        }
    }

    $query = "UPDATE `glpi_notifications`
             SET   `itemtype` = 'CartridgeItem'
             WHERE `itemtype` = 'Cartridge'";
    $DB->queryOrDie($query, "0.83 update glpi_notifications for Cartridge");

    $query = "UPDATE `glpi_notificationtemplates`
             SET   `itemtype` = 'CartridgeItem'
             WHERE `itemtype` = 'Cartridge'";
    $DB->queryOrDie($query, "0.83 update glpi_notificationtemplates for Cartridge");

    $query = "UPDATE `glpi_notifications`
             SET   `itemtype` = 'ConsumableItem'
             WHERE `itemtype` = 'Consumable'";
    $DB->queryOrDie($query, "0.83 update glpi_notifications for Consumable");

    $query = "UPDATE `glpi_notificationtemplates`
             SET   `itemtype` = 'ConsumableItem'
             WHERE `itemtype` = 'Consumable'";
    $DB->queryOrDie($query, "0.83 update glpi_notificationtemplates for Consumable");

    $migration->createRule(
        ['sub_type'      => 'RuleTicket',
            'entities_id'   => 0,
            'is_recursive'  => 1,
            'is_active'     => 0,
            'match'         => 'AND',
            'name'          => 'Ticket location from item'
        ],
        [['criteria'   => 'locations_id',
            'condition'  => Rule::PATTERN_DOES_NOT_EXISTS,
            'pattern'    => 1
        ],
            ['criteria'   => 'items_locations',
                'condition'  => Rule::PATTERN_EXISTS,
                'pattern'    => 1
            ]
        ],
        [['field'        => 'locations_id',
            'action_type'  => 'fromitem',
            'value'        => 1
        ]
        ]
    );

    $migration->createRule(
        ['sub_type'      => 'RuleTicket',
            'entities_id'   => 0,
            'is_recursive'  => 1,
            'is_active'     => 0,
            'match'         => 'AND',
            'name'          => 'Ticket location from user'
        ],
        [['criteria'   => 'locations_id',
            'condition'  => Rule::PATTERN_DOES_NOT_EXISTS,
            'pattern'    => 1
        ],
            ['criteria'   => 'users_locations',
                'condition'  => Rule::PATTERN_EXISTS,
                'pattern'    => 1
            ]
        ],
        [['field'        => 'locations_id',
            'action_type'  => 'fromuser',
            'value'        => 1
        ]
        ]
    );

   // Change begin_date id for budget
    $query = ("UPDATE `glpi_displaypreferences`
              SET `num` = '5'
              WHERE `itemtype` = 'Budget'
                    AND `num` = '2'");
    $DB->query($query);

    migrateComputerDevice('DeviceProcessor', 'frequency', 'integer', ['serial' => 'string']);

    migrateComputerDevice('DeviceMemory', 'size', 'integer', ['serial' => 'string']);

    migrateComputerDevice('DeviceHardDrive', 'capacity', 'integer', ['serial' => 'string']);

    migrateComputerDevice('DeviceGraphicCard', 'memory', 'integer');
    migrateComputerDevice('DeviceNetworkCard', 'mac', 'string');
    migrateComputerDevice('DeviceSoundCard');
    migrateComputerDevice('DeviceMotherboard');
    migrateComputerDevice('DeviceDrive');
    migrateComputerDevice('DeviceControl');
    migrateComputerDevice('DevicePci');
    migrateComputerDevice('DeviceCase');
    migrateComputerDevice('DevicePowerSupply');

    $migration->migrationOneTable('glpi_computers_softwareversions');

   //Rename fields in glpi_computers_softwareversions with inaproprious signification
    $migration->changeField(
        'glpi_computers_softwareversions',
        'is_deleted',
        'is_deleted_computer',
        'bool'
    );
    $migration->changeField(
        'glpi_computers_softwareversions',
        'is_template',
        'is_template_computer',
        'bool'
    );
    $migration->migrationOneTable('glpi_computers_softwareversions');

    $types = ['glpi_computers_items', 'glpi_computervirtualmachines',
        'glpi_computers_softwareversions', 'glpi_computerdisks', 'glpi_networkports',
        'glpi_computers_softwarelicenses', 'glpi_networknames', 'glpi_ipaddresses'
    ];

    $devices = [
        'Item_DeviceMotherboard',
        'Item_DeviceProcessor',
        'Item_DeviceMemory',
        'Item_DeviceHardDrive',
        'Item_DeviceNetworkCard',
        'Item_DeviceDrive',
        'Item_DeviceControl',
        'Item_DeviceGraphicCard',
        'Item_DeviceSoundCard',
        'Item_DevicePci',
        'Item_DeviceCase',
        'Item_DevicePowerSupply'
    ];

    foreach ($devices as $type) {
        $types[] = getTableForItemType($type);
    }
   //Add is_deleted for relations
    foreach ($types as $table) {
        if ($DB->tableExists($table)) {
            if ($migration->addField($table, 'is_deleted', 'bool', ['value' => 0])) {
                $migration->migrationOneTable($table);
                $migration->addKey($table, 'is_deleted');
            }
        }
    }

   ///For computers, rename is is_ocs_import to is_dynamic
    $migration->changeField('glpi_computers', 'is_ocs_import', 'is_dynamic', 'bool');
    $migration->migrationOneTable('glpi_computers');
    $migration->dropKey("glpi_computers", 'is_ocs_import');
    $migration->addKey("glpi_computers", 'is_dynamic');

   //Add field is_dynamic
    $types = array_merge($types, ['glpi_printers', 'glpi_phones', 'glpi_peripherals',
        'glpi_networkequipments', 'glpi_networkports',
        'glpi_monitors', 'glpi_networknames', 'glpi_ipaddresses'
    ]);
    foreach ($types as $table) {
        if ($migration->addField($table, 'is_dynamic', 'bool')) {
            $migration->migrationOneTable($table);
            $migration->addKey($table, 'is_dynamic');
        }
    }

    $ADDTODISPLAYPREF['ReservationItem'] = [5];

   // split validation rights in both

    $migration->changeField('glpi_profiles', 'validate_ticket', 'validate_request', 'char');
    $migration->changeField('glpi_profiles', 'create_validation', 'create_request_validation', 'char');
    $migration->migrationOneTable('glpi_profiles');

    $migration->addField(
        'glpi_profiles',
        'validate_incident',
        'char',
        ['update' => 'validate_request']
    );
    $migration->addField(
        'glpi_profiles',
        'create_incident_validation',
        'char',
        ['update' => 'create_request_validation']
    );

   // add rights to delete all validation
    $migration->addField(
        'glpi_profiles',
        'delete_validations',
        'char',
        ['update' => 'delete_ticket']
    );

   // add rights to manage public rssfeed
    $migration->addField(
        'glpi_profiles',
        'rssfeed_public',
        'char',
        ['update' => 'reminder_public',
            'after'  => 'reminder_public'
        ]
    );

   // add ticket templates
    $migration->addField('glpi_profiles', 'tickettemplates_id', 'integer');

   // Drop not needed fields
    $migration->dropField('glpi_tickettemplatepredefinedfields', 'entities_id');
    $migration->dropField('glpi_tickettemplatepredefinedfields', 'is_recursive');
    $migration->dropField('glpi_tickettemplatemandatoryfields', 'entities_id');
    $migration->dropField('glpi_tickettemplatemandatoryfields', 'is_recursive');
    $migration->dropField('glpi_tickettemplatehiddenfields', 'entities_id');
    $migration->dropField('glpi_tickettemplatehiddenfields', 'is_recursive');

   // Clean unlinked calendar segments and holidays
    $query = "DELETE
             FROM `glpi_calendars_holidays`
             WHERE `glpi_calendars_holidays`.`calendars_id`
                     NOT IN (SELECT `glpi_calendars`.`id`
                             FROM `glpi_calendars`)";
    $DB->queryOrDie($query, "0.84 clean glpi_calendars_holidays");

    $query = "DELETE
             FROM `glpi_calendarsegments`
             WHERE `glpi_calendarsegments`.`calendars_id`
                     NOT IN (SELECT `glpi_calendars`.`id`
                             FROM `glpi_calendars`)";
    $DB->queryOrDie($query, "0.84 clean glpi_calendarsegments");

   // Add keys for serial, otherserial and uuid
    $newindexes = ['serial'      => ['glpi_computers', 'glpi_items_deviceharddrives',
        'glpi_items_devicememories',
        'glpi_items_deviceprocessors', 'glpi_monitors',
        'glpi_networkequipments', 'glpi_peripherals',
        'glpi_phones', 'glpi_printers'
    ],
        'otherserial' => ['glpi_computers', 'glpi_monitors',
            'glpi_networkequipments', 'glpi_peripherals',
            'glpi_phones', 'glpi_printers'
        ],
        'uuid'        => ['glpi_computers', 'glpi_computervirtualmachines']
    ];
    foreach ($newindexes as $field => $tables) {
        foreach ($tables as $table) {
            $migration->addKey($table, $field);
        }
    }

   // Clean unlinked ticket_problem
    $query = "DELETE
             FROM `glpi_problems_tickets`
             WHERE `glpi_problems_tickets`.`tickets_id`
                     NOT IN (SELECT `glpi_tickets`.`id`
                             FROM `glpi_tickets`)";
    $DB->queryOrDie($query, "0.84 clean glpi_problems_tickets");

    $query = "DELETE
             FROM `glpi_problems_tickets`
             WHERE `glpi_problems_tickets`.`problems_id`
                     NOT IN (SELECT `glpi_problems`.`id`
                             FROM `glpi_problems`)";
    $DB->queryOrDie($query, "0.84 clean glpi_problems_tickets");

   // Clean unlinked softwarelicense_computer
    $query = "DELETE
             FROM `glpi_computers_softwarelicenses`
             WHERE `glpi_computers_softwarelicenses`.`softwarelicenses_id`
                     NOT IN (SELECT `glpi_softwarelicenses`.`id`
                             FROM `glpi_softwarelicenses`)";
    $DB->queryOrDie($query, "0.84 clean glpi_computers_softwarelicenses");

    $query = "DELETE
             FROM `glpi_computers_softwarelicenses`
             WHERE `glpi_computers_softwarelicenses`.`computers_id`
                     NOT IN (SELECT `glpi_computers`.`id`
                             FROM `glpi_computers`)";
    $DB->queryOrDie($query, "0.84 clean glpi_computers_softwarelicenses");

   // Clean unlinked items_problems
    $query = "DELETE
             FROM `glpi_items_problems`
             WHERE `glpi_items_problems`.`problems_id`
                     NOT IN (SELECT `glpi_problems`.`id`
                             FROM `glpi_problems`)";
    $DB->queryOrDie($query, "0.84 clean glpi_items_problems");

    $toclean = ['Computer', 'Monitor', 'NetworkEquipment',
        'Peripheral', 'Phone', 'Printer', 'Software'
    ];
    foreach ($toclean as $type) {
        $query = "DELETE
               FROM `glpi_items_problems`
               WHERE `glpi_items_problems`.`itemtype` = '$type'
                     AND `glpi_items_problems`.`items_id`
                        NOT IN (SELECT `" . getTableForItemType($type) . "`.`id`
                              FROM `" . getTableForItemType($type) . "`)";
        $DB->queryOrDie($query, "0.84 clean glpi_items_problems");
    }
   // ************ Keep it at the end **************
   //TRANS: %s is the table or item to migrate
    $migration->displayMessage(sprintf(__('Data migration - %s'), 'glpi_displaypreferences'));

    foreach ($ADDTODISPLAYPREF as $type => $tab) {
        $query = "SELECT DISTINCT `users_id`
                FROM `glpi_displaypreferences`
                WHERE `itemtype` = '$type'";

        if ($result = $DB->query($query)) {
            if ($DB->numrows($result) > 0) {
                while ($data = $DB->fetchAssoc($result)) {
                    $query = "SELECT MAX(`rank`)
                         FROM `glpi_displaypreferences`
                         WHERE `users_id` = '" . $data['users_id'] . "'
                               AND `itemtype` = '$type'";
                    $result = $DB->query($query);
                    $rank   = $DB->result($result, 0, 0);
                    $rank++;

                    foreach ($tab as $newval) {
                        $query = "SELECT *
                            FROM `glpi_displaypreferences`
                            WHERE `users_id` = '" . $data['users_id'] . "'
                                  AND `num` = '$newval'
                                  AND `itemtype` = '$type'";
                        if ($result2 = $DB->query($query)) {
                            if ($DB->numrows($result2) == 0) {
                                 $query = "INSERT INTO `glpi_displaypreferences`
                                         (`itemtype` ,`num` ,`rank` ,`users_id`)
                                  VALUES ('$type', '$newval', '" . $rank++ . "',
                                          '" . $data['users_id'] . "')";
                                 $DB->query($query);
                            }
                        }
                    }
                }
            } else { // Add for default user
                $rank = 1;
                foreach ($tab as $newval) {
                    $query = "INSERT INTO `glpi_displaypreferences`
                                (`itemtype` ,`num` ,`rank` ,`users_id`)
                         VALUES ('$type', '$newval', '" . $rank++ . "', '0')";
                    $DB->query($query);
                }
            }
        }
    }

   // must always be at the end
    $migration->executeMigration();

    return $updateresult;
}


/**
 * @param $origin
 * @param $id
 * @param $itemtype
 * @param $items_id
 * @param $error
 **/
function logNetworkPortError($origin, $id, $itemtype, $items_id, $error)
{
    global $migration;

    $migration->log(
        $origin . " - NetworkPort[" . $id . "]=" . $itemtype . "[" . $items_id . "]: " . $error,
        true
    );
}


/**
 * @param $itemtype
 * @param $items_id
 * @param $main_items_id
 * @param $main_itemtype
 * @param $entities_id
 * @param $IP
 **/
function createNetworkNameFromItem(
    $itemtype,
    $items_id,
    $main_items_id,
    $main_itemtype,
    $entities_id,
    $IP
) {
    global $migration;

   // Using gethostbyaddr() allows us to define its reald internet name according to its IP.
   //   But each gethostbyaddr() may reach several milliseconds. With very large number of
   //   NetworkPorts or NetworkeEquipment, the migration may take several minutes or hours ...
   //$computerName = gethostbyaddr($IP);
    $computerName = $IP;
    if ($computerName != $IP) {
        $position = strpos($computerName, ".");
        $name     = substr($computerName, 0, $position);
        $domain   = substr($computerName, $position + 1);
        $query    = "SELECT `id`
                   FROM `glpi_fqdns`
                   WHERE `fqdn` = '$domain'";
        $result = $DB->query($query);

        if ($DB->numrows($result) == 1) {
            $data     = $DB->fetchAssoc($result);
            $domainID = $data['id'];
        }
    } else {
        $name     = "migration-" . str_replace('.', '-', $computerName);
        $domainID = 0;
    }

    $IPaddress = new IPAddress();
    if ($IPaddress->setAddressFromString($IP)) {
        $input = ['name'         => $name,
            'fqdns_id'     => $domainID,
            'entities_id'  => $entities_id,
            'items_id'     => $items_id,
            'itemtype'     => $itemtype
        ];

        $networknames_id = $migration->insertInTable('glpi_networknames', $input);

        $input = $IPaddress->setArrayFromAddress(
            ['entities_id'   => $entities_id,
                'itemtype'      => 'NetworkName',
                'items_id'      => $networknames_id
            ],
            "version",
            "name",
            "binary"
        );

        $migration->insertInTable($IPaddress->getTable(), $input);
    } else { // Don't add the NetworkName if the address is not valid
       // phpcs:ignore SlevomatCodingStandard.Namespaces.FullyQualifiedExceptions
        addNetworkPortMigrationError($items_id, 'invalid_address');
       // phpcs:ignore SlevomatCodingStandard.Namespaces.FullyQualifiedExceptions
        logNetworkPortError('invalid IP address', $items_id, $main_itemtype, $main_items_id, "$IP");
    }

    unset($IPaddress);
}


/**
 * @param $port
 * @param $fields
 * @param $setNetworkCard
 **/
function updateNetworkPortInstantiation($port, $fields, $setNetworkCard)
{
    global $DB, $migration;

    $query = "SELECT `origin_glpi_networkports`.`name`,
                    `origin_glpi_networkports`.`id`,
                    `origin_glpi_networkports`.`mac`, ";

    $addleftjoin         = '';
    $manage_netinterface = false;
    if ($port instanceof NetworkPortEthernet) {
        $addleftjoin = "LEFT JOIN `glpi_networkinterfaces`
                        ON (`origin_glpi_networkports`.`networkinterfaces_id`
                              = `glpi_networkinterfaces` .`id`)";
        $query .= "`glpi_networkinterfaces`.`name` AS networkinterface, ";
        $manage_netinterface = true;
    }

    foreach ($fields as $SQL_field => $field) {
        $query .= "$SQL_field AS $field, ";
    }
    $query .= "`origin_glpi_networkports`.`itemtype`, `origin_glpi_networkports`.`items_id`
              FROM `origin_glpi_networkports`
              $addleftjoin
              WHERE `origin_glpi_networkports`.`id`
                                     IN (SELECT `id`
                                         FROM `glpi_networkports`
                                         WHERE `instantiation_type` = '" . $port->getType() . "')";
    foreach ($DB->request($query) as $portInformation) {
        $input = ['networkports_id' => $portInformation['id']];
        if ($manage_netinterface) {
            if (preg_match('/TX/i', $portInformation['networkinterface'])) {
                $input['type'] = 'T';
            }
            if (preg_match('/SX/i', $portInformation['networkinterface'])) {
                $input['type'] = 'SX';
            }
            if (preg_match('/LX/i', $portInformation['networkinterface'])) {
                $input['type'] = 'LX';
            }
            unset($portInformation['networkinterface']);
        }

        foreach ($fields as $field) {
            $input[$field] = $portInformation[$field];
        }

        if (($setNetworkCard) && ($portInformation['itemtype'] == 'Computer')) {
            $query = "SELECT link.`id` AS link_id,
                          device.`designation` AS name
                   FROM `glpi_devicenetworkcards` as device,
                        `glpi_computers_devicenetworkcards` as link
                   WHERE link.`computers_id` = " . $portInformation['items_id'] . "
                         AND device.`id` = link.`devicenetworkcards_id`
                         AND link.`specificity` = '" . $portInformation['mac'] . "'";
            $result = $DB->query($query);

            if ($DB->numrows($result) > 0) {
                $set_first = ($DB->numrows($result) == 1);
                while ($link = $DB->fetchAssoc($result)) {
                    if ($set_first || ($link['name'] == $portInformation['name'])) {
                        $input['items_devicenetworkcards_id'] = $link['link_id'];
                        break;
                    }
                }
            }
        }
        $migration->insertInTable($port->getTable(), $input);
    }
}


/**
 * @param $networkports_id
 * @param $motive
 **/
function addNetworkPortMigrationError($networkports_id, $motive)
{
    global $DB;

    if (countElementsInTable("glpi_networkportmigrations", ['id' => $networkports_id]) == 0) {
        $query = "INSERT INTO `glpi_networkportmigrations`
                       (SELECT *" . str_repeat(', 0', count(NetworkPortMigration::getMotives())) . "
                        FROM `origin_glpi_networkports`
                        WHERE `id` = '$networkports_id')";
        $DB->queryOrDie($query, "0.84 error on copy of network port during migration");
    }

    $query = "UPDATE `glpi_networkportmigrations`
             SET `$motive` = '1'
             WHERE `id`='$networkports_id'";
    $DB->queryOrDie($query, "0.84 append of motive to migration of network port error");
}


/**
 * Update all Network Organisation
 *
 * @param $ADDTODISPLAYPREF
 **/
function updateNetworkFramework(&$ADDTODISPLAYPREF)
{
    global $DB, $migration;

    $ADDTODISPLAYPREF['FQDN']                 = [11];
    $ADDTODISPLAYPREF['WifiNetwork']          = [10];
    $ADDTODISPLAYPREF['NetworkPortMigration'] = [];
    $ADDTODISPLAYPREF['IPNetwork']            = [14, 10, 11, 12, 13];
    $ADDTODISPLAYPREF['NetworkName']          = [12, 13];

    $optionIndex = 10;
    foreach (NetworkPortMigration::getMotives() as $key => $name) {
        $ADDTODISPLAYPREF['NetworkPortMigration'][] = $optionIndex++;
    }

    $migration->displayMessage(sprintf(
        __('Data migration - %s'),
        'Network framework'
    ));

    $originTables = [];
    foreach (['glpi_networkports', 'glpi_networkequipments'] as $table) {
        $originTables[$table] = 'origin_' . $table;
    }

    if (!$DB->tableExists('origin_glpi_networkequipments')) {
       // remove of mac field from glpi_networkequipments is done at the end of migration
       // framework process
        if (!$DB->fieldExists('glpi_networkequipments', 'mac')) {
           // Nothing to be done : migration of NetworkPort already OK !

           // But don't add display preference for NetworkPortMigration if none exists
            if (!$DB->tableExists('glpi_networkportmigrations')) {
                unset($ADDTODISPLAYPREF['NetworkPortMigration']);
            }

            $migration->displayWarning(
                'Network Framework already migrated: nothing to be done!',
                false
            );

            return;
        }

        foreach ($originTables as $table => $originTable) {
            if (!$DB->tableExists($originTable) && $DB->tableExists($table)) {
                $migration->copyTable($table, $originTable);
                $migration->displayWarning("To be safe, we are working on $originTable. " .
                                       "It is a copy of $table", false);
            }
        }
    }

   // Remove all tables created by any previous migration
    $new_network_ports = ['glpi_fqdns', 'glpi_ipaddresses', 'glpi_ipaddresses_ipnetworks',
        'glpi_ipnetworks', 'glpi_networkaliases', 'glpi_networknames',
        'glpi_networkportaggregates', 'glpi_networkportdialups',
        'glpi_networkportethernets', 'glpi_networkportlocals',
        'glpi_networkportmigrations', 'glpi_networkportwifis',
        'glpi_wifinetworks'
    ];

    foreach ($new_network_ports as $table) {
        $migration->dropTable($table);
    }

   // Create the glpi_networkportmigrations that is a copy of origin_glpi_networkports
    $query = "CREATE TABLE `glpi_networkportmigrations` LIKE `origin_glpi_networkports`";
    $DB->queryOrDie($query, "0.84 create glpi_networkportmigrations");

   // And add the error motive fields
    foreach (NetworkPortMigration::getMotives() as $key => $name) {
        $migration->addField('glpi_networkportmigrations', $key, 'bool');
    }
    $migration->migrationOneTable('glpi_networkportmigrations');

    $migration->displayMessage(sprintf(__('Data migration - %s'), 'glpi_fqdns'));

   // Adding FQDN table
    if (!$DB->tableExists('glpi_fqdns')) {
        $query = "CREATE TABLE `glpi_fqdns` (
                  `id` int NOT NULL AUTO_INCREMENT,
                  `entities_id` int NOT NULL DEFAULT '0',
                  `is_recursive` tinyint NOT NULL DEFAULT '0',
                  `name` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
                  `fqdn` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
                  `comment` text COLLATE utf8_unicode_ci,
                  PRIMARY KEY (`id`),
                  KEY `entities_id` (`entities_id`),
                  KEY `name` (`name`),
                  KEY `fqdn` (`fqdn`),
                  KEY `is_recursive` (`is_recursive`)
                ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci";

        $DB->queryOrDie($query, "0.84 create glpi_fqdns");

        $fqdn = new FQDN();

       // Then, populate it from domains (beware that "domains" can be FQDNs and Windows workgroups)
        $query = "SELECT DISTINCT LOWER(`name`) AS name, `comment`
                FROM `glpi_domains`";
        foreach ($DB->request($query) as $domain) {
            $domainName = $domain['name'];
           // We ensure that domains have at least 1 dote to be sure it is not a Windows workgroup
            if ((strpos($domainName, '.') !== false) && (FQDN::checkFQDN($domainName))) {
                $migration->insertInTable(
                    $fqdn->getTable(),
                    ['entities_id' => 0,
                        'name'        => $domainName,
                        'fqdn'        => $domainName,
                        'comment'     => $domain['comment']
                    ]
                );
            }
        }
    }

    $migration->displayMessage(sprintf(__('Data migration - %s'), 'glpi_ipaddresses'));

   // Adding IPAddress table
    if (!$DB->tableExists('glpi_ipaddresses')) {
        $query = "CREATE TABLE `glpi_ipaddresses` (
                  `id` int NOT NULL AUTO_INCREMENT,
                  `entities_id` int NOT NULL DEFAULT '0',
                  `items_id` int NOT NULL DEFAULT '0',
                  `itemtype` varchar(100) COLLATE utf8_unicode_ci NOT NULL,
                  `version` tinyint unsigned DEFAULT '0',
                  `name` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
                  `binary_0`  int unsigned NOT NULL DEFAULT '0',
                  `binary_1`  int unsigned NOT NULL DEFAULT '0',
                  `binary_2`  int unsigned NOT NULL DEFAULT '0',
                  `binary_3`  int unsigned NOT NULL DEFAULT '0',
                  PRIMARY KEY (`id`),
                  KEY `entities_id` (`entities_id`),
                  KEY `textual` (`name`),
                  KEY `binary` (`binary_0`, `binary_1`, `binary_2`, `binary_3`),
                  KEY `item` (`itemtype`, `items_id`)
                ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci";

        $DB->queryOrDie($query, "0.84 create glpi_ipaddresses");
    }

    $migration->displayMessage(sprintf(__('Change of the database layout - %s'), 'glpi_wifinetworks'));

   // Adding WifiNetwork table
    if (!$DB->tableExists('glpi_wifinetworks')) {
        $query = "CREATE TABLE `glpi_wifinetworks` (
                 `id` int NOT NULL AUTO_INCREMENT,
                 `entities_id` int NOT NULL DEFAULT '0',
                 `is_recursive` tinyint NOT NULL DEFAULT '0',
                 `name` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
                 `essid` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
                 `mode` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL
                        COMMENT 'ad-hoc, access_point',
                 `comment` text COLLATE utf8_unicode_ci,
                 PRIMARY KEY (`id`),
                 KEY `entities_id` (`entities_id`),
                 KEY `essid` (`essid`),
                 KEY `name` (`name`)
               ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci";
        $DB->queryOrDie($query, "0.84 create glpi_wifinetworks");
    }

    $migration->displayMessage(sprintf(__('Data migration - %s'), "glpi_ipnetworks"));

   // Adding IPNetwork table
    if (!$DB->tableExists('glpi_ipnetworks')) {
        $query = "CREATE TABLE `glpi_ipnetworks` (
                  `id` int NOT NULL AUTO_INCREMENT,
                  `entities_id` int NOT NULL DEFAULT '0',
                  `is_recursive` tinyint NOT NULL DEFAULT '0',
                  `ipnetworks_id` int NOT NULL DEFAULT '0',
                  `completename` text COLLATE utf8_unicode_ci,
                  `level` int NOT NULL DEFAULT '0',
                  `ancestors_cache` longtext COLLATE utf8_unicode_ci,
                  `sons_cache` longtext COLLATE utf8_unicode_ci,
                  `addressable` tinyint NOT NULL DEFAULT '0',
                  `version` tinyint unsigned DEFAULT '0',
                  `name` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
                  `address` varchar(40) COLLATE utf8_unicode_ci DEFAULT NULL,
                  `address_0`  int unsigned NOT NULL DEFAULT '0',
                  `address_1`  int unsigned NOT NULL DEFAULT '0',
                  `address_2`  int unsigned NOT NULL DEFAULT '0',
                  `address_3`  int unsigned NOT NULL DEFAULT '0',
                  `netmask` varchar(40) COLLATE utf8_unicode_ci DEFAULT NULL,
                  `netmask_0`  int unsigned NOT NULL DEFAULT '0',
                  `netmask_1`  int unsigned NOT NULL DEFAULT '0',
                  `netmask_2`  int unsigned NOT NULL DEFAULT '0',
                  `netmask_3`  int unsigned NOT NULL DEFAULT '0',
                  `gateway` varchar(40) COLLATE utf8_unicode_ci DEFAULT NULL,
                  `gateway_0`  int unsigned NOT NULL DEFAULT '0',
                  `gateway_1`  int unsigned NOT NULL DEFAULT '0',
                  `gateway_2`  int unsigned NOT NULL DEFAULT '0',
                  `gateway_3`  int unsigned NOT NULL DEFAULT '0',
                  `comment` text COLLATE utf8_unicode_ci,
                  PRIMARY KEY (`id`),
                  KEY `network_definition` (`entities_id`,`address`,`netmask`),
                  KEY `address` (`address_0`, `address_1`, `address_2`, `address_3`),
                  KEY `netmask` (`netmask_0`, `netmask_1`, `netmask_2`, `netmask_3`),
                  KEY `gateway` (`gateway_0`, `gateway_1`, `gateway_2`, `gateway_3`),
                  KEY `name` (`name`)
                ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci";

        $DB->queryOrDie($query, "0.84 create glpi_ipnetworks");

       // Retrieve all the networks from the current network ports and add them to the IPNetworks
        $query = "SELECT DISTINCTROW INET_NTOA(INET_ATON(`ip`)&INET_ATON(`netmask`)) AS address,
                     `netmask`, `gateway`, `entities_id`
                FROM `origin_glpi_networkports`
                ORDER BY `gateway` DESC";
        $address = new IPAddress();
        $netmask = new IPNetmask();
        $gateway = new IPAddress();
        $network = new IPNetwork();
        foreach ($DB->request($query) as $entry) {
            $address = $entry['address'];
            $netmask = $entry['netmask'];
            $gateway = $entry['gateway'];
            $entities_id = $entry['entities_id'];

            if (
                (empty($address)) || ($address == '0.0.0.0') || (empty($netmask))
                || ($netmask == '0.0.0.0') || ($netmask == '255.255.255.255')
            ) {
                continue;
            }

            if ($gateway == '0.0.0.0') {
                $gateway = '';
            }

            $networkDefinition = "$address/$netmask";
            $networkName       = $networkDefinition . (empty($gateway) ? "" : " - " . $gateway);

            $input             = ['entities_id'   => $entities_id,
                'name'          => $networkName,
                'network'       => $networkDefinition,
                'gateway'       => $gateway,
                'ipnetworks_id' => 0,
                'addressable'   => 1,
                'completename'  => $networkName,
                'level'         => 1
            ];

            $preparedInput = $network->prepareInput($input);

            if (is_array($preparedInput['input'])) {
                $input = $preparedInput['input'];
                if (isset($preparedInput['error'])) {
                    $query = "SELECT id, items_id, itemtype
                         FROM origin_glpi_networkports
                         WHERE INET_NTOA(INET_ATON(`ip`)&INET_ATON(`netmask`)) = '$address'
                               AND `netmask` = '$netmask'
                               AND `gateway` = '$gateway'
                               AND `entities_id` = '$entities_id'";
                    $result = $DB->query($query);
                    foreach ($DB->request($query) as $data) {
                        // phpcs:ignore SlevomatCodingStandard.Namespaces.FullyQualifiedExceptions
                        addNetworkPortMigrationError($data['id'], 'invalid_gateway');
                        // phpcs:ignore SlevomatCodingStandard.Namespaces.FullyQualifiedExceptions
                        logNetworkPortError(
                            'network warning',
                            $data['id'],
                            $data['itemtype'],
                            $data['items_id'],
                            $preparedInput['error']
                        );
                    }
                }
                $migration->insertInTable($network->getTable(), $input);
            } else if (isset($preparedInput['error'])) {
                $query = "SELECT id, items_id, itemtype
                      FROM origin_glpi_networkports
                      WHERE INET_NTOA(INET_ATON(`ip`)&INET_ATON(`netmask`)) = '" . $entry['address'] . "'
                            AND `netmask` = '$netmask'
                            AND `gateway` = '$gateway'
                            AND `entities_id` = '$entities_id'";
                $result = $DB->query($query);
                foreach ($DB->request($query) as $data) {
                   // phpcs:ignore SlevomatCodingStandard.Namespaces.FullyQualifiedExceptions
                    addNetworkPortMigrationError($data['id'], 'invalid_network');
                   // phpcs:ignore SlevomatCodingStandard.Namespaces.FullyQualifiedExceptions
                    logNetworkPortError(
                        'network error',
                        $data['id'],
                        $data['itemtype'],
                        $data['items_id'],
                        $preparedInput['error']
                    );
                }
            }
        }
    }

    $migration->displayMessage(sprintf(__('Data migration - %s'), "glpi_ipnetworks_vlans"));

   // Adding IPNetwork table
    if (!$DB->tableExists('glpi_ipnetworks_vlans')) {
        $query = "CREATE TABLE `glpi_ipnetworks_vlans` (
                  `id` int NOT NULL AUTO_INCREMENT,
                  `ipnetworks_id` int NOT NULL DEFAULT '0',
                  `vlans_id` int NOT NULL DEFAULT '0',
                  PRIMARY KEY (`id`),
                  UNIQUE KEY `link` (`ipnetworks_id`, `vlans_id`)
                ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;";

        $DB->queryOrDie($query, "0.84 create glpi_ipnetworks_vlans");
    }

    $migration->displayMessage(sprintf(__('Data migration - %s'), "glpi_networknames"));

   // Adding NetworkName table
    if (!$DB->tableExists('glpi_networknames')) {
        $query = "CREATE TABLE `glpi_networknames` (
                  `id` int NOT NULL AUTO_INCREMENT,
                  `entities_id` int NOT NULL DEFAULT '0',
                  `items_id` int NOT NULL DEFAULT '0',
                  `itemtype` varchar(100) COLLATE utf8_unicode_ci NOT NULL,
                  `name` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
                  `comment` text COLLATE utf8_unicode_ci,
                  `fqdns_id` int NOT NULL DEFAULT '0',
                  `is_deleted` tinyint NOT NULL DEFAULT '0',
                  `is_dynamic` tinyint NOT NULL DEFAULT '0',
                  PRIMARY KEY (`id`),
                  KEY `entities_id` (`entities_id`),
                  KEY `FQDN` (`name`,`fqdns_id`),
                  KEY `name` (`name`),
                  KEY `item` (`itemtype`, `items_id`),
                  KEY `fqdns_id` (`fqdns_id`)
                ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci";

        $DB->queryOrDie($query, "0.84 create glpi_networknames");

       // Retrieve all the networks from the current network ports and add them to the IPNetworks
        $query = "SELECT `ip`, `id`, `entities_id`, `itemtype`, `items_id`
                FROM `origin_glpi_networkports`
                WHERE `ip` <> ''";

        foreach ($DB->request($query) as $entry) {
            if (empty($entry["ip"])) {
                continue;
            }

            createNetworkNameFromItem(
                'NetworkPort',
                $entry['id'],
                $entry['items_id'],
                $entry['itemtype'],
                $entry['entities_id'],
                $entry["ip"]
            );
        }
    }

    $migration->displayMessage(sprintf(__('Change of the database layout - %s'), "glpi_networkaliases"));

   // Adding NetworkAlias table
    if (!$DB->tableExists('glpi_networkaliases')) {
        $query = "CREATE TABLE `glpi_networkaliases` (
                  `id` int NOT NULL AUTO_INCREMENT,
                  `entities_id` int NOT NULL DEFAULT '0',
                  `networknames_id` int NOT NULL DEFAULT '0',
                  `name` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
                  `fqdns_id` int NOT NULL DEFAULT '0',
                  `comment` text COLLATE utf8_unicode_ci,
                  PRIMARY KEY (`id`),
                  KEY `entities_id` (`entities_id`),
                  KEY `name` (`name`),
                  KEY `networknames_id` (`networknames_id`)
                ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci";

        $DB->queryOrDie($query, "0.84 create glpi_networkaliases");
    }

    $migration->displayMessage(sprintf(__('Data migration - %s'), "glpi_ipaddresses_ipnetworks"));

   // Adding IPAddress_IPNetwork table
    if (!$DB->tableExists('glpi_ipaddresses_ipnetworks')) {
        $query = "CREATE TABLE `glpi_ipaddresses_ipnetworks` (
                  `id` int NOT NULL AUTO_INCREMENT,
                  `ipaddresses_id` int NOT NULL DEFAULT '0',
                  `ipnetworks_id` int NOT NULL DEFAULT '0',
                  PRIMARY KEY (`id`),
                  UNIQUE KEY `unicity` (`ipaddresses_id`,`ipnetworks_id`),
                  KEY `ipnetworks_id` (`ipnetworks_id`),
                  KEY `ipaddresses_id` (`ipaddresses_id`)
                ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;";

        $DB->queryOrDie($query, "0.84 create glpi_ipaddresses_ipnetworks");
    }

    $migration->displayMessage(sprintf(__('Change of the database layout - %s'), "glpi_networkinterfaces"));

   // Update NetworkPorts
    $migration->addField(
        'glpi_networkports',
        'instantiation_type',
        'string',
        ['after'  => 'name',
            'update' => "'NetworkPortEthernet'"
        ]
    );

    $migration->displayMessage(sprintf(__('Data migration - %s'), "glpi_networkports"));

   // Retrieve all the networks from the current network ports and add them to the IPNetwork
    $query = "SELECT *
             FROM `glpi_networkinterfaces`";

    foreach ($DB->request($query) as $entry) {
        $instantiation_type = "";
        switch ($entry['name']) {
            case 'Local':
                $instantiation_type = "NetworkPortLocal";
                break;

            case 'Ethernet':
                $instantiation_type = "NetworkPortEthernet";
                break;

            case 'Wifi':
                $instantiation_type = "NetworkPortWifi";
                break;

            case 'Dialup':
                $instantiation_type = "NetworkPortDialup";
                break;

            default:
                if (
                    preg_match('/TX/i', $entry['name'])
                    || preg_match('/SX/i', $entry['name'])
                    || preg_match('/Ethernet/i', $entry['name'])
                ) {
                    $instantiation_type = "NetworkPortEthernet";
                }
                break;
        }
       /// In case of unknown Interface Type, we should have to set instantiation_type to ''
       /// Thus we should be able to convert it later to correct type (ethernet, wifi, loopback ...)
        if (!empty($instantiation_type)) {
            $query = "UPDATE `glpi_networkports`
                   SET `instantiation_type` = '$instantiation_type'
                   WHERE `id` IN (SELECT `id`
                                  FROM `origin_glpi_networkports`
                                  WHERE `networkinterfaces_id` = '" . $entry['id'] . "')";
            $DB->queryOrDie($query, "0.84 update instantiation_type field of glpi_networkports");
           // Clear $instantiation_type for next check inside the loop
            unset($instantiation_type);
        }
    }

    foreach (
        ['ip', 'gateway', 'netmask', 'netpoints_id', 'networkinterfaces_id',
            'subnet'
        ] as $field
    ) {
        $migration->dropField('glpi_networkports', $field);
    }

    foreach (['ip', 'mac'] as $field) {
        $migration->dropField('glpi_networkequipments', $field);
    }

    $migration->displayMessage(sprintf(
        __('Data migration - %s'),
        'Index mac field and transform address mac to lower'
    ));

    $query = "UPDATE `glpi_networkports`
             SET `mac` = LOWER(`mac`)";
    $DB->queryOrDie($query, "0.84 transforme MAC to lower case");

    $migration->addKey('glpi_networkports', 'mac');

    $migration->displayMessage(sprintf(
        __('Data migration - %s'),
        'Update migration of interfaces errors'
    ));

    $query = "SELECT id
             FROM `glpi_networkports`
             WHERE `instantiation_type` = ''";

    foreach ($DB->request($query) as $networkPortID) {
       // phpcs:ignore SlevomatCodingStandard.Namespaces.FullyQualifiedExceptions
        addNetworkPortMigrationError($networkPortID['id'], 'unknown_interface_type');
    }

    $migration->displayMessage(sprintf(__('Change of the database layout - %s'), "glpi_networkportethernets"));

   // Adding NetworkPortEthernet table
    if (!$DB->tableExists('glpi_networkportethernets')) {
        $query = "CREATE TABLE `glpi_networkportethernets` (
                  `id` int NOT NULL AUTO_INCREMENT,
                  `networkports_id` int NOT NULL DEFAULT '0',
                  `items_devicenetworkcards_id` int NOT NULL DEFAULT '0',
                  `netpoints_id` int NOT NULL DEFAULT '0',
                  `type` varchar(10) COLLATE utf8_unicode_ci DEFAULT '' COMMENT 'T, LX, SX',
                  `speed` int NOT NULL DEFAULT '10' COMMENT 'Mbit/s: 10, 100, 1000, 10000',
                  PRIMARY KEY (`id`),
                  UNIQUE KEY `networkports_id` (`networkports_id`),
                  KEY `card` (`items_devicenetworkcards_id`),
                  KEY `netpoint` (`netpoints_id`),
                  KEY `type` (`type`),
                  KEY `speed` (`speed`)
                ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci";

        $DB->queryOrDie($query, "0.84 create glpi_networkportethernets");

        $port = new NetworkPortEthernet();
        updateNetworkPortInstantiation($port, ['`netpoints_id`' => 'netpoints_id'], true);
    }

    $migration->displayMessage(sprintf(__('Change of the database layout - %s'), "glpi_networkportwifis"));

   // Adding NetworkPortWifi table
    if (!$DB->tableExists('glpi_networkportwifis')) {
        $query = "CREATE TABLE `glpi_networkportwifis` (
                  `id` int NOT NULL AUTO_INCREMENT,
                  `networkports_id` int NOT NULL DEFAULT '0',
                  `items_devicenetworkcards_id` int NOT NULL DEFAULT '0',
                  `wifinetworks_id` int NOT NULL DEFAULT '0',
                  `networkportwifis_id` int NOT NULL DEFAULT '0'
                                        COMMENT 'only useful in case of Managed node',
                  `version` varchar(20) COLLATE utf8_unicode_ci DEFAULT NULL
                            COMMENT 'a, a/b, a/b/g, a/b/g/n, a/b/g/n/y',
                  `mode` varchar(20) COLLATE utf8_unicode_ci DEFAULT NULL
                         COMMENT 'ad-hoc, managed, master, repeater, secondary, monitor, auto',
                  PRIMARY KEY (`id`),
                  UNIQUE KEY `networkports_id` (`networkports_id`),
                  KEY `card` (`items_devicenetworkcards_id`),
                  KEY `essid` (`wifinetworks_id`),
                  KEY `version` (`version`),
                  KEY `mode` (`mode`)
                ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci";

        $DB->queryOrDie($query, "0.84 create glpi_networkportwifis");

        $port = new NetworkPortWifi();
        updateNetworkPortInstantiation($port, [], true);
    }

    $migration->displayMessage(sprintf(__('Change of the database layout - %s'), "glpi_networkportlocals"));

   // Adding NetworkPortLocal table
    if (!$DB->tableExists('glpi_networkportlocals')) {
        $query = "CREATE TABLE `glpi_networkportlocals` (
                  `id` int NOT NULL AUTO_INCREMENT,
                  `networkports_id` int NOT NULL DEFAULT '0',
                  PRIMARY KEY (`id`),
                  UNIQUE KEY `networkports_id` (`networkports_id`)
                ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci";

        $DB->queryOrDie($query, "0.84 create glpi_networkportlocals");

        $port = new NetworkPortLocal();
        updateNetworkPortInstantiation($port, [], false);
    }

    $migration->displayMessage(sprintf(__('Change of the database layout - %s'), "glpi_networkportdialups"));

   // Adding NetworkPortDialup table
    if (!$DB->tableExists('glpi_networkportdialups')) {
        $query = "CREATE TABLE `glpi_networkportdialups` (
                  `id` int NOT NULL AUTO_INCREMENT,
                  `networkports_id` int NOT NULL DEFAULT '0',
                  PRIMARY KEY (`id`),
                  UNIQUE KEY `networkports_id` (`networkports_id`)
                ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci";

        $DB->queryOrDie($query, "0.84 create glpi_networkportdialups");

        $port = new NetworkPortDialup();
        updateNetworkPortInstantiation($port, [], true);
    }

    $migration->displayMessage(sprintf(__('Change of the database layout - %s'), "glpi_networkportaggregates"));

   // Adding NetworkPortAggregate table
    if (!$DB->tableExists('glpi_networkportaggregates')) {
        $query = "CREATE TABLE `glpi_networkportaggregates` (
                  `id` int NOT NULL AUTO_INCREMENT,
                  `networkports_id` int NOT NULL DEFAULT '0',
                  `networkports_id_list` TEXT DEFAULT NULL
                             COMMENT 'array of associated networkports_id',
                  PRIMARY KEY (`id`),
                  UNIQUE KEY `networkports_id` (`networkports_id`)
                ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci";

        $DB->queryOrDie($query, "0.84 create glpi_networkportaggregates");

       // Transform NetworkEquipment local MAC address as a networkport that aggregates all ports
        $query = "SELECT *
                FROM `origin_glpi_networkequipments`
                WHERE `mac` != ''
                      OR `ip` != ''";
        $port_input = ['itemtype'           => 'NetworkEquipment',
            'logical_number'     => '0',
            'name'               => 'management',
            'instantiation_type' => 'NetworkPortAggregate'
        ];
        foreach ($DB->request($query) as $equipment) {
            $networkequipments_id       = $equipment['id'];

            $query = "SELECT `id`, `ip`, `mac`
                   FROM `origin_glpi_networkports`
                   WHERE `itemtype` = 'NetworkEquipment'
                         AND `items_id` = '$networkequipments_id'
                         AND (`ip` = '" . $equipment['ip'] . "'
                              OR `mac` = '" . $equipment['mac'] . "')";

            $both = [];
            $mac  = [];
            $ip   = [];
            foreach ($DB->request($query) as $ports) {
                if ($ports['ip'] == $equipment['ip']) {
                    if ($ports['mac'] == $equipment['mac']) {
                        $both[] = $ports['id'];
                    } else {
                        $ip[] = $ports['id'];
                    }
                } else {
                    $mac[] = $ports['id'];
                }
            }

            if (count($both) != 1) { // Only add a NetworkPort if there is 0 or more than one element !
                $port_input['items_id']     = $networkequipments_id;
                $port_input['entities_id']  = $equipment['entities_id'];
                $port_input['is_recursive'] = $equipment['is_recursive'];
                $port_input['mac']          = strtolower($equipment['mac']);

                $networkports_id = $migration->insertInTable('glpi_networkports', $port_input);

                $aggregate_input                         = [];
                $aggregate_input['networkports_id']      = $networkports_id;
                $aggregate_input['networkports_id_list'] = exportArrayToDB($both);

                $migration->insertInTable('glpi_networkportaggregates', $aggregate_input);

                createNetworkNameFromItem(
                    'NetworkPort',
                    $networkports_id,
                    $equipment['id'],
                    'NetworkEquipment',
                    $equipment['entities_id'],
                    $equipment['ip']
                );

                foreach ($both as $aggregated_networkports_id) {
                     $query = "DELETE
                         FROM `glpi_networknames`
                         WHERE `itemtype` = 'NetworkPort'
                               AND `items_id` = '$aggregated_networkports_id'";
                     $DB->query($query);

                     $query = "UPDATE `glpi_networkports`
                         SET `mac` = ''
                         WHERE `id` = '$aggregated_networkports_id'";
                     $DB->query($query);
                }
            }
        }
    }

    $migration->displayMessage(sprintf(__('Change of the database layout - %s'), "glpi_networkportaliases"));

   // Adding NetworkPortAlias table
    if (!$DB->tableExists('glpi_networkportaliases')) {
        $query = "CREATE TABLE `glpi_networkportaliases` (
                  `id` int NOT NULL AUTO_INCREMENT,
                  `networkports_id` int NOT NULL DEFAULT '0',
                  `networkports_id_alias` int NOT NULL DEFAULT '0',
                  PRIMARY KEY (`id`),
                  UNIQUE KEY `networkports_id` (`networkports_id`),
                  KEY `networkports_id_alias` (`networkports_id_alias`)
                ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci";

        $DB->queryOrDie($query, "0.84 create glpi_networkportaliases");

       // New element, so, we don't need to create items
    }

    $migration->addField('glpi_networkports_vlans', 'tagged', 'bool', ['value' => '0']);
    $migration->addField('glpi_vlans', 'entities_id', 'integer', ['value' => '0',
        'after' => 'id'
    ]);
    $migration->addKey('glpi_vlans', 'entities_id');
    $migration->addField('glpi_vlans', 'is_recursive', 'bool', ['value' => '0',
        'after' => 'entities_id',
        'update' => '1'
    ]);
    $migration->addKey('glpi_vlans', 'tag');

    $migration->displayMessage(sprintf(
        __('Data migration - %s'),
        'Update connections between IPAddress and IPNetwork'
    ));

   // Here, we are sure that there is only IPv4 addresses. So, the SQL requests are simplified
    $query = "SELECT `id`, `address_3`, `netmask_3`
             FROM `glpi_ipnetworks`";

    if ($network_result = $DB->query($query)) {
        unset($query);
        while ($ipnetwork_row = $DB->fetchAssoc($network_result)) {
            $ipnetworks_id = $ipnetwork_row['id'];
            $netmask       = floatval($ipnetwork_row['netmask_3']);
            $address       = floatval($ipnetwork_row['address_3']) & $netmask;

            $query = "SELECT `id`
                   FROM `glpi_ipaddresses`
                   WHERE (`glpi_ipaddresses`.`binary_3` & '$netmask') = $address
                         AND `glpi_ipaddresses`.`version` = '4'
                   GROUP BY `items_id`";

            if ($ipaddress_result = $DB->query($query)) {
                unset($query);
                while ($link = $DB->fetchAssoc($ipaddress_result)) {
                    $query = "INSERT INTO `glpi_ipaddresses_ipnetworks`
                                (`ipaddresses_id`, `ipnetworks_id`)
                         VALUES ('" . $link['id'] . "', '$ipnetworks_id')";
                    $DB->query($query);
                    unset($query);
                }
            }
        }
    }

    $migration->displayMessage(sprintf(
        __('Change of the database layout - %s'),
        'Drop table glpi_networkportmigrations if empty'
    ));

    if (countElementsInTable("glpi_networkportmigrations") == 0) {
        $migration->dropTable("glpi_networkportmigrations");
        $migration->dropTable("glpi_networkportinterfaces");
        unset($ADDTODISPLAYPREF['NetworkPortMigration']);
    }

   // We migrate glpi_networkequipments: mac field presence is used to check if framework has
   // already been migrated
    $migration->migrationOneTable('glpi_networkequipments');

    foreach ($originTables as $table) {
        $migration->dropTable($table);
    }
}


/**
 * @param $deviceType
 * @param $new_specif               (default NULL)
 * @param $new_specif_type          (default NULL)
 * @param $other_specif      array
 */
function migrateComputerDevice(
    $deviceType,
    $new_specif = null,
    $new_specif_type = null,
    array $other_specif = []
) {
    global $DB, $migration;

    $table        = getTableForItemType('Item_' . $deviceType);
    $device_table = getTableForItemType($deviceType);
    $migration->renameTable(getTableForItemType('Computer_' . $deviceType), $table);

    $migration->changeField($table, 'computers_id', 'items_id', 'integer', ['value' => 0]);
    $migration->addField($table, 'itemtype', 'string', ['after'  => 'items_id',
        'update' => "'Computer'"
    ]);

    if (!empty($new_specif) && !empty($new_specif_type)) {
        $migration->changeField($table, 'specificity', $new_specif, $new_specif_type);
        $migration->changeField(
            $device_table,
            'specif_default',
            $new_specif . '_default',
            $new_specif_type
        );

       // Update the log ...
        $query = "UPDATE `glpi_logs`
                SET `itemtype_link` = 'Item_" . $deviceType . "#" . $new_specif . "'
                WHERE `itemtype_link` = '$deviceType'";
        $DB->queryOrDie($query, "0.84 adapt glpi_logs to new item_devices");
    }

    foreach ($other_specif as $field => $format) {
        $migration->addField($table, $field, $format);
    }
    $migration->migrationOneTable($table);
}

Zerion Mini Shell 1.0