Valider ea856bff rédigé par cedric@yterium.com's avatar cedric@yterium.com
Parcourir les fichiers

Ajout d'un champ langue a la table spip_urls :

- on le nomme langue et pas lang pour eviter les ambiguites avec le champ lang des objets qui apparait dans les jointures sans prefixe de table, via le champ titre "titre, lang"
- action/editer_url gere la langue lors de l'insertion d'une URL en evitant les conflit selon les regles suivantes :
  - si aucune URL n'existe, la langue est ignoree et forcee a '' qui est la valeur par defaut et signifie 'URL par defaut independante de la langue'
  - on peut avoir une URL perma par objet et par langue (donc une perma langue='' et une perma langue='en' pour un meme objet par exemple)
Par defaut, si on ne fournit aucune langue lors de l'insertion des URLS (ce qui est le cas des modules existant), tout se comporte comme avant sans rupture de compatibilite

- le formulaire #EDITER_URL_OBJET affiche la langue de chaque URL quand il y en a une
- on peut y definir des URLs avec langue en prefixant la saisie : "en:my-smart-url" fixera la langue a 'en' pour l'URL (sous reserve des conditions ci-dessus : si c'est la premiere URL de l'objet elle sera en langue='')
- le prefixe doit correspondre a une langue connue de SPIP, sinon il est ignore et l'URL est reformatee

- les modules de langue propre et arbo sont juste impactes pour extraire en priorite l'URL avec la langue=''

A noter que les modules de langue perso existants dans la nature ne sont pas impactes et continueront a fonctionner comme avant tant qu'il n'y a pas d'URLs en base avec une langue differente de ''.
Un dysfonctionnement -relatif- n'apparaitrait qu'a partir du moment ou des URLs de langue diverses existeraient en base

Ce commit ne fournit pas de module d'URL exploitant ce champ langue
parent e1e37ba5
Chargement en cours
Chargement en cours
Chargement en cours
Chargement en cours
+131 −35
Numéro de ligne d'origine Numéro de ligne de diff Ligne de diff
@@ -22,7 +22,16 @@ function action_editer_url_dist() {

}


/**
 * Nettoyer une URL :
 * supprimer le html, le rang, extraire les multi, translitterer
 * @param string $titre
 * @param int $longueur_maxi
 * @param int $longueur_min
 * @param string $separateur
 * @param string $filtre
 * @return string
 */
