Changeset 100835 in spip-zone


Ignore:
Timestamp:
Dec 4, 2016, 10:45:00 AM (3 years ago)
Author:
cedric@…
Message:

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

Location:
_core_/plugins/urls_etendues
Files:
8 edited

Legend:

Unmodified
Added
Removed
  • _core_/plugins/urls_etendues/action/editer_url.php

    r95586 r100835  
    2323}
    2424
    25 
     25/**
     26 * Nettoyer une URL :
     27 * supprimer le html, le rang, extraire les multi, translitterer
     28 * @param string $titre
     29 * @param int $longueur_maxi
     30 * @param int $longueur_min
     31 * @param string $separateur
     32 * @param string $filtre
     33 * @return string
     34 */
    2635function url_nettoyer($titre, $longueur_maxi, $longueur_min = 0, $separateur = '-', $filtre = '') {
    2736
     
    8392}
    8493
     94/**
     95 * Inserer une URL en base avec multiples controles et gestion des collisions
     96 * en essayant d'eviter des problemes de race condition
     97 * @param array $set
     98 * @param bool $confirmer
     99 * @param string $separateur
     100 * @return bool
     101 */
    85102function url_insert(&$set, $confirmer, $separateur) {
    86103        $has_parent = true;
     
    92109        if (!isset($set['segments'])) {
    93110                $set['segments'] = count(explode('/', $set['url']));
     111        }
     112        if (!isset($set['langue'])) {
     113                $set['langue'] = '';
    94114        }
    95115        $perma = false;
     
    156176                        if (
    157177                                !is_dir(_DIR_RACINE . $set['url']) and !file_exists(_DIR_RACINE . $set['url'])
    158                                 and sql_countsel('spip_urls', $where . url_sql_quote_like($set['url']))
     178                                and $existing = sql_fetsel('*','spip_urls', $where . url_sql_quote_like($set['url']))
    159179                        ) {
    160                                 sql_updateq('spip_urls', array('url' => $set['url'], 'date' => date('Y-m-d H:i:s')),
    161                                         $where . url_sql_quote_like($set['url']));
    162                                 spip_log("reordonne " . $set['type'] . " " . $set['id_objet'], "urls");
     180                                $refresh = array(
     181                                        'url' => $set['url'],
     182                                        'date' => date('Y-m-d H:i:s'),
     183                                );
     184                                // si c'est une URL avec langue est qu'ici on a pas de langue, on ecrase
     185                                if ($existing['langue']) {
     186                                        if (!$set['langue']){
     187                                                $refresh['langue'] = '';
     188                                        }
     189                                        elseif($set['langue'] !== $existing['langue']) {
     190                                                $set['url'] .= $separateur . $set['langue'];
     191                                                return url_insert_replay($set, $confirmer, $separateur, $has_parent, $perma);
     192                                        }
     193                                }
     194                                // sinon c'est une URL sans langue (generique)
     195                                else {
     196                                        // si c'est pas une URL perma manuelle,
     197                                        // on ignore la langue de cette URL, l'URL generique s'appliquera
     198                                        if (!$perma) {
     199                                                unset($set['langue']);
     200                                        }
     201                                        else {
     202                                                $refresh['langue'] = $set['langue'];
     203                                        }
     204                                }
     205                                sql_updateq('spip_urls', $refresh, $where . url_sql_quote_like($set['url']));
     206                                spip_log("refresh " . $set['type'] . " " . $set['id_objet'].' refresh:'.serialize($refresh), "urls");
    163207                                $redate = false;
    164208                        } else {
    165209                                $set['url'] .= $separateur . $set['id_objet'];
    166                                 if (strlen($set['url']) > 200) //serveur out ? retourner au mieux
    167                                 {
    168                                         return false;
    169                                 } elseif (sql_countsel('spip_urls', $where . url_sql_quote_like($set['url']))) {
    170                                         sql_updateq('spip_urls', array('url' => $set['url'], 'date' => date('Y-m-d H:i:s')),
    171                                                 $where . url_sql_quote_like($set['url']));
    172                                         $redate = false;
    173                                 } else {
    174                                         // remettre id_parent et perma comme il faut si besoin
    175                                         if (!$has_parent) {
    176                                                 unset($set['id_parent']);
    177                                         }
    178                                         if ($perma) {
    179                                                 $set['perma'] = true;
    180                                         }
    181 
    182                                         return url_insert($set, $confirmer, $separateur);
    183                                 }
     210                                return url_insert_replay($set, $confirmer, $separateur, $has_parent, $perma);
    184211                        }
    185212                }
    186213        }
    187214
     215        $reset = array();
     216        // si on a fixe une langue pour cette URL mais qu'il n'y a pas d'URL generique pour cet objet (avec langue='')
     217        // on retire la langue car c'est l'URL generique par defaut
     218        if ($set['langue']) {
     219                if (!sql_countsel('spip_urls',
     220                        "type=" . sql_quote($set['type'])
     221                        . " AND id_objet=" . intval($set['id_objet'])
     222                        . " AND id_parent=" . intval($set['id_parent'])
     223                        . " AND langue=" . sql_quote(''))){
     224                        $set['langue'] = $reset['langue'] = '';
     225                }
     226        }
     227        if ($redate) {
     228                $reset['date'] = date('Y-m-d H:i:s');
     229        }
     230
    188231        $where_thisurl = 'url=' . sql_quote($set['url']) . " AND id_parent=" . intval($set['id_parent']); // maj
    189         if ($redate) {
    190                 sql_updateq('spip_urls', array('date' => date('Y-m-d H:i:s')), $where_thisurl);
    191         }
    192 
    193         // si url perma, poser le flag sur la seule url qu'on vient de mettre
     232        if ($reset) {
     233                sql_updateq('spip_urls', $reset, $where_thisurl);
     234        }
     235
     236        // si url perma, poser le flag sur la seule url qu'on vient de mettre (au sein de celles qui ont la meme langue)
    194237        if ($perma) {
    195238                sql_update('spip_urls', array('perma' => "($where_thisurl)"),
    196                         "type=" . sql_quote($set['type']) . " AND id_objet=" . intval($set['id_objet']));
    197         }
    198 
    199         spip_log("Creation de l'url propre '" . $set['url'] . "' pour " . $set['type'] . " " . $set['id_objet'] . " (parent " . $set['id_parent'] . " perma " . ($perma ? "1" : "0") . ")",
    200                 "urls");
     239                        "type=" . sql_quote($set['type']) . " AND id_objet=" . intval($set['id_objet'])." AND langue=" . sql_quote($set['langue']));
     240        }
     241
     242        spip_log("Creation de l'url propre '" . $set['url'] . "' pour "
     243                . $set['type'] . " " . $set['id_objet']
     244                . " (parent [" . $set['id_parent'] . "] langue [" . $set['langue'] . "] perma [" . ($perma ? "1" : "0") . "])", "urls");
    201245
    202246        return true;
    203247}
    204248
     249/**
     250 * Rejouer une insertion qui a echoue avec une url modifiee (rallongee)
     251 * on s'assure que la longueur de l'URL n'est pas problematique, et on remet le $set comme il faut
     252 * @param array $set
     253 * @param bool $confirmer
     254 * @param string $separateur
     255 * @param bool $has_parent
     256 * @param bool $perma
     257 * @return bool
     258 */
     259function url_insert_replay($set, $confirmer, $separateur, $has_parent, $perma) {
     260        //var_dump('url_insert_replay');
     261        if (strlen($set['url']) > 200) //serveur out ? retourner au mieux
     262        {
     263                return false;
     264        }
     265        else {
     266                // remettre id_parent et perma comme il faut si besoin
     267                if (!$has_parent) {
     268                        unset($set['id_parent']);
     269                }
     270                if ($perma) {
     271                        $set['perma'] = true;
     272                }
     273                //var_dump($set);
     274                return url_insert($set, $confirmer, $separateur);
     275        }
     276}
     277
     278/**
     279 * Faire un quote de l'URL pour une condition LIKE, donc en echapant les caracteres specifiques aux like
     280 * @param $url
     281 * @return string
     282 */
    205283function url_sql_quote_like($url) {
    206284        return sql_quote(str_replace(array("%", "_"), array("\\%", "\\_"), $url)) . " ESCAPE " . sql_quote('\\');
    207285}
    208286
    209 function url_verrouiller($objet, $id_objet, $url) {
    210         $where = "id_objet=" . intval($id_objet) . " AND type=" . sql_quote($objet);
    211         $where .= " AND url=" . sql_quote($url);
    212 
    213         // pour verrouiller une url, on fixe sa date dans le futur, dans 10 ans
    214         sql_updateq('spip_urls', array('date' => date('Y-m-d H:i:s', time() + 10 * 365.25 * 24 * 3600)), $where);
    215 }
    216 
     287/**
     288 * Verrouiller une URL
     289 * poser le flag sur une unique url d'un objet
     290 * (au sein de celles qui ont la meme langue : on peut avoir plusieurs URLs perma, une par langue)
     291 *
     292 * @param string $url
     293 * @param int $id_parent
     294 * @param $url
     295 */
     296function url_verrouiller($url, $id_parent=0) {
     297        $where_thisurl = 'url=' . sql_quote($url) . " AND id_parent=" . intval($id_parent);
     298        $row = sql_fetsel('*','spip_urls',$where_thisurl);
     299
     300        // on fait un update unique pour changer toutes les URLs concernees d'un coup
     301        if ($row) {
     302                sql_update('spip_urls', array('perma' => "($where_thisurl)"),
     303                        "type=" . sql_quote($row['type']) . " AND id_objet=" . intval($row['id_objet'])." AND langue=" . sql_quote($row['langue']));
     304        }
     305}
     306
     307/**
     308 * Supprimer une URL
     309 * @param $objet
     310 * @param $id_objet
     311 * @param string $url
     312 */
    217313function url_delete($objet, $id_objet, $url = "") {
    218314        $where = "id_objet=" . intval($id_objet) . " AND type=" . sql_quote($objet);
  • _core_/plugins/urls_etendues/base/urls.php

    r94396 r100835  
    5151                // URL permanente, prioritaire
    5252                "perma" => "TINYINT(1) DEFAULT '0' NOT NULL",
     53                // langue des urls : on le nomme langue et pas lang pour eviter les ambiguites avec le champ lang des objets
     54                // qui apparait dans les jointures sans prefixe de table, via le champ titre "titre, lang"
     55                'langue' => "VARCHAR(10) DEFAULT '' NOT NULL",
     56
    5357        );
    5458
    5559        $spip_urls_key = array(
    5660                "PRIMARY KEY" => "id_parent, url",
    57                 "KEY type" => "type, id_objet"
     61                "KEY type" => "type, id_objet",
     62                'KEY langue' => 'langue',
    5863        );
    5964
  • _core_/plugins/urls_etendues/formulaires/editer_url_objet.php

    r100808 r100835  
    2828}
    2929
     30function urls_verifier_langue($langue) {
     31        include_spip('inc/lang');
     32        if (!match_langue($langue)) {
     33                return false;
     34        }
     35
     36        if (isset($GLOBALS['meta']['langues_proposees']) and $GLOBALS['meta']['langues_proposees']) {
     37                $all_langs = explode(',',$GLOBALS['meta']['langues_proposees']);
     38                if (!in_array($langue, $all_langs)) {
     39                        return false;
     40                }
     41        }
     42
     43        return true;
     44}
     45
     46/**
     47 * Verifier la saisie de l'URL
     48 * on peut prefixer par une langue au format
     49 * fr:Mon-URL-fr
     50 * en:My-english-url
     51 * pour specifier la langue de l'URL (mais il faut que le module d'URL la prenne en charge)
     52 * @param $type
     53 * @param $id
     54 * @return array
     55 */
    3056function formulaires_editer_url_objet_verifier_dist($type, $id) {
    3157        $erreurs = array();
    3258        include_spip('action/editer_url');
     59        $langue = '';
    3360        if (!$url = _request('url')) {
    3461                $erreurs['url'] = _T('info_obligatoire');
    3562        } else {
     63                if (preg_match(";^([a-z_]{2,9}):;", $url, $m)
     64                  and urls_verifier_langue($m[1])) {
     65                        $langue = trim($m[1]);
     66                        $url = substr($url, strlen($m[0]));
     67                }
     68
    3669                $type_urls = (isset($GLOBALS['type_urls']) ? $GLOBALS['type_urls'] : $GLOBALS['meta']['type_urls']);
    3770                if ($type_urls == 'arbo' and strpos($url, '/') !== false) {
     
    5083                }
    5184                if (!isset($erreurs['url']) and $url != $url_clean) {
    52                         set_request('url', $url_clean);
     85                        set_request('url', ($langue?"$langue:":"") . $url_clean);
    5386                        $erreurs['url'] = _T('urls:verifier_url_nettoyee');
    5487                }
     
    68101        $valeurs = array('editable' => true);
    69102
     103        $url = _request('url');
     104        $langue = '';
     105        if (preg_match(";^([a-z_]{2,9}):;", $url, $m)
     106          and urls_verifier_langue($m[1])) {
     107                $langue = trim($m[1]);
     108                $url = substr($url, strlen($m[0]));
     109        }
     110
    70111        include_spip('action/editer_url');
    71112        // les urls manuelles sont toujours permanentes
    72         $set = array('url' => _request('url'), 'type' => $type, 'id_objet' => $id, 'perma' => 1);
     113        $set = array('url' => $url, 'type' => $type, 'id_objet' => $id, 'perma' => 1, 'langue' => $langue);
    73114
    74115        $type_urls = (isset($GLOBALS['type_urls']) ? $GLOBALS['type_urls'] : $GLOBALS['meta']['type_urls']);
  • _core_/plugins/urls_etendues/paquet.xml

    r100814 r100835  
    22        prefix="urls"
    33        categorie="statistique"
    4         version="1.6.0"
     4        version="2.0.0"
    55        etat="stable"
    66        compatibilite="[3.1.0;3.1.*]"
    77        logo="prive/themes/spip/images/url-32.png"
    8         schema="1.1.4"
     8        schema="2.0.0"
    99>       
    1010
  • _core_/plugins/urls_etendues/prive/objets/liste/urls.html

    r93431 r100835  
    2323                        <th class='objet' scope='col'>[(#TRI{type,<:urls:info_objet:> <:info_numero_abbreviation:>,ajax})]</th>
    2424                        <th class='parent' scope='col'><:urls:info_id_parent:></th>
     25                        <th class='langue secondaire' scope='col'></th>
    2526                        <th class='date secondaire' scope='col'>[(#TRI{date,<:date:>,ajax})]</th>
    2627                        <th class="action"></th>
     
    3435                        <td class='objet'><a href="[(#ID_OBJET|generer_url_entite{#TYPE})]">[(#TYPE|objet_info{texte_objet}|_T)]&nbsp;#ID_OBJET</a></td>
    3536                        <td class='parent'>[(#ID_PARENT|?{#ID_PARENT})]</td>
     37                        <td class='langue secondaire'>#LANGUE</td>
    3638                        <td class='date secondaire'>[(#DATE|affdate_jourcourt)]</td>
    3739                        <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>
  • _core_/plugins/urls_etendues/urls/arbo.php

    r100834 r100835  
    314314                "O.$col_id=$id_objet",
    315315                '',
    316                 $order_by_parent . 'U.perma DESC, U.date DESC', 1);
     316                $order_by_parent . 'U.perma DESC, U.langue=\'\' DESC, U.date DESC', 1);
    317317        if ($row) {
    318318                $urls[$type][$id_objet] = $row;
  • _core_/plugins/urls_etendues/urls/propres.php

    r100833 r100835  
    155155        // Recuperer une URL propre correspondant a l'objet.
    156156        // mais urls a 1 segment uniquement (pas d'urls /)
    157         // de preference avec id_parent=0, puis perma, puis par date desc
     157        // de preference avec id_parent=0, puis perma, puis langue='' puis par date desc
    158158        $row = sql_fetsel("U.url, U.date, U.id_parent, U.perma, $champ_titre",
    159159                "$table AS O LEFT JOIN spip_urls AS U ON (U.type='$type' AND U.id_objet=O.$col_id)",
    160                 "O.$col_id=$id_objet AND (U.segments IS NULL OR U.segments=1)", '', 'U.id_parent=0 DESC, U.perma DESC, U.date DESC',
     160                "O.$col_id=$id_objet AND (U.segments IS NULL OR U.segments=1)", '', 'U.id_parent=0 DESC, U.perma DESC, U.langue=\'\' DESC, U.date DESC',
    161161                1);
    162162
  • _core_/plugins/urls_etendues/urls_administrations.php

    r94396 r100835  
    6161        );
    6262
     63        $maj['2.0.0'] = array(
     64                array('sql_alter', "table spip_urls ADD langue VARCHAR(10) DEFAULT '' NOT NULL"),
     65                array('sql_alter', "table spip_urls ADD KEY langue (langue)"),
     66        );
     67
    6368        include_spip('base/upgrade');
    6469        maj_plugin($nom_meta_base_version, $version_cible, $maj);
Note: See TracChangeset for help on using the changeset viewer.