/** * * API pour aider les plus demunis * Permet d'indiquer que tels champs extras se limitent a telle ou telle rubrique * et cela en creant a la volee les fonctions d'autorisations adequates. * * Exemples : * restreindre_extras('article', array('nom', 'prenom'), array(8, 12)); * restreindre_extras('site', 'url_doc', 18, true); // recursivement aux sous rubriques * * @param string $objet objet possedant les extras * @param mixed $noms nom des extras a restreindre * @param mixed $ids identifiant (des rubriques par defaut) sur lesquelles s'appliquent les champs * @param string $cible type de la fonction de test qui sera appelee, par defaut "rubrique". Peut aussi etre "secteur", "groupe" ou des fonctions definies * @param bool $recursif application recursive sur les sous rubriques ? ATTENTION, c'est gourmand en requetes SQL :) * * @return bool : true si on a fait quelque chose */ function restreindre_extras($objet, $noms=array(), $ids=array(), $cible='rubrique', $recursif=false) { if (!$objet or !$noms or !$ids) { return false; } if (!is_array($noms)) { $noms = array($noms); } if (!is_array($ids)) { $ids = array($ids); } $objet = objet_type($objet); $ids = var_export($ids, true); $recursif = var_export($recursif, true); $m = '_modifierextra_dist'; $v = '_voirextra_dist'; foreach ($noms as $nom) { $f = "autoriser_$objet" . "_$nom"; $code = " if (!function_exists('$f$m')) { function $f$m(\$faire, \$type, \$id, \$qui, \$opt) { return _restreindre_extras_objet('$objet', \$id, \$opt, $ids, '$cible', $recursif); } } if (!function_exists('$f$v')) { function $f$v(\$faire, \$type, \$id, \$qui, \$opt) { return autoriser('modifierextra', \$type, \$id, \$qui, \$opt); } } "; # echo $code; eval($code); } return true; }
/** * supprime/compte les elements listes d'un type donne * * @param nom $table * @param tableau $ids (si $id==-1, on vide/compte tout) * @param booleen $compter * @return array(nb objets, nb objets lies, ids trouves) */ function cs_corbeille_gerer($table, $ids=array(), $vider=false) { $params = cs_corbeille_table_infos($table); if (isset($params['table'])) $table = $params['table']; include_spip('base/abstract_sql'); $type = objet_type($table); $table_sql = table_objet_sql($type); $id_table = id_table_objet($type); if (!$params['statut']) return false; //echo "$type - $table_sql - $id_table - ",table_objet_sql($type),'<hr>'; // determine les index des elements a supprimer $ids = $ids===-1 ?array_map('reset',sql_allfetsel($id_table,$table_sql,'statut='.sql_quote($params['statut']))) :array_map('reset',sql_allfetsel($id_table,$table_sql,sql_in($id_table,$ids).' AND statut='.sql_quote($params['statut']))); if (!count($ids)) return array(0, 0, array()); // compte/supprime les elements definis par la liste des index if($vider) sql_delete($table_sql,sql_in($id_table,$ids)); $nb = count($ids); // compte/supprime des elements lies $nb_lies = 0; $f = $vider?'sql_delete':'sql_countsel'; if ($table_liee=$params['tableliee']) { $trouver_table = charger_fonction('trouver_table','base'); foreach($table_liee as $unetable) { $desc = $trouver_table($unetable); if (isset($desc['field'][$id_table])) $nb_lies += $f($unetable,sql_in($id_table,$ids)); elseif(isset($desc['field']['id_objet']) AND isset($desc['field']['objet'])) $nb_lies += $f($unetable,sql_in('id_objet',$ids)." AND objet=".sql_quote($type)); } } return array($nb, $vider?'-1':$nb_lies, $ids); }
/** * Décomposer un champ id_truc en (id_objet,objet,truc) * * Exemple : décompose id_article en (id_objet,objet,article) * * @param string $champ * Nom du champ à décomposer * @return array|string * Tableau si décomposable : 'id_objet', 'objet', Type de l'objet * Chaine sinon : le nom du champ (non décomposable donc) */ function decompose_champ_id_objet($champ) { if ($champ !== 'id_objet' and preg_match(',^id_([a-z_]+)$,', $champ, $regs)) { return array('id_objet', 'objet', objet_type($regs[1])); } return $champ; }
/** * Trouver le label d'un champ de révision * * Quelques champs ont un label dans dans les chaînes de langue de SPIP * Pour un champ particulier d'un objet particulier, le pipeline revisions_chercher_label * peut être utilisé * * @param string $champ * Le nom du champ révisionné * @param string $objet * Le type d'objet révisionné * @return string $label * Le label du champ */ function label_champ($champ, $objet = false) { $label = ""; // si jointure: renvoyer le nom des objets joints if (strncmp($champ, 'jointure_', 9) == 0) { return _T(objet_info(objet_type(substr($champ, 9)), 'texte_objets')); } switch ($champ) { case 'surtitre': $label = "texte_sur_titre"; break; case 'soustitre': $label = "texte_sous_titre"; break; case 'nom_site': $label = "lien_voir_en_ligne"; break; case 'email': $label = "entree_adresse_email_2"; break; case 'login': $label = "item_login"; break; case 'chapo': $champ = "chapeau"; default: $label = pipeline('revisions_chercher_label', array('args' => array('champ' => $champ, 'objet' => $objet), 'data' => $label ? $label : 'info_' . $champ)); break; } return $label ? _T($label) : ""; }
/** * Afficher le diff d'un champ texte generique * @param string $champ * @param string $old * @param string $new * @param string $format * apercu, diff ou complet * @return string */ function afficher_diff_jointure_dist($champ, $old, $new, $format = 'diff') { $join = substr($champ, 9); $objet = objet_type($join); $old = explode(',', $old); $new = explode(',', $new); $liste = array(); // les communs $intersection = array_intersect($new, $old); foreach ($intersection as $id) { if ($id = intval(trim($id))) { $liste[$id] = "<a href='" . generer_url_entite($id, $objet) . "' title='" . _T(objet_info($objet, 'texte_objet')) . " {$id}'>" . generer_info_entite($id, $objet, 'titre') . "</a>"; } } // les supprimes $old = array_diff($old, $intersection); foreach ($old as $id) { if ($id = intval(trim($id))) { $liste[$id] = "<span class='diff-supprime'>" . "<a href='" . generer_url_entite($id, $objet) . "' title='" . _T(objet_info($objet, 'texte_objet')) . " {$id}'>" . generer_info_entite($id, $objet, 'titre') . "</a>" . "</span>"; } } // les ajoutes $new = array_diff($new, $intersection); foreach ($new as $id) { if ($id = intval(trim($id))) { $liste[$id] = "<span class='diff-ajoute'>" . "<a href='" . generer_url_entite($id, $objet) . "' title='" . _T(objet_info($objet, 'texte_objet')) . " {$id}'>" . generer_info_entite($id, $objet, 'titre') . "</a>" . "</span>"; } } ksort($liste); $liste = implode(', ', $liste); return $liste; }
/** * Déclaration des alias de tables et filtres automatiques de champs * * @pipeline declarer_tables_interfaces * @param array $interfaces * Déclarations d'interface pour le compilateur * @return array * Déclarations d'interface pour le compilateur */ function massicot_declarer_tables_interfaces($interfaces) { $interfaces = ajouter_traitement_automatique($interfaces, 'massicoter_document(%s)', 'FICHIER', 'documents'); $interfaces = ajouter_traitement_automatique($interfaces, 'massicoter_logo_document(%s, $Pile[1])', 'LOGO_DOCUMENT'); $interfaces = ajouter_traitement_automatique($interfaces, 'massicoter_document(%s)', 'URL_DOCUMENT', 'documents'); /* On traîte aussi les balises #HAUTEUR et #LARGEUR des documents */ $interfaces = ajouter_traitement_automatique($interfaces, 'massicoter_largeur(%s, $Pile[1])', 'LARGEUR', 'documents'); $interfaces = ajouter_traitement_automatique($interfaces, 'massicoter_largeur(%s, $Pile[1])', 'HAUTEUR', 'documents'); /* Pour chaque objet éditorial existant, ajouter un traitement sur les logos */ if (isset($GLOBALS['spip_connect_version'])) { foreach (lister_tables_objets_sql() as $table => $valeurs) { if ($table !== 'spip_documents') { $interfaces = ajouter_traitement_automatique($interfaces, 'massicoter_logo(%s, ' . objet_type($table) . ', $Pile[1][\'' . id_table_objet($table) . '\'])', strtoupper('LOGO_' . objet_type($table))); $interfaces = ajouter_traitement_automatique($interfaces, 'massicoter_logo(%s, ' . objet_type($table) . ', $Pile[1][\'' . id_table_objet($table) . '\'])', strtoupper('LOGO_' . objet_type($table)) . '_NORMAL'); $interfaces = ajouter_traitement_automatique($interfaces, 'massicoter_logo(%s, ' . objet_type($table) . ', $Pile[1][\'' . id_table_objet($table) . '\'], \'logo_survol\')', strtoupper('LOGO_' . objet_type($table)) . '_SURVOL'); } } } /* sans oublier #LOGO_ARTICLE_RUBRIQUE… */ $interfaces = ajouter_traitement_automatique($interfaces, 'massicoter_logo(%s,null,null,null,$Pile[0])', 'LOGO_ARTICLE_RUBRIQUE'); /* …ni les #LOGO_SITE_SPIP ! */ $interfaces = ajouter_traitement_automatique($interfaces, 'massicoter_logo(%s,"site","0","",$Pile[0])', 'LOGO_SITE_SPIP'); $interfaces = ajouter_traitement_automatique($interfaces, 'massicoter_logo(%s,"site","0","logo_survol",$Pile[0])', 'LOGO_SITE_SPIP_SURVOL'); return $interfaces; }
function action_dereferencer_traduction_rubrique_dist() { $securiser_action = charger_fonction('securiser_action', 'inc'); $arg = $securiser_action(); list($type, $id_objet) = explode('/', $arg); if (!$type = objet_type($type) or !$id_objet = intval($id_objet)) { if (!_AJAX) { include_spip('inc/minipres'); minipres('Arguments incompris'); } else { spip_log('Arguments incompris dans action dereferencer_traduction_rubrique'); return false; } } $objet = table_objet($type); $_id_objet = id_table_objet($objet); $table = table_objet_sql($objet); $id_trad_old = sql_getfetsel('id_trad', $table, "$_id_objet = " . sql_quote($id_objet)); if ($id_trad_old) { include_spip('inc/modifier'); modifier_contenu($objet, $id_objet, array('invalideur' => "id='$objet/$id_objet'"), array('id_trad' => 0)); // si la deliaison fait qu'il ne reste plus que la source // dans le groupe de traduction on lui remet l'id_trad a 0 if (1 == $nb_dans_groupe = sql_countsel($table, array('id_trad = ' . sql_quote($id_trad_old)))) { modifier_contenu($objet, $id_trad_old, array('invalideur' => "id='$objet/$id_trad_old'"), array('id_trad' => 0)); } } }
/** * Permet de faire un comptage par table liee * * @syntaxe `{compteur table[, champ]}` * @link http://www.spip-contrib.net/Classer-les-articles-par-nombre-de#forum409210 * * @example * Pour avoir les auteurs classes par articles et * le nombre d'article de chacun : * * ``` * <BOUCLE1(AUTEURS){compteur articles}{par compteur_articles}> * #ID_AUTEUR : #COMPTEUR{articles} * </BOUCLE1> * ``` * * @note * Avec un seul argument {compteur autre_table} le groupby est fait * implicitement sur la cle primaire de la boucle en cours. * Avec un second argument {compteur autre_table,champ_fusion} * le groupby est fait sur le champ_fusion" * * @param string $idb * Identifiant de la boucle * @param Boucle[] $boucles * AST du squelette * @param Critere $crit * Paramètres du critère dans cette boucle * @param bool $left * true pour utiliser un left join plutôt qu'un inner join. * @return void */ function critere_compteur($idb, &$boucles, $crit, $left = false) { $boucle =& $boucles[$idb]; if (isset($crit->param[1])) { $_fusion = calculer_liste($crit->param[1], array(), $boucles, $boucle->id_parent); } else { $_fusion = "''"; } $params = $crit->param; $table = reset($params); $table = $table[0]->texte; $op = false; if (preg_match(',^(\\w+)([<>=])([0-9]+)$,', $table, $r)) { $table = $r[1]; if (count($r) >= 3) { $op = $r[2]; } if (count($r) >= 4) { $op_val = $r[3]; } } $type = objet_type($table); $type_id = id_table_objet($type); /** * Si la clé primaire est une clé multiple, on prend la première partie * Utile pour compter les versions de spip_versions par exemple */ if (count($types = explode(',', $type_id)) > 1) { $type_id = $types[0]; } $table_sql = table_objet_sql($type); $trouver_table = charger_fonction('trouver_table', 'base'); $arrivee = array($table, $trouver_table($table, $boucle->sql_serveur)); $depart = array($boucle->id_table, $trouver_table($boucle->id_table, $boucle->sql_serveur)); // noter les jointures deja installees $joins = array_keys($boucle->from); if ($compt = calculer_jointure($boucle, $depart, $arrivee)) { if ($_fusion != "''") { // en cas de jointure, on ne veut pas du group_by sur la cle primaire ! // cela casse le compteur ! foreach ($boucle->group as $k => $group) { if ($group == $boucle->id_table . '.' . $boucle->primary) { unset($boucle->group[$k]); } } $boucle->group[] = '".($gb=' . $_fusion . ')."'; } $boucle->select[] = "COUNT({$compt}.{$type_id}) AS compteur_{$table}"; if ($op) { $boucle->having[] = array("'" . $op . "'", "'compteur_" . $table . "'", $op_val); } if ($left) { foreach ($boucle->from as $k => $val) { if (!in_array($k, $joins)) { $boucle->from_type[$k] = 'left'; } } } } }
function cextras_objets_valides(){ $objets = array(); $objets_extensibles = pipeline("objets_extensibles", array( 'article' => _T('cextras:table_article'), 'auteur' => _T('cextras:table_auteur'), 'breve' => _T('cextras:table_breve'), 'groupes_mot' => _T('cextras:table_groupes_mot'), 'mot' => _T('cextras:table_mot'), 'rubrique' => _T('cextras:table_rubrique'), 'site' => _T('cextras:table_site') )); ksort($objets_extensibles); foreach ($objets_extensibles as $objet => $traduction) { $objets[$objet] = array( 'table' => table_objet_sql($objet), 'type' => objet_type(table_objet($objet)), 'nom' => $traduction, ); } return $objets; }
function action_deplacer_objets_dist() { include_spip('inc/autoriser'); if (!autoriser('ecrire')) { return plan_json_erreur(_T("plan:erreur_autorisation_insuffisante") . " " . _T("plan:erreur_deplacement_impossible")); } include_spip('base/objets'); $objet = objet_type(_request('objet')); $table = table_objet_sql($objet); $_id_table = id_table_objet($table); $ids = _request('id_objet'); $id_rubrique_old = _request('id_rubrique_source'); $id_rubrique_new = _request('id_rubrique_destination'); if (!is_array($ids) or !$objet) { return plan_json_erreur(_T("plan:erreur_aucun_identifiant") . " " . _T("plan:erreur_deplacement_impossible")); } if ($id_rubrique_old == $id_rubrique_new) { return plan_json_erreur(_T("plan:erreur_rubriques_parentes_incorrectes") . " " . _T("plan:erreur_deplacement_impossible")); } if ($objet != 'rubrique' and !$id_rubrique_new) { return plan_json_erreur(_T("plan:erreur_rubriques_parentes_incorrectes") . " " . _T("plan:erreur_deplacement_impossible")); } $ids = array_filter($ids); if ($objet == 'rubrique') { $champ = 'id_parent'; } else { $champ = 'id_rubrique'; } // ne modifier que si les emplacements n'ont pas déjà changé ! $ids = sql_allfetsel($_id_table, $table, array(sql_in($_id_table, $ids), $champ . '=' . sql_quote($id_rubrique_old))); $ids = array_map('array_shift', $ids); include_spip('action/editer_objet'); $errors = $success = array(); $modifs = array('id_parent' => $id_rubrique_new); foreach ($ids as $id) { if (autoriser('modifier', $objet, $id)) { if ($err = objet_modifier($objet, $id, $modifs)) { $errors["{$objet}-{$id}"] = $err; } else { $success["{$objet}-{$id}"] = true; } } else { $errors["{$objet}-{$id}"] = _T("plan:erreur_autorisation_insuffisante") . " " . _T("plan:erreur_deplacement_impossible"); } } // dans certains cas… on ne reçoit pas d'erreur… et pourtant ! if (!$errors) { // on verifie qu'il n'y a plus d'objets à l'ancien emplacement $ids = sql_allfetsel($_id_table, $table, array(sql_in($_id_table, $ids), $champ . '=' . sql_quote($id_rubrique_old))); $ids = array_map('array_shift', $ids); if ($ids) { foreach ($ids as $id) { $errors["{$objet}-{$id}"] = _T("plan:erreur_deplacement"); unset($success["{$objet}-{$id}"]); } } } return plan_json_envoi(array('done' => true, 'success' => $success, 'errors' => $errors)); }
function critere_archives($idb, &$boucles, $crit) { $boucle =& $boucles[$idb]; $objet = objet_type($boucle->id_table); $date = objet_info($objet, 'date'); $champ_date = "'" . $boucle->id_table . "." . $date . "'"; $boucle->where[] = array('REGEXP', $champ_date, "sql_quote(('^' . interdire_scripts(entites_html(\$Pile[0]['" . VAR_DATE . "']))))"); }
/** * Préparer les listes `id_article IN (...)` pour les parties WHERE * et calcul des `points` pour la partie SELECT des requêtes du moteur de recherche * * Le paramètre $serveur est utilisé pour savoir sur quelle base on cherche * mais l'index des résultats est toujours stocké sur le serveur principal * car on ne sait pas si la base distante dispose d'une table spip_resultats * ni meme si on aurait le droit d'ecrire dedans * * @param string $recherche * chaine recherchee * @param string $table * table dans laquelle porte la recherche * @param bool $cond * critere conditionnel sur {recherche?} * @param string $serveur * serveur de base de donnees * @param array $modificateurs * modificateurs de boucle, ie liste des criteres presents * @param string $primary * cle primaire de la table de recherche * @return array */ function inc_prepare_recherche_dist($recherche, $table = 'articles', $cond = false, $serveur = '', $modificateurs = array(), $primary = '') { static $cache = array(); $delai_fraicheur = min(_DELAI_CACHE_resultats, time() - (isset($GLOBALS['meta']['derniere_modif']) ? $GLOBALS['meta']['derniere_modif'] : 0)); // si recherche n'est pas dans le contexte, on va prendre en globals // ca permet de faire des inclure simple. if (!isset($recherche) and isset($GLOBALS['recherche'])) { $recherche = $GLOBALS['recherche']; } // traiter le cas {recherche?} if ($cond and !strlen($recherche)) { return array("0 as points", ''); } $rechercher = false; if (!isset($cache[$serveur][$table][$recherche])) { $hash_serv = $serveur ? substr(md5($serveur), 0, 16) : ''; $hash = substr(md5($recherche . $table), 0, 16); $where = "(resultats.recherche='{$hash}' AND resultats.table_objet=" . sql_quote($table) . " AND resultats.serveur='{$hash_serv}')"; $row = sql_fetsel('UNIX_TIMESTAMP(NOW())-UNIX_TIMESTAMP(resultats.maj) AS fraicheur', 'spip_resultats AS resultats', $where, '', 'fraicheur DESC', '0,1'); if (!$row or $row['fraicheur'] > $delai_fraicheur or defined('_VAR_MODE') and _VAR_MODE == 'recalcul') { $rechercher = true; } } // si on n'a pas encore traite les donnees dans une boucle precedente if ($rechercher) { //$tables = liste_des_champs(); $x = objet_type($table); $points = recherche_en_base($recherche, $x, array('score' => true, 'toutvoir' => true, 'jointures' => true), $serveur); // pas de résultat, pas de point $points = isset($points[$x]) ? $points[$x] : array(); // permettre aux plugins de modifier le resultat $points = pipeline('prepare_recherche', array('args' => array('type' => $x, 'recherche' => $recherche, 'serveur' => $serveur, 'modificateurs' => $modificateurs), 'data' => $points)); // supprimer les anciens resultats de cette recherche // et les resultats trop vieux avec une marge // pas de AS resultats dans un delete (mysql) $whered = str_replace(array("resultats.recherche", "resultats.table_objet", "resultats.serveur"), array("recherche", "table_objet", "serveur"), $where); sql_delete('spip_resultats', 'NOT(' . sql_date_proche('maj', 0 - ($delai_fraicheur + 100), " SECOND") . ") OR ({$whered})"); // inserer les resultats dans la table de cache des resultats if (count($points)) { $tab_couples = array(); foreach ($points as $id => $p) { $tab_couples[] = array('recherche' => $hash, 'id' => $id, 'points' => $p['score'], 'table_objet' => $table, 'serveur' => $hash_serv); } sql_insertq_multi('spip_resultats', $tab_couples, array()); } } if (!isset($cache[$serveur][$table][$recherche])) { if (!$serveur) { $cache[$serveur][$table][$recherche] = array("resultats.points AS points", $where); } else { if (sql_countsel('spip_resultats as resultats', $where)) { $rows = sql_allfetsel('resultats.id,resultats.points', 'spip_resultats as resultats', $where); } $cache[$serveur][$table][$recherche] = generer_select_where_explicites($table, $primary, $rows, $serveur); } } return $cache[$serveur][$table][$recherche]; }
/** * Retrouve la traduction d'un rôle dans un objet donné * * @param string $role * Le role dans la base de donnée * @param string $objet * L'objet sur lequel est le rôle * @return string * Le texte du rôle dans la langue en cours * **/ function filtre_role_dist($role, $objet) { if (!$role) return ''; if (!$objet) return $role; $roles = roles_presents(table_objet(objet_type($objet))); if (isset($roles['titres'][$role])) { return _T($roles['titres'][$role]); } return $role; }
function inc_icone_renommer_dist($fond, $fonction) { $size = 24; if (preg_match("/(?:-([0-9]{1,3}))?([.](gif|png))?\$/i", $fond, $match) and (isset($match[0]) and $match[0] or isset($match[1]) and $match[1])) { if (isset($match[1]) and $match[1]) { $size = $match[1]; } $type = substr($fond, 0, -strlen($match[0])); if (!isset($match[2]) or !$match[2]) { $fond .= ".png"; } } else { $type = $fond; $fond .= ".png"; } $rtl = false; if (preg_match(',[-_]rtl$,i', $type, $match)) { $rtl = true; $type = substr($type, 0, -strlen($match[0])); } // objet_type garde invariant tout ce qui ne commence par par id_, spip_ // et ne finit pas par un s, sauf si c'est une exception declaree $type = objet_type($type, false); $dir = "images/"; $f = "{$type}-{$size}.png"; if ($icone = find_in_theme($dir . $f)) { $dir = dirname($icone); $fond = $icone; if ($rtl and $fr = "{$type}-rtl-{$size}.png" and file_exists($dir . '/' . $fr)) { $type = "{$type}-rtl"; } $action = $fonction; if ($action == "supprimer.gif") { $action = "del"; } elseif ($action == "creer.gif") { $action = "new"; } elseif ($action == "edit.gif") { $action = "edit"; } if (!in_array($action, array('del', 'new', 'edit'))) { $action = ""; } if ($action) { if ($fa = "{$type}-{$action}-{$size}.png" and file_exists($dir . '/' . $fa)) { $fond = $dir . '/' . $fa; $fonction = ""; } else { $fonction = "{$action}-{$size}.png"; } } // c'est bon ! return array($fond, $fonction); } return array($fond, $fonction); }
function cextras_objets_valides(){ $objets = array(); foreach (array('article','auteur','breve','groupes_mot','mot','rubrique','site') as $objet) { $objets[$objet] = array( 'table' => table_objet_sql($objet), 'type' => objet_type($objet), 'nom' => _T('cextras:table_'.$objet), ); } return $objets; }
function quete_parent_lang($table,$id,$connect=''){ static $cache_quete = array(); if (!isset($cache_quete[$connect][$table][$id]) AND in_array($table,array('spip_rubriques','spip_articles','spip_syndic','spip_breves'))){ $select = ($table=='spip_rubriques'?'id_parent':'id_rubrique'); $select .= in_array($table,array('spip_rubriques','spip_articles','spip_breves'))?", lang":""; $_id = id_table_objet(objet_type($table)); $cache_quete[$connect][$table][$id] = sql_fetsel($select, $table,"$_id=".intval($id),'','','','',$connect); } return $cache_quete[$connect][$table][$id]; }
function definir($params=array()) { foreach ($params as $cle=>$valeur) { if (isset($this->$cle)) { $this->$cle = $valeur; } } // calculer _objet et _table_sql $this->_type = objet_type(table_objet($this->table)); // article $this->_objet = table_objet($this->_type); // articles $this->_table_sql = table_objet_sql($this->table); // spip_articles // calculer l'id du champ extra $this->make_id(); }
/** * Afficher la puce statut d'un objet * * Utilise une fonction spécifique pour un type d'objet si elle existe, tel que * puce_statut_$type_dist(), sinon tente avec puce_statut_changement_rapide(). * * @see puce_statut_changement_rapide() * * @param int $id_objet * Identifiant de l'objet * @param string $statut * Statut actuel de l'objet * @param int $id_parent * Identifiant du parent * @param string $type * Type d'objet * @param bool $ajax * Indique s'il ne faut renvoyer que le coeur du menu car on est * dans une requete ajax suite à un post de changement rapide * @param bool $menu_rapide * Indique si l'on peut changer le statut, ou si on l'affiche simplement * @return string * Code HTML de l'image de puce de statut à insérer (et du menu de changement si présent) */ function inc_puce_statut_dist($id_objet, $statut, $id_parent, $type, $ajax = false, $menu_rapide = _ACTIVER_PUCE_RAPIDE) { static $f_puce_statut = array(); $type = objet_type($type); // cas prioritaire : fonction perso, qui permet aussi de gerer les cas historiques if (!isset($f_puce_statut[$type]) or is_null($f_puce_statut[$type])) { $f_puce_statut[$type] = charger_fonction($type, 'puce_statut', true); } if ($f_puce_statut[$type]) { return $f_puce_statut[$type]($id_objet, $statut, $id_parent, $type, $ajax, $menu_rapide); } elseif (!is_null($puce = puce_statut_changement_rapide($id_objet, $statut, $id_parent, $type, $ajax, $menu_rapide))) { return $puce; } else { return http_img_pack("{$type}-16.png", ''); } }
function exec_iconifier_args($id, $primary, $script, $iframe=false) { $type = objet_type(table_objet(substr($primary, 3))); if (!preg_match('/^\w+$/', "$primary$script") OR !autoriser('iconifier', $type, $id)) { include_spip('inc/minipres'); echo minipres(); } else { $iconifier = charger_fonction('iconifier', 'inc'); $ret = $iconifier($primary, $id, $script, $visible=true); if ($iframe!=='iframe') ajax_retour($ret); else { echo "<div class='upload_answer upload_document_added'>$ret</div>"; } } }?>
/** * Lister les compositions disponibles : toutes ou pour un type donne * Si informer est a false, on ne charge pas les infos du xml * * @param string $type * @param bool $informer * @return array */ function compositions_lister_disponibles($type, $informer=true){ include_spip('inc/compositions'); $type_match = ""; if (strlen($type)){ $type = objet_type($type); // securite $type_match = $type; } else { // _ pour le cas des groupe_mots $type_match = "[a-z0-9_]+"; } // rechercher les skel du type article-truc.html // truc ne doit pas commencer par un chiffre pour eviter de confondre avec article-12.html $match = "($type_match)("._COMPOSITIONS_MATCH.")?[.]html$"; // lister les compositions disponibles $liste = find_all_in_path(compositions_chemin(),$match); $res = array(); if (count($liste)){ foreach($liste as $s) { $base = preg_replace(',[.]html$,i','',$s); if (preg_match(",$match,ims",basename($s),$regs) AND ($composition = !$informer OR $composition = compositions_charger_infos($base))) { $regs = array_pad($regs, 4, null); $res[$regs[1]][$regs[3]] = $composition; // retenir les skels qui ont un xml associe } } } // Pipeline compositions_lister_disponibles $res = pipeline('compositions_lister_disponibles',array( 'args'=>array('type' => $type,'informer' => $informer), 'data'=> $res ) ); return $res; }
/** * Retourne le couple parent,lang pour toute table * en pratique id_rubrique si present (ou id_parent pour table rubriques) * et champ lang si present * * @param string $table * @param int $id * @param string $connect * @return array */ function quete_parent_lang($table, $id, $connect = '') { static $cache_quete = array(); if (!isset($cache_quete[$connect][$table][$id])) { if (!isset($cache_quete[$connect][$table]['_select'])) { $trouver_table = charger_fonction('trouver_table', 'base'); if (!($desc = $trouver_table($table, $connect)) or !isset($desc['field']['id_rubrique'])) { // pas de parent rubrique, on passe $cache_quete[$connect][$table]['_select'] = false; } else { $select = $table == 'spip_rubriques' ? 'id_parent' : 'id_rubrique'; $select .= isset($desc['field']['lang']) ? ", lang" : ""; $cache_quete[$connect][$table]['_select'] = $select; $cache_quete[$connect][$table]['_id'] = id_table_objet(objet_type($table)); } } if ($cache_quete[$connect][$table]['_select']) { $cache_quete[$connect][$table][$id] = sql_fetsel($cache_quete[$connect][$table]['_select'], $table, $cache_quete[$connect][$table]['_id'] . "=" . intval($id), '', '', '', '', $connect); } } return isset($cache_quete[$connect][$table][$id]) ? $cache_quete[$connect][$table][$id] : null; }
function suivre_invalideur($cond, $modif = true) { if (!$modif) { return; } // determiner l'objet modifie : forum, article, etc if (preg_match(',["\']([a-z_]+)[/"\'],', $cond, $r)) { $objet = objet_type($r[1]); } // stocker la date_modif_$objet (ne sert a rien pour le moment) if (isset($objet)) { ecrire_meta('derniere_modif_' . $objet, time()); } // si $derniere_modif_invalide est un array('article', 'rubrique') // n'affecter la meta que si un de ces objets est modifie if (is_array($GLOBALS['derniere_modif_invalide'])) { if (in_array($objet, $GLOBALS['derniere_modif_invalide'])) { ecrire_meta('derniere_modif', time()); } } else { ecrire_meta('derniere_modif', time()); } }
function inc_prix_ht($type_objet, $id_objet, $arrondi = '') { $prix_ht = 0; // Cherchons d'abord si l'objet existe bien if ($type_objet and $id_objet = intval($id_objet) and include_spip('base/connect_sql') and $type_objet = objet_type($type_objet) and $table_sql = table_objet_sql($type_objet) and $cle_objet = id_table_objet($type_objet) and $ligne = sql_fetsel('*', $table_sql, "{$cle_objet} = {$id_objet}")) { // Existe-t-il une fonction précise pour le prix HT de ce type d'objet : prix_ht_<objet>() dans prix/<objet>.php if ($fonction_ht = charger_fonction('ht', "prix/{$type_objet}", true)) { // On passe la ligne SQL en paramètre pour ne pas refaire la requête $prix_ht = $fonction_ht($id_objet, $ligne); } elseif ($ligne['prix_ht']) { $prix_ht = $ligne['prix_ht']; } elseif ($ligne['prix']) { $prix_ht = $ligne['prix']; } // Enfin on passe dans un pipeline pour modifier le prix HT $prix_ht = pipeline('prix_ht', array('args' => array('id_objet' => $id_objet, 'type_objet' => $type_objet, 'prix_ht' => $prix_ht), 'data' => $prix_ht)); } // Si on demande un arrondi, on le fait if ($arrondi) { $prix_ht = round($prix_ht, $arrondi); } return $prix_ht; }
function medias_post_edition($flux) { // le serveur n'est pas toujours la $serveur = isset($flux['args']['serveur']) ? $flux['args']['serveur'] : ''; // si on ajoute un document, mettre son statut a jour if ($flux['args']['action'] == 'ajouter_document') { include_spip('action/editer_document'); // mettre a jour le statut si necessaire document_instituer($flux['args']['id_objet']); } elseif ($flux['args']['table'] !== 'spip_documents') { $type = isset($flux['args']['type']) ? $flux['args']['type'] : objet_type($flux['args']['table']); // verifier d'abord les doublons ! include_spip('inc/autoriser'); if (autoriser('autoassocierdocument', $type, $flux['args']['id_objet'])) { $table_objet = isset($flux['args']['table_objet']) ? $flux['args']['table_objet'] : table_objet($flux['args']['table'], $serveur); $marquer_doublons_doc = charger_fonction('marquer_doublons_doc', 'inc'); $marquer_doublons_doc($flux['data'], $flux['args']['id_objet'], $type, id_table_objet($type, $serveur), $table_objet, $flux['args']['table'], '', $serveur); } if ($flux['args']['action'] == 'instituer' or isset($flux['data']['statut'])) { include_spip('base/abstract_sql'); $id = $flux['args']['id_objet']; $docs = array_map('reset', sql_allfetsel('id_document', 'spip_documents_liens', 'id_objet=' . intval($id) . ' AND objet=' . sql_quote($type))); include_spip('action/editer_document'); foreach ($docs as $id_document) { // mettre a jour le statut si necessaire document_instituer($id_document); } } } else { if ($flux['args']['table'] !== 'spip_documents') { // verifier les doublons ! $marquer_doublons_doc = charger_fonction('marquer_doublons_doc', 'inc'); $marquer_doublons_doc($flux['data'], $flux['args']['id_objet'], $flux['args']['type'], id_table_objet($flux['args']['type'], $serveur), $flux['args']['table_objet'], $flux['args']['spip_table_objet'], '', $serveur); } } return $flux; }
function base_trouver_table_dist($nom, $serveur=''){ static $nom_cache_desc_sql=array(); global $tables_principales, $tables_auxiliaires, $table_des_tables; if (!spip_connect($serveur) OR !preg_match('/^[a-zA-Z0-9._-]*/',$nom)) return null; $connexion = &$GLOBALS['connexions'][$serveur ? strtolower($serveur) : 0]; // le nom du cache depend du serveur mais aussi du nom de la db et du prefixe // ce qui permet une auto invalidation en cas de modif manuelle du fichier // de connexion, et tout risque d'ambiguite if (!isset($nom_cache_desc_sql[$serveur])) $nom_cache_desc_sql[$serveur] = _DIR_CACHE . 'sql_desc_' . ($serveur ? "$serveur_":"") . substr(md5($connexion['db'].":".$connexion['prefixe']),0,8) .'.txt'; // un appel avec $nom vide est une demande explicite de vidange du cache des descriptions if (!$nom){ spip_unlink($nom_cache_desc_sql[$serveur]); $connexion['tables'] = array(); return null; } $nom_sql = $nom; if (preg_match('/\.(.*)$/', $nom, $s)) $nom_sql = $s[1]; else $nom_sql = $nom; $desc = ''; // base sous SPIP: gerer les abreviations explicites des noms de table if ($connexion['spip_connect_version']) { include_spip('public/interfaces'); if (isset($table_des_tables[$nom])) { $nom = $table_des_tables[$nom]; $nom_sql = 'spip_' . $nom; } } // si c'est la premiere table qu'on cherche // et si on est pas explicitement en recalcul // on essaye de recharger le cache des decriptions de ce serveur // dans le fichier cache if (!isset($connexion['tables'][$nom]) AND $GLOBALS['var_mode']!=='recalcul' AND (!isset($connexion['tables']) OR !$connexion['tables'])) { if (lire_fichier($nom_cache_desc_sql[$serveur],$desc_cache) AND $desc_cache=unserialize($desc_cache)) $connexion['tables'] = $desc_cache; } if (!isset($connexion['tables'][$nom])) { include_spip('base/serial'); if (isset($tables_principales[$nom_sql])) $fdesc = $tables_principales[$nom_sql]; // meme si pas d'abreviation declaree, trouver la table spip_$nom // si c'est une table principale, // puisqu'on le fait aussi pour les tables auxiliaires elseif ($nom_sql==$nom AND isset($tables_principales['spip_' .$nom])){ $nom_sql = 'spip_' . $nom; $fdesc = &$tables_principales[$nom_sql]; } else { include_spip('base/auxiliaires'); if (isset($tables_auxiliaires['spip_' .$nom])) { $nom_sql = 'spip_' . $nom; $fdesc = &$tables_auxiliaires[$nom_sql]; } else { # table locale a cote de SPIP, comme non SPIP: $fdesc = array(); } } // faut il interpreter le prefixe 'spip_' ? $transposer_spip = ($nom_sql != $nom); // La *vraie* base a la priorite if (true /* !$bdesc OR !$bdesc['field'] */) { $desc = sql_showtable($nom_sql, $transposer_spip, $serveur); if (!$desc OR !$desc['field']) { if (!$fdesc) { spip_log("trouver_table: table inconnue '$serveur' '$nom'"); return null; } // on ne sait pas lire la structure de la table : // on retombe sur la description donnee dans les fichiers spip $desc = $fdesc; } } // S'il n'y a pas de key (cas d'une VIEW), // on va inventer une PRIMARY KEY en prenant le premier champ // de la table if (!$desc['key']){ $p = array_keys($desc['field']); $desc['key']['PRIMARY KEY'] = array_shift($p); } $desc['table']= $nom_sql; $desc['connexion']= $serveur; // objet_type peut provoquer un appel reentrant ici. // pour ne pas faire de boucle infinie, on stocke ce qu'on a deja trouve $connexion['tables'][$nom] = $desc; $table = table_objet(objet_type($nom)); $desc['titre'] = isset($GLOBALS['table_titre'][$table]) ? $GLOBALS['table_titre'][$table] : (isset($desc['field']['titre']) ? 'titre' : ''); $connexion['tables'][$nom] = $desc; // une nouvelle table a ete decrite // mettons donc a jour le cache des descriptions de ce serveur if (is_writeable(_DIR_CACHE)) ecrire_fichier($nom_cache_desc_sql[$serveur],serialize($connexion['tables'])); } $connexion['tables'][$nom]['id_table']=$nom; return $connexion['tables'][$nom]; }
/** * Fonction codant et décodant les URLs des objets SQL mis en page par SPIP * * @api * @param string $id * numero de la cle primaire si nombre, URL a decoder si pas numerique * @param string $entite * surnom de la table SQL (donne acces au nom de cle primaire) * @param string $args * query_string a placer apres cle=$id&.... * @param string $ancre * ancre a mettre a la fin de l'URL a produire * @param bool|string $public * produire l'URL publique ou privee (par defaut: selon espace) * si string : serveur de base de donnee (nom du connect) * @param string $type * fichier dans le repertoire ecrire/urls determinant l'apparence * @return string|array * url codee ou fonction de decodage * array : derogatoire, la fonction d'url retourne (objet,id_objet) utilises par nettoyer_raccourcis_typo() pour generer un lien titre * (cas des raccourcis personalises [->spip20] : il faut implementer une fonction generer_url_spip et une fonction generer_url_ecrire_spip) */ function generer_url_entite($id = '', $entite = '', $args = '', $ancre = '', $public = NULL, $type = NULL) { if ($public === NULL) { $public = !test_espace_prive(); } $entite = objet_type($entite); // cas particulier d'appels sur objet/id_objet... if (!$public) { if (!$entite) { return ''; } if (!function_exists('generer_url_ecrire_objet')) { include_spip('inc/urls'); } $res = generer_url_ecrire_objet($entite, $id, $args, $ancre, false); } else { if ($type === NULL) { $type = isset($GLOBALS['type_urls']) ? $GLOBALS['type_urls'] : (isset($GLOBALS['meta']['type_urls']) ? $GLOBALS['meta']['type_urls'] : "page"); // sinon type "page" par défaut } $f = charger_fonction($type, 'urls', true); // se rabattre sur les urls page si les urls perso non dispo if (!$f) { $f = charger_fonction('page', 'urls', true); } // si $entite='', on veut la fonction de passage URL ==> id // sinon on veut effectuer le passage id ==> URL if (!$entite) { return $f; } // mais d'abord il faut tester le cas des urls sur une // base distante if (is_string($public) and $g = charger_fonction('connect', 'urls', true)) { $f = $g; } $res = $f(intval($id), $entite, $args, $ancre, $public); } if ($res) { return $res; } // Sinon c'est un raccourci ou compat SPIP < 2 if (!function_exists($f = 'generer_url_' . $entite)) { if (!function_exists($f .= '_dist')) { $f = ''; } } if ($f) { $url = $f($id, $args, $ancre); if (strlen($args)) { $url .= strstr($url, '?') ? '&' . $args : '?' . $args; } return $url; } // On a ete gentil mais la .... spip_log("generer_url_entite: entite {$entite} ({$f}) inconnue {$type} {$public}"); return ''; }
function cextras_pre_edition($flux){ // recuperer les champs crees par les plugins if ($extras = cextras_get_extras_match($flux['args']['table'])) { // recherchons un eventuel prefixe utilise pour poster les champs $type = objet_type(table_objet($flux['args']['table'])); $prefixe = _request('prefixe_champs_extras_' . $type); if (!$prefixe) { $prefixe = ''; } foreach ($extras as $c) { if (_request('cextra_' . $prefixe . $c->champ)) { $extra = _request($prefixe . $c->champ); if (is_array($extra)) $extra = join(',',$extra); $flux['data'][$c->champ] = corriger_caracteres($extra); } } } return $flux; }
/** * Retourne le type de logo tel que `art` depuis le nom de clé primaire * de l'objet * * C'est par défaut le type d'objet, mais il existe des exceptions historiques * déclarées par la globale `$table_logos` * * @global table_logos Exceptions des types de logo * * @param string $_id_objet * Nom de la clé primaire de l'objet * @return string * Type du logo **/ function type_du_logo($_id_objet) { return isset($GLOBALS['table_logos'][$_id_objet]) ? $GLOBALS['table_logos'][$_id_objet] : objet_type(preg_replace(',^id_,', '', $_id_objet)); }
/** * Autoriser une action * * Voir autoriser() pour une description complète * * @see autoriser() * * @param string $faire * une action ('modifier', 'publier'...) * @param string $type * type d'objet ou nom de table ('article') * @param int $id * id de l'objet sur lequel on veut agir * @param null|int|array $qui * si null on prend alors visiteur_session * un id_auteur (on regarde dans la base) * un tableau auteur complet, y compris [restreint] * @param null|array $opt * options sous forme de tableau associatif * @return bool * true si la personne peut effectuer l'action */ function autoriser_dist($faire, $type = '', $id = 0, $qui = NULL, $opt = NULL) { // Qui ? visiteur_session ? // si null ou '' (appel depuis #AUTORISER) on prend l'auteur loge if ($qui === NULL or $qui === '') { $qui = $GLOBALS['visiteur_session'] ? $GLOBALS['visiteur_session'] : array('statut' => '', 'id_auteur' => 0, 'webmestre' => 'non'); } elseif (is_numeric($qui)) { $qui = sql_fetsel("*", "spip_auteurs", "id_auteur=" . $qui); } // Admins restreints, on construit ici (pas generique mais...) // le tableau de toutes leurs rubriques (y compris les sous-rubriques) if (_ADMINS_RESTREINTS and is_array($qui)) { $qui['restreint'] = isset($qui['id_auteur']) ? liste_rubriques_auteur($qui['id_auteur']) : array(); } spip_log("autoriser {$faire} {$type} {$id} (" . (isset($qui['nom']) ? $qui['nom'] : '') . ") ?", "autoriser" . _LOG_DEBUG); // passer par objet_type pour avoir les alias // et supprimer les _ $type = str_replace('_', '', strncmp($type, "_", 1) == 0 ? $type : objet_type($type, false)); // Si une exception a ete decretee plus haut dans le code, l'appliquer if (isset($GLOBALS['autoriser_exception'][$faire][$type][$id]) and autoriser_exception($faire, $type, $id, 'verifier')) { return true; } // Chercher une fonction d'autorisation // Dans l'ordre on va chercher autoriser_type_faire[_dist], autoriser_type[_dist], // autoriser_faire[_dist], autoriser_defaut[_dist] $fonctions = $type ? array('autoriser_' . $type . '_' . $faire, 'autoriser_' . $type . '_' . $faire . '_dist', 'autoriser_' . $type, 'autoriser_' . $type . '_dist', 'autoriser_' . $faire, 'autoriser_' . $faire . '_dist', 'autoriser_defaut', 'autoriser_defaut_dist') : array('autoriser_' . $faire, 'autoriser_' . $faire . '_dist', 'autoriser_defaut', 'autoriser_defaut_dist'); foreach ($fonctions as $f) { if (function_exists($f)) { $a = $f($faire, $type, $id, $qui, $opt); break; } } spip_log("{$f}({$faire},{$type},{$id}," . (isset($qui['nom']) ? $qui['nom'] : '') . "): " . ($a ? 'OK' : 'niet'), "autoriser" . _LOG_DEBUG); return $a; }
/** * 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'); } $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); }