17

Classement du contenu

Créez site20 en copiant site19.

  1. /cms
    1. ...
    2. site19
    3. site20

Dans ce chapitre, nous allons classer les nœuds en fils.

Pour tester le résultat en ligne, entrez http://www.frasq.org/cms/site20/fr/fil/1 dans la barre d'adresse de votre navigateur. Le site affiche le contenu du fil 1 en français. Entrez http://www.frasq.org/cms/site20/en/thread/1 pour afficher sa traduction en anglais.

Un fil a un titre, un nom, un extrait et un nuage de mots qui lui sont associés. Un fil contient une liste ordonnée de nœuds. Cliquez sur le lien Informations légales pour afficher le nœud 1.

Démarrez le processeur de commandes de MySQL et entrez dans la BD du site :

$ mysql -u root -p
mysql> use frasqdb2;

NOTE : Utilisez phpMyAdmin pour plus de confort.

Ajoutez la table thread puis la table thread_locale à la BD du site :

CREATE TABLE thread (
  thread_id INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
  user_id INT(10) NOT NULL DEFAULT '1',
  thread_type enum('thread') NOT NULL DEFAULT 'thread',
  created datetime NOT NULL,
  modified datetime NOT NULL,
  PRIMARY KEY (thread_id)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;

Un thread contient les propriétés d'un fil communes à toutes les langues : son identifiant, l'identifiant de l'utilisateur qui l'a modifié pour la dernière fois, le type du fil, ses dates de création et de modification. Le type d'un fil permettra une interprétation particulière de son contenu - livre, blog, forum, wiki, etc. La clé primaire d'un thread est son identifiant.

CREATE TABLE thread_locale (
  thread_id INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
  locale enum('fr','en') NOT NULL DEFAULT 'fr',
  name VARCHAR(100) NOT NULL,
  title VARCHAR(100) NOT NULL,
  abstract text,
  cloud text,
  PRIMARY KEY (thread_id,locale)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;

Un thread_locale contient les propriétés d'un fil qui dépendent de la langue : la désignation de la langue du contenu, le nom du fil, son titre, l'extrait et la liste de mots associés au fil. L'identifiant d'un thread_locale correspond à l'identifiant d'un thread. Les désignations des langues doivent correspondre aux langues listées par le paramètre de configuration $supported_languages défini dans le fichier includes/config.inc. La clé primaire d'un thread_locale est son identifiant et la désignation de la langue de son contenu.

Le lien entre un fil et les nœuds qu'il contient est fait par la table thread_node :

CREATE TABLE thread_node (
  thread_id INT(10) UNSIGNED NOT NULL,
  node_id INT(10) UNSIGNED NOT NULL,
  `number` INT(4) UNSIGNED NOT NULL,
  PRIMARY KEY (thread_id,node_id)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;

Un thread_node liste et ordonne les nœuds d'un fil. L'identifiant d'un thread_id correspond à l'identifiant d'un thread. node_id correspond à l'identifiant d'un nœud dans node. La clé primaire d'un thread_node est l'identifiant d'un fil et l'identifiant d'un nœud.

Créez un premier fil :

INSERT INTO thread (thread_id, user_id, `type`, created, modified) VALUES
(1, 1, 'thread', NOW(), NOW());

Le fil 1 est créé par l'utilisateur 1, l'administrateur du site. Vérifiez dans la table user.

Ajoutez sa description en français :

INSERT INTO thread_locale (thread_id, locale, name, title, abstract, cloud) VALUES
(1, 'fr', 'classeur', 'Classeur', 'Articles, notes et pages diverses.', 'articles notes informations');

Ajoutez la version en anglais :

INSERT INTO thread_locale (thread_id, locale, name, title, abstract, cloud) VALUES
(1, 'en', 'folder', 'Folder', 'Articles, notes and various pages.', 'articles notes information');

Associez le nœud 1 avec le fil 1 et placez-le en première position :

INSERT INTO thread_node VALUES(1, 1, 1);

Essayez quelques requêtes sur la BD :

SELECT thread_id FROM thread WHERE thread_id=1 LIMIT 1;

Vérifie que le fil 1 a bien été créé.

SELECT thread_id FROM thread_locale WHERE name='folder' LIMIT 1;

Vérifie le nom du fil 1 en anglais.

SELECT tn.node_id AS node_id FROM thread_node tn WHERE tn.thread_id=1 AND tn.node_id=1 LIMIT 1;

Vérifie que le nœud 1 appartient au fil 1.

SELECT tn.node_id AS node_id FROM thread_node tn JOIN node_locale nl ON nl.node_id=tn.node_id WHERE tn.thread_id=1 AND nl.name='legal-information' LIMIT 1;

Retourne l'identifiant du nœud 1 du fil 1 d'après son nom en anglais.

SELECT tn.node_id, `tn.number` AS node_number, nl.name AS node_name, nl.title AS node_title, nl.abstract AS node_abstract, nl.cloud AS node_cloud FROM thread_node tn JOIN node_locale nl ON nl.node_id=tn.node_id AND nl.locale='fr' WHERE tn.thread_id=1 ORDER BY `tn.number`

Retourne toutes les propriétés de tous les nœuds du fil 1 en français.

Ajoutez le fichier thread.inc dans le dossier models avec le contenu suivant :

  1. function thread_id($thread) {
  2.     if (is_numeric($thread)) {
  3.         $tabthread=db_prefix_table('thread');
  4.  
  5.         $sql="SELECT thread_id FROM $tabthread WHERE thread_id=$thread LIMIT 1";
  6.     }
  7.     else {
  8.         $sqlname=db_sql_arg($thread, true);
  9.  
  10.         $tabthreadlocale=db_prefix_table('thread_locale');
  11.  
  12.         $sql="SELECT thread_id FROM $tabthreadlocale WHERE name=$sqlname LIMIT 1";
  13.     }
  14.  
  15.     $r = db_query($sql);
  16.  
  17.     return $r ? $r[0]['thread_id'] : false;
  18. }

thread_id retourne le thread_id du fil dont l'identifiant ou le nom est $thread, ou false si un fil avec thread_id ou thread_name à la valeur $thread n'existe pas.

  1. function thread_node_id($thread_id, $node) {
  2.     if (is_numeric($node)) {
  3.         $tabthreadnode=db_prefix_table('thread_node');
  4.  
  5.         $sql="SELECT tn.node_id AS node_id FROM $tabthreadnode tn WHERE tn.thread_id=$thread_id AND tn.node_id=$node LIMIT 1";
  6.     }
  7.     else {
  8.         $sqlname = db_sql_arg($node, true);
  9.  
  10.         $tabthreadnode=db_prefix_table('thread_node');
  11.         $tabnodelocale=db_prefix_table('node_locale');
  12.  
  13.         $sql="SELECT tn.node_id AS node_id FROM $tabthreadnode tn JOIN $tabnodelocale nl ON nl.node_id=tn.node_id WHERE tn.thread_id=$thread_id AND nl.name=$sqlname LIMIT 1";
  14.     }
  15.  
  16.     $r = db_query($sql);
  17.  
  18.     return $r ? $r[0]['node_id'] : false;
  19. }

thread_node_id retourne le node_id du nœud contenu dans le fil $thread_id dont l'identifiant ou le nom est $node, ou false si le fil $thread_id ne contient pas un nom avec node_id ou node_name à la valeur $node.

  1. function thread_get($lang, $thread_id) {
  2.     $sqllang=db_sql_arg($lang, false);
  3.  
  4.     $tabthread=db_prefix_table('thread');
  5.     $tabthreadlocale=db_prefix_table('thread_locale');
  6.  
  7.     $sql="SELECT tloc.name AS thread_name, tloc.title AS thread_title, tloc.abstract AS thread_abstract, tloc.cloud AS thread_cloud, t.thread_type AS thread_type, UNIX_TIMESTAMP(t.created) AS thread_created, UNIX_TIMESTAMP(t.modified) AS thread_modified FROM $tabthread t JOIN $tabthreadlocale tloc ON tloc.thread_id=t.thread_id AND tloc.locale=$sqllang WHERE t.thread_id=$thread_id LIMIT 1";
  8.  
  9.     $r = db_query($sql);
  10.  
  11.     return $r ? $r[0] : false;
  12. }

thread_get retourne tous les attributs pour la langue $lang du fil dont l'identifiant est $thread_id, ou false en cas d'erreur. Remarquez que les champs thread_created et thread_modified sont convertis en temps Unix.

  1. function thread_get_contents($lang, $thread_id) {
  2.     $sqllang=db_sql_arg($lang, false);
  3.  
  4.     $tabthreadnode=db_prefix_table('thread_node');
  5.     $tabnodelocale=db_prefix_table('node_locale');
  6.  
  7.     $sql="SELECT tn.node_id, tn.number AS node_number, nl.name AS node_name, nl.title AS node_title, nl.abstract AS node_abstract, nl.cloud AS node_cloud FROM $tabthreadnode tn LEFT JOIN $tabnodelocale nl ON nl.node_id=tn.node_id AND nl.locale=$sqllang WHERE tn.thread_id=$thread_id ORDER BY tn.number";
  8.  
  9.     $r = db_query($sql);
  10.  
  11.     return $r;
  12. }

thread_get_contents retourne le contenu du fil $thread_id pour la langue $lang, ou false en cas d'erreur.

Créez l'action thread en ajoutant le fichier thread.php puis le fichier threadsummary.php dans le dossier actions avec les contenus suivants :

  1. /cms/site20
    1. actions
      1. thread.php
      2. threadsummary.php
  1. function thread($lang, $arglist=false) {
  2.     $thread=false;
  3.  
  4.     if (is_array($arglist)) {
  5.         if (isset($arglist[0])) {
  6.             $thread=$arglist[0];
  7.         }
  8.     }
  9.  
  10.     if (!$thread) {
  11.         return run('error/notfound', $lang);
  12.     }
  13.  
  14.     require_once 'actions/threadsummary.php';
  15.  
  16.     return threadsummary($lang, $thread);
  17. }
  1. require_once 'models/thread.inc';
  2.  
  3. function threadsummary($lang, $thread) {
  4.     $thread_id = thread_id($thread);
  5.     if (!$thread_id) {
  6.         return run('error/notfound', $lang);
  7.     }
  8.  
  9.     $r = thread_get($lang, $thread_id);
  10.     if (!$r) {
  11.         return run('error/notfound', $lang);
  12.     }
  13.     extract($r); /* thread_name thread_title thread_abstract thread_cloud */
  14.  
  15.     head('title', $thread_title);
  16.     head('description', $thread_abstract);
  17.     head('keywords', $thread_cloud);
  18.  
  19.     $validate=url('thread', $lang) . '/'. $thread_name;
  20.     $banner = build('banner', $lang, compact('validate'));
  21.  
  22.     $r = thread_get_contents($lang, $thread_id);
  23.  
  24.     $thread_contents = array();
  25.  
  26.     if ($r) {
  27.         $node_uri = url('node', $lang);
  28.         foreach ($r as $c) {
  29.             extract($c);    /* node_id node_name node_title node_number */
  30.             $node_url = $node_uri . '/' . $node_id;
  31.             $thread_contents[] = compact('node_title' , 'node_url');
  32.         }
  33.     }
  34.  
  35.     $content = view('threadsummary', $lang, compact('thread_title', 'thread_abstract', 'thread_cloud', 'thread_contents'));
  36.  
  37.     $output = layout('standard', compact('banner', 'content'));
  38.  
  39.     return $output;
  40. }

Pour donner accès à l'action thread, ajoutez un alias par langue dans le fichier includes/aliases.inc :

  1.         'fil'                   => 'thread',
  1.         'thread'                => 'thread',

Ajoutez la vue du sommaire d'un fil dans les dossiers views/fr pour la version en français et views/en pour la version en anglais :

  1. /cms/site20
    1. views
      1. fr
        1. threadsummary.phtml
      2. en
        1. threadsummary.phtml
  1. <h3><?php echo htmlspecialchars($thread_title, ENT_COMPAT, 'UTF-8'); ?></h3>
  2. <?php if ($thread_abstract): ?>
  3. <h5>Extrait</h5>
  4. <p><?php echo htmlspecialchars($thread_abstract, ENT_COMPAT, 'UTF-8'); ?></p>
  5. <?php endif; ?>
  6. <?php if ($thread_cloud): ?>
  7. <h6>Nuage</h6>
  8. <p class="smaller"><?php echo htmlspecialchars($thread_cloud, ENT_COMPAT, 'UTF-8'); ?></p>
  9. <?php endif; ?>
  10. <h4>Contenu</h4>
  11. <ol>
  12. <?php foreach ($thread_contents as $c): ?>
  13. <?php extract($c)/* node_title node_url */ ?>
  14. <li><a href="<?php echo $node_url; ?>"><?php echo htmlspecialchars($node_title, ENT_COMPAT, 'UTF-8'); ?></a></li>
  15. <?php endforeach; ?>
  16. </ol>
  1. <h3><?php echo htmlspecialchars($thread_title, ENT_COMPAT, 'UTF-8'); ?></h3>
  2. <?php if ($thread_abstract): ?>
  3. <h5>Abstract</h5>
  4. <p><?php echo htmlspecialchars($thread_abstract, ENT_COMPAT, 'UTF-8'); ?></p>
  5. <?php endif; ?>
  6. <?php if ($thread_cloud): ?>
  7. <h6>Cloud</h6>
  8. <p class="smaller"><?php echo htmlspecialchars($thread_cloud, ENT_COMPAT, 'UTF-8'); ?></p>
  9. <?php endif; ?>
  10. <h4>Contents</h4>
  11. <ol>
  12. <?php foreach ($thread_contents as $c): ?>
  13. <?php extract($c)/* node_title node_url */ ?>
  14. <li><a href="<?php echo $node_url; ?>"><?php echo htmlspecialchars($node_title, ENT_COMPAT, 'UTF-8'); ?></a></li>
  15. <?php endforeach; ?>
  16. </ol>

Entrez http://localhost/cms/site20/fr/fil/1 puis http://localhost/cms/site20/en/node/1 dans la barre d'adresse de votre navigateur.

Commentaires

Votre commentaire :
[p] [b] [i] [u] [s] [quote] [pre] [br] [code] [url] [email] strip aide 2000

Entrez un maximum de 2000 caractères.
Améliorez la présentation de votre texte avec les balises de formatage suivantes :
[p]paragraphe[/p], [b]gras[/b], [i]italique[/i], [u]souligné[/u], [s]barré[/s], [quote]citation[/quote], [pre]tel quel[/pre], [br]à la ligne,
[url]http://www.izend.org[/url], [url=http://www.izend.org]site[/url], [email]izend@izend.org[/email], [email=izend@izend.org]izend[/email],
[code]commande[/code], [code=langage]code source en c, java, php, html, javascript, xml, css, sql, bash, dos, make, etc.[/code].