Exemple #1
0
/**
 * Chargement du formulaire d'édition de liens
 *
 * #FORMULAIRE_EDITER_LIENS{auteurs,article,23}
 *   pour associer des auteurs à l'article 23, sur la table pivot spip_auteurs_liens
 * #FORMULAIRE_EDITER_LIENS{article,23,auteurs}
 *   pour associer des auteurs à l'article 23, sur la table pivot spip_articles_liens
 * #FORMULAIRE_EDITER_LIENS{articles,auteur,12}
 *   pour associer des articles à l'auteur 12, sur la table pivot spip_articles_liens
 * #FORMULAIRE_EDITER_LIENS{auteur,12,articles}
 *   pour associer des articles à l'auteur 12, sur la table pivot spip_auteurs_liens
 *
 * @param string $a
 * @param string|int $b
 * @param int|string $c
 * @param bool $editable
 * @return array
 */
function formulaires_editer_liens_charger_dist($a, $b, $c, $editable = true)
{
    list($table_source, $objet, $id_objet, $objet_lien) = determine_source_lien_objet($a, $b, $c);
    if (!$table_source or !$objet or !$objet_lien or !$id_objet) {
        return false;
    }
    $objet_source = objet_type($table_source);
    $table_sql_source = table_objet_sql($objet_source);
    // verifier existence de la table xxx_liens
    include_spip('action/editer_liens');
    if (!objet_associable($objet_lien)) {
        return false;
    }
    // L'éditabilité :) est définie par un test permanent (par exemple "associermots") ET le 4ème argument
    $editable = ($editable and autoriser('associer' . $table_source, $objet, $id_objet));
    if (!$editable and !count(objet_trouver_liens(array($objet_lien => '*'), array($objet_lien == $objet_source ? $objet : $objet_source => '*')))) {
        return false;
    }
    $valeurs = array('id' => "{$table_source}-{$objet}-{$id_objet}-{$objet_lien}", '_vue_liee' => $table_source . "_lies", '_vue_ajout' => $table_source . "_associer", '_objet_lien' => $objet_lien, 'id_lien_ajoute' => _request('id_lien_ajoute'), 'objet' => $objet, 'id_objet' => $id_objet, 'objet_source' => $objet_source, 'table_source' => $table_source, 'recherche' => '', 'visible' => 0, 'ajouter_lien' => '', 'supprimer_lien' => '', '_oups' => _request('_oups'), 'editable' => $editable);
    return $valeurs;
}
Exemple #2
0
function inc_recherche_to_array_dist($recherche, $options = array())
{
    // options par defaut
    $options = array_merge(array('score' => true, 'champs' => false, 'toutvoir' => false, 'matches' => false, 'jointures' => false), $options);
    include_spip('inc/rechercher');
    include_spip('inc/autoriser');
    $requete = array("SELECT" => array(), "FROM" => array(), "WHERE" => array(), "GROUPBY" => array(), "ORDERBY" => array(), "LIMIT" => "", "HAVING" => array());
    $table = sinon($options['table'], 'article');
    if ($options['champs']) {
        $champs = $options['champs'];
    } else {
        $l = liste_des_champs();
        $champs = $l['article'];
    }
    $serveur = $options['serveur'];
    list($methode, $q, $preg) = expression_recherche($recherche, $options);
    $jointures = $options['jointures'] ? liste_des_jointures() : array();
    $_id_table = id_table_objet($table);
    // c'est un pis-aller : ca a peu de chance de marcher, mais mieux quand meme que en conservant la ','
    // (aka ca marche au moins dans certains cas comme avec spip_formulaires_reponses_champs)
    if (strpos($_id_table, ",") !== false) {
        $_id_table = explode(',', $_id_table);
        $_id_table = reset($_id_table);
    }
    $requete['SELECT'][] = "t." . $_id_table;
    $a = array();
    // Recherche fulltext
    foreach ($champs as $champ => $poids) {
        if (is_array($champ)) {
            spip_log("requetes imbriquees interdites");
        } else {
            if (strpos($champ, ".") === FALSE) {
                $champ = "t.{$champ}";
            }
            $requete['SELECT'][] = $champ;
            $a[] = $champ . ' ' . $methode . ' ' . $q;
        }
    }
    if ($a) {
        $requete['WHERE'][] = join(" OR ", $a);
    }
    $requete['FROM'][] = table_objet_sql($table) . ' AS t';
    $results = array();
    $s = sql_select($requete['SELECT'], $requete['FROM'], $requete['WHERE'], implode(" ", $requete['GROUPBY']), $requete['ORDERBY'], $requete['LIMIT'], $requete['HAVING'], $serveur);
    while ($t = sql_fetch($s, $serveur) and (!isset($t['score']) or $t['score'] > 0)) {
        $id = intval($t[$_id_table]);
        if ($options['toutvoir'] or autoriser('voir', $table, $id)) {
            // indiquer les champs concernes
            $champs_vus = array();
            $score = 0;
            $matches = array();
            $vu = false;
            foreach ($champs as $champ => $poids) {
                $champ = explode('.', $champ);
                $champ = end($champ);
                // translitteration_rapide uniquement si on est deja en utf-8
                $value = $GLOBALS['meta']['charset'] == 'utf-8' ? translitteration_rapide($t[$champ]) : translitteration($t[$champ]);
                if ($n = $options['score'] || $options['matches'] ? preg_match_all($preg, $value, $regs, PREG_SET_ORDER) : preg_match($preg, $value)) {
                    $vu = true;
                    if ($options['champs']) {
                        $champs_vus[$champ] = $t[$champ];
                    }
                    if ($options['score']) {
                        $score += $n * $poids;
                    }
                    if ($options['matches']) {
                        $matches[$champ] = $regs;
                    }
                    if (!$options['champs'] and !$options['score'] and !$options['matches']) {
                        break;
                    }
                }
            }
            if ($vu) {
                if (!isset($results)) {
                    $results = array();
                }
                $results[$id] = array();
                if ($champs_vus) {
                    $results[$id]['champs'] = $champs_vus;
                }
                if ($score) {
                    $results[$id]['score'] = $score;
                }
                if ($matches) {
                    $results[$id]['matches'] = $matches;
                }
            }
        }
    }
    // Gerer les donnees associees
    // ici on est un peu naze : pas capables de reconstruire une jointure complexe
    // on ne sait passer que par table de laison en 1 coup
    if (isset($jointures[$table]) and $joints = recherche_en_base($recherche, $jointures[$table], array_merge($options, array('jointures' => false)))) {
        include_spip('action/editer_liens');
        $trouver_table = charger_fonction('trouver_table', 'base');
        $cle_depart = id_table_objet($table);
        $table_depart = table_objet($table, $serveur);
        $desc_depart = $trouver_table($table_depart, $serveur);
        $depart_associable = objet_associable($table);
        foreach ($joints as $table_liee => $ids_trouves) {
            // on peut definir une fonction de recherche jointe pour regler les cas particuliers
            if (!($rechercher_joints = charger_fonction("rechercher_joints_{$table}_{$table_liee}", "inc", true) or $rechercher_joints = charger_fonction("rechercher_joints_objet_{$table_liee}", "inc", true) or $rechercher_joints = charger_fonction("rechercher_joints_{$table}_objet_lie", "inc", true))) {
                $cle_arrivee = id_table_objet($table_liee);
                $table_arrivee = table_objet($table_liee, $serveur);
                $desc_arrivee = $trouver_table($table_arrivee, $serveur);
                // cas simple : $cle_depart dans la table_liee
                if (isset($desc_arrivee['field'][$cle_depart])) {
                    $s = sql_select("{$cle_depart}, {$cle_arrivee}", $desc_arrivee['table_sql'], sql_in($cle_arrivee, array_keys($ids_trouves)), '', '', '', '', $serveur);
                } elseif (isset($desc_depart['field'][$cle_arrivee])) {
                    $s = sql_select("{$cle_depart}, {$cle_arrivee}", $desc_depart['table_sql'], sql_in($cle_arrivee, array_keys($ids_trouves)), '', '', '', '', $serveur);
                } elseif ($l = objet_associable($table_liee)) {
                    list($primary, $table_liens) = $l;
                    $s = sql_select("id_objet as {$cle_depart}, {$primary} as {$cle_arrivee}", $table_liens, array("objet='{$table}'", sql_in($primary, array_keys($ids_trouves))), '', '', '', '', $serveur);
                } elseif ($l = $depart_associable) {
                    list($primary, $table_liens) = $l;
                    $s = sql_select("{$primary} as {$cle_depart}, id_objet as {$cle_arrivee}", $table_liens, array("objet='{$table_liee}'", sql_in('id_objet', array_keys($ids_trouves))), '', '', '', '', $serveur);
                } elseif ($t = $trouver_table($table_arrivee . "_" . $table_depart, $serveur) or $t = $trouver_table($table_depart . "_" . $table_arrivee, $serveur)) {
                    $s = sql_select("{$cle_depart},{$cle_arrivee}", $t["table_sql"], sql_in($cle_arrivee, array_keys($ids_trouves)), '', '', '', '', $serveur);
                }
            } else {
                list($cle_depart, $cle_arrivee, $s) = $rechercher_joints($table, $table_liee, array_keys($ids_trouves), $serveur);
            }
            while ($t = is_array($s) ? array_shift($s) : sql_fetch($s)) {
                $id = $t[$cle_depart];
                $joint = $ids_trouves[$t[$cle_arrivee]];
                if (!isset($results)) {
                    $results = array();
                }
                if (!isset($results[$id])) {
                    $results[$id] = array();
                }
                if (isset($joint['score']) and $joint['score']) {
                    if (!isset($results[$id]['score'])) {
                        $results[$id]['score'] = 0;
                    }
                    $results[$id]['score'] += $joint['score'];
                }
                if (isset($joint['champs']) and $joint['champs']) {
                    foreach ($joint['champs'] as $c => $val) {
                        $results[$id]['champs'][$table_liee . '.' . $c] = $val;
                    }
                }
                if (isset($joint['matches']) and $joint['matches']) {
                    foreach ($joint['matches'] as $c => $val) {
                        $results[$id]['matches'][$table_liee . '.' . $c] = $val;
                    }
                }
            }
        }
    }
    return $results;
}
Exemple #3
0
/**
 * Lorsqu'un champ versionée est une jointure, récuperer tous les liens
 * et les mettre sous forme de liste énumérée
 * 
 * @param string $objet
 * @param string $id_objet
 * @param string $jointure
 * @return string
 */
