-<?php\r
-/**\r
- * Crayons \r
- * plugin for spip \r
- * (c) Fil, toggg 2006-2013\r
- * licence GPL\r
- */\r
-\r
-if (!defined("_ECRIRE_INC_VERSION")) return;\r
-\r
-define('_PREG_CRAYON', ',crayon\b[^<>\'"]+?\b((\w+)-(\w+)-(\w+(?:-\w+)*))\b,');\r
-\r
-// Compatibilite pour 1.92 : on a besoin de sql_fetch et table_objet_sql\r
-if ($GLOBALS['spip_version_code'] < '1.93' AND $f = charger_fonction('compat_crayons', 'inc'))\r
- $f();\r
-\r
-// Autoriser les crayons sur les tables non SPIP ?\r
-// Par defaut : oui (pour les admins complets, si autoriser_defaut_dist()) ;\r
-// mettre a false en cas de mutualisation par prefixe de table,\r
-// sinon on ne peut pas garantir que les sites sont hermetiques\r
-if(!defined('_CRAYONS_TABLES_EXTERNES'))\r
- define('_CRAYONS_TABLES_EXTERNES', true);\r
-\r
-// Autorisations non prevues par le core\r
-include_spip('inc/autoriser');\r
-\r
-include_spip('inc/crayons-json');\r
-\r
-if (!function_exists('autoriser_meta_modifier_dist')) {\r
-/**\r
- * Autorisation d'éditer les configurations dans spip_meta\r
- *\r
- * Les admins complets OK pour certains champs,\r
- * Sinon, il faut être webmestre\r
- *\r
- * @note\r
- * Attention sur les SPIP < 11515 (avant 04/2008) inc/autoriser\r
- * passe seulement intval($id) alors qu'ici la cle est une chaine...\r
- *\r
- * @param string $faire Action demandée\r
- * @param string $type Type d'objet sur lequel appliquer l'action\r
- * @param int $id Identifiant de l'objet\r
- * @param array $qui Description de l'auteur demandant l'autorisation\r
- * @param array $opt Options de cette autorisation\r
- * @return bool true s'il a le droit, false sinon\r
-**/\r
-function autoriser_meta_modifier_dist($faire, $type, $id, $qui, $opt) {\r
- // Certaines cles de configuration sont echapées ici (cf #EDIT_CONFIG{demo/truc})\r
- // $id = str_replace('__', '/', $id);\r
- if (in_array("$id", array(\r
- 'nom_site', 'slogan_site', 'descriptif_site', 'email_webmaster'\r
- )))\r
- return autoriser('configurer', null, null, $qui);\r
- else\r
- return autoriser('webmestre', null, null, $qui);\r
-}\r
-}\r
-\r
-// table spip_messages, la c'est tout simplement non (peut mieux faire,\r
-// mais c'est a voir dans le core/organiseur ou dans autorite)\r
-if (defined('_DIR_PLUGIN_ORGANISEUR'))\r
- include_spip('organiseur_autoriser');\r
-if (!function_exists('autoriser_message_modifier_dist')) {\r
- function autoriser_message_modifier_dist($faire, $type, $id, $qui, $opt) {\r
- return false;\r
- }\r
-}\r
-//compat 192 documents\r
-if ($GLOBALS['spip_version_code'] < '1.93'){\r
- if (!function_exists('get_spip_doc')){\r
- function get_spip_doc($fichier) {\r
- // fichier distant\r
- if (preg_match(',^\w+://,', $fichier))\r
- return $fichier;\r
-\r
- // gestion d'erreurs, fichier=''\r
- if (!strlen($fichier))\r
- return false;\r
-\r
- // fichier normal\r
- return (strpos($fichier, _DIR_IMG) === false)\r
- ? _DIR_IMG . $fichier\r
- : $fichier;\r
- }\r
- }\r
-}\r
-\r
-// Autoriser l'usage des crayons ?\r
-function autoriser_crayonner_dist($faire, $type, $id, $qui, $opt) {\r
- // Le type pouvant etre une table, verifier les autoriser('modifier')\r
- // correspondant ; ils demandent le nom de l'objet: spip_articles => article\r
- // ex: spip_articles => 'article'\r
- $type = preg_replace(',^spip_(.*?)s?$,', '\1', $type);\r
- if (strlen($GLOBALS['table_prefix']))\r
- $type = preg_replace(',^'.$GLOBALS['table_prefix'].'_(.*?)s?$,', '\1', $type);\r
-\r
- // Tables non SPIP ? Si elles sont interdites il faut regarder\r
- // quelle table on appelle, et verifier si elle est "interne"\r
- if (!_CRAYONS_TABLES_EXTERNES) {\r
- include_spip('base/serial');\r
- include_spip('base/auxiliaires');\r
- include_spip('public/parametrer');\r
- if (!isset($GLOBALS['tables_principales']['spip_'.table_objet($type)])\r
- AND !isset($GLOBALS['tables_auxiliaires']['spip_'.table_objet($type)]))\r
- return false;\r
- }\r
-\r
- // Traduire le modele en liste de champs\r
- if (isset($opt['modele']))\r
- $opt['champ'] = $opt['modele'];\r
-\r
- // Pour un auteur, si le champ est statut ou email, signaler l'option\r
- // ad hoc (cf. inc/autoriser)\r
- if ($type == 'auteur'\r
- AND in_array($opt['champ'], array('statut', 'email')))\r
- $opt[$opt['champ']] = true;\r
-\r
- return (\r
- autoriser('modifier', $type, $id, $qui, $opt)\r
- );\r
-}\r
-\r
-// Si un logo est demande, on renvoie la date dudit logo (permettra de gerer\r
-// un "modifie par ailleurs" si la date a change, rien de plus)\r
-function valeur_champ_logo($table, $id, $champ) {\r
- $chercher_logo = charger_fonction('chercher_logo', 'inc');\r
- $on = $chercher_logo($id, id_table_objet($table), 'on');\r
- return $on ? filemtime($on[0]) : false;\r
-}\r
-\r
-// Idem : si un doc est demande, on renvoie la date du doc\r
-function valeur_champ_document($table, $id, $champ) {\r
- $s = spip_query("SELECT date FROM spip_documents WHERE id_document="._q($id));\r
- if ($t = sql_fetch($s))\r
- return $t['date'];\r
-}\r
-\r
-function valeur_champ_vignette($table, $id, $champ) {\r
- $vignette = sql_getfetsel('id_vignette','spip_documents','id_document='.intval($id));\r
- if(is_numeric($vignette) && ($vignette > 0)){\r
- $date = sql_getfetsel('date','spip_documents','id_document='.intval($vignette));\r
- }\r
- return $date ? $date : false;\r
-}\r
-// cette fonction de revision recoit le fichier upload a passer en logo\r
-// en reference : le nom du widget, pour aller chercher d'autres donnees\r
-// (ex: supprimer)\r
-function logo_revision($id, $file, $type, $ref) {\r
- $chercher_logo = charger_fonction('chercher_logo', 'inc');\r
- $_id_objet = id_table_objet($type);\r
-\r
- // Chargement d'un nouveau logo ?\r
- if ($file['logo']) {\r
- define('FILE_UPLOAD', true); // message pour crayons_json_export :(\r
-\r
- // supprimer l'ancien logo\r
- $on = $chercher_logo($id, $_id_objet, 'on');\r
- if ($on) @unlink($on[0]);\r
-\r
- // ajouter le nouveau\r
- include_spip('action/iconifier');\r
- action_spip_image_ajouter_dist(\r
- type_du_logo($_id_objet).'on'.$id, false, false\r
- ); // beurk\r
- }\r
-\r
- else\r
-\r
- // Suppression du logo ?\r
- if ($wid = array_pop($ref)\r
- AND $_POST['content_'.$wid.'_logo_supprimer'] == 'on') {\r
- if ($on = $chercher_logo($id, $_id_objet, 'on'))\r
- @unlink($on[0]);\r
- }\r
-\r
- // Reduire le logo ?\r
- if (is_array($cfg = @unserialize($GLOBALS['meta']['crayons']))\r
- AND $max = intval($cfg['reduire_logo'])) {\r
- $on = $chercher_logo($id, $_id_objet, 'on');\r
- include_spip('inc/filtres');\r
- @copy($on[0], $temp = _DIR_VAR.'tmp'.rand(0,999).'.'.$on[3]);\r
- $img1 = filtrer('image_reduire', $temp, $max);\r
- $img2 = preg_replace(',[?].*,', '', extraire_attribut($img1, 'src'));\r
- if (@file_exists($img2)\r
- AND $img2 != $temp) {\r
- @unlink($on[0]);\r
- $dest = $on[1].$on[2].'.'\r
- .preg_replace(',^.*\.(gif|jpg|png)$,', '\1', $img2);\r
- @rename($img2,$dest);\r
- }\r
- @unlink($temp);\r
- }\r
-\r
- return true;\r
-}\r
-\r
-\r
-// cette fonction de revision recoit le fichier upload a passer en document\r
-function document_fichier_revision($id, $data, $type, $ref) {\r
-\r
- $s = spip_query("SELECT * FROM spip_documents WHERE id_document=".intval($id));\r
- if (!$t = sql_fetch($s))\r
- return false;\r
-\r
- /*\r
- // Envoi d'une URL de document distant ?\r
- // TODO: verifier l'extension distante, sinon tout explose\r
- if ($data['fichier']\r
- AND preg_match(',^(https?|ftp)://.+,', $data['fichier'])) {\r
- include_spip('inc/modifier');\r
- modifier_contenu('document', $id,\r
- array('champs' => array('fichier', 'distant')),\r
- array('fichier' => $data['fichier'], 'distant' => 'oui')\r
- );\r
- return true;\r
- }\r
- else\r
- */\r
-\r
- // Chargement d'un nouveau doc ?\r
- if ($data['document']) {\r
-\r
- $arg = $data['document'];\r
- \r
- /** \r
- * Méthode >= SPIP 3.0 \r
- * ou SPIP 2.x + Mediathèque\r
- */ \r
- if($ajouter_documents = charger_fonction('ajouter_documents','action',true)){ \r
- $actifs = $ajouter_documents($id,array($arg),'', 0,$t['mode']);\r
- $x = reset($actifs);\r
- if(is_numeric($x))\r
- return true;\r
- else\r
- return false;\r
- }\r
- /**\r
- * Méthode SPIP < 3.0\r
- */\r
- else if($ajouter_documents = charger_fonction('ajouter_documents','inc',true)){ \r
- check_upload_error($arg['error']);\r
- $x = $ajouter_documents($arg['tmp_name'], $arg['name'],\r
- 'article', 0, 'document', null, $actifs);\r
- // $actifs contient l'id_document nouvellement cree\r
- // on recopie les donnees interessantes dans l'ancien\r
- $extension=", extension ";\r
- //compat 192\r
- if ($GLOBALS['spip_version_code'] < '1.93')\r
- $extension="";\r
-\r
- if ($id_new = array_pop($actifs)\r
- AND $s = spip_query("SELECT fichier, taille, largeur, hauteur $extension, distant FROM spip_documents\r
- WHERE id_document="._q($id_new))\r
- AND $new = sql_fetch($s)) {\r
- define('FILE_UPLOAD', true); // message pour crayons_json_export :(\r
-\r
- // Une vignette doit rester une image\r
- if ($t['mode'] == 'vignette'\r
- AND !in_array($new['extension'], array('jpg', 'gif', 'png')))\r
- return false;\r
-\r
- // Maintenant on est bon, on recopie les nouvelles donnees\r
- // dans l'ancienne ligne spip_documents\r
- include_spip('inc/modifier');\r
- modifier_contenu('document', $id,\r
- # 'champs' inutile a partir de SPIP 11348\r
- array('champs' => array_keys($new)),\r
- $new);\r
-\r
- // supprimer l'ancien document (sauf s'il etait distant)\r
- if ($t['distant'] != 'oui'\r
- AND file_exists(get_spip_doc($t['fichier'])))\r
- supprimer_fichier(get_spip_doc($t['fichier']));\r
-\r
- // Effacer la ligne temporaire de spip_document\r
- spip_query("DELETE FROM spip_documents WHERE id_document="._q($id_new));\r
-\r
- // oublier id_document temporaire (ca marche chez moi, sinon bof)\r
- spip_query("ALTER TABLE spip_documents AUTO_INCREMENT="._q($id_new));\r
-\r
- return true;\r
- }\r
- }\r
- }\r
-}\r
-\r
-// cette fonction de revision soit supprime la vignette d'un document,\r
-// soit recoit le fichier upload a passer ou remplacer la vignette du document\r
-function vignette_revision($id, $data, $type, $ref) {\r
- $s = sql_fetsel("id_document,id_vignette","spip_documents","id_document=".intval($id));\r
- if (!is_array($s))\r
- return false;\r
-\r
- include_spip('inc/modifier');\r
- include_spip('inc/documents');\r
- include_spip('action/editer_document');//pour revision_document\r
- // Chargement d'un nouveau doc ?\r
- if ($data['vignette']) {\r
- define('FILE_UPLOAD', true);\r
- if(is_numeric($s['id_vignette']) && ($s['id_vignette']>0)){\r
- spip_log('suppression de la vignette');\r
- // Suppression du document\r
- $vignette = sql_getfetsel('fichier', 'spip_documents', 'id_document='.intval($s['id_vignette']));\r
- if (@file_exists($f = get_spip_doc($vignette))) { \r
- spip_log("efface $f"); \r
- supprimer_fichier($f); \r
- }\r
- sql_delete('spip_documents', 'id_document='.intval($s['id_vignette']));\r
- sql_delete('spip_documents_liens', 'id_document='.intval($s['id_vignette']));\r
-\r
- pipeline('post_edition',\r
- array(\r
- 'args' => array(\r
- 'operation' => 'supprimer_document',\r
- 'table' => 'spip_documents',\r
- 'id_objet' => $s['id_vignette']\r
- ),\r
- 'data' => null\r
- )\r
- );\r
- $id_vignette = 0;\r
- }\r
-\r
- $arg = $data['vignette'];\r
- check_upload_error($arg['error']);\r
- // Ajout du document comme vignette\r
-\r
- /**\r
- * Méthode >= SPIP 3.0 \r
- * ou SPIP 2.x + Mediatheque\r
- */\r
- if($ajouter_documents = charger_fonction('ajouter_documents','action',true)){\r
- $x = $ajouter_documents(null,array($arg),'', 0, 'vignette');\r
- $vignette = reset($x);\r
- if(intval($vignette))\r
- document_modifier($id, array('id_vignette'=>$vignette));\r
- else if($id_vignette)\r
- document_modifier($id, array('id_vignette'=>$id_vignette));\r
- }\r
- /**\r
- * Méthode < SPIP 3.0\r
- */\r
- else if($ajouter_documents = charger_fonction('ajouter_documents','inc',true)){\r
- // On remet l'id_vignette a 0 si on l'a supprimé\r
- if($id_vignette) revision_document($s['id_document'], array('id_vignette'=>0));\r
- $x = $ajouter_documents($arg['tmp_name'], $arg['name'],'','', 'vignette', $id, $actifs);\r
- }\r
- \r
- }else\r
- // Suppression de la vignette ?\r
- if ($wid = array_pop($ref)\r
- AND $_POST['content_'.$wid.'_vignette_supprimer'] == 'on') {\r
- if(is_numeric($s['id_vignette']) && ($s['id_vignette']>0)){\r
- // Suppression du document\r
- $vignette = sql_getfetsel('fichier', 'spip_documents', 'id_document='.intval($s['id_vignette']));\r
- if (@file_exists($f = get_spip_doc($vignette))) { \r
- spip_log("efface $f"); \r
- supprimer_fichier($f); \r
- }\r
- sql_delete('spip_documents', 'id_document='.intval($s['id_vignette']));\r
- sql_delete('spip_documents_liens', 'id_document='.intval($s['id_vignette']));\r
-\r
- pipeline('post_edition',\r
- array(\r
- 'args' => array(\r
- 'operation' => 'supprimer_document',\r
- 'table' => 'spip_documents',\r
- 'id_objet' => $s['id_vignette']\r
- ),\r
- 'data' => null\r
- )\r
- );\r
-\r
- // On remet l'id_vignette a 0\r
- revision_document($s['id_document'], array('id_vignette'=>0));\r
- }\r
- }\r
- return true;\r
-}\r
-\r
-\r
-function colonne_table($type, $col) {\r
- list($distant,$table) = distant_table($type);\r
- $nom_table = '';\r
- if (!(($tabref = &crayons_get_table($table, $nom_table))\r
- && isset($tabref['field'][$col])\r
- && ($brut = $tabref['field'][$col]))) {\r
- return false;\r
- }\r
- $ana = explode(' ', $brut);\r
- $sta = 0;\r
- $sep = '';\r
- $ret = array('brut' => $brut,\r
- 'type' => '', 'notnull' => false, 'long' => 0, 'def' => '');\r
- foreach ($ana as $mot) {\r
- switch ($sta) {\r
- case 0: $ret['type'] = ($mot = strtolower($mot));\r
- case 1: if ($mot[strlen($mot) - 1] == ')') {\r
- $pos = strpos($mot, '(');\r
- $ret['type'] = strtolower(substr($mot, 0, $pos++));\r
- $vir = explode(',', substr($mot, $pos, -1));\r
- if ($ret['type'] == 'enum') {\r
- $ret['enum'] = $vir;\r
- } elseif (count($vir) > 1) {\r
- $ret['long'] = $vir;\r
- } else {\r
- $ret['long'] = $vir[0];\r
- }\r
- $sta = 1;\r
- continue;\r
- }\r
- if (!$sta) {\r
- $sta = 1;\r
- continue;\r
- }\r
- case 2: switch (strtolower($mot)) {\r
- case 'not':\r
- $sta = 3;\r
- continue;\r
- case 'default':\r
- $sta = 4;\r
- continue;\r
- }\r
- continue;\r
- case 3: $ret['notnull'] = strtolower($mot) == 'null';\r
- $sta = 2;\r
- continue;\r
- case 4: $df1 = strpos('"\'', $mot[0]) !== false? $mot[0] : '';\r
- $sta = 5;\r
- case 5: $ret['def'] .= $sep . $mot;\r
- if (!$df1) {\r
- $sta = 2;\r
- continue;\r
- }\r
- if ($df1 == $mot[strlen($mot) - 1]) {\r
- $ret['def'] = substr($ret['def'], 1, -1);\r
- $sta = 2;\r
- }\r
- $sep = ' ';\r
- continue;\r
- }\r
- }\r
- return $ret;\r
-}\r
-\r
-\r
-/**\r
- * Obtient le nom de la table ainsi que sa ou ses clés primaires\r
- *\r
- * @param string $type\r
- * Table sur laquelle s'applique le crayon.\r
- * Ce type peut contenir le nom d'un connecteur distant tel que `{connect}__{table}`\r
- *\r
- * @return array|bool\r
- * - false si on ne trouve pas de table ou de table ayant de clé primaire\r
- * - liste :\r
- * - - nom de la table sql\r
- * - - tableau des noms de clés primaires\r
-**/\r
-function crayons_get_table_name_and_primary($type) {\r
- static $types = array();\r
- if (isset($types[$type])) {\r
- return $types[$type];\r
- }\r
-\r
- $nom_table = '';\r
- if ($tabref = &crayons_get_table($type, $nom_table)\r
- and ($tabid = explode(',', $tabref['key']['PRIMARY KEY'])))\r
- {\r
- return $types[$type] = array($nom_table, $tabid);\r
- }\r
- spip_log('crayons: table ' . $type . ' inconnue');\r
- return $types[$type] = false;\r
-}\r
-\r
-\r
-function table_where($type, $id, $where_en_tableau = false) {\r
-\r
-\r
- if (!$infos = crayons_get_table_name_and_primary($type)) {\r
- return array(false, false);\r
- }\r
-\r
- list($nom_table, $tabid) = $infos;\r
-\r
-\r
- if (is_scalar($id))\r
- $id = explode('-', $id);\r
- // sortie tableau pour sql_updateq\r
- if ($where_en_tableau) {\r
- $where = array();\r
- foreach ($id as $idcol => $idval) {\r
- $where[] = '`' . (is_int($idcol) ? trim($tabid[$idcol]) : $idcol) . '`=' . sql_quote($idval);\r
- }\r
- // sinon sortie texte pour sql_query\r
- } else {\r
-\r
- $where = $and = '';\r
- foreach ($id as $idcol => $idval) {\r
- $where .= $and . '`' . (is_int($idcol) ? trim($tabid[$idcol]) : $idcol) . '`=' . _q($idval);\r
- $and = ' AND ';\r
- }\r
- }\r
- return array($nom_table, $where);\r
-}\r
-// var_dump(colonne_table('forum', 'id_syndic')); die();\r
-\r
-function valeur_colonne_table_dist($type, $col, $id) {\r
-\r
- // Table introuvable ou sans clé primaire\r
- if (!$infos = crayons_get_table_name_and_primary($type)) {\r
- return false;\r
- }\r
- $table = reset($infos);\r
-\r
- $r = array();\r
-\r
- // valeurs non SQL\r
- foreach ($col as $champ) {\r
- if (function_exists($f = 'valeur_champ_'.$table.'_'.$champ) OR function_exists($f = 'valeur_champ_'.$champ)) {\r
- $r[$champ] = $f($table, $id, $champ);\r
- $col = array_diff($col, array($champ));\r
- }\r
- }\r
-\r
- // valeurs SQL\r
- if (count($col)) {\r
- list($distant, $table) = distant_table($type);\r
- list($nom_table, $where) = table_where($type, $id);\r
-\r
- if ($s = spip_query(\r
- 'SELECT `' . implode($col, '`, `') .\r
- '` FROM ' . $nom_table . ' WHERE ' . $where, $distant)\r
- AND $t = sql_fetch($s)){\r
- $r = array_merge($r, $t);\r
- }\r
- }\r
-\r
- return $r;\r
-}\r
-\r
-/**\r
- * Extrait la valeur d'une ou plusieurs colonnes d'une table\r
- *\r
- * @param string $table\r
- * Type d'objet de la table (article)\r
- * @param string|array $col\r
- * Nom de la ou des colonnes (ps)\r
- * @param string $id\r
- * Identifiant de l'objet\r
- * @return array\r
- * Couples Nom de la colonne => Contenu de la colonne\r
-**/\r
-function valeur_colonne_table($table, $col, $id) {\r
- if (!is_array($col))\r
- $col = array($col);\r
-\r
- if (function_exists($f = $table.'_valeur_colonne_table_dist')\r
- OR function_exists($f = $table.'_valeur_colonne_table')\r
- OR $f = 'valeur_colonne_table_dist')\r
- return $f($table, $col, $id);\r
-}\r
-\r
-/**\r
- * Extrait la valeur d'une configuration en meta\r
- *\r
- * Pour ces données, il n'y a toujours qu'une colonne (valeur),\r
- * mais on gère l'enregistrement et la lecture via lire_config ou ecrire_config\r
- * dès que l'on demande des sous parties d'une configuration.\r
- *\r
- * On ne retourne alors ici dans 'valeur' que la sous-partie demandée si\r
- * c'est le cas.\r
- *\r
- * @param string $table\r
- * Nom de la table (meta)\r
- * @param array $col\r
- * Nom des colonnes (valeur)\r
- * @param string $id\r
- * Nom ou clé de configuration (descriptif_site ou demo__truc pour demo/truc)\r
- * @return array\r
- * Couple valeur => Contenu de la configuration\r
-**/\r
-function meta_valeur_colonne_table_dist($table, $col, $id) {\r
- // Certaines clés de configuration sont echapées ici (cf #EDIT_CONFIG{demo/truc})\r
- $id = str_replace('__', '/', $id);\r
-\r
- // Éviter de planter les vieux SPIP\r
- if (false === strpos($id, '/')) {\r
- $config = isset($GLOBALS['meta'][$id]) ? $GLOBALS['meta'][$id] : '';\r
- // SPIP 3 ou Bonux 2 ou CFG\r
- } else {\r
- include_spip('inc/config');\r
- $config = lire_config($id, '');\r
- }\r
- return array('valeur' => $config);\r
-}\r
-\r
-\r
-function return_log($var) {\r
- die(crayons_json_export(array('$erreur'=> var_export($var,true))));\r
-}\r
-\r
-function _U($texte, $params=array()) {\r
- include_spip('inc/charsets');\r
- return unicode2charset(html2unicode(_T($texte, $params)));\r
-}\r
-\r
-/**\r
- * Obtenir la configuration des crayons\r
- *\r
- * @note wdgcfg = widget config :-)\r
- * \r
- * @return array\r
- * Couples : attribut => valeur\r
-**/\r
-function wdgcfg() {\r
- $php = function_exists('crayons_config') ? crayons_config() : array();\r
- include_spip('inc/meta');\r
- lire_metas();\r
- global $meta;\r
- $metacrayons = empty($meta['crayons']) ? array() : unserialize($meta['crayons']);\r
- $wdgcfg = array();\r
- foreach (array(\r
- 'msgNoChange' => false,\r
- 'msgAbandon' => false, /* etait: true */\r
- 'filet' => false,\r
- 'yellow_fade' => false,\r
- 'clickhide' => false /* etait: true */\r
- )\r
- as $cfgi => $def) {\r
- $wdgcfg[$cfgi] = isset($php[$cfgi]) ? $php[$cfgi] :\r
- isset($metacrayons[$cfgi]) ? $metacrayons[$cfgi] : $def;\r
- }\r
- return $wdgcfg;\r
-}\r
-\r
-function &crayons_get_table($type, &$nom_table) {\r
- list($distant,$table) = distant_table($type);\r
- static $return = array();\r
- static $noms = array();\r
- if (!isset($return[$table])) {\r
- $try = array(table_objet_sql($table), 'spip_'.table_objet($table), 'spip_' . $table . 's', $table . 's', 'spip_' . $table, $table);\r
-\r
- // premiere possibilite (à partir de 1.9.3) : regarder directement la base\r
- if (function_exists('sql_showtable')) {\r
- foreach ($try as $nom) {\r
- if ($q = sql_showtable($nom , !$distant , $distant)) {\r
- $noms[$table] = $nom;\r
- $return[$table] = $q;\r
- break;\r
- }\r
- }\r
- }\r
-\r
- // seconde, une heuristique 1.9.2\r
- if (!isset($return[$table])) {\r
- include_spip('base/serial');\r
- include_spip('base/auxiliaires');\r
- include_spip('public/parametrer');\r
- foreach(array('tables_principales', 'tables_auxiliaires') as $categ) {\r
- foreach ($try as $nom) {\r
- if (isset($GLOBALS[$categ][$nom])) {\r
- $noms[$table] = $nom;\r
- $return[$table] = & $GLOBALS[$categ][$nom];\r
- break 2;\r
- }\r
- }\r
- }\r
- }\r
- }\r
-\r
- $nom_table = $noms[$table];\r
- return $return[$table];\r
-}\r
-\r
-function distant_table($type) {\r
- //separation $type en $distant $table\r
- //separateur double underscore "__"\r
- strstr($type,'__')? list($distant,$table) = explode('__',$type) : list($distant,$table) = array(False,$type);\r
- return array($distant,$table);\r
-}\r
-?>\r
+<?php
+/**
+ * Crayons
+ * plugin for spip
+ * (c) Fil, toggg 2006-2013
+ * licence GPL
+ */
+
+if (!defined('_ECRIRE_INC_VERSION')) {
+ return;
+}
+
+define('_PREG_CRAYON', ',crayon\b[^<>\'"]+?\b((\w+)-(\w+)-(\w+(?:-\w+)*))\b,');
+
+// Compatibilite pour 1.92 : on a besoin de sql_fetch et table_objet_sql
+if ($GLOBALS['spip_version_code'] < '1.93' and $f = charger_fonction('compat_crayons', 'inc')) {
+ $f();
+}
+
+// Autoriser les crayons sur les tables non SPIP ?
+// Par defaut : oui (pour les admins complets, si autoriser_defaut_dist()) ;
+// mettre a false en cas de mutualisation par prefixe de table,
+// sinon on ne peut pas garantir que les sites sont hermetiques
+if (!defined('_CRAYONS_TABLES_EXTERNES')) {
+ define('_CRAYONS_TABLES_EXTERNES', true);
+}
+
+// Autorisations non prevues par le core
+include_spip('inc/autoriser');
+
+include_spip('inc/crayons-json');
+
+if (!function_exists('autoriser_meta_modifier_dist')) {
+/**
+ * Autorisation d'éditer les configurations dans spip_meta
+ *
+ * Les admins complets OK pour certains champs,
+ * Sinon, il faut être webmestre
+ *
+ * @note
+ * Attention sur les SPIP < 11515 (avant 04/2008) inc/autoriser
+ * passe seulement intval($id) alors qu'ici la cle est une chaine...
+ *
+ * @param string $faire Action demandée
+ * @param string $type Type d'objet sur lequel appliquer l'action
+ * @param int $id Identifiant de l'objet
+ * @param array $qui Description de l'auteur demandant l'autorisation
+ * @param array $opt Options de cette autorisation
+ * @return bool true s'il a le droit, false sinon
+**/
+function autoriser_meta_modifier_dist($faire, $type, $id, $qui, $opt) {
+ // Certaines cles de configuration sont echapées ici (cf #EDIT_CONFIG{demo/truc})
+ // $id = str_replace('__', '/', $id);
+ if (in_array($id, array('nom_site', 'slogan_site', 'descriptif_site', 'email_webmaster'))) {
+ return autoriser('configurer', null, null, $qui);
+ } else {
+ return autoriser('webmestre', null, null, $qui);
+ }
+}
+}
+
+// table spip_messages, la c'est tout simplement non (peut mieux faire,
+// mais c'est a voir dans le core/organiseur ou dans autorite)
+if (defined('_DIR_PLUGIN_ORGANISEUR')) {
+ include_spip('organiseur_autoriser');
+}
+
+if (!function_exists('autoriser_message_modifier_dist')) {
+ function autoriser_message_modifier_dist($faire, $type, $id, $qui, $opt) {
+ return false;
+ }
+}
+//compat 192 documents
+if ($GLOBALS['spip_version_code'] < '1.93') {
+ if (!function_exists('get_spip_doc')) {
+ function get_spip_doc($fichier) {
+ // fichier distant
+ if (preg_match(',^\w+://,', $fichier)) {
+ return $fichier;
+ }
+ // gestion d'erreurs, fichier=''
+ if (!strlen($fichier)) {
+ return false;
+ }
+
+ // fichier normal
+ return (strpos($fichier, _DIR_IMG) === false) ? _DIR_IMG . $fichier : $fichier;
+ }
+ }
+}
+
+// Autoriser l'usage des crayons ?
+function autoriser_crayonner_dist($faire, $type, $id, $qui, $opt) {
+ // Le type pouvant etre une table, verifier les autoriser('modifier')
+ // correspondant ; ils demandent le nom de l'objet: spip_articles => article
+ // ex: spip_articles => 'article'
+ $type = preg_replace(',^spip_(.*?)s?$,', '\1', $type);
+ if (strlen($GLOBALS['table_prefix'])) {
+ $type = preg_replace(',^'.$GLOBALS['table_prefix'].'_(.*?)s?$,', '\1', $type);
+ }
+
+ // Tables non SPIP ? Si elles sont interdites il faut regarder
+ // quelle table on appelle, et verifier si elle est "interne"
+ if (!_CRAYONS_TABLES_EXTERNES) {
+ include_spip('base/serial');
+ include_spip('base/auxiliaires');
+ include_spip('public/parametrer');
+ if (!isset($GLOBALS['tables_principales']['spip_'.table_objet($type)])
+ and !isset($GLOBALS['tables_auxiliaires']['spip_'.table_objet($type)])) {
+ return false;
+ }
+ }
+
+ // Traduire le modele en liste de champs
+ if (isset($opt['modele'])) {
+ $opt['champ'] = $opt['modele'];
+ }
+
+ // Pour un auteur, si le champ est statut ou email, signaler l'option
+ // ad hoc (cf. inc/autoriser)
+ if ($type == 'auteur'
+ and in_array($opt['champ'], array('statut', 'email'))) {
+ $opt[$opt['champ']] = true;
+ }
+
+ return (
+ autoriser('modifier', $type, $id, $qui, $opt)
+ );
+}
+
+// Si un logo est demande, on renvoie la date dudit logo (permettra de gerer
+// un "modifie par ailleurs" si la date a change, rien de plus)
+function valeur_champ_logo($table, $id, $champ) {
+ $chercher_logo = charger_fonction('chercher_logo', 'inc');
+ $on = $chercher_logo($id, id_table_objet($table), 'on');
+ return $on ? filemtime($on[0]) : false;
+}
+
+// Idem : si un doc est demande, on renvoie la date du doc
+function valeur_champ_document($table, $id, $champ) {
+ $s = spip_query('SELECT date FROM spip_documents WHERE id_document=' . _q($id));
+ if ($t = sql_fetch($s)) {
+ return $t['date'];
+ }
+}
+
+function valeur_champ_vignette($table, $id, $champ) {
+ $vignette = sql_getfetsel('id_vignette', 'spip_documents', 'id_document=' . intval($id));
+ if (is_numeric($vignette) && ($vignette > 0)) {
+ $date = sql_getfetsel('date', 'spip_documents', 'id_document=' . intval($vignette));
+ }
+ return $date ? $date : false;
+}
+// cette fonction de revision recoit le fichier upload a passer en logo
+// en reference : le nom du widget, pour aller chercher d'autres donnees
+// (ex: supprimer)
+function logo_revision($id, $file, $type, $ref) {
+ $chercher_logo = charger_fonction('chercher_logo', 'inc');
+ $_id_objet = id_table_objet($type);
+
+ // Chargement d'un nouveau logo ?
+ if ($file['logo']) {
+ define('FILE_UPLOAD', true); // message pour crayons_json_export :(
+
+ if (include_spip('action/editer_logo')
+ and function_exists('logo_modifier')) {
+ logo_modifier($type, $id, 'on', $file['logo']);
+ } else {
+ // compat SPIP < 3.1
+ // supprimer l'ancien logo
+ $on = $chercher_logo($id, $_id_objet, 'on');
+ if ($on) {
+ @unlink($on[0]);
+ }
+
+ // ajouter le nouveau
+ include_spip('action/iconifier');
+ action_spip_image_ajouter_dist(type_du_logo($_id_objet) . 'on' . $id, false, false); // beurk
+ }
+ } else {
+ // Suppression du logo ?
+ if ($wid = array_pop($ref)
+ and $_POST['content_'.$wid.'_logo_supprimer'] == 'on') {
+ if (include_spip('action/editer_logo')
+ and function_exists('logo_supprimer')) {
+ logo_supprimer($type, $id, 'on');
+ } else {
+ if ($on = $chercher_logo($id, $_id_objet, 'on')) {
+ @unlink($on[0]);
+ }
+ }
+ }
+ }
+
+ // Reduire le logo ?
+ if (is_array($cfg = @unserialize($GLOBALS['meta']['crayons']))
+ and $max = intval($cfg['reduire_logo'])) {
+ $on = $chercher_logo($id, $_id_objet, 'on');
+ include_spip('inc/filtres');
+ @copy($on[0], $temp = _DIR_VAR . 'tmp' . rand(0, 999) . '.' . $on[3]);
+ $img1 = filtrer('image_reduire', $temp, $max);
+ $img2 = preg_replace(',[?].*,', '', extraire_attribut($img1, 'src'));
+ if (@file_exists($img2)
+ and $img2 != $temp) {
+ if (include_spip('action/editer_logo')
+ and function_exists('logo_modifier')) {
+ logo_modifier($type, $id, 'on', $img2);
+ } else {
+ @unlink($on[0]);
+ $dest = $on[1].$on[2].'.'
+ .preg_replace(',^.*\.(gif|jpg|png)$,', '\1', $img2);
+ @rename($img2, $dest);
+ }
+ }
+ @unlink($temp);
+ }
+
+ return true;
+}
+
+
+// cette fonction de revision recoit le fichier upload a passer en document
+function document_fichier_revision($id, $data, $type, $ref) {
+
+ $s = spip_query('SELECT * FROM spip_documents WHERE id_document=' . intval($id));
+ if (!$t = sql_fetch($s)) {
+ return false;
+ }
+
+ /*
+ // Envoi d'une URL de document distant ?
+ // TODO: verifier l'extension distante, sinon tout explose
+ if ($data['fichier']
+ AND preg_match(',^(https?|ftp)://.+,', $data['fichier'])) {
+ include_spip('inc/modifier');
+ modifier_contenu('document', $id,
+ array('champs' => array('fichier', 'distant')),
+ array('fichier' => $data['fichier'], 'distant' => 'oui')
+ );
+ return true;
+ }
+ else
+ */
+
+ // Chargement d'un nouveau doc ?
+ if ($data['document']) {
+ $arg = $data['document'];
+ /**
+ * Méthode >= SPIP 3.0
+ * ou SPIP 2.x + Mediathèque
+ */
+ if ($ajouter_documents = charger_fonction('ajouter_documents', 'action', true)) {
+ $actifs = $ajouter_documents($id, array($arg), '', 0, $t['mode']);
+ $x = reset($actifs);
+ if (is_numeric($x)) {
+ return true;
+ } else {
+ return false;
+ }
+ } elseif ($ajouter_documents = charger_fonction('ajouter_documents', 'inc', true)) {
+ /**
+ * Méthode SPIP < 3.0
+ */
+ check_upload_error($arg['error']);
+ $x = $ajouter_documents($arg['tmp_name'], $arg['name'],
+ 'article', 0, 'document', null, $actifs);
+ // $actifs contient l'id_document nouvellement cree
+ // on recopie les donnees interessantes dans l'ancien
+ $extension = ', extension ';
+ //compat 192
+ if ($GLOBALS['spip_version_code'] < '1.93') {
+ $extension = '';
+ }
+
+ if ($id_new = array_pop($actifs)
+ and $s = spip_query("SELECT fichier, taille, largeur, hauteur $extension, distant FROM spip_documents
+ WHERE id_document="._q($id_new))
+ and $new = sql_fetch($s)) {
+ define('FILE_UPLOAD', true); // message pour crayons_json_export :(
+
+ // Une vignette doit rester une image
+ if ($t['mode'] == 'vignette'
+ and !in_array($new['extension'], array('jpg', 'gif', 'png'))) {
+ return false;
+ }
+
+ // Maintenant on est bon, on recopie les nouvelles donnees
+ // dans l'ancienne ligne spip_documents
+ include_spip('inc/modifier');
+ modifier_contenu(
+ 'document',
+ $id,
+ # 'champs' inutile a partir de SPIP 11348
+ array('champs' => array_keys($new)),
+ $new
+ );
+
+ // supprimer l'ancien document (sauf s'il etait distant)
+ if ($t['distant'] != 'oui'
+ and file_exists(get_spip_doc($t['fichier']))) {
+ supprimer_fichier(get_spip_doc($t['fichier']));
+ }
+
+ // Effacer la ligne temporaire de spip_document
+ spip_query('DELETE FROM spip_documents WHERE id_document='.intval($id_new));
+
+ // oublier id_document temporaire (ca marche chez moi, sinon bof)
+ spip_query('ALTER TABLE spip_documents AUTO_INCREMENT='.intval($id_new));
+
+ return true;
+ }
+ }
+ }
+}
+
+// cette fonction de revision soit supprime la vignette d'un document,
+// soit recoit le fichier upload a passer ou remplacer la vignette du document
+function vignette_revision($id, $data, $type, $ref) {
+ $s = sql_fetsel('id_document,id_vignette', 'spip_documents', 'id_document = '.intval($id));
+ if (!is_array($s)) {
+ return false;
+ }
+
+ include_spip('inc/modifier');
+ include_spip('inc/documents');
+ include_spip('action/editer_document');//pour revision_document
+ // Chargement d'un nouveau doc ?
+ if ($data['vignette']) {
+ define('FILE_UPLOAD', true);
+ if (is_numeric($s['id_vignette']) and ($s['id_vignette'] > 0)) {
+ spip_log('suppression de la vignette');
+ // Suppression du document
+ $vignette = sql_getfetsel('fichier', 'spip_documents', 'id_document='.intval($s['id_vignette']));
+ if (@file_exists($f = get_spip_doc($vignette))) {
+ spip_log("efface $f");
+ supprimer_fichier($f);
+ }
+ sql_delete('spip_documents', 'id_document='.intval($s['id_vignette']));
+ sql_delete('spip_documents_liens', 'id_document='.intval($s['id_vignette']));
+
+ pipeline(
+ 'post_edition',
+ array(
+ 'args' => array(
+ 'operation' => 'supprimer_document',
+ 'table' => 'spip_documents',
+ 'id_objet' => $s['id_vignette']
+ ),
+ 'data' => null
+ )
+ );
+ $id_vignette = 0;
+ }
+
+ $arg = $data['vignette'];
+ check_upload_error($arg['error']);
+ // Ajout du document comme vignette
+
+ /**
+ * Méthode >= SPIP 3.0
+ * ou SPIP 2.x + Mediatheque
+ */
+ if ($ajouter_documents = charger_fonction('ajouter_documents', 'action', true)) {
+ $x = $ajouter_documents(null,array($arg),'', 0, 'vignette');
+ $vignette = reset($x);
+ if (intval($vignette)) {
+ document_modifier($id, array('id_vignette'=>$vignette));
+ } elseif ($id_vignette) {
+ document_modifier($id, array('id_vignette'=>$id_vignette));
+ }
+ } elseif ($ajouter_documents = charger_fonction('ajouter_documents', 'inc', true)) {
+ /**
+ * Méthode < SPIP 3.0
+ */
+ // On remet l'id_vignette a 0 si on l'a supprimé
+ if ($id_vignette) {
+ revision_document($s['id_document'], array('id_vignette' => 0));
+ }
+ $x = $ajouter_documents($arg['tmp_name'], $arg['name'],'','', 'vignette', $id, $actifs);
+ }
+ } elseif ($wid = array_pop($ref)
+ and $_POST['content_'.$wid.'_vignette_supprimer'] == 'on') {
+ if (is_numeric($s['id_vignette']) and ($s['id_vignette']>0)) {
+ // Suppression du document
+ $vignette = sql_getfetsel('fichier', 'spip_documents', 'id_document='.intval($s['id_vignette']));
+ if (@file_exists($f = get_spip_doc($vignette))) {
+ spip_log("efface $f");
+ supprimer_fichier($f);
+ }
+ sql_delete('spip_documents', 'id_document='.intval($s['id_vignette']));
+ sql_delete('spip_documents_liens', 'id_document = ' . intval($s['id_vignette']));
+
+ pipeline(
+ 'post_edition',
+ array(
+ 'args' => array(
+ 'operation' => 'supprimer_document',
+ 'table' => 'spip_documents',
+ 'id_objet' => $s['id_vignette']
+ ),
+ 'data' => null
+ )
+ );
+
+ // On remet l'id_vignette a 0
+ revision_document($s['id_document'], array('id_vignette'=>0));
+ }
+ }
+ return true;
+}
+
+
+function colonne_table($type, $col) {
+ list($distant,$table) = distant_table($type);
+ $nom_table = '';
+ if (!(($tabref = &crayons_get_table($table, $nom_table))
+ && isset($tabref['field'][$col])
+ && ($brut = $tabref['field'][$col]))) {
+ return false;
+ }
+ $ana = explode(' ', $brut);
+ $sta = 0;
+ $sep = '';
+ $ret = array('brut' => $brut,
+ 'type' => '', 'notnull' => false, 'long' => 0, 'def' => '');
+ foreach ($ana as $mot) {
+ switch ($sta) {
+ case 0:
+ $ret['type'] = ($mot = strtolower($mot));
+ continue;
+ case 1:
+ if ($mot[strlen($mot) - 1] == ')') {
+ $pos = strpos($mot, '(');
+ $ret['type'] = strtolower(substr($mot, 0, $pos++));
+ $vir = explode(',', substr($mot, $pos, -1));
+ if ($ret['type'] == 'enum') {
+ $ret['enum'] = $vir;
+ } elseif (count($vir) > 1) {
+ $ret['long'] = $vir;
+ } else {
+ $ret['long'] = $vir[0];
+ }
+ $sta = 1;
+ continue;
+ }
+ if (!$sta) {
+ $sta = 1;
+ continue;
+ }
+ continue;
+ case 2:
+ switch (strtolower($mot)) {
+ case 'not':
+ $sta = 3;
+ continue;
+ case 'default':
+ $sta = 4;
+ continue;
+ }
+ continue;
+ case 3:
+ $ret['notnull'] = strtolower($mot) == 'null';
+ $sta = 2;
+ continue;
+ case 4:
+ $df1 = strpos('"\'', $mot[0]) !== false? $mot[0] : '';
+ $sta = 5;
+ continue;
+ case 5:
+ $ret['def'] .= $sep . $mot;
+ if (!$df1) {
+ $sta = 2;
+ continue;
+ }
+ if ($df1 == $mot[strlen($mot) - 1]) {
+ $ret['def'] = substr($ret['def'], 1, -1);
+ $sta = 2;
+ }
+ $sep = ' ';
+ continue;
+ }
+ }
+ return $ret;
+}
+
+
+/**
+ * Obtient le nom de la table ainsi que sa ou ses clés primaires
+ *
+ * @param string $type
+ * Table sur laquelle s'applique le crayon.
+ * Ce type peut contenir le nom d'un connecteur distant tel que `{connect}__{table}`
+ *
+ * @return array|bool
+ * - false si on ne trouve pas de table ou de table ayant de clé primaire
+ * - liste :
+ * - - nom de la table sql
+ * - - tableau des noms de clés primaires
+**/
+function crayons_get_table_name_and_primary($type) {
+ static $types = array();
+ if (isset($types[$type])) {
+ return $types[$type];
+ }
+
+ $nom_table = '';
+ if ($tabref = &crayons_get_table($type, $nom_table)
+ and ($tabid = explode(',', $tabref['key']['PRIMARY KEY']))) {
+ return $types[$type] = array($nom_table, $tabid);
+ }
+ spip_log('crayons: table ' . $type . ' inconnue');
+ return $types[$type] = false;
+}
+
+
+function table_where($type, $id, $where_en_tableau = false) {
+ if (!$infos = crayons_get_table_name_and_primary($type)) {
+ return array(false, false);
+ }
+
+ list($nom_table, $tabid) = $infos;
+
+ if (is_scalar($id)) {
+ $id = explode('-', $id);
+ }
+ // sortie tableau pour sql_updateq
+ if ($where_en_tableau) {
+ $where = array();
+ foreach ($id as $idcol => $idval) {
+ $where[] = '`' . (is_int($idcol) ? trim($tabid[$idcol]) : $idcol) . '`=' . sql_quote($idval);
+ }
+ // sinon sortie texte pour sql_query
+ } else {
+ $where = $and = '';
+ foreach ($id as $idcol => $idval) {
+ $where .= $and . '`' . (is_int($idcol) ? trim($tabid[$idcol]) : $idcol) . '`=' . _q($idval);
+ $and = ' AND ';
+ }
+ }
+ return array($nom_table, $where);
+}
+// var_dump(colonne_table('forum', 'id_syndic')); die();
+
+function valeur_colonne_table_dist($type, $col, $id) {
+
+ // Table introuvable ou sans clé primaire
+ if (!$infos = crayons_get_table_name_and_primary($type)) {
+ return false;
+ }
+ $table = reset($infos);
+
+ $r = array();
+
+ // valeurs non SQL
+ foreach ($col as $champ) {
+ if (function_exists($f = 'valeur_champ_'.$table.'_'.$champ)
+ or function_exists($f = 'valeur_champ_'.$champ)) {
+ $r[$champ] = $f($table, $id, $champ);
+ $col = array_diff($col, array($champ));
+ }
+ }
+
+ // valeurs SQL
+ if (count($col)) {
+ list($distant, $table) = distant_table($type);
+ list($nom_table, $where) = table_where($type, $id);
+
+ if ($s = spip_query(
+ 'SELECT `' . implode($col, '`, `') .
+ '` FROM ' . $nom_table . ' WHERE ' . $where,
+ $distant
+ ) and $t = sql_fetch($s)) {
+ $r = array_merge($r, $t);
+ }
+ }
+
+ return $r;
+}
+
+/**
+ * Extrait la valeur d'une ou plusieurs colonnes d'une table
+ *
+ * @param string $table
+ * Type d'objet de la table (article)
+ * @param string|array $col
+ * Nom de la ou des colonnes (ps)
+ * @param string $id
+ * Identifiant de l'objet
+ * @return array
+ * Couples Nom de la colonne => Contenu de la colonne
+**/
+function valeur_colonne_table($table, $col, $id) {
+ if (!is_array($col)) {
+ $col = array($col);
+ }
+
+ if (function_exists($f = $table . '_valeur_colonne_table_dist')
+ or function_exists($f = $table.'_valeur_colonne_table')
+ or $f = 'valeur_colonne_table_dist') {
+ return $f($table, $col, $id);
+ }
+}
+
+/**
+ * Extrait la valeur d'une configuration en meta
+ *
+ * Pour ces données, il n'y a toujours qu'une colonne (valeur),
+ * mais on gère l'enregistrement et la lecture via lire_config ou ecrire_config
+ * dès que l'on demande des sous parties d'une configuration.
+ *
+ * On ne retourne alors ici dans 'valeur' que la sous-partie demandée si
+ * c'est le cas.
+ *
+ * @param string $table
+ * Nom de la table (meta)
+ * @param array $col
+ * Nom des colonnes (valeur)
+ * @param string $id
+ * Nom ou clé de configuration (descriptif_site ou demo__truc pour demo/truc)
+ * @return array
+ * Couple valeur => Contenu de la configuration
+**/
+function meta_valeur_colonne_table_dist($table, $col, $id) {
+ // Certaines clés de configuration sont echapées ici (cf #EDIT_CONFIG{demo/truc})
+ $id = str_replace('__', '/', $id);
+
+ // Éviter de planter les vieux SPIP
+ if (false === strpos($id, '/')) {
+ $config = isset($GLOBALS['meta'][$id]) ? $GLOBALS['meta'][$id] : '';
+ // SPIP 3 ou Bonux 2 ou CFG
+ } else {
+ include_spip('inc/config');
+ $config = lire_config($id, '');
+ }
+ return array('valeur' => $config);
+}
+
+
+function return_log($var) {
+ die(crayons_json_export(array('$erreur'=> var_export($var, true))));
+}
+
+function _U($texte, $params = array()) {
+ include_spip('inc/charsets');
+ return unicode2charset(html2unicode(_T($texte, $params)));
+}
+
+/**
+ * Obtenir la configuration des crayons
+ *
+ * @note wdgcfg = widget config :-)
+ *
+ * @return array
+ * Couples : attribut => valeur
+**/
+function wdgcfg() {
+ $php = function_exists('crayons_config') ? crayons_config() : array();
+ include_spip('inc/meta');
+ lire_metas();
+ global $meta;
+ $metacrayons = empty($meta['crayons']) ? array() : unserialize($meta['crayons']);
+ $wdgcfg = array();
+ foreach (array(
+ 'msgNoChange' => false,
+ 'msgAbandon' => false, /* etait: true */
+ 'filet' => false,
+ 'yellow_fade' => false,
+ 'clickhide' => false /* etait: true */
+ ) as $cfgi => $def) {
+ $wdgcfg[$cfgi] = isset($php[$cfgi]) ? $php[$cfgi] :
+ isset($metacrayons[$cfgi]) ? $metacrayons[$cfgi] : $def;
+ }
+ return $wdgcfg;
+}
+
+function &crayons_get_table($type, &$nom_table) {
+ list($distant,$table) = distant_table($type);
+ static $return = array();
+ static $noms = array();
+ if (!isset($return[$table])) {
+ $try = array(table_objet_sql($table), 'spip_'.table_objet($table), 'spip_' . $table . 's', $table . 's', 'spip_' . $table, $table);
+
+ // premiere possibilite (à partir de 1.9.3) : regarder directement la base
+ if (function_exists('sql_showtable')) {
+ foreach ($try as $nom) {
+ if ($q = sql_showtable($nom, !$distant, $distant)) {
+ $noms[$table] = $nom;
+ $return[$table] = $q;
+ break;
+ }
+ }
+ }
+
+ // seconde, une heuristique 1.9.2
+ if (!isset($return[$table])) {
+ include_spip('base/serial');
+ include_spip('base/auxiliaires');
+ include_spip('public/parametrer');
+ foreach (array('tables_principales', 'tables_auxiliaires') as $categ) {
+ foreach ($try as $nom) {
+ if (isset($GLOBALS[$categ][$nom])) {
+ $noms[$table] = $nom;
+ $return[$table] = & $GLOBALS[$categ][$nom];
+ break 2;
+ }
+ }
+ }
+ }
+ }
+
+ $nom_table = $noms[$table];
+ return $return[$table];
+}
+
+function distant_table($type) {
+ //separation $type en $distant $table
+ //separateur double underscore "__"
+ strstr($type, '__') ? list($distant,$table) = explode('__', $type) : list($distant, $table) = array(false, $type);
+ return array($distant,$table);
+}