function url_nettoyer($titre, $longueur_maxi, $longueur_min = 0, $separateur = '-', $filtre = '') {

	$titre = supprimer_tags(supprimer_numero(extraire_multi($titre)));
@@ -82,6 +91,14 @@ function url_nettoyer($titre, $longueur_maxi, $longueur_min = 0, $separateur = '
	return $url;
}

/**
 * Inserer une URL en base avec multiples controles et gestion des collisions
 * en essayant d'eviter des problemes de race condition
 * @param array $set
 * @param bool $confirmer
 * @param string $separateur
 * @return bool
 */
function url_insert(&$set, $confirmer, $separateur) {
	$has_parent = true;
	# assurer la coherence des champs techniques si non fournis
@@ -92,6 +109,9 @@ function url_insert(&$set, $confirmer, $separateur) {
	if (!isset($set['segments'])) {
		$set['segments'] = count(explode('/', $set['url']));
	}
	if (!isset($set['langue'])) {
		$set['langue'] = '';
	}
	$perma = false;
	if (isset($set['perma']) and $set['perma']) {
		unset($set['perma']);
@@ -155,65 +175,141 @@ function url_insert(&$set, $confirmer, $separateur) {
				. " AND url LIKE ";
			if (
				!is_dir(_DIR_RACINE . $set['url']) and !file_exists(_DIR_RACINE . $set['url'])
				and sql_countsel('spip_urls', $where . url_sql_quote_like($set['url']))
				and $existing = sql_fetsel('*','spip_urls', $where . url_sql_quote_like($set['url']))
			) {
				sql_updateq('spip_urls', array('url' => $set['url'], 'date' => date('Y-m-d H:i:s')),
					$where . url_sql_quote_like($set['url']));
				spip_log("reordonne " . $set['type'] . " " . $set['id_objet'], "urls");
				$refresh = array(
					'url' => $set['url'],
					'date' => date('Y-m-d H:i:s'),
				);
				// si c'est une URL avec langue est qu'ici on a pas de langue, on ecrase
				if ($existing['langue']) {
					if (!$set['langue']){
						$refresh['langue'] = '';
					}
					elseif($set['langue'] !== $existing['langue']) {
						$set['url'] .= $separateur . $set['langue'];
						return url_insert_replay($set, $confirmer, $separateur, $has_parent, $perma);
					}
				}
				// sinon c'est une URL sans langue (generique)
				else {
					// si c'est pas une URL perma manuelle,
					// on ignore la langue de cette URL, l'URL generique s'appliquera
					if (!$perma) {
						unset($set['langue']);
					}
					else {
						$refresh['langue'] = $set['langue'];
					}
				}
				sql_updateq('spip_urls', $refresh, $where . url_sql_quote_like($set['url']));
				spip_log("refresh " . $set['type'] . " " . $set['id_objet'].' refresh:'.serialize($refresh), "urls");
				$redate = false;
			} else {
				$set['url'] .= $separateur . $set['id_objet'];
				if (strlen($set['url']) > 200) //serveur out ? retourner au mieux
				{
					return false;
				} elseif (sql_countsel('spip_urls', $where . url_sql_quote_like($set['url']))) {
					sql_updateq('spip_urls', array('url' => $set['url'], 'date' => date('Y-m-d H:i:s')),
						$where . url_sql_quote_like($set['url']));
					$redate = false;
				} else {
					// remettre id_parent et perma comme il faut si besoin
					if (!$has_parent) {
						unset($set['id_parent']);
				return url_insert_replay($set, $confirmer, $separateur, $has_parent, $perma);
			}
					if ($perma) {
						$set['perma'] = true;
		}

					return url_insert($set, $confirmer, $separateur);
	}

	$reset = array();
	// si on a fixe une langue pour cette URL mais qu'il n'y a pas d'URL generique pour cet objet (avec langue='')
	// on retire la langue car c'est l'URL generique par defaut
	if ($set['langue']) {
		if (!sql_countsel('spip_urls',
			"type=" . sql_quote($set['type'])
			. " AND id_objet=" . intval($set['id_objet'])
			. " AND id_parent=" . intval($set['id_parent'])
			. " AND langue=" . sql_quote(''))){
			$set['langue'] = $reset['langue'] = '';
		}
	}
	if ($redate) {
		$reset['date'] = date('Y-m-d H:i:s');
	}

	$where_thisurl = 'url=' . sql_quote($set['url']) . " AND id_parent=" . intval($set['id_parent']); // maj
	if ($redate) {
		sql_updateq('spip_urls', array('date' => date('Y-m-d H:i:s')), $where_thisurl);
	if ($reset) {
		sql_updateq('spip_urls', $reset, $where_thisurl);
	}

	// si url perma, poser le flag sur la seule url qu'on vient de mettre
	// si url perma, poser le flag sur la seule url qu'on vient de mettre (au sein de celles qui ont la meme langue)
	if ($perma) {
		sql_update('spip_urls', array('perma' => "($where_thisurl)"),
			"type=" . sql_quote($set['type']) . " AND id_objet=" . intval($set['id_objet']));
			"type=" . sql_quote($set['type']) . " AND id_objet=" . intval($set['id_objet'])." AND langue=" . sql_quote($set['langue']));
	}

	spip_log("Creation de l'url propre '" . $set['url'] . "' pour " . $set['type'] . " " . $set['id_objet'] . " (parent " . $set['id_parent'] . " perma " . ($perma ? "1" : "0") . ")",
		"urls");
	spip_log("Creation de l'url propre '" . $set['url'] . "' pour "
		. $set['type'] . " " . $set['id_objet']
		. " (parent [" . $set['id_parent'] . "] langue [" . $set['langue'] . "] perma [" . ($perma ? "1" : "0") . "])", "urls");

	return true;
}

/**
 * Rejouer une insertion qui a echoue avec une url modifiee (rallongee)
 * on s'assure que la longueur de l'URL n'est pas problematique, et on remet le $set comme il faut
 * @param array $set
 * @param bool $confirmer
 * @param string $separateur
 * @param bool $has_parent
 * @param bool $perma
 * @return bool
 */
function url_insert_replay($set, $confirmer, $separateur, $has_parent, $perma) {
	//var_dump('url_insert_replay');
	if (strlen($set['url']) > 200) //serveur out ? retourner au mieux
	{
		return false;
	}
	else {
		// remettre id_parent et perma comme il faut si besoin
		if (!$has_parent) {
			unset($set['id_parent']);
		}
		if ($perma) {
			$set['perma'] = true;
		}
		//var_dump($set);
		return url_insert($set, $confirmer, $separateur);
	}
}

/**
 * Faire un quote de l'URL pour une condition LIKE, donc en echapant les caracteres specifiques aux like
 * @param $url
 * @return string
 */
function url_sql_quote_like($url) {
	return sql_quote(str_replace(array("%", "_"), array("\\%", "\\_"), $url)) . " ESCAPE " . sql_quote('\\');
}

function url_verrouiller($objet, $id_objet, $url) {
	$where = "id_objet=" . intval($id_objet) . " AND type=" . sql_quote($objet);
	$where .= " AND url=" . sql_quote($url);

	// pour verrouiller une url, on fixe sa date dans le futur, dans 10 ans
	sql_updateq('spip_urls', array('date' => date('Y-m-d H:i:s', time() + 10 * 365.25 * 24 * 3600)), $where);
/**
 * Verrouiller une URL
 * poser le flag sur une unique url d'un objet
 * (au sein de celles qui ont la meme langue : on peut avoir plusieurs URLs perma, une par langue)
 *
 * @param string $url
 * @param int $id_parent
 * @param $url
 */
function url_verrouiller($url, $id_parent=0) {
	$where_thisurl = 'url=' . sql_quote($url) . " AND id_parent=" . intval($id_parent);
	$row = sql_fetsel('*','spip_urls',$where_thisurl);

	// on fait un update unique pour changer toutes les URLs concernees d'un coup
	if ($row) {
		sql_update('spip_urls', array('perma' => "($where_thisurl)"),
			"type=" . sql_quote($row['type']) . " AND id_objet=" . intval($row['id_objet'])." AND langue=" . sql_quote($row['langue']));
	}
}

/**
 * Supprimer une URL
 * @param $objet
 * @param $id_objet
 * @param string $url
 */
function url_delete($objet, $id_objet, $url = "") {
	$where = "id_objet=" . intval($id_objet) . " AND type=" . sql_quote($objet);
	if (strlen($url)) {
+6 −1
Numéro de ligne d'origine Numéro de ligne de diff Ligne de diff
@@ -50,11 +50,16 @@ function urls_declarer_tables_auxiliaires($tables_auxiliaires) {
		"segments" => "SMALLINT(3) DEFAULT '1' NOT NULL",
		// URL permanente, prioritaire
		"perma" => "TINYINT(1) DEFAULT '0' NOT NULL",
		// langue des urls : on le nomme langue et pas lang pour eviter les ambiguites avec le champ lang des objets
		// qui apparait dans les jointures sans prefixe de table, via le champ titre "titre, lang"
		'langue' => "VARCHAR(10) DEFAULT '' NOT NULL",

	);

	$spip_urls_key = array(
		"PRIMARY KEY" => "id_parent, url",
		"KEY type" => "type, id_objet"
		"KEY type" => "type, id_objet",
		'KEY langue' => 'langue',
	);

	$tables_auxiliaires['spip_urls'] = array(
+43 −2
Numéro de ligne d'origine Numéro de ligne de diff Ligne de diff
@@ -27,12 +27,45 @@ function formulaires_editer_url_objet_charger_dist($type, $id) {
	return $valeurs;
}

function urls_verifier_langue($langue) {
	include_spip('inc/lang');
	if (!match_langue($langue)) {
		return false;
	}

	if (isset($GLOBALS['meta']['langues_proposees']) and $GLOBALS['meta']['langues_proposees']) {
		$all_langs = explode(',',$GLOBALS['meta']['langues_proposees']);
		if (!in_array($langue, $all_langs)) {
			return false;
		}
	}

	return true;
}

/**
 * Verifier la saisie de l'URL
 * on peut prefixer par une langue au format
 * fr:Mon-URL-fr
 * en:My-english-url
 * pour specifier la langue de l'URL (mais il faut que le module d'URL la prenne en charge)
 * @param $type
 * @param $id
 * @return array
 */
function formulaires_editer_url_objet_verifier_dist($type, $id) {
	$erreurs = array();
	include_spip('action/editer_url');
	$langue = '';
	if (!$url = _request('url')) {
		$erreurs['url'] = _T('info_obligatoire');
	} else {
		if (preg_match(";^([a-z_]{2,9}):;", $url, $m)
		  and urls_verifier_langue($m[1])) {
			$langue = trim($m[1]);
			$url = substr($url, strlen($m[0]));
		}

		$type_urls = (isset($GLOBALS['type_urls']) ? $GLOBALS['type_urls'] : $GLOBALS['meta']['type_urls']);
		if ($type_urls == 'arbo' and strpos($url, '/') !== false) {
			$url = explode('/', $url);
@@ -49,7 +82,7 @@ function formulaires_editer_url_objet_verifier_dist($type, $id) {
			$url_clean = url_nettoyer($url, 255);
		}
		if (!isset($erreurs['url']) and $url != $url_clean) {
			set_request('url', $url_clean);
			set_request('url', ($langue?"$langue:":"") . $url_clean);
			$erreurs['url'] = _T('urls:verifier_url_nettoyee');
		}
	}
@@ -67,9 +100,17 @@ function formulaires_editer_url_objet_verifier_dist($type, $id) {
function formulaires_editer_url_objet_traiter_dist($type, $id) {
	$valeurs = array('editable' => true);

	$url = _request('url');
	$langue = '';
	if (preg_match(";^([a-z_]{2,9}):;", $url, $m)
	  and urls_verifier_langue($m[1])) {
		$langue = trim($m[1]);
		$url = substr($url, strlen($m[0]));
	}

	include_spip('action/editer_url');
	// les urls manuelles sont toujours permanentes
	$set = array('url' => _request('url'), 'type' => $type, 'id_objet' => $id, 'perma' => 1);
	$set = array('url' => $url, 'type' => $type, 'id_objet' => $id, 'perma' => 1, 'langue' => $langue);

	$type_urls = (isset($GLOBALS['type_urls']) ? $GLOBALS['type_urls'] : $GLOBALS['meta']['type_urls']);
	if (include_spip("urls/$type_urls")
+2 −2
Numéro de ligne d'origine Numéro de ligne de diff Ligne de diff
<paquet
	prefix="urls"
	categorie="statistique"
	version="1.6.0"
	version="2.0.0"
	etat="stable"
	compatibilite="[3.1.0;3.1.*]"
	logo="prive/themes/spip/images/url-32.png"
	schema="1.1.4"
	schema="2.0.0"
>	

	<nom>Urls Etendues</nom>
+2 −0
Numéro de ligne d'origine Numéro de ligne de diff Ligne de diff
@@ -22,6 +22,7 @@
			<th class='url principale' scope='col'>[(#TRI{url,<:urls:label_tri_url:>,ajax})]</th>
			<th class='objet' scope='col'>[(#TRI{type,<:urls:info_objet:> <:info_numero_abbreviation:>,ajax})]</th>
			<th class='parent' scope='col'><:urls:info_id_parent:></th>
			<th class='langue secondaire' scope='col'></th>
			<th class='date secondaire' scope='col'>[(#TRI{date,<:date:>,ajax})]</th>
			<th class="action"></th>
		</tr>
@@ -33,6 +34,7 @@
			<td class='url principale'>#URL</td>
			<td class='objet'><a href="[(#ID_OBJET|generer_url_entite{#TYPE})]">[(#TYPE|objet_info{texte_objet}|_T)]&nbsp;#ID_OBJET</a></td>
			<td class='parent'>[(#ID_PARENT|?{#ID_PARENT})]</td>
			<td class='langue secondaire'>#LANGUE</td>
			<td class='date secondaire'>[(#DATE|affdate_jourcourt)]</td>
			<td class='action'>[(#AUTORISER{modifierurl,#TYPE,#ID_OBJET})[(#BOUTON_ACTION{[(#CHEMIN_IMAGE{supprimer-12}|balise_img{<:urls:bouton_supprimer_url:>})],[(#URL_ACTION_AUTEUR{supprimer_url,[(#ID_PARENT)-#URL],#SELF})],ajax})]]</td>
		</tr>
Chargement en cours