array( 'page' => 'article', 'texte_retour' => 'icone_retour_article', 'texte_modifier' => 'icone_modifier_article', 'texte_creer' => 'icone_ecrire_article', 'texte_objets' => 'public:articles', 'texte_objet' => 'public:article', 'texte_signale_edition' => 'texte_travail_article', 'info_aucun_objet' => 'info_aucun_article', 'info_1_objet' => 'info_1_article', 'info_nb_objets' => 'info_nb_articles', 'texte_logo_objet' => 'logo_article', 'texte_langue_objet' => 'titre_langue_article', 'texte_definir_comme_traduction_objet' => 'trad_lier', 'titre' => 'titre, lang', 'date' => 'date', 'principale' => 'oui', 'introduction_longueur' => '500', 'champs_editables' => array( 'surtitre', 'titre', 'soustitre', 'descriptif', 'nom_site', 'url_site', 'chapo', 'texte', 'ps', 'virtuel' ), 'champs_versionnes' => array( 'id_rubrique', 'surtitre', 'titre', 'soustitre', 'jointure_auteurs', 'descriptif', 'nom_site', 'url_site', 'chapo', 'texte', 'ps' ), 'field' => array( 'id_article' => 'bigint(21) NOT NULL', 'surtitre' => "text DEFAULT '' NOT NULL", 'titre' => "text DEFAULT '' NOT NULL", 'soustitre' => "text DEFAULT '' NOT NULL", 'id_rubrique' => "bigint(21) DEFAULT '0' NOT NULL", 'descriptif' => "text DEFAULT '' NOT NULL", 'chapo' => "mediumtext DEFAULT '' NOT NULL", 'texte' => "longtext DEFAULT '' NOT NULL", 'ps' => "mediumtext DEFAULT '' NOT NULL", 'date' => "datetime DEFAULT '0000-00-00 00:00:00' NOT NULL", 'statut' => "varchar(10) DEFAULT '0' NOT NULL", 'id_secteur' => "bigint(21) DEFAULT '0' NOT NULL", 'maj' => 'TIMESTAMP', 'export' => "VARCHAR(10) DEFAULT 'oui'", 'date_redac' => "datetime DEFAULT '0000-00-00 00:00:00' NOT NULL", 'visites' => "integer DEFAULT '0' NOT NULL", 'referers' => "integer DEFAULT '0' NOT NULL", 'popularite' => "DOUBLE DEFAULT '0' NOT NULL", 'accepter_forum' => "CHAR(3) DEFAULT '' NOT NULL", 'date_modif' => "datetime DEFAULT '0000-00-00 00:00:00' NOT NULL", 'lang' => "VARCHAR(10) DEFAULT '' NOT NULL", 'langue_choisie' => "VARCHAR(3) DEFAULT 'non'", 'id_trad' => "bigint(21) DEFAULT '0' NOT NULL", 'nom_site' => "tinytext DEFAULT '' NOT NULL", 'url_site' => "text DEFAULT '' NOT NULL", 'virtuel' => "text DEFAULT '' NOT NULL", ), 'key' => array( 'PRIMARY KEY' => 'id_article', 'KEY id_rubrique' => 'id_rubrique', 'KEY id_secteur' => 'id_secteur', 'KEY id_trad' => 'id_trad', 'KEY lang' => 'lang', 'KEY statut' => 'statut, date', ), 'join' => array( 'id_article' => 'id_article', 'id_rubrique' => 'id_rubrique' ), 'rechercher_champs' => array( 'surtitre' => 5, 'titre' => 8, 'soustitre' => 5, 'chapo' => 3, 'texte' => 1, 'ps' => 1, 'nom_site' => 1, 'url_site' => 1, 'descriptif' => 4 ), 'rechercher_jointures' => array( 'auteur' => array('nom' => 10), ), 'statut' => array( array( 'champ' => 'statut', 'publie' => 'publie', 'previsu' => 'publie,prop,prepa/auteur', 'post_date' => 'date', 'exception' => array('statut', 'tout') ) ), 'statut_titres' => array( 'prepa' => 'info_article_redaction', 'prop' => 'info_article_propose', 'publie' => 'info_article_publie', 'refuse' => 'info_article_refuse', 'poubelle' => 'info_article_supprime' ), 'statut_textes_instituer' => array( 'prepa' => 'texte_statut_en_cours_redaction', 'prop' => 'texte_statut_propose_evaluation', 'publie' => 'texte_statut_publie', 'refuse' => 'texte_statut_refuse', 'poubelle' => 'texte_statut_poubelle', ), 'texte_changer_statut' => 'texte_article_statut', 'aide_changer_statut' => 'artstatut', 'tables_jointures' => array( 'profondeur' => 'rubriques', #'id_auteur' => 'auteurs_liens' // declaration generique plus bas ), ), 'spip_auteurs' => array( 'page' => 'auteur', 'texte_retour' => 'icone_retour', 'texte_ajouter' => 'titre_ajouter_un_auteur', 'texte_modifier' => 'admin_modifier_auteur', 'texte_objets' => 'icone_auteurs', 'texte_objet' => 'public:auteur', 'info_aucun_objet' => 'info_aucun_auteur', 'info_1_objet' => 'info_1_auteur', 'info_nb_objets' => 'info_nb_auteurs', 'texte_logo_objet' => 'logo_auteur', 'texte_creer_associer' => 'creer_et_associer_un_auteur', 'titre' => "nom AS titre, '' AS lang", 'date' => 'date', 'principale' => 'oui', 'champs_editables' => array('nom', 'email', 'bio', 'nom_site', 'url_site', 'imessage', 'pgp'), 'champs_versionnes' => array('nom', 'bio', 'email', 'nom_site', 'url_site', 'login'), 'field' => array( 'id_auteur' => 'bigint(21) NOT NULL', 'nom' => "text DEFAULT '' NOT NULL", 'bio' => "text DEFAULT '' NOT NULL", 'email' => "tinytext DEFAULT '' NOT NULL", 'nom_site' => "tinytext DEFAULT '' NOT NULL", 'url_site' => "text DEFAULT '' NOT NULL", 'login' => 'VARCHAR(255) BINARY', 'pass' => "tinytext DEFAULT '' NOT NULL", 'low_sec' => "tinytext DEFAULT '' NOT NULL", 'statut' => "varchar(255) DEFAULT '0' NOT NULL", 'webmestre' => "varchar(3) DEFAULT 'non' NOT NULL", 'maj' => 'TIMESTAMP', 'pgp' => "TEXT DEFAULT '' NOT NULL", 'htpass' => "tinytext DEFAULT '' NOT NULL", 'en_ligne' => "datetime DEFAULT '0000-00-00 00:00:00' NOT NULL", 'alea_actuel' => 'tinytext', 'alea_futur' => 'tinytext', 'prefs' => 'text', 'cookie_oubli' => 'tinytext', 'source' => "VARCHAR(10) DEFAULT 'spip' NOT NULL", 'lang' => "VARCHAR(10) DEFAULT '' NOT NULL" ), 'key' => array( 'PRIMARY KEY' => 'id_auteur', 'KEY login' => 'login', 'KEY statut' => 'statut', 'KEY en_ligne' => 'en_ligne', ), 'join' => array( 'id_auteur' => 'id_auteur', 'login' => 'login' ), 'rechercher_champs' => array( 'nom' => 5, 'bio' => 1, 'email' => 1, 'nom_site' => 1, 'url_site' => 1, 'login' => 1 ), // 2 conditions pour les auteurs : statut!=poubelle, // et avoir des articles publies 'statut' => array( array( 'champ' => 'statut', 'publie' => '!5poubelle', 'previsu' => '!5poubelle', 'exception' => 'statut' ), array( 'champ' => array( array('spip_auteurs_liens', 'id_auteur'), array( 'spip_articles', array('id_objet', 'id_article', 'objet', 'article') ), 'statut' ), 'publie' => 'publie', 'previsu' => '!', 'post_date' => 'date', 'exception' => array('statut', 'lien', 'tout') ), ), 'statut_images' => array( 'auteur-6forum-16.png', '0minirezo' => 'auteur-0minirezo-16.png', '1comite' => 'auteur-1comite-16.png', '6forum' => 'auteur-6forum-16.png', '5poubelle' => 'auteur-5poubelle-16.png', 'nouveau' => '' ), 'statut_titres' => array( 'titre_image_visiteur', '0minirezo' => 'titre_image_administrateur', '1comite' => 'titre_image_redacteur_02', '6forum' => 'titre_image_visiteur', '5poubelle' => 'titre_image_auteur_supprime', ), 'tables_jointures' => array(#'auteurs_liens' // declaration generique plus bas ), ), 'spip_rubriques' => array( 'page' => 'rubrique', 'url_voir' => 'rubrique', 'url_edit' => 'rubrique_edit', 'texte_retour' => 'icone_retour', 'texte_objets' => 'public:rubriques', 'texte_objet' => 'public:rubrique', 'texte_modifier' => 'icone_modifier_rubrique', 'texte_creer' => 'icone_creer_rubrique', 'texte_ajouter' => 'titre_ajouter_une_rubrique', 'texte_creer_associer' => 'creer_et_associer_une_rubrique', 'info_aucun_objet' => 'info_aucun_rubrique', 'info_1_objet' => 'info_1_rubrique', 'info_nb_objets' => 'info_nb_rubriques', 'texte_logo_objet' => 'logo_rubrique', 'texte_langue_objet' => 'titre_langue_rubrique', 'texte_definir_comme_traduction_objet' => 'texte_definir_comme_traduction_rubrique', 'titre' => 'titre, lang', 'date' => 'date', 'principale' => 'oui', 'introduction_longueur' => '600', 'champs_editables' => array('titre', 'texte', 'descriptif', 'extra'), 'champs_versionnes' => array('titre', 'descriptif', 'texte'), 'field' => array( 'id_rubrique' => 'bigint(21) NOT NULL', 'id_parent' => "bigint(21) DEFAULT '0' NOT NULL", 'titre' => "text DEFAULT '' NOT NULL", 'descriptif' => "text DEFAULT '' NOT NULL", 'texte' => "longtext DEFAULT '' NOT NULL", 'id_secteur' => "bigint(21) DEFAULT '0' NOT NULL", 'maj' => 'TIMESTAMP', 'statut' => "varchar(10) DEFAULT '0' NOT NULL", 'date' => "datetime DEFAULT '0000-00-00 00:00:00' NOT NULL", 'lang' => "VARCHAR(10) DEFAULT '' NOT NULL", 'langue_choisie' => "VARCHAR(3) DEFAULT 'non'", 'statut_tmp' => "varchar(10) DEFAULT '0' NOT NULL", 'date_tmp' => "datetime DEFAULT '0000-00-00 00:00:00' NOT NULL", 'profondeur' => "smallint(5) DEFAULT '0' NOT NULL" ), 'key' => array( 'PRIMARY KEY' => 'id_rubrique', 'KEY lang' => 'lang', 'KEY id_parent' => 'id_parent', ), 'rechercher_champs' => array( 'titre' => 8, 'descriptif' => 5, 'texte' => 1 ), 'statut' => array( array( 'champ' => 'statut', 'publie' => 'publie', 'previsu' => '!', 'exception' => array('statut', 'tout') ), ), 'tables_jointures' => array(#'id_auteur' => 'auteurs_liens' // declaration generique plus bas ), ), // toutes les tables ont le droit a une jointure sur les auteurs array('tables_jointures' => array('id_auteur' => 'auteurs_liens')) ); // avant d'appeller les pipeline qui peuvent generer une reentrance a l'install // initialiser la signature $md5 = md5(serialize($infos_tables)); $GLOBALS['tables_principales'] = pipeline('declarer_tables_principales', $GLOBALS['tables_principales']); $GLOBALS['tables_auxiliaires'] = pipeline('declarer_tables_auxiliaires', $GLOBALS['tables_auxiliaires']); $infos_tables = pipeline('declarer_tables_objets_sql', $infos_tables); // completer les informations manquantes ou implicites $all = array(); foreach (array_keys($infos_tables) as $t) { // les cles numeriques servent a declarer // les proprietes applicables a tous les objets // on les mets de cote if (is_numeric($t)) { $all = array_merge_recursive($all, $infos_tables[$t]); unset($infos_tables[$t]); } else { $infos_tables[$t] = renseigner_table_objet_sql($t, $infos_tables[$t]); } } // repercuter les proprietes generales communes a tous les objets foreach (array_keys($infos_tables) as $t) { foreach ($all as $i => $v) { if (in_array($i, array('tables_jointures', 'champs_versionnes'))) { $add = $all[$i]; // eviter les doublons de declaration de table jointure (ex des mots sur auteurs) // pour les declarations generiques avec cles numeriques if ($i == 'tables_jointures' and isset($infos_tables[$t][$i]) and count($infos_tables[$t][$i])) { $doublons = array_intersect($infos_tables[$t][$i], $add); foreach ($doublons as $d) { if (is_numeric(array_search($d, $infos_tables[$t][$i])) and is_numeric($k = array_search($d, $add)) ) { unset($add[$k]); } } } $infos_tables[$t][$i] = array_merge(isset($infos_tables[$t][$i]) ? $infos_tables[$t][$i] : array(), $add); } else { $infos_tables[$t][$i] = array_merge_recursive( isset($infos_tables[$t][$i]) ? $infos_tables[$t][$i] : array(), $all[$i] ); } } } // completer les tables principales et auxiliaires // avec celles declarees uniquement dans declarer_table_objets_sql // pour assurer la compat en transition foreach ($infos_tables as $table => $infos) { $principale_ou_auxiliaire = ($infos['principale'] ? 'tables_principales' : 'tables_auxiliaires'); // memoriser des champs eventuels declares par des plugins dans le pipeline tables_xxx // qui a ete appelle avant $mem = (isset($GLOBALS[$principale_ou_auxiliaire][$table]) ? $GLOBALS[$principale_ou_auxiliaire][$table] : array()); // l'ajouter au tableau $GLOBALS[$principale_ou_auxiliaire][$table] = array(); if (isset($infos['field']) and isset($infos['key'])) { foreach (array('field', 'key', 'join') as $k) { if (isset($infos_tables[$table][$k])) { $GLOBALS[$principale_ou_auxiliaire][$table][$k] = &$infos_tables[$table][$k]; } } } else { // ici on ne renvoie que les declarations, donc RIEN // pour avoir la vrai description en base, il faut passer par trouver_table $GLOBALS[$principale_ou_auxiliaire][$table] = array(); } if (count($mem)) { foreach (array_keys($mem) as $k) { if (isset($GLOBALS[$principale_ou_auxiliaire][$table][$k])) { $GLOBALS[$principale_ou_auxiliaire][$table][$k] = array_merge( $GLOBALS[$principale_ou_auxiliaire][$table][$k], $mem[$k] ); } else { $GLOBALS[$principale_ou_auxiliaire][$table][$k] = $mem[$k]; } } } } // recuperer les interfaces (table_titre, table_date) // on ne le fait que dans un second temps pour que table_objet soit fonctionnel // dans le pipeline de declarer_tables_interfaces include_spip('public/interfaces'); foreach (array_keys($infos_tables) as $t) { $infos_tables[$t] = renseigner_table_objet_interfaces($t, $infos_tables[$t]); } $deja_la = false; // signature $md5 = md5(serialize($infos_tables)); } if ($table_sql === '::md5') { return $md5; } if ($table_sql and !isset($infos_tables[$table_sql])) { #$desc = renseigner_table_objet_sql($table_sql,$desc); $desc = renseigner_table_objet_interfaces($table_sql, $desc); return $desc; } if ($table_sql) { return isset($infos_tables[$table_sql]) ? $infos_tables[$table_sql] : array(); } return $infos_tables; } /** * Déclare les tables principales du Core * * Tables principales, hors objets éditoriaux. * * @param array $tables_principales * Description des tables principales déjà déclarées * @return void **/ function base_serial(&$tables_principales) { $spip_jobs = array( 'id_job' => 'bigint(21) NOT NULL', 'descriptif' => "text DEFAULT '' NOT NULL", 'fonction' => 'varchar(255) NOT NULL', //nom de la fonction 'args' => "longblob DEFAULT '' NOT NULL", // arguments 'md5args' => "char(32) NOT NULL default ''", // signature des arguments 'inclure' => 'varchar(255) NOT NULL', // fichier a inclure ou path/ pour charger_fonction 'priorite' => 'smallint(6) NOT NULL default 0', 'date' => "datetime DEFAULT '0000-00-00 00:00:00' NOT NULL", // date au plus tot 'status' => 'tinyint NOT NULL default 1', ); $spip_jobs_key = array( 'PRIMARY KEY' => 'id_job', 'KEY date' => 'date', 'KEY status' => 'status', ); /// Attention: mes_fonctions peut avoir deja defini cette variable /// il faut donc rajouter, mais pas reinitialiser $tables_principales['spip_jobs'] = array('field' => &$spip_jobs, 'key' => &$spip_jobs_key); } /** * Déclare les tables auxiliaires du Core * * @param array $tables_auxiliaires * Description des tables auxiliaires déjà déclarées * @return void **/ function base_auxiliaires(&$tables_auxiliaires) { $spip_resultats = array( 'recherche' => "char(16) DEFAULT '' NOT NULL", 'id' => 'INT UNSIGNED NOT NULL', 'points' => "INT UNSIGNED DEFAULT '0' NOT NULL", 'table_objet' => "varchar(30) DEFAULT '' NOT NULL", 'serveur' => "char(16) DEFAULT '' NOT NULL", // hash md5 partiel du serveur de base ('' pour le serveur principal) 'maj' => 'TIMESTAMP' ); $spip_resultats_key = array(// pas de cle ni index, ca fait des insertions plus rapides et les requetes jointes utilisees en recheche ne sont pas plus lentes ... ); $spip_auteurs_liens = array( 'id_auteur' => "bigint(21) DEFAULT '0' NOT NULL", 'id_objet' => "bigint(21) DEFAULT '0' NOT NULL", 'objet' => "VARCHAR (25) DEFAULT '' NOT NULL", 'vu' => "VARCHAR(6) DEFAULT 'non' NOT NULL" ); $spip_auteurs_liens_key = array( 'PRIMARY KEY' => 'id_auteur,id_objet,objet', 'KEY id_auteur' => 'id_auteur', 'KEY id_objet' => 'id_objet', 'KEY objet' => 'objet', ); $spip_meta = array( 'nom' => 'VARCHAR (255) NOT NULL', 'valeur' => "text DEFAULT ''", 'impt' => "ENUM('non', 'oui') DEFAULT 'oui' NOT NULL", 'maj' => 'TIMESTAMP' ); $spip_meta_key = array( 'PRIMARY KEY' => 'nom' ); $spip_jobs_liens = array( 'id_job' => "bigint(21) DEFAULT '0' NOT NULL", 'id_objet' => "bigint(21) DEFAULT '0' NOT NULL", 'objet' => "VARCHAR (25) DEFAULT '' NOT NULL", ); $spip_jobs_liens_key = array( 'PRIMARY KEY' => 'id_job,id_objet,objet', 'KEY id_job' => 'id_job' ); $tables_auxiliaires['spip_auteurs_liens'] = array( 'field' => &$spip_auteurs_liens, 'key' => &$spip_auteurs_liens_key ); $tables_auxiliaires['spip_meta'] = array( 'field' => &$spip_meta, 'key' => &$spip_meta_key ); $tables_auxiliaires['spip_resultats'] = array( 'field' => &$spip_resultats, 'key' => &$spip_resultats_key ); $tables_auxiliaires['spip_jobs_liens'] = array( 'field' => &$spip_jobs_liens, 'key' => &$spip_jobs_liens_key ); } /** * Auto remplissage des informations non explicites * sur un objet d'une table sql * * - table_objet * - table_objet_surnoms * - type * - type_surnoms * - url_voir * - url_edit * - icone_objet * * - texte_retour * - texte_modifier * - texte_creer * - texte_creer_associer * - texte_ajouter * - texte_objets * - texte_objet * * - info_aucun_objet * - info_1_objet * - info_nb_objets * * - texte_logo_objet * - texte_langue_objet * - texte_definir_comme_traduction_objet * * - principale * - champs_contenu : utlisé pour générer l'affichage par défaut du contenu * - editable * - champs_editables : utilisé pour prendre en compte le post lors de l'édition * * - champs_versionnes * * L'objet doit définir de lui même ces champs pour gérer des statuts : * - statut * - statut_images * - statut_titres * - statut_textes_instituer * - texte_changer_statut * - aide_changer_statut * * - modeles : permet de declarer les modeles associes a cet objet * * Les infos non renseignées sont auto-déduites par conventions * ou laissées vides * * @param string $table_sql * @param array $infos * @return array */ function renseigner_table_objet_sql($table_sql, &$infos) { if (!isset($infos['type'])) { // si on arrive de base/trouver_table, on a la cle primaire : // s'en servir pour extrapoler le type if (isset($infos['key']['PRIMARY KEY'])) { $primary = $infos['key']['PRIMARY KEY']; $primary = explode(',', $primary); $primary = reset($primary); $infos['type'] = preg_replace(',^spip_|^id_|s$,', '', $primary); } else { $infos['type'] = preg_replace(',^spip_|s$,', '', $table_sql); } } if (!isset($infos['type_surnoms'])) { $infos['type_surnoms'] = array(); } if (!isset($infos['table_objet'])) { $infos['table_objet'] = preg_replace(',^spip_,', '', $table_sql); } if (!isset($infos['table_objet_surnoms'])) { $infos['table_objet_surnoms'] = array(); } if (!isset($infos['principale'])) { $infos['principale'] = (isset($GLOBALS['tables_principales'][$table_sql]) ? 'oui' : false); } // normaliser pour pouvoir tester en php $infos['principale']? // et dans une boucle {principale=oui} $infos['principale'] = (($infos['principale'] and $infos['principale'] != 'non') ? 'oui' : false); // declarer et normaliser pour pouvoir tester en php $infos['editable']? // et dans une boucle {editable=oui} if (!isset($infos['editable'])) { $infos['editable'] = 'oui'; } $infos['editable'] = (($infos['editable'] and $infos['editable'] != 'non') ? 'oui' : false); // les urls publiques sont par defaut page=type pour les tables principales, et rien pour les autres // seules les exceptions sont donc a declarer if (!isset($infos['page'])) { $infos['page'] = ($infos['principale'] ? $infos['type'] : ''); } if (!isset($infos['url_voir'])) { $infos['url_voir'] = $infos['type']; } if (!isset($infos['url_edit'])) { $infos['url_edit'] = $infos['url_voir'] . ($infos['editable'] ? '_edit' : ''); } if (!isset($infos['icone_objet'])) { $infos['icone_objet'] = $infos['type']; } // chaines de langue // par defaut : objet:icone_xxx_objet if (!isset($infos['texte_retour'])) { $infos['texte_retour'] = 'icone_retour'; } if (!isset($infos['texte_modifier'])) { $infos['texte_modifier'] = $infos['type'] . ':' . 'icone_modifier_' . $infos['type']; } if (!isset($infos['texte_creer'])) { $infos['texte_creer'] = $infos['type'] . ':' . 'icone_creer_' . $infos['type']; } if (!isset($infos['texte_creer_associer'])) { $infos['texte_creer_associer'] = $infos['type'] . ':' . 'texte_creer_associer_' . $infos['type']; } if (!isset($infos['texte_ajouter'])) { // Ajouter un X $infos['texte_ajouter'] = $infos['type'] . ':' . 'texte_ajouter_' . $infos['type']; } if (!isset($infos['texte_objets'])) { $infos['texte_objets'] = $infos['type'] . ':' . 'titre_' . $infos['table_objet']; } if (!isset($infos['texte_objet'])) { $infos['texte_objet'] = $infos['type'] . ':' . 'titre_' . $infos['type']; } if (!isset($infos['texte_logo_objet'])) { // objet:titre_logo_objet "Logo de ce X" $infos['texte_logo_objet'] = $infos['type'] . ':' . 'titre_logo_' . $infos['type']; } if (!isset($infos['texte_langue_objet'])) { // objet:texte_langue_objet "Langue de ce X" $infos['texte_langue_objet'] = $infos['type'] . ':' . 'titre_langue_' . $infos['type']; } if (!isset($infos['texte_definir_comme_traduction_objet'])) { // "Ce X est une traduction du X numéro :" $infos['texte_definir_comme_traduction_objet'] = $infos['type'] . ':' . 'texte_definir_comme_traduction_' . $infos['type']; } // objet:info_aucun_objet if (!isset($infos['info_aucun_objet'])) { $infos['info_aucun_objet'] = $infos['type'] . ':' . 'info_aucun_' . $infos['type']; } // objet:info_1_objet if (!isset($infos['info_1_objet'])) { $infos['info_1_objet'] = $infos['type'] . ':' . 'info_1_' . $infos['type']; } // objet:info_nb_objets if (!isset($infos['info_nb_objets'])) { $infos['info_nb_objets'] = $infos['type'] . ':' . 'info_nb_' . $infos['table_objet']; } if (!isset($infos['champs_editables'])) { $infos['champs_editables'] = array(); } if (!isset($infos['champs_versionnes'])) { $infos['champs_versionnes'] = array(); } if (!isset($infos['rechercher_champs'])) { $infos['rechercher_champs'] = array(); } if (!isset($infos['rechercher_jointures'])) { $infos['rechercher_jointures'] = array(); } if (!isset($infos['modeles'])) { $infos['modeles'] = array($infos['type']); } return $infos; } /** * Renseigner les infos d'interface compilateur pour les tables objets * complete la declaration precedente * * titre * date * statut * tables_jointures * * @param $table_sql * @param $infos * @return array */ function renseigner_table_objet_interfaces($table_sql, &$infos) { if (!isset($infos['titre'])) { if (isset($infos['table_objet']) and isset($GLOBALS['table_titre'][$infos['table_objet']])) { $infos['titre'] = $GLOBALS['table_titre'][$infos['table_objet']]; } else { $infos['titre'] = ((isset($infos['field']['titre'])) ? 'titre,' : "'' as titre,"); $infos['titre'] .= ((isset($infos['field']['lang'])) ? 'lang' : "'' as lang"); } } if (!isset($infos['date'])) { if (isset($infos['table_objet']) and isset($GLOBALS['table_date'][$infos['table_objet']])) { $infos['date'] = $GLOBALS['table_date'][$infos['table_objet']]; } else { $infos['date'] = ((isset($infos['field']['date'])) ? 'date' : ''); } } if (!isset($infos['statut'])) { $infos['statut'] = isset($GLOBALS['table_statut'][$table_sql]) ? $GLOBALS['table_statut'][$table_sql] : ''; } if (!isset($infos['tables_jointures'])) { $infos['tables_jointures'] = array(); } if (isset($GLOBALS['tables_jointures'][$table_sql])) { $infos['tables_jointures'] = array_merge($infos['tables_jointures'], $GLOBALS['tables_jointures'][$table_sql]); } return $infos; } /** * Retourne la liste des tables principales et leurs descriptions * * @api * @return array * Liste et descriptions des tables principales **/ function lister_tables_principales() { static $done = false; if (!$done or !count($GLOBALS['tables_principales'])) { lister_tables_objets_sql(); $done = true; } return $GLOBALS['tables_principales']; } /** * Retourne la liste des tables auxiliaires et leurs descriptions * * @api * @return array * Liste et descriptions des tables auxiliaires **/ function lister_tables_auxiliaires() { static $done = false; if (!$done or !count($GLOBALS['tables_auxiliaires'])) { lister_tables_objets_sql(); $done = true; } return $GLOBALS['tables_auxiliaires']; } /** * Recenser les surnoms de table_objet * * @return array */ function lister_tables_objets_surnoms() { static $surnoms = null; static $md5 = null; if (!$surnoms or $md5 != lister_tables_objets_sql('::md5') ) { // passer dans un pipeline qui permet aux plugins de declarer leurs exceptions // pour compatibilite, car il faut dorenavent utiliser // declarer_table_objets_sql $surnoms = pipeline( 'declarer_tables_objets_surnoms', array( # pour les modeles # a enlever ? 'doc' => 'documents', 'img' => 'documents', 'emb' => 'documents', ) ); $infos_tables = lister_tables_objets_sql(); foreach ($infos_tables as $t => $infos) { // cas de base type=>table // et preg_replace(',^spip_|^id_|s$,',table)=>table if ($infos['table_objet']) { // securite, si la fonction est appelee trop tot, c'est vide // optimisations pour table_objet //$surnoms[$infos['type']] = $infos['table_objet']; $surnoms[preg_replace(',^spip_|^id_|s$,', '', $infos['table_objet'])] = $infos['table_objet']; $surnoms[preg_replace(',^spip_|^id_|s$,', '', $infos['type'])] = $infos['table_objet']; if (is_array($infos['table_objet_surnoms']) and count($infos['table_objet_surnoms'])) { foreach ($infos['table_objet_surnoms'] as $surnom) { $surnoms[$surnom] = $infos['table_objet']; } } } } $md5 = lister_tables_objets_sql('::md5'); } return $surnoms; } /** * Recenser les surnoms de table_objet * * @return array */ function lister_types_surnoms() { static $surnoms = null; static $md5 = null; if (!$surnoms or $md5 != lister_tables_objets_sql('::md5') ) { // passer dans un pipeline qui permet aux plugins de declarer leurs exceptions // pour compatibilite, car il faut dorenavent utiliser // declarer_table_objets_sql $surnoms = pipeline('declarer_type_surnoms', array('racine-site' => 'site')); $infos_tables = lister_tables_objets_sql(); foreach ($infos_tables as $t => $infos) { if ($infos['type']) { // securite, si la fonction est appelee trop tot, c'est vide // optimisations pour objet_type //$surnoms[$infos['type']] = $infos['type']; $surnoms[preg_replace(',^spip_|^id_|s$,', '', $infos['table_objet'])] = $infos['type']; $surnoms[preg_replace(',^spip_|^id_|s$,', '', $infos['type'])] = $infos['type']; // surnoms declares if (is_array($infos['type_surnoms']) and count($infos['type_surnoms'])) { foreach ($infos['type_surnoms'] as $surnom) { $surnoms[$surnom] = $infos['type']; } } } } $md5 = lister_tables_objets_sql('::md5'); } return $surnoms; } /** * Retourne la liste des tables SQL qui concernent SPIP * * Cette liste n'est calculée qu'une fois par serveur pour l'ensemble du hit * * @param string $serveur * Nom du fichier de connexion à la base de données * @return array * Couples (nom de la table SQL => même nom, sans 'spip_' devant) **/ function lister_tables_spip($serveur = '') { static $tables = array(); if (!isset($tables[$serveur])) { $tables[$serveur] = array(); if (!function_exists('sql_alltable')) { include_spip('base/abstract_sql'); } $ts = sql_alltable(null, $serveur); // toutes les tables "spip_" (ou prefixe perso) $connexion = $GLOBALS['connexions'][$serveur ? $serveur : 0]; $spip = $connexion['prefixe'] . '_'; foreach ($ts as $t) { $t = substr($t, strlen($spip)); $tables[$serveur]["spip_$t"] = $t; } } return $tables[$serveur]; } /** * Retourne la liste des tables SQL, Spip ou autres * * Cette liste n'est calculée qu'une fois par serveur pour l'ensemble du hit * * @param string $serveur * Nom du fichier de connexion à la base de données * @return array * Couples (nom de la table SQL => même nom) **/ function lister_toutes_tables($serveur){ static $tables = array(); if (!isset($tables[$serveur])){ $tables[$serveur] = array(); if (!function_exists("sql_alltable")) include_spip("base/abstract_sql"); $ts = sql_alltable('%',$serveur); // toutes les tables foreach ($ts as $t){ $tables[$serveur][$t] = $t; } } return $tables[$serveur]; } /** * Retrouve le nom d'objet à partir de la table * * - spip_articles -> articles * - id_article -> articles * - article -> articles * * @api * @param string $type * Nom de la table SQL (le plus souvent) * Tolère un nom de clé primaire. * @param string $serveur * Nom du connecteur * @return string * Nom de l'objet **/ function table_objet($type, $serveur = '') { $surnoms = lister_tables_objets_surnoms(); $type = preg_replace(',^spip_|^id_|s$,', '', $type); if (!$type) { return; } if (isset($surnoms[$type])) { return $surnoms[$type]; } if ($serveur !== false) { $t = lister_tables_spip($serveur); $trouver_table = charger_fonction('trouver_table', 'base'); $typetrim = rtrim($type, 's') . 's'; if ((isset($t[$typetrim]) or in_array($typetrim, $t)) and ($desc = $trouver_table(rtrim($type, 's') . 's', $serveur)) ) { return $desc['id_table']; } elseif ((isset($t[$type]) or in_array($type, $t)) and ($desc = $trouver_table($type, $serveur)) ) { return $desc['id_table']; } spip_log('table_objet(' . $type . ') calculee sans verification'); #spip_log(debug_backtrace(),'db'); } return rtrim($type, 's') . 's'; # cas historique ne devant plus servir, sauf si $serveur=false } /** * Retrouve la table sql à partir de l'objet ou du type * * - articles -> spip_articles * - article -> spip_articles * - id_article -> spip_articles * * @api * @param string $type * Nom ou type de l'objet * Tolère un nom de clé primaire. * @param string $serveur * Nom du connecteur * @return string * Nom de la table SQL **/ function table_objet_sql($type, $serveur = '') { $nom = table_objet($type, $serveur); if (!isset($GLOBALS['table_des_tables']['articles'])) { // eviter de multiples inclusions include_spip('public/interfaces'); } if (isset($GLOBALS['table_des_tables'][$nom])) { $nom = $GLOBALS['table_des_tables'][$nom]; $nom = "spip_$nom"; } else { $infos_tables = lister_tables_objets_sql(); if (isset($infos_tables["spip_$nom"])) { $nom = "spip_$nom"; } elseif ($serveur !== false) { $t = lister_tables_spip($serveur); if (isset($t[$nom]) or in_array($nom, $t)) { $trouver_table = charger_fonction('trouver_table', 'base'); if ($desc = $trouver_table($nom, $serveur)) { return $desc['table_sql']; } } } } return $nom; } /** * Retrouve la clé primaire à partir du nom d'objet ou de table * * - articles -> id_article * - article -> id_article * - spip_articles -> id_article * * @api * @param string $type * Nom de la table SQL ou de l'objet * @param string $serveur * Nom du connecteur * @return string * Nom de la clé primaire **/ function id_table_objet($type, $serveur = '') { static $trouver_table = null; $type = objet_type($type, $serveur); if (!$type) { return; } $t = table_objet($type); if (!$trouver_table) { $trouver_table = charger_fonction('trouver_table', 'base'); } $ts = lister_tables_spip($serveur); if ( in_array($t, $ts) or in_array($t, lister_toutes_tables($serveur)) ){ $desc = $trouver_table($t, $serveur); if (isset($desc['key']['PRIMARY KEY'])) { return $desc['key']['PRIMARY KEY']; } if (!$desc or isset($desc['field']["id_$type"])) { return "id_$type"; } // sinon renvoyer le premier champ de la table... $keys = array_keys($desc['field']); return array_shift($keys); } return "id_$type"; } /** * Retrouve le type d'objet à partir du nom d'objet ou de table * * - articles -> article * - spip_articles -> article * - id_article -> article * * @api * @param string $table_objet * Nom de l'objet ou de la table SQL * @param string $serveur * Nom du connecteur * @return string * Type de l'objet **/ function objet_type($table_objet, $serveur = '') { if (!$table_objet) { return; } $surnoms = lister_types_surnoms(); // scenario de base // le type est decline a partir du nom de la table en enlevant le prefixe eventuel // et la marque du pluriel // on accepte id_xx en entree aussi $type = preg_replace(',^spip_|^id_|s$,', '', $table_objet); if (isset($surnoms[$type])) { return $surnoms[$type]; } // securite : eliminer les caracteres non \w $type = preg_replace(',[^\w-],', '', $type); // si le type redonne bien la table c'est bon // oui si table_objet ressemblait deja a un type if ($type == $table_objet or (table_objet($type, $serveur) == $table_objet) or (table_objet_sql($type, $serveur) == $table_objet) ) { return $type; } // si on ne veut pas chercher en base if ($serveur === false) { return $type; } // sinon on passe par la cle primaire id_xx pour trouver le type // car le s a la fin est incertain // notamment en cas de pluriel derogatoire // id_jeu/spip_jeux id_journal/spip_journaux qui necessitent tout deux // une declaration jeu => jeux, journal => journaux // dans le pipeline declarer_tables_objets_surnoms $trouver_table = charger_fonction('trouver_table', 'base'); $ts = lister_tables_spip($serveur); $desc = false; if (in_array($table_objet, $ts)) { $desc = $trouver_table($table_objet); } if (!$desc and in_array($table_objet = table_objet($type, $serveur), $ts)) { $desc = $trouver_table($table_objet, $serveur); } // si le type est declare : bingo ! if ($desc and isset($desc['type'])) { return $desc['type']; } // on a fait ce qu'on a pu return $type; } /** * Determininer si un objet est publie ou non * * On se base pour cela sur sa declaration de statut * pour des cas particuliers non declarables, on permet de fournir une fonction * base_xxxx_test_si_publie qui sera appele par la fonction * * @param string $objet * @param int $id_objet * @param string $serveur * @return bool */ function objet_test_si_publie($objet, $id_objet, $serveur = '') { // voir si une fonction est definie pour faire le boulot // elle a la priorite dans ce cas if ($f = charger_fonction($objet . '_test_si_publie', 'base', true)) { return $f($objet, $id_objet, $serveur); } // sinon on se fie a la declaration de l'objet si presente $id_table = $table_objet = table_objet($objet); $id_table_objet = id_table_objet($objet, $serveur); $trouver_table = charger_fonction('trouver_table', 'base'); if ($desc = $trouver_table($table_objet, $serveur) and isset($desc['statut']) and $desc['statut'] ) { $boucle = new Boucle(); $boucle->show = $desc; $boucle->nom = 'objet_test_si_publie'; $boucle->id_boucle = $id_table; $boucle->id_table = $id_table; $boucle->sql_serveur = $serveur; $boucle->select[] = $id_table_objet; $boucle->from[$table_objet] = table_objet_sql($objet, $serveur); $boucle->where[] = $id_table . '.' . $id_table_objet . '=' . intval($id_objet); include_spip('public/compiler'); include_spip('public/composer'); instituer_boucle($boucle, false, true); $res = calculer_select( $boucle->select, $boucle->from, $boucle->from_type, $boucle->where, $boucle->join, $boucle->group, $boucle->order, $boucle->limit, $boucle->having, $table_objet, $id_table, $serveur ); if (sql_fetch($res)) { return true; } return false; } // si pas d'info statut ni de fonction : l'objet est publie return true; }