function recuperer_valeur_champ_jointure($objet, $id_objet, $jointure)
{
    $objet_joint = objet_type($jointure);
    include_spip('action/editer_liens');
    $v = array();
    if (objet_associable($objet_joint)) {
        $liens = objet_trouver_liens(array($objet_joint => '*'), array($objet => $id_objet));
        foreach ($liens as $l) {
            $v[] = $l[$objet_joint];
        }
    } elseif (objet_associable($objet)) {
        $liens = objet_trouver_liens(array($objet => $id_objet), array($objet_joint => '*'));
        foreach ($liens as $l) {
            $v[] = $l[$objet];
        }
    }
    sort($v);
    return implode(",", $v);
}
Exemple #4
0
/**
 * Optimiser la base de donnee en supprimant les forums orphelins
 *
 * @param int $n
 * @return int
 */
function forum_optimiser_base_disparus($flux)
{
    $n =& $flux['data'];
    $mydate = $flux['args']['date'];
    # les forums lies a une id_objet inexistant
    $r = sql_select("DISTINCT objet", 'spip_forum');
    while ($t = sql_fetch($r)) {
        if ($type = $t['objet']) {
            $spip_table_objet = table_objet_sql($type);
            $id_table_objet = id_table_objet($type);
            # les forums lies a un objet inexistant
            $res = sql_select("forum.id_forum AS id", "spip_forum AS forum\n\t\t\t\t\t\t\t\tLEFT JOIN {$spip_table_objet} AS O\n\t\t\t\t\t\t\t\t\tON O.{$id_table_objet}=forum.id_objet", "forum.objet=" . sql_quote($type) . " AND O.{$id_table_objet} IS NULL AND forum.id_objet>0");
            $n += optimiser_sansref('spip_forum', 'id_forum', $res);
        }
    }
    //
    // Forums
    //
    sql_delete("spip_forum", "statut='redac' AND maj < {$mydate}");
    // nettoyer les documents des forums en spam&poubelle pour eviter de sortir des quota disques
    // bizarrement on ne nettoie jamais les messages eux meme ?
    include_spip('action/editer_liens');
    if (objet_associable('document')) {
        $res = sql_select('L.id_document,F.id_forum', "spip_documents_liens AS L JOIN spip_forum AS F ON (F.id_forum=L.id_objet AND L.objet='forum')", "F.statut IN ('off','spam')");
        while ($row = sql_fetch($res)) {
            include_spip('inc/autoriser');
            // si un seul lien (ce forum donc), on supprime le document
            // si un document est attache a plus d'un forum, c'est un cas bizarre ou gere a la main
            // on ne touche a rien !
            if (count(objet_trouver_liens(array('document' => $row['id_document']), '*')) == 1) {
                autoriser_exception('supprimer', 'document', $row['id_document']);
                if ($supprimer_document = charger_fonction('supprimer_document', 'action', true)) {
                    $supprimer_document($row['id_document']);
                }
            }
        }
    }
    //
    // CNIL -- Informatique et libertes
    //
    // masquer le numero IP des vieux forums
    //
    ## date de reference = 4 mois
    ## definir a 0 pour desactiver
    if (!defined('_CNIL_PERIODE')) {
        define('_CNIL_PERIODE', 3600 * 24 * 31 * 4);
    }
    if (_CNIL_PERIODE) {
        $critere_cnil = 'date_heure<"' . date('Y-m-d', time() - _CNIL_PERIODE) . '"' . ' AND statut != "spam"' . ' AND (ip LIKE "%.%" OR ip LIKE "%:%")';
        # ipv4 ou ipv6
        $c = sql_countsel('spip_forum', $critere_cnil);
        if ($c > 0) {
            spip_log("CNIL: masquer IP de {$c} forums anciens");
            sql_update('spip_forum', array('ip' => 'MD5(ip)'), $critere_cnil);
        }
    }
    return $flux;
}
Exemple #5
0
/**
 * Lister des rôles connus en base pour une liaion, pour un objet source
 *
 * On retourne cette liste dans le datalist de saisie libre role.
 *
 * @param string $objet_source Objet dont on veut récupérer la liste des identifiants
 * @param string $objet Objet sur lequel est liée la source
 * @param string $objet_lien Objet dont on utilise la table de liaison (c'est forcément soit $objet_source, soit $objet)
 * @return array|bool
 *     - Tableau de roles : tableau de description des roles,
 *     - false si pas de role déclarés
 */
