<?php
// +-------------------------------------------------+
// 2002-2004 PMB Services / www.sigb.net pmb@sigb.net et contributeurs (voir www.sigb.net)
// +-------------------------------------------------+
// $Id: addon.inc.php,v 1.8.2.32.2.4.2.11.2.51 2026/04/27 09:26:03 jparis Exp $

if (stristr($_SERVER['REQUEST_URI'], ".inc.php")) {
    die("no access");
}

global $pmb_bdd_subversion, $pmb_bdd_version, $pmb_version_brut, $pmb_version_patch;
global $pmb_subversion_database_as_it_shouldbe;
global $pmb_bdd_subversion_error;

function traite_addon_rqt($requete = "", $message = "")
{
    global $charset, $pmb_bdd_subversion;
    global $db_update_log_version, $db_update_step, $db_update_error;

    $retour = "Successful";
    if ($charset == "utf-8") {
        $requete = encoding_normalize::utf8_encode($requete);
        $message = encoding_normalize::utf8_encode($message);
    }
    pmb_mysql_query($requete);
    $erreur_no = pmb_mysql_errno();
    $erreur_msg = pmb_mysql_error();

    if ($erreur_no) {
        switch ($erreur_no) {
            case "1060":
                $retour = "Field already exists, no problem.";
                break;
            case "1061":
                $retour = "Key already exists, no problem.";
                break;
            case "1091":
                $retour = "Object already deleted, no problem.";
                break;
            default:
                if (! $db_update_error) {
                    $db_update_error = $db_update_step;
                    $query_error = "UPDATE parametres SET valeur_param='" . $db_update_error . "' WHERE type_param='pmb' AND sstype_param='bdd_subversion_error' AND valeur_param=0";
                    pmb_mysql_query($query_error);
                }
                $retour = "<font color=\"#FF0000\">Error may be fatal : <i>" . $erreur_msg . "<i></font>";
                break;
        }
    }
    $result = pmb_mysql_query("SHOW TABLES LIKE 'db_update_logs'");
    if (pmb_mysql_num_rows($result)) {
        $query_log = " INSERT INTO db_update_logs (db_update_log_type, db_update_log_version, db_update_log_query, db_update_log_message, db_update_log_error, db_update_log_result)
        VALUES ('addon', '" . $db_update_log_version . $db_update_step . "', '" . addslashes($requete) . "', '" . addslashes($message) . "', $erreur_no, '" . addslashes(strip_tags($retour)) . "')";
        pmb_mysql_query($query_log);
    }
    return "<tr><td><font size='1'><span data-alter='action'>" . $message ."</span></font></td><td><font size='1'><span data-alter='result'>" . $retour . "</span></font></td></tr>";
}
echo "<table>";

/**
 * ****************** AJOUTER ICI LES MODIFICATIONS ******************************
 */

// Formate et verifie que $pmb_bdd_subversion est <= à $pmb_subversion_database_as_it_shouldbe
$pmb_bdd_subversion = intval($pmb_bdd_subversion);
$pmb_subversion_database_as_it_shouldbe = intval($pmb_subversion_database_as_it_shouldbe);
if($pmb_bdd_subversion > $pmb_subversion_database_as_it_shouldbe ) {
    $pmb_bdd_subversion =  $pmb_subversion_database_as_it_shouldbe;
}
$pmb_bdd_subversion_error = intval($pmb_bdd_subversion_error);

$db_update_log_version = "PMB : " . $pmb_version_brut . "." . $pmb_version_patch . "; BDD : " . $pmb_bdd_version . "_";
$db_update_step = $pmb_bdd_subversion;

//Raz erreur $pmb_bdd_subversion_error
if($pmb_bdd_subversion <= $pmb_bdd_subversion_error) {
    $query_raz = "UPDATE parametres SET valeur_param=0 WHERE type_param='pmb' AND sstype_param='bdd_subversion_error'";
    pmb_mysql_query($query_raz);
}

while ($db_update_step < $pmb_subversion_database_as_it_shouldbe) {
    switch ($db_update_step) {

        case 0:
            // DG - Texte apparaissant avant la liste des ouvrages dans le courrier ou mail d'invalidation
            if (pmb_mysql_num_rows(pmb_mysql_query("SELECT 1 FROM parametres WHERE type_param='pdflettreresa' AND sstype_param='before_list_unconfirmed'")) == 0) {
                $rqt = "INSERT INTO parametres (type_param, sstype_param, valeur_param, comment_param, section_param, gestion)
            VALUES ('pdflettreresa', 'before_list_unconfirmed', 'Suite à votre demande de réservation, nous vous informons que nous avons annulé la confirmation du ou des ouvrages ci-dessous car ils ne sont pas disponibles à ces dates.', 'Texte apparaissant avant la liste des ouvrages dans le courrier ou mail d\'invalidation', '', 0)";
                echo traite_addon_rqt($rqt, 'INSERT pdflettreresa_before_list_unconfirmed INTO parametres');
            }

            // DG - Texte apparaissant avant la liste des ouvrages dans le courrier ou mail de suppression
            if (pmb_mysql_num_rows(pmb_mysql_query("SELECT 1 FROM parametres WHERE type_param='pdflettreresa' AND sstype_param='before_list_deleted'")) == 0) {
                $rqt = "INSERT INTO parametres (type_param, sstype_param, valeur_param, comment_param, section_param, gestion)
            VALUES ('pdflettreresa', 'before_list_deleted', 'Suite à votre demande de réservation, nous sommes dans le regret de vous informer que le ou les ouvrages ci-dessous ne sont pas disponibles.', 'Texte apparaissant avant la liste des ouvrages dans le courrier ou mail de suppression', '', 0)";
                echo traite_addon_rqt($rqt, 'INSERT pdflettreresa_before_list_deleted INTO parametres');
            }

            // DG - Texte apparaissant après la liste des ouvrages
            if (pmb_mysql_num_rows(pmb_mysql_query("SELECT 1 FROM parametres WHERE type_param='pdflettreresa' AND sstype_param='after_list_unconfirmed'")) == 0) {
                $rqt = "INSERT INTO parametres (type_param, sstype_param, valeur_param, comment_param, section_param, gestion)
            VALUES ('pdflettreresa', 'after_list_unconfirmed', '', 'Texte apparaissant après la liste des ouvrages dans le courrier ou mail d\'invalidation', '', 0)";
                echo traite_addon_rqt($rqt, 'INSERT pdflettreresa_after_list_unconfirmed INTO parametres');
            }

            // DG - Texte apparaissant après la liste des ouvrages
            if (pmb_mysql_num_rows(pmb_mysql_query("SELECT 1 FROM parametres WHERE type_param='pdflettreresa' AND sstype_param='after_list_deleted'")) == 0) {
                $rqt = "INSERT INTO parametres (type_param, sstype_param, valeur_param, comment_param, section_param, gestion)
            VALUES ('pdflettreresa', 'after_list_deleted', '', 'Texte apparaissant après la liste des ouvrages dans le courrier ou mail de suppression', '', 0)";
                echo traite_addon_rqt($rqt, 'INSERT pdflettreresa_after_list_deleted INTO parametres');
            }
            break;
        case 1:
            // DG - Gestion des groupes de champs personnalisés
            $rqt = "create table if not exists custom_fields_groups (
				id_group int(10) unsigned NOT NULL AUTO_INCREMENT,
				group_type varchar(255) not null default '',
				group_name varchar(255) not null default '',
				group_title varchar(255) not null default '',
                group_fields mediumtext,
	    		primary key (id_group)) ";
            echo traite_addon_rqt($rqt,"create table if not exists custom_fields_groups");
            break;
        case 2:
            // TS - ajout d'une option rgaa pour le parametre rmc_responsive
            $rqt = "UPDATE parametres SET comment_param = 'Affichage de la recherche multi-critères responsive .\n 0 : Non\n 1 : Oui\n 2 : Oui (compatible RGAA)' WHERE type_param = 'opac' AND sstype_param = 'rmc_responsive'  ";
            echo traite_addon_rqt($rqt, "UPDATE opac_rmc_responsive INTO parametres");
            break;
        case 3:
            // GN - Ajout d'une taille maximum pour le stockage des fichiers pour les listes de lecture avec la recherche sémantique
            if (pmb_mysql_num_rows(pmb_mysql_query("SELECT 1 FROM parametres WHERE type_param='ai' AND sstype_param='empr_total_upload_max_size'")) == 0) {
                $rqt = "INSERT INTO parametres (type_param, sstype_param, valeur_param, comment_param, section_param, gestion)
                    VALUES ('ai', 'empr_total_upload_max_size', '10', 'Poids total des fichiers que le lecteur peut uploader en Mo', '', 0)";
                echo traite_addon_rqt($rqt, 'INSERT empr_total_upload_max_size INTO parametres artificial_intelligence');
            }

            // GN - Ajout dans la sous-session "Listes de lecture partagées" dans "Intelligence artificielle"
            $rqt = "UPDATE parametres SET section_param = 'shared_lists' WHERE type_param = 'ai' AND sstype_param = 'empr_total_upload_max_size' AND section_param != 'shared_lists';";
            echo traite_addon_rqt($rqt, "UPDATE empr_total_upload_max_size SET section_param='shared_lists'");
            break;
        case 4:
            // JP - Déplacement du paramètre opac_meta_keywords dans les paramètres inutilisés
            if (pmb_mysql_num_rows(pmb_mysql_query("SELECT 1 FROM parametres WHERE type_param = 'opac' AND sstype_param = 'meta_keywords'")) != 0) {
                $rqt = "UPDATE parametres SET section_param = 'z_unused' WHERE type_param = 'opac' AND sstype_param = 'meta_keywords'";
                echo traite_addon_rqt($rqt, "UPDATE parametres SET section_param = 'z_unused' WHERE type_param = 'opac' AND sstype_param = 'meta_keywords'");
            }
            break;
        case 5:
            //DG - Ajout d'une colonne "num_increment_day_of_month" pour le jour de départ du cycle (numéro)
            if (pmb_mysql_num_rows(pmb_mysql_query("SHOW COLUMNS FROM custom_fields_groups LIKE 'group_title_button_add'")) == 0) {
                $rqt = "ALTER TABLE custom_fields_groups ADD group_title_button_add varchar(255) not null default '' AFTER group_title";
                echo traite_addon_rqt($rqt, "ALTER TABLE custom_fields_groups ADD group_title_button_add");
            }
            break;
        case 6:
            // DG - Liste des adresses pot de miel présentes sur les pages OPAC
            if (pmb_mysql_num_rows(pmb_mysql_query("SELECT 1 FROM parametres WHERE type_param='security' AND sstype_param='honey_pot_email'")) == 0) {
                $rqt = "INSERT INTO parametres (type_param, sstype_param, valeur_param, comment_param, section_param, gestion)
            VALUES ('security', 'honey_pot_email', '', 'Liste des adresses pot de miel présentes sur les pages OPAC pour les \"robots\", à séparer par des points-virgules', '', 0)";
                echo traite_addon_rqt($rqt, 'INSERT security_honey_pot_email INTO parametres');
            }
            break;
        case 7:
            // DB - Modification du commentaire du paramètre opac_resa_popup
            if (pmb_mysql_num_rows(pmb_mysql_query("SELECT 1 FROM parametres WHERE type_param='opac' AND sstype_param='resa_popup'"))) {
                $comment_param = "Mode d'affichage des réservations et suggestions :\r\n\r\n 0 : Dans la page\n 1 : Dans un popup\r\n 2 : Dans un nouvel onglet / une nouvelle fenêtre";
                $rqt = "UPDATE parametres SET comment_param='" . addslashes($comment_param) . "' WHERE type_param='opac' AND sstype_param='resa_popup'";
                echo traite_addon_rqt($rqt, "UPDATE comment_param opac_resa_popup");
            }
            break;
        case 8:
        	// JP - Ajout d'un paramètre pour définir une URL de redirection de la page 404 à l'OPAC
        	if (pmb_mysql_num_rows(pmb_mysql_query("SELECT 1 FROM parametres WHERE type_param='opac' and sstype_param='redirection_url_404'")) == 0){
        		$rqt = "INSERT INTO parametres (id_param, type_param, sstype_param, valeur_param, gestion, comment_param)
            		VALUES (0, 'opac', 'redirection_url_404', '', '0', 'URL de redirection de l\'erreur 404 à l\'OPAC')";
        		echo traite_addon_rqt($rqt, "INSERT opac_redirection_url_404 INTO parametres");
        	}

        	// RT - JP - Implémentation du module SEO
        	$rqt = "CREATE TABLE IF NOT EXISTS seo_page_type(
	            id_page_type INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
	            type INT(10) UNSIGNED NOT NULL DEFAULT 0,
	            indexable TINYINT(1) NOT NULL DEFAULT 0,
	            followable TINYINT(1) NOT NULL DEFAULT 0,
	            PRIMARY KEY(id_page_type))";
        	echo traite_addon_rqt($rqt, "CREATE TABLE IF NOT EXISTS seo_page_type");

        	$rqt = "CREATE TABLE IF NOT EXISTS seo_subpage_type(
	            id_subpage_type INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
	            type INT(10) UNSIGNED NOT NULL DEFAULT 0,
	            indexable TINYINT(1) NOT NULL DEFAULT 0,
	            followable TINYINT(1) NOT NULL DEFAULT 0,
	            num_page_type INT(10) UNSIGNED NOT NULL DEFAULT 0,
	            PRIMARY KEY(id_subpage_type))";
        	echo traite_addon_rqt($rqt, "CREATE TABLE IF NOT EXISTS seo_subpage_type");

        	$rqt = "CREATE TABLE IF NOT EXISTS seo_sitemap_entry(
	            id_sitemap_entry INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
	            type VARCHAR(100) NOT NULL DEFAULT '',
	            in_sitemap TINYINT(1) NOT NULL DEFAULT 0,
	            priority FLOAT(3, 2) NOT NULL DEFAULT 0,
	            frequency_update VARCHAR(100) NOT NULL DEFAULT '',
	            sitemap_order INT(10) UNSIGNED NOT NULL DEFAULT 0,
	            settings MEDIUMBLOB NOT NULL DEFAULT '{}',
	            num_parent INT(10) UNSIGNED NOT NULL DEFAULT 0,
	            PRIMARY KEY(id_sitemap_entry))";
        	echo traite_addon_rqt($rqt, "CREATE TABLE IF NOT EXISTS seo_sitemap_entry");
        	break;
        case 9:
            // DG - Ajout du champ expl_custom_fields permettant de préciser les valeurs par défaut des CP expl en bulletinage
            $rqt = "ALTER TABLE abts_abts ADD expl_custom_fields MEDIUMTEXT";
            echo traite_addon_rqt($rqt,"ALTER TABLE abts_abts ADD expl_custom_fields");
            break;
        case 10:
            // DB - Verification compatibilite WebP
            if( (imagetypes() & IMG_WEBP) == 0 ) {
                $rqt="UPDATE IGNORE parametres set valeur_param='png' where type_param='opac' and sstype_param ='img_cache_type'";
                echo traite_addon_rqt($rqt,"change opac_img_cache_type to png into parametres");
            }
            break;
        case 11:
            // GN - Modification de la tables certificates
            $rqt ="ALTER TABLE certificates DROP COLUMN private_key";
            echo traite_addon_rqt($rqt,"ALTER TABLE certificates DROP COLUMN private_key");
            $rqt ="ALTER TABLE certificates DROP COLUMN name";
            echo traite_addon_rqt($rqt,"ALTER TABLE certificates DROP COLUMN name");
            $rqt ="ALTER TABLE certificates DROP COLUMN cert";
            echo traite_addon_rqt($rqt,"ALTER TABLE certificates DROP COLUMN cert");
            $rqt="ALTER TABLE certificates ADD settings MEDIUMBLOB NOT NULL DEFAULT ''";
            echo traite_addon_rqt($rqt,"ALTER TABLE certificates ADD settings");
            break;
        case 12:
            // QV - [IA] Template pour l'indexation des entites afin de calculer les embeddings
            $rqt = "CREATE TABLE IF NOT EXISTS embeddings_template (
                entity_type int(10) unsigned NOT NULL,
                template text NOT NULL DEFAULT '',
                PRIMARY KEY (entity_type)
            )";
            echo traite_addon_rqt($rqt, "CREATE TABLE embeddings_template");

            if (pmb_mysql_num_rows(pmb_mysql_query("SELECT 1 FROM embeddings_template WHERE entity_type=" . TYPE_NOTICE)) == 0) {
                global $base_path;
                $template = file_get_contents($base_path . '/includes/templates/embeddings_template/record.tpl.html');

                $rqt = "INSERT INTO embeddings_template (entity_type, template) VALUES (" . TYPE_NOTICE . ", '" . addslashes($template) . "')";
                echo traite_addon_rqt($rqt, "INSERT entity_type=" . TYPE_NOTICE . " INTO embeddings_template");
            }
            break;
        case 13:
            // DB & RT - Lien entre types et themes de demandes
            if (pmb_mysql_num_rows(pmb_mysql_query("SHOW COLUMNS FROM demandes_theme LIKE 'allowed_types'")) == 0) {
                $rqt = "ALTER TABLE demandes_theme ADD allowed_types TEXT NOT NULL";
                echo traite_addon_rqt($rqt, "ALTER TABLE demandes_theme ADD allowed_types");
            }
            break;
        case 14:
            // JP & DG - Pouvoir forcer la remise en HT ou TTC
            //ROLLBACK
            break;
        case 15:
            // GN - Ajout d'un paramètre utilisateur pour les animations (Localisation par défaut)
            $rqt = "ALTER TABLE users ADD deflt_animation_location TINYINT UNSIGNED DEFAULT 0 NOT NULL ";
            echo traite_addon_rqt($rqt, "ALTER TABLE users ADD deflt_animation_location");
            break;
        case 16:
            // QV - Ajout du type de public dans les animations
            $rqt = "CREATE TABLE IF NOT EXISTS anim_public_type (
                id_public_type int(10) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
                label varchar(255) NOT NULL DEFAULT ''
            )";
            echo traite_addon_rqt($rqt, "CREATE TABLE anim_public_type");

            if (pmb_mysql_num_rows(pmb_mysql_query("SHOW COLUMNS FROM anim_animations LIKE 'num_public_type'")) == 0) {
                $rqt = "ALTER TABLE anim_animations ADD num_public_type int(11) DEFAULT 0 NOT NULL";
                echo traite_addon_rqt($rqt, "ALTER TABLE anim_animations ADD num_public_type");
            }
            break;
        case 17:
        	// QV - Blocage avec le commentaire d'exemplaire (pret)
        	if (pmb_mysql_num_rows(pmb_mysql_query("SELECT 1 FROM parametres WHERE type_param = 'selfservice' and sstype_param='loan_expl_note_block'")) == 0) {
        		$rqt = "INSERT INTO parametres (id_param, type_param, sstype_param, valeur_param, gestion, comment_param)
                    VALUES (0, 'selfservice', 'loan_expl_note_block', '1', '1', 'Bloquer le document si un message exemplaire est défini') ";
        		echo traite_addon_rqt($rqt, "INSERT selfservice_loan_expl_note_block='1' INTO parametres") ;
        	}
        	break;
        case 18:
            // TS & DB - nettoyage des sources de vignettes comprenant gamannecy
            $query_ext_links = "SELECT *  FROM `thumbnail_sources` WHERE `class` LIKE '%RecordExternallinksThumbnailSource' AND settings LIKE '%gamannecy%'";
            $result_ext_links = pmb_mysql_query($query_ext_links);
            if (pmb_mysql_num_rows($result_ext_links)) {
                $row_ext_links = pmb_mysql_fetch_assoc($result_ext_links);
                $settings = json_decode($row_ext_links['settings'], true);

                //settings contient un tableau "links"
                if(!empty($settings['links']) && is_countable($settings['links'])) {

                    for ($i = 0; $i <= count($settings['links']); $i++) {
                        if ( ($settings['links'][$i]['name'] == 'gamannecy') || (stripos($settings['links'][$i]['url'], 'gamannecy') !== false) ) {
                            unset($settings['links'][$i]);
                        }
                    }

                    $settings['links'] = array_values($settings['links']);
                    $new_settings = json_encode($settings);
                    $q = "UPDATE thumbnail_sources SET settings = '" . addslashes($new_settings) . "' WHERE id = " . $row_ext_links['id'];
                    echo traite_addon_rqt($q, "UPDATE thumbnail_sources");

                //settings ne contient pas de tableau "links"
                } elseif (empty($settings['links']) && is_countable($settings)) {
                    for ($i = 0; $i <= count($settings); $i++) {
                        if ( ($settings[$i]['name'] == 'gamannecy') || (stripos($settings[$i]['url'], 'gamannecy') !== false) ) {
                            unset($settings[$i]);
                        }
                    }
                    $settings = array_values($settings);
                    $new_settings = json_encode($settings);
                    $q = "UPDATE thumbnail_sources SET settings = '" . addslashes($new_settings) . "' WHERE id = " . $row_ext_links['id'];
                    echo traite_addon_rqt($q, "UPDATE thumbnail_sources");
                }
            }
            break;
        case 19:
            //TS - Nettoyage et rechargement de l'autoload
            // nouvelle classe searcher_items.class.php
            netbase_cache::clean_autoload_files();
            break;
        case 20:
            // DB- Statut de notice par défaut en sélection de ligne commande
            if (!pmb_mysql_num_rows(pmb_mysql_query("SHOW COLUMNS FROM users LIKE 'deflt3sel_notice_statut'"))){
                $rqt = "ALTER TABLE users ADD deflt3sel_notice_statut INT(3) UNSIGNED DEFAULT 0 NOT NULL" ;
                echo traite_addon_rqt($rqt,"ALTER users ADD deflt3sel_notice_statut");
            }
            break;
        case 21:
        	//RT - Suppression de la colonne dsi_tag.type pour les bases l'ayant encore
        	$query_test = "SHOW COLUMNS FROM dsi_tag LIKE 'type'";
        	$result = pmb_mysql_query($query_test);
        	if (pmb_mysql_num_rows($result) > 0) {
        		$q = "ALTER TABLE dsi_tag DROP COLUMN type";
        		echo traite_addon_rqt($q, "ALTER TABLE dsi_tag DROP COLUMN type");
        	}
        	break;
    }
    $db_update_step ++;
}

/**
 * ****************** JUSQU'ICI *************************************************
 */
/* PENSER à faire +1 au paramètre $pmb_subversion_database_as_it_shouldbe dans includes/config.inc.php */
/* COMMITER les deux fichiers addon.inc.php ET config.inc.php en même temps */
echo traite_addon_rqt("update parametres set valeur_param='" . $db_update_step . "' where type_param='pmb' and sstype_param='bdd_subversion'", "Update to $db_update_step database subversion.");
echo "<table>";
