Exemple #1
0
function ajouter_version($id_objet, $objet, $champs, $titre_version = "", $id_auteur)
{
    $paras = $paras_old = $paras_champ = $fragments = array();
    // Attention a une edition anonyme (type wiki): id_auteur n'est pas
    // definie, on enregistre alors le numero IP
    $str_auteur = intval($id_auteur) ? intval($id_auteur) : $GLOBALS['ip'];
    // si pas de titre dans cette version, la marquer 'non' permanente,
    // et elle pourra etre fusionnee avec une revision ulterieure dans un delai < _INTERVALLE_REVISIONS
    // permet de fusionner plusieurs editions consecutives champs par champs avec les crayons
    $permanent = empty($titre_version) ? 'non' : '';
    // Detruire les tentatives d'archivages non abouties en 1 heure
    sql_delete('spip_versions', "id_objet=" . intval($id_objet) . " AND objet=" . sql_quote($objet) . " AND id_version <= 0 AND date < DATE_SUB(" . sql_quote(date('Y-m-d H:i:s')) . ", INTERVAL " . _INTERVALLE_REVISIONS . " SECOND)");
    // Signaler qu'on opere en mettant un numero de version negatif
    // distinctif (pour eviter la violation d'unicite)
    // et un titre contenant en fait le moment de l'insertion
    list($ms, $sec) = explode(' ', microtime());
    $date = $sec . substr($ms, 1, 4);
    // SQL ne ramene que 4 chiffres significatifs apres la virgule pour 0.0+titre_version
    $datediff = ($sec - mktime(0, 0, 0, 9, 1, 2007)) * 1000000 + substr($ms, 2, strlen($ms) - 4);
    $valeurs = array('id_objet' => $id_objet, 'objet' => $objet, 'id_version' => 0 - $datediff, 'date' => date('Y-m-d H:i:s'), 'id_auteur' => $str_auteur, 'titre_version' => $date);
    sql_insertq('spip_versions', $valeurs);
    // Eviter les validations entremelees en s'endormant s'il existe
    // une version <0 plus recente mais pas plus vieille que 10s
    // Une <0 encore plus vieille est une operation avortee,
    // on passe outre (vaut mieux archiver mal que pas du tout).
    // Pour tester:
    // 0. mettre le delai a 30
    // 1. decommenter le premier sleep(15)
    // 2. enregistrer une modif
    // 3. recommenter le premier sleep(15), decommenter le second.
    // 4. enregistrer une autre modif dans les 15 secondes
    # 	  sleep(15);
    $delai = $sec - 10;
    while (sql_countsel('spip_versions', "id_objet=" . intval($id_objet) . " AND objet=" . sql_quote($objet) . " AND id_version < 0 AND 0.0+titre_version < {$date} AND titre_version<>" . sql_quote($date, '', 'text') . " AND 0.0+titre_version > {$delai}")) {
        spip_log("version {$objet} {$id_objet} :insertion en cours avant {$date} ({$delai})");
        sleep(1);
        $delai++;
    }
    #   sleep(15); 	spip_log("sortie $sec $delai");
    // Determiner le numero du prochain fragment
    $next = sql_fetsel("id_fragment", "spip_versions_fragments", "id_objet=" . intval($id_objet) . " AND objet=" . sql_quote($objet), "", "id_fragment DESC", "1");
    $onlylock = '';
    // Examiner la derniere version
    $row = sql_fetsel("id_version, champs, id_auteur, date, permanent", "spip_versions", "id_objet=" . intval($id_objet) . " AND objet=" . sql_quote($objet) . " AND id_version > 0", '', "id_version DESC", "1");
    // le champ id_auteur est un varchar dans cette table
    if ($row) {
        $id_version = $row['id_version'];
        $paras_old = recuperer_fragments($id_objet, $objet, $id_version);
        $champs_old = $row['champs'];
        if ($row['id_auteur'] != $str_auteur or $row['permanent'] != 'non' or strtotime($row['date']) < time() - _INTERVALLE_REVISIONS) {
            spip_log(strtotime($row['date']), 'revisions');
            spip_log(time(), 'revisions');
            spip_log(_INTERVALLE_REVISIONS, 'revisions');
            $id_version++;
        } else {
            $champs = reconstuire_version(unserialize($champs_old), $paras_old, $champs);
            $onlylock = 're';
        }
    } else {
        $id_version = 1;
    }
    spip_log($str_auteur, 'revisions');
    spip_log($row, 'revisions');
    spip_log($id_version, 'revisions');
    $next = !$next ? 1 : $next['id_fragment'] + 1;
    // Generer les nouveaux fragments
    $codes = array();
    foreach ($champs as $nom => $texte) {
        $codes[$nom] = array();
        $paras = separer_paras($texte, $paras);
        $paras_champ[$nom] = count($paras);
    }
    // Apparier les fragments de maniere optimale
    $n = count($paras);
    if ($n) {
        // Tables d'appariement dans les deux sens
        list(, $trans) = apparier_paras($paras_old, $paras);
        reset($champs);
        $nom = '';
        // eviter une notice PHP au tout debut de la boucle
        // on ajoute ''=>0 en debut de tableau.
        $paras_champ = array($nom => 0) + $paras_champ;
        for ($i = 0; $i < $n; $i++) {
            while ($i >= $paras_champ[$nom]) {
                list($nom, ) = each($champs);
            }
            // Lier au fragment existant si possible, sinon creer un nouveau fragment
            $id_fragment = isset($trans[$i]) ? $trans[$i] : $next++;
            $codes[$nom][] = $id_fragment;
            $fragments[$id_fragment] = $paras[$i];
        }
    }
    foreach ($champs as $nom => $t) {
        $codes[$nom] = join(' ', $codes[$nom]);
        # avec la ligne qui suit, un champ qu'on vide ne s'enregistre pas
        # if (!strlen($codes[$nom])) unset($codes[$nom]);
    }
    // Enregistrer les modifications
    ajouter_fragments($id_objet, $objet, $id_version, $fragments);
    // Si l'insertion ne servait que de verrou,
    // la detruire apres mise a jour de l'ancienne entree,
    // sinon la mise a jour efface en fait le verrou.
    if (!$onlylock) {
        sql_updateq('spip_versions', array('id_version' => $id_version, 'date' => date('Y-m-d H:i:s'), 'champs' => serialize($codes), 'permanent' => $permanent, 'titre_version' => $titre_version), "id_objet=" . intval($id_objet) . " AND objet=" . sql_quote($objet) . " AND id_version < 0 AND titre_version='{$date}'");
    } else {
        sql_updateq('spip_versions', array('date' => date('Y-m-d H:i:s'), 'champs' => serialize($codes), 'permanent' => $permanent, 'titre_version' => $titre_version), "id_objet=" . intval($id_objet) . " AND objet=" . sql_quote($objet) . " AND id_version={$id_version}");
        sql_delete("spip_versions", "id_objet=" . intval($id_objet) . " AND objet=" . sql_quote($objet) . " AND id_version < 0 AND titre_version ='{$date}'");
    }
    spip_log($onlylock . "memorise la version {$id_version} de l'objet {$objet} {$id_objet} {$titre_version}");
    return $id_version;
}
Exemple #2
0
 /**
  * Découper les paragraphes d'un texte en fragments
  *
  * @param string $texte Texte à fragmenter
  * @return string[]       Tableau de fragments (paragraphes)
  **/
 public function segmenter($texte)
 {
     return separer_paras($texte);
 }