function roles_connus_en_base($objet_source, $objet, $objet_lien)
{
    static $done = array();
    // stocker le résultat
    $hash = "{$objet_source}-{$objet}-{$objet_lien}";
    if (isset($done[$hash])) {
        return $done[$hash];
    }
    if (!($lien = objet_associable($objet_lien))) {
        return $done[$hash] = false;
    }
    // pas de roles sur ces objets, on sort
    $roles = roles_presents($objet_lien, $objet_lien == $objet ? $objet_source : $objet);
    if (!$roles) {
        return $done[$hash] = false;
    }
    list($primary, $l) = $lien;
    $colone_role = $roles['colonne'];
    $all = sql_allfetsel("DISTINCT {$colone_role}", $l, "objet=" . sql_quote($objet_source == $objet_lien ? $objet : $objet_source));
    $done[$hash] = array_map("reset", $all);
    return $done[$hash];
}
Exemple #6
0
/**
 * Chargement du formulaire d'édition de liens
 *
 * #FORMULAIRE_EDITER_LIENS{auteurs,article,23}
 *   pour associer des auteurs à l'article 23, sur la table pivot spip_auteurs_liens
 * #FORMULAIRE_EDITER_LIENS{article,23,auteurs}
 *   pour associer des auteurs à l'article 23, sur la table pivot spip_articles_liens
 * #FORMULAIRE_EDITER_LIENS{articles,auteur,12}
 *   pour associer des articles à l'auteur 12, sur la table pivot spip_articles_liens
 * #FORMULAIRE_EDITER_LIENS{auteur,12,articles}
 *   pour associer des articles à l'auteur 12, sur la table pivot spip_auteurs_liens
 *
 * @param string $a
 * @param string|int $b
 * @param int|string $c
 * @param array|bool $options
 *    - Si array, tableau d'options
 *    - Si bool : valeur de l'option 'editable' uniquement
 *
 * @return array
 */
