L'objectif général est de proposer des interfaces de visualisations globales d'un wikini qui peuvent répondre aux questions de
PourquoiCartographier
Le Handler
Le handler sert simplement a appeler d'autres scripts rangés dans un dossier /svg placé dans le dossier /page. Il s'agit en fait d'une sorte de principe de
sous-handler qui permet d'en rajouter selon les besoins sans modifer l'existant.
<?php
/*
Description: Handlers pour affichages SVG
auteurs: Yann Le Guennec - Charles Nepote
version 0.2
22.02.2005
*/
header("Content-type: image/svg+xml");
$a['reseaupagecourante'] = 1;
$a['touteslespages'] = 1;
$b = $_GET['svg'];
if(isset($a[$b])) {
$url = $this->config["handler_path"]."/page/svg/".$b.".php";
if(is_file($url)) {
include($url);
}
}
?>
Les sous-handlers sont donc rangés dans le dossier /svg et leur nom est simplement passé en paramètre du handler principal.
Les sous-handlers sont actuellement :
demo:
http://www.x-arn.org/w3/systeme/svg&svg=touteslespages
demo:
http://www.x-arn.org/w3/systeme/svg&svg=reseaupagecourante
La version de demo (qui me sert de version de developpement) est accessible à partir de toutes les pages du wiki ARN
(suivre le lien
SVG)
http://www.x-arn.org/w3/
Les graphes commencent à être pertinents :
- l'enregistrement des liens de menu permanents dans la table wikini_links a été désactivé en rajoutant $this->StopLinkTracking?(); au debut des actions header.php et footer.php et $this->StartLinkTracking?(); en fin de header.php , ainsi, seuls les liens de contenu sont pris en compte.
- je ne comprends pas, ça fonctionnait avec la version 0.1 de wikini mais je n'arrive pas à faire fonctionner ce principe avec la 0.4, sans trouver d'ou ça vient...une idée ? Problème résolu de la manière suivante, dans wakka.php la fonction:
function TrackLinkTo($tag) { $_SESSION["linktable"][] = $tag; }
function TrackLinkTo($tag) { if($_SESSION["linktracking"] == 1) $_SESSION["linktable"][] = $tag; }
ce qui me semble un peu étrange...
- De fait j'ai rapporté le bug dans RapportsDeBogues mais à mon sens cela nécessite plus de discussions au niveau du comportement du linktracking par rapport aux actions. C'est pourquoi j'ai créé la page DevActionsEntetePiedDePageEtLinkTracking. Actuellement (version 0.4.3 et versions cvs) il est impossible de stopper le linktracking via la méthode prévue à cet effet. -- LordFarquaad
touteslespages.php
- génère un fichier SVG
- visualisation des liens entrants et sortants pour la page courante et le réseau secondaire des liens entre toutes ces pages. La taille de chaque page est proportionnelle au nombre de liens entrants (jaune) et sortants (rouge) de cette page dans le contexte du réseau de la page courante (blanche et au centre par defaut).
<?php
/*
Visualisation de toutes les pages
chaque page est représentée par une ellipse
sa hauteur est proportionnelle au nombre liens entrants dans la page (i)
sa largeur est proportionnelle au nombre liens sortants de la page (o)
sa couleur est fonction du nombre de modifications enregistrées (tend vers le rouge)
*/
$prefix = $this->config["table_prefix"];
if(isset($_GET['type']) && $_GET['type'] == 'soc')
{
//mesure le nombre d'intervenants différents sur une page
$query = "SELECT tag, COUNT(user) as nb_modif FROM ".$prefix."pages GROUP BY tag";
}
else
{
//mesure le nombre de versions de la page
$query = "SELECT tag, COUNT(id) as nb_modif FROM ".$prefix."pages GROUP BY tag";
}
if ($pagesM = $this->LoadAll($query))
{
foreach ($pagesM as $page)
{
$id = strtolower($page['tag']);
//if($id != '')
//{
$p[$id] = array();
$p[$id]['n'] = $page['tag'];
$p[$id]['nbin'] = 0;
$p[$id]['nbout'] = 0;
$p[$id]['nbm'] = $page['nb_modif'];
$col = $p[$id]['nbm'] * 4; // couleur proportionnelle, a ajuster en fonction de l'activité globale
if($col > 255) { $col = 255 ;}
$p[$id]['col'] = "rgb(".$col.",0,0)"; // couleur ~ nombre de versions dans la BDD
//}
}
}
$query = "SELECT from_tag, to_tag, COUNT(from_tag) as nb_from_tag FROM ".$prefix."links GROUP BY to_tag";
if ($pagesF = $this->LoadAll($query))
{
foreach ($pagesF as $page)
{
$id = strtolower($page['to_tag']);
if(!is_array($p[$id])) // variable page non encore initialisée = page non enregistrée
{
$p[$id] = array();
$p[$id]['n'] = $page['to_tag'];
$p[$id]['nbin'] = 0;
$p[$id]['nbout'] = 0;
$p[$id]['nbm'] = 0;
$p[$id]['col'] = "rgb(0,0,255)"; // + page sans lien sortant
}
$p[$id]['nbin'] = $page['nb_from_tag']; // nombre de liens entrants
}
}
$query = "SELECT from_tag, to_tag, COUNT(to_tag) as nb_to_tag FROM ".$prefix."links GROUP BY from_tag";
if ($pagesT = $this->LoadAll($query))
{
foreach ($pagesT as $page)
{
$id = strtolower($page['from_tag']);
if(!is_array($p[$id]))
{
$p[$id] = array();
$p[$id]['n'] = $page['from_tag'];
$p[$id]['nbin'] = 0;
$p[$id]['nbout'] = 0;
$p[$id]['nbm'] = 0;
$p[$id]['col'] = "rgb(0,255,0)"; // page pas encore enregistrée sans lien entrant
}
$p[$id]['nbout'] = $page['nb_to_tag']; //nombre de liens sortants
}
}
$svg_body_rect = "";
$svg_body_el = "";
$svg_body_txt = "";
foreach ($p as $paf)
{
$xr = rand(0,5000);
$yr = rand(0,2000);
$wr = (1+$paf['nbout']) * 10; // largeur ~ liens sortants
$hr = (1+$paf['nbin']) * 10; // hauteur ~ liens entrants
$svg_body_rect .= "<rect x=\"$xr\" y=\"$yr\" width=\"$wr\" height=\"$hr\"/>\n";
$svg_body_el .= "<ellipse fill=\"".$paf['col']."\" cx=\"$xr\" cy=\"$yr\" rx=\"$wr\" ry=\"$hr\"/>\n";
$svg_body_txt .= "<a xlink:href=\"".$this->config["base_url"].$paf['n']."\"><text onmouseover=\"selection(evt)\" onmouseout=\"deselection(evt)\" x=\"$xr\" y=\"$yr\">".$paf['n']." : i" .$paf['nbin']. " : o". $paf['nbout'] . "</text></a>\n";
}
//preserveAspectRatio=\"none\"
$svg_head = "<?xml version=\"1.0\" encoding=\"iso-8859-1\" ?> \r\n";
$svg_head .= "<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.0//EN\" \n \"http://www.w3.org/TR/2001/PR-SVG-20010719/DTD/svg10.dtd\">\n";
$svg_head .= "<svg width=\"100%\" height=\"100%\" viewBox=\"0,0,5000,2000\"
xml:base=\"http://x-arn.org/y/\"
xmlns=\"http://www.w3.org/2000/svg\"
xmlns:xlink=\"http://www.w3.org/1999/xlink\"> \n";
$svg_head .= "<style type=\"text/css\"> \n";
$svg_head .= " <![CDATA[ \n";
$svg_head .= " #fond { fill:#fff }\n";
$svg_head .= " text { fill:#000; font-family:arial; font-size: 2em; }\n";
//$svg_head .= " rect { fill:#fff; fill-opacity: 0.2; stroke: #000; stroke-width:1; }\n";
$svg_head .= " ellipse { fill-opacity: 0.2; stroke: #000; stroke-width:1; }\n";
$svg_head .= " ]]> \n";
$svg_head .= " </style> \n";
$svg_head .= "<rect id=\"fond\" x=\"0\" y=\"0\" width=\"100%\" height=\"100%\" />\n";
$svg_foot .= "</svg>";
$svg = $svg_head . $svg_body_el . $svg_body_txt . $svg_foot;
print($svg);
?>
reseaupagecourante.php
<?php
/*
Description: Handler pour l'affichage SVG du réseau de liens d'une page wikini
auteurs: Yann Le Guennec - Charles Nepote
version : 0.0.5
Paramètres utilisateurs:
script = on : active le script de déplacement des mots
subnet = off : desactive le réseau de liens secondaires
center = off : ne centre pas le rectangle de la page courante
style = dark | white (defaut) : styles de couleurs
*/
$styles = array("white"=>"", "dark"=>"");
$affich_param = ""; // pour affichage dans le commentaire du source SVG
$svg_uri = "/svg&svg=reseaupagecourante";
if(isset($_GET['script']) && $_GET['script'] == 'on') {
$script = true;
$svg_uri .= "&script=on";
$affich_param .= " script : on\n";
} else {
$script = false;
$affich_param .= " script : off\n";
}
if(isset($_GET['subnet']) && $_GET['subnet'] == 'off') {
$subnet = false;
$svg_uri .= "&subnet=off";
$affich_param .= " subnet : off\n";
} else {
$subnet = true;
$affich_param .= " subnet : on\n";
}
if(isset($_GET['center']) && $_GET['center'] == 'off') {
$center = false;
$svg_uri .= "&center=off";
$affich_param .= " center : off\n";
} else {
$center = true;
$affich_param .= " center : on\n";
}
if(isset($_GET['style'])) {
$style = $_GET['style'];
if(isset($styles[$style])) {
$svg_uri .= "&style=$style";
} else {
$style = "white";
}
} else {
$style = "white";
}
$affich_param .= " style : $style\n";
$n = 0; // nombre de pages liées à la page courante
$p = array();
//page courante
$id = $this->getPageTag();
$p[$id]['n'] = $id; // nom de la page
$p[$id]['c'] = 'cur'; // classe css
$p[$id]['w'] = 10; // largeur de zone par defaut
//Backlinks
if ($pagesFrom = $this->LoadPagesLinkingTo($this->getPageTag()))
{
foreach ($pagesFrom as $pageFrom)
{
$id = $pageFrom["tag"];
if($id != $this->getPageTag())// exclusion des liens de la page vers elle même
{
if(!is_array($p[$id])) // si le neud n'est pas deja enregistré
{
$p[$id]['n'] = $id;
$p[$id]['c'] = 'in';
$p[$id]['w'] = 10;
$n++; // incremente le nombre de noeuds
}
// le noeud existe deja ou pas : on incremente la taille du rectangle
$p[$id]['w']++;
$p[$this->getPageTag()]['w']++;
}
}
}
//Liens sortants
$query = "select to_tag as tag from ".$this->config["table_prefix"]."links where from_tag = '".mysql_escape_string($this->getPageTag())."' order by tag";
if ($pagesTo = $this->LoadAll($query))
{
foreach ($pagesTo as $pageTo)
{
$id = $pageTo["tag"];
if($id != $this->getPageTag()) //exclusion des liens de la page vers elle même
{
if(!is_array($p[$id])) // si le neud n'est pas deja enregistré
{
$p[$id]['n'] = $pageTo["tag"];
$p[$id]['c'] = 'out';
$p[$id]['w'] = 10;
$n++;
}
else
{
$p[$id]['c'] = 'inout'; // lien entrant et sortant
}
$p[$id]['w']++;
$p[$this->getPageTag()]['w']++;
}
}
}
// taille de police
// la taille de police augmente de 1 em à chaque 30 noeuds supplémentaires dans le graphe
$fontsize = ceil($n/30);
$styles["white"] = "
#fond { fill:#fff; }
text { fill:#808080; font-family:arial; font-size:".$fontsize."em;}
rect.cur { fill:#ffffff; fill-opacity:0.7; stroke:#ff0000; stroke-width:1;}
rect.in { fill:#ffff00; fill-opacity:0.5; stroke:#ffff00; stroke-width:1; }
rect.out { fill:#ffcccc; fill-opacity:0.5; stroke:#ff0000; stroke-width:1; }
rect.inout { fill:#ff0000; fill-opacity:0.5; stroke:#ff0000; stroke-width:1; }
line { stroke:#808080; opacity:0.1; stroke-width:1;}
line.in { stroke:#ffff00; opacity:0.5 }
line.out { stroke:#ffcccc; opacity:0.5 }
line.inout { stroke:#ff0000; opacity:0.5; stroke-width:3; }
";
$styles["dark"] = "
#fond { fill:#000; }
text { fill:#ccc; font-family:arial; font-size:".$fontsize."em;}
rect.cur { fill:#ff0000; fill-opacity:1; }
rect.in { fill:#00ff00; fill-opacity:0.5; stroke:#00ff00; stroke-width:1; }
rect.out { fill:#0000ff; fill-opacity:0.5; stroke:#0000ff; stroke-width:1; }
rect.inout { fill:#ff00ff; fill-opacity:0.5; stroke:#ff00ff; stroke-width:1; }
line { stroke:#808080; opacity:0.1; stroke-width:1;}
line.in { stroke:#00ff00; opacity:0.5 }
line.out { stroke:#0000ff; opacity:0.5 }
line.inout { stroke:#ff00ff; opacity:0.5; stroke-width:3; }
";
// calcul de la viewbox
if($n < 3) { $n = 3; }
$vw = $n * 50;
$vh = round($n*100/3);
//agrandissement pour limiter les debordements
//largeur de la viewbox
$vxw = round($vw + 1000/$n);
//hauteur de la viewbox
$vxh = round($vh + 1000/$n);
//$vxw = $vw+10;
//$vxh = $vh+10;
$viewbox = "0 0 $vxw $vxh";
// attribution de coordonnées aléatoires
while(list($k,$v) = each($p))
{
$p[$k]['x'] = rand(0, $vw);
$p[$k]['y'] = rand(0, $vh);
}
if($center) {
$p[$this->getPageTag()]['x'] = $vxw / 2;
$p[$this->getPageTag()]['y'] = $vxh / 2;
}
// coordonnées du centre du rectangle de la page courante
//$p[$this->getPageTag()]['w'] = $n;
$cur_w = $p[$this->getPageTag()]['w'];
$cur_x = $p[$this->getPageTag()]['x'];
$cur_y = $p[$this->getPageTag()]['y'];
$x1 = ($cur_w/2) + $cur_x;
$y1 = ($cur_w/2) + $cur_y;
$svg_head = ""; // début du fichier svg
$svg_links = ""; // couche de carrés cliquables
$svg_txt = ""; // nom des pages
$svg_lines = ""; // liaisons avec la page courante
$svg_rs = ""; // reseau de liens secondaires
$svg_foot = ""; // fin de fichier
//ecriture du SVG
$svg_head = "<?xml version=\"1.0\" encoding=\"iso-8859-1\" ?> \r\n";
$svg_head .= "<!--
Cartographie des ".$n." pages liées à la page ".$this->getPageTag().".
Généré par svg.php - version 0.0.4.
Le ".date("Y-m-d H:i:s")."
$affich_param
--> \n";
$svg_head .= "<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.0//EN\" \n \"http://www.w3.org/TR/2001/PR-SVG-20010719/DTD/svg10.dtd\">\n";
$svg_head .= "<svg width=\"100%\" height=\"100%\" viewBox=\"$viewbox\" preserveAspectRatio=\"none\"
xml:base=\"http://x-arn.org/y/\"
xmlns=\"http://www.w3.org/2000/svg\"
xmlns:xlink=\"http://www.w3.org/1999/xlink\"> \n";
$svg_head .= "<style type=\"text/css\"> \n";
$svg_head .= " <![CDATA[ \n";
$svg_head .= $styles[$style];
$svg_head .= " ]]> \n";
$svg_head .= " </style> \n";
$svg_head .= "<rect id=\"fond\" x=\"0\" y=\"0\" width=\"100%\" height=\"100%\" />\n";
if($script)
{
$svg_head .= " <script type=\"text/ecmascript\"><![CDATA[
function a(evt,i) {
//doc = evt.target.ownerDocument;
doc = evt.getTarget().getOwnerDocument();
text_id = 't[' + i + ']';
text_element = doc.getElementById(text_id);
x= text_element.getAttribute('x');
if(x==10) {
b(evt,i);
} else {
text_element.setAttribute('x', 10);
text_element.setAttribute('style', 'fill:#ccc');
}
}
function b(evt,i) {
doc = evt.getTarget().getOwnerDocument();
text_id = 't[' + i + ']';
rect_id = 'r[' + i + ']';
text_element = doc.getElementById(text_id);
rect_element = doc.getElementById(rect_id);
x= rect_element.getAttribute('x');
text_element.setAttribute('x', x);
text_element.setAttribute('style', 'fill:#000');
}
function c(evt,i) {
doc = evt.getTarget().getOwnerDocument();
text_id = 't[' + i + ']';
text_element = doc.getElementById(text_id);
text_element.setAttribute('style', 'fill:#ff0000');
}
function d(evt,i) {
doc = evt.getTarget().getOwnerDocument();
text_id = 't[' + i + ']';
text_element = doc.getElementById(text_id);
x = text_element.getAttribute('x');
if(x==10) {
text_element.setAttribute('style', 'fill:#ccc');
} else {
text_element.setAttribute('style', 'fill:#000');
}
}
]]>
</script>\n";
}
//variables pour les identifiants des éléments
$i = 0;
$j = 0;
//valeurs par defaut : pas de script
$mouseEvent1 = "";
$mouseEvent2 = "";
$mouseEvent3 = "";
foreach ($p as $page)
{
// réseau de liens secondaires
if($subnet)
{
$nompage = $page['n'];
if($nompage != $this->getPageTag()) // exclusion de la recherche de backlinks sur la page courante
{
if ($retroLiens = $this->LoadPagesLinkingTo($nompage)) //backlinks
{
foreach ($retroLiens as $retroLien)
{
$id = $retroLien["tag"]; //$p[$id]['n'] est donc une page qui pointe vers p[$nompage]
if(is_array($p[$id]) && $p[$id]['n'] != $this->getPageTag())
{
$svg_rs .= "<line id=\"l[$i]\" x1=\"".$p[$id]['x']."\" y1=\"".$p[$id]['y']."\" x2=\"".$page['x']."\" y2=\"".$page['y']."\"/>\n";
$page['w']++; //incrementation de la taille de la page liée
$i++;
}
}
}
}
}
if($script)
{
$mouseEvent1 = " onmouseover=\"b(evt,$j)\" ";
$mouseEvent2 = " onmouseover=\"c(evt,$j)\" onmouseout=\"d(evt,$j)\" ";
$mouseEvent3 = " onmouseover=\"a(evt,$j)\" ";
}
//ajuste les coords de ligne au centre des carrés
$page['cx'] = ($page['w']/2) + $page['x'];
$page['cy'] = ($page['w']/2) + $page['y'];
//rectangle de page en lien vers le SVG correspondant
$svg_links .= "<a id=\"ar[$j]\" $mouseEvent1 xlink:href=\"".$this->config["base_url"].$page['n']."$svg_uri\"><rect id=\"r[$j]\" x=\"".$page['x']."\" y=\"".$page['y']."\" width=\"".$page['w']."\" height=\"".$page['w']."\" class=\"".$page['c']."\"/></a>\n";
//rectangle equivalent sous le premier pour lien vers page dans wiki
$y2 = $page['y'] + $page['w'];
$svg_links .= "<a id=\"ar2[$j]\" $mouseEvent2 xlink:href=\"".$this->config["base_url"].$page['n']."\"><rect id=\"r2[$j]\" x=\"".$page['x']."\" y=\"$y2\" width=\"".$page['w']."\" height=\"".$page['w']."\" class=\"".$page['c']."\"/></a>\n";
//texte : nom de la page
$script ? $x = 10 : $x = $page['x'];
$script ? $svg_txt .= "" : $svg_txt .= "<a xlink:href=\"".$this->config["base_url"].$page['n']."$svg_uri\">";
$svg_txt .= "<text id=\"t[$j]\" $mouseEvent3 x=\"$x\" y=\"".$page['y']."\">".$page['n'];
$svg_txt .= "</text>";
$script ? $svg_txt .= "" : $svg_txt .= "</a>";
$svg_txt .= "\n";
//ligne sur la page courante
$svg_lines .= "<line id=\"l[$i]\" class=\"".$page['c']."\" x1=\"$x1\" y1=\"$y1\" x2=\"".$page['cx']."\" y2=\"".$page['cy']."\"/>\n";
$i++;
$j++;
}
$svg_foot .= "</svg>";
$svg = $svg_head . $svg_rs . $svg_lines . $svg_txt . $svg_links . $svg_foot;
print($svg);
?>
Installation
- Avec une version WikiNi 0.1.1.0.3, il faut rajouter dans la fonction Run de wakka.php :
case "svg":
header("Content-type: image/svg+xml");
print($this->Method($this->method));
break;
DEMO
Sur wikini.net (version 0.0.1)
Liste des changements effectués
- adapter automatiquement le graphe à la taille de la fenêtre du navigateur
- mettre au premier plan les carrés cliquables
- améliorer légèrement la taille du code généré (supprimer la classe de style et appliquer le style "rs" à l'attribut <line> tout court )
- lien vers les pages du wiki
- chaque taille de carré correspond au nombre de liens qui pointent vers cette page
- taille de la police + celle des carrés proportionnelle au nombre de liens et noeuds.
- augmenter l'épaisseur des lignes "inout" pour montrer le flux à double sens
- numéro de version en commentaire dans le code généré (+ le nombre de liens à titre de débogage)
- v0.0.4 : gestion des options d'affichage et interactions dans paramètres utilisateurs (url)
- v0.0.5 (reseaupagecourante.php) différencier graphiquement le label de la page en cours (+ au centre par defaut)
TODO
Remarques / Options
- il est fréquent, même sur des pages où la place ne manque pas, que deux éléments de texte se touchent, n'y a-t-il rien à faire ?
+ Lorsque deux noms se chevauchent et pour améliorer globalement l'interactivité, il est possible de colorer un titre au passage de la souris :
- théoriquement avec la pseudo-classe CSS2 :hover : en pratique elle semble être gérée seulement par Mozilla
- en pratique il est possible d'utiliser les évènements SVG, plus couteux en code, mais qui semblent fonctionner : par exemple :
- <a xlink:href="http://www.x-arn.org/y/wakka.php?wiki=Assemblages"><text x="146" y="235">Assemblages
- <set attributeName="fill" from="blue" to="red" begin="mouseover" end="mouseout"/>
- </text></a>
- L'idéal serait d'arriver à obtenir un fond opaque et un passage au premier plan pour masquer ce qu'il y a derrière un texte.
--
CharlesNepote
Après quelques essais pour placer un fond sous un texte, le tout au premier plan dans l'arbre XML du SVG, et le tout manipulé par le DOM, il s'avère que le plug in a du mal à suivre sur les gros graphes même si ça semble correct dans le principe... la version 0.0.3 prend une autre option et propose une solution globale qui me semble assez ludique et exploratoire, voire utilisable :) .... à tester...
--
YannLeGuennec
détails de prog
Pour la taille des titres il suffit d'ajouter un compteur $nb dans ton calcul des backlinks puis :
$size = round((1/$nb)*10, 1);
if ($size<"1") $size = "1";
et enfin
$svg_head .= " text { fill:#000; font-family:arial; font-size:".$size."em; } \n";
si on fait ça, la taille de police est à 1 dès que l'on a 10 noeuds ? la solution retenue pour le moment est :
$fontsize = ceil($n/30);
la taille de police augmente de 1 em à chaque 30 noeuds supplémentaires dans le graphe
Commentaires pour la version 0.0.3
Version très surprenante mais en définitive très séduisante :
- le faisceau partant du centre du carré du haut est bien vu
- la gestion des labels, très innovante, résoud en grande partie le problème du chevauchement (le problème ne se pose plus que pour l'impression mais c'est un moindre mal)
- la taille du texte est bien ajustée : pas trop grosse lorsqu'il n'y a que quelques liens ; correctement lisible jusqu'à 78 liens ; et encore lisible à 148 liens (on atteint les limites)
A revoir ?
J'ai eu cette impression aussi. D'un autre coté ce type de représentation pose des questions sur qui me semble avoir du sens sur la structure du wiki visualisé. Cette disproportion vient en partie du fait que la taille de chaque rectangle est dans cette version proportionnelle à son poids relatif sur l'ensemble du wiki et non plus seulement dans le réseau de liens de la page courante. Ainsi
PagePrincipale par exemple pourra apparaître énorme par rapport à la page courante parcequ'elle fait partie du menu qui se trouve sur toutes les pages. On peut donc équilibrer la taille des rectangles en jouant sur les paramètres de la visualisation, mais on peut aussi s'interroger sur la relation qui unit la page courante avec la
PagePrincipale, et s'il ne serait pas judicieux d'exclure les liens de menu de la représentation. En travaillant uniquement sur les liens de 'contenu' de la page, on avancerait peut-être finalement vers des représentations proches des réseaux sémantiques ou cartes de concepts.
Questions :
- faut-il que les labels (1) soient tous à gauche (cas actuel) ou (2) tous en place au début de l'affichage :
- (1) l'avantage c'est qu'on a une vue plus synthétique et graphique ; mais l'utilisateur se voit ensuite contraint de faire défiler sa souris sur la colonne gauche pour distribuer les labels
- (2) est l'antithèse de (1)
Personnellement je préfère l'option vision graphique au chargement du SVG, ceci dit c'est une modification très simple à réaliser qui pourrait peut-être être paramétrée par l'utilisateur
- l'usage du script EcmaScript? est-il absolument nécessaire ?
> désactivé par défaut, activable en passant script=on en parametre. Comme ça on peut récupérer quelquechose d'exploitable dans la version de mozilla qui ne gèrent pas le script par exemple
Utilisation des liens relatifs
Pour utiliser des liens relatifs, d'après
http://www.w3.org/TR/2001/REC-xmlbase-20010627/, le code devrait être (noter le xml:base) :
<svg xml:base="http://www.x-arn.org/y/" width="100%" height="100%" viewBox="0 0 1500 1000" preserveAspectRatio="none" xmlns="http://www.w3.org/2000/svg" >
<!-- ...... -->
<a xlink:href="wakka.php?wiki=ToutesLesActions"><text x="1169" y="349">ToutesLesActions</text></a>
<!-- ...... -->
mais ça ne fonctionne pas en local chez moi... il y a pourtant une substantielle économie de code à faire...
Je vais creuser ça.
--
CharlesNepote
Bugs
- Le handler présente la faille include, c'est à dire la faille la plus dangereuse et la plus fréquente sur les sites web en php: le include($url); permet d'inclure n'importe quel fichier auquel le serveur a accès. Dans le cas présent, l'ajout forcé de ".php" dans l'url réduit la faille à ce type de fichiers, mais elle est tout de même bien présente ! Par exemple pour que le handler svg nous resorte la page en html:
- (NB.: votre navigateur risque de tenter de l'afficher comme du svg à cause du content-type, mais vous pouvez contourner cela en utilisant par exemple wannabrowser.com)
- -- LordFarquaad
Argh, merci
LordFarquaad! (la v0.2 devrait régler le problème). tu as récupéré le login/pass
MySQL ? normalement non, il n'était possible que d'executer d'autres fichiers PHP de la distrib ? --yann
- Non en effet, je ne connais pas l'arborescence invisible de ton site, et les fichiers de wikini ne présentent actuellement aucun risque par rapport à cette faille. (NB.: les futures actions d'administration pourraient en présenter un...) Mais sur certains serveurs il est parfois possible d'exécuter des fichiers se trouvant pratiquement n'importe où, donc par exemple si j'étais sur le même serveur que toi, j'aurais pu tenter d'exécuter un de mes scripts par cette intermédiaire...
En fait ce que je te conseille de faire pour assurer la sécurité tout en permettant la modularité, c'est de n'autoriser que des modules svg dont le nom n'est composé que de chiffres et de lettres. Comme ça, impossible de remonter dans les répertoires. (interdire simplement les slash/antislash pourrait aussi faire l'affaire mais bon, on sait jamais...) --
LordFarquaad