function formulaires_editer_liens_charger_dist($a, $b, $c, $options = array())
{
    // compat avec ancienne signature ou le 4eme argument est $editable
    if (!is_array($options)) {
        $options = array('editable' => $options);
    } elseif (!isset($options['editable'])) {
        $options['editable'] = true;
    }
    $editable = $options['editable'];
    list($table_source, $objet, $id_objet, $objet_lien) = determine_source_lien_objet($a, $b, $c);
    if (!$table_source or !$objet or !$objet_lien or !$id_objet) {
        return false;
    }
    $objet_source = objet_type($table_source);
    $table_sql_source = table_objet_sql($objet_source);
    // verifier existence de la table xxx_liens
    include_spip('action/editer_liens');
    if (!objet_associable($objet_lien)) {
        return false;
    }
    // L'éditabilité :) est définie par un test permanent (par exemple "associermots") ET le 4ème argument
    include_spip('inc/autoriser');
    $editable = ($editable and autoriser('associer' . $table_source, $objet, $id_objet) and autoriser('modifier', $objet, $id_objet));
    if (!$editable and !count(objet_trouver_liens(array($objet_lien => '*'), array($objet_lien == $objet_source ? $objet : $objet_source => '*')))) {
        return false;
    }
    // squelettes de vue et de d'association
    // ils sont différents si des rôles sont définis.
    $skel_vue = $table_source . "_lies";
    $skel_ajout = $table_source . "_associer";
    // description des roles
    include_spip('inc/roles');
    if ($roles = roles_presents($objet_source, $objet)) {
        // on demande de nouveaux squelettes en conséquence
        $skel_vue = $table_source . "_roles_lies";
        $skel_ajout = $table_source . "_roles_associer";
    }
    $valeurs = array('id' => "{$table_source}-{$objet}-{$id_objet}-{$objet_lien}", '_vue_liee' => $skel_vue, '_vue_ajout' => $skel_ajout, '_objet_lien' => $objet_lien, 'id_lien_ajoute' => _request('id_lien_ajoute'), 'objet' => $objet, 'id_objet' => $id_objet, 'objet_source' => $objet_source, 'table_source' => $table_source, 'recherche' => '', 'visible' => 0, 'ajouter_lien' => '', 'supprimer_lien' => '', 'qualifier_lien' => '', '_roles' => $roles, '_oups' => _request('_oups'), 'editable' => $editable);
    // les options non definies dans $valeurs sont passees telles quelles au formulaire html
    $valeurs = array_merge($options, $valeurs);
    return $valeurs;
}
/**
 * Fonction générique qui
 * applique une operation de liaison entre un ou des objets et des objets listés
 *
 * $objets_source et $objets_lies sont de la forme
 * array($objet=>$id_objets,...)
 * $id_objets peut lui meme etre un scalaire ou un tableau pour une liste d'objets du meme type
 *
 * Les objets sources sont les pivots qui portent les liens
 * et pour lesquels une table spip_xxx_liens existe
 * (auteurs, documents, mots)
 *
 * on peut passer optionnellement une qualification du (des) lien(s) qui sera
 * alors appliquee dans la foulee.
 * En cas de lot de liens, c'est la meme qualification qui est appliquee a tous
 *
 * @internal
 * @param string $operation
 *     Nom de la fonction PHP qui traitera l'opération
 * @param array $objets_source
 *     Liste de ou des objets source
 *     De la forme array($objet=>$id_objets,...), où $id_objets peut lui
 *     même être un scalaire ou un tableau pour une liste d'objets du même type
 * @param array $objets_lies
 *     Liste de ou des objets liés
 *     De la forme array($objet=>$id_objets,...), où $id_objets peut lui
 *     même être un scalaire ou un tableau pour une liste d'objets du même type
 * @param null|array $set
 *     Liste de coupels champs valeur, soit array(champs => valeur)
 *     En fonction des opérations il peut servir à différentes utilisations
 * @return bool|int|array
 */
function objet_traiter_liaisons($operation, $objets_source, $objets_lies, $set = null)
{
    // accepter une syntaxe minimale pour supprimer tous les liens
    if ($objets_lies == '*') {
        $objets_lies = array('*' => '*');
    }
    $modifs = 0;
    // compter le nombre de modifications
    $echec = null;
    foreach ($objets_source as $objet => $ids) {
        if ($a = objet_associable($objet)) {
            list($primary, $l) = $a;
            if (!is_array($ids)) {
                $ids = array($ids);
            } elseif (reset($ids) == "NOT") {
                // si on demande un array('NOT',...) => recuperer la liste d'ids correspondants
                $where = lien_where($primary, $ids, '*', '*');
                $ids = sql_allfetsel($primary, $l, $where);
                $ids = array_map('reset', $ids);
            }
            foreach ($ids as $id) {
                $res = $operation($objet, $primary, $l, $id, $objets_lies, $set);
                if ($res === false) {
                    spip_log("objet_traiter_liaisons [Echec] : {$operation} sur {$objet}/{$primary}/{$l}/{$id}", _LOG_ERREUR);
                    $echec = true;
                } else {
                    $modifs = $modifs ? is_array($res) ? array_merge($modifs, $res) : $modifs + $res : $res;
                }
            }
        } else {
            $echec = true;
        }
    }
    return $echec ? false : $modifs;
    // pas d'erreur
}