Академический Документы
Профессиональный Документы
Культура Документы
Conclusion 40
Annexes
Abstract
nternet est une invention formida- Après un petit état des lieux des sites
ble. de groupe sur le net, je vous explique-
Et quand Internet est entré dans ma vie, rai pourquoi avoir choisi ce sujet en
à l’époque où il fallait presque penser à particulier.
pédaler pour que les pages s’affichent Je développerai ensuite l’idée en tant
plus vite, il ne payait pas de mine. que telle et les techniques employées
Et pourtant, Internet a révolutionné pour arriver à mes fins.
bien des choses, à commencer par le Je vous emmènerai enfin, plonger la
fait que j’ai pu trouver une orientation tête la première dans une visite guidée
de vie qui me tentait : créer des sites du système.
web. Ma passion pour l’infographie est J’essaierai autant que possible de ne
venue par la suite. pas faire l’impasse sur l’essentiel, sans
Après quelques années d’expériences, pour autant vous perdre dans des ex-
seul, puis en cours à l’INPRES, nous en plications à rallonge.
arrivons à ce PFE, qui réunit mes deux
passions : la musique et le web.
Mon PFE parle donc de musique et de
sites web, et plus particulièrement du
développement de mon projet : conce-
voir un moteur de sites internet sim-
ple, mais complet, pour permettre à
des groupes de musique de créer sans
peine leur site.
Avant de nous lancer dans le vif du
sujet, j’aimerais profiter des dernières
lignes de cette introduction pour quel-
ques remerciements :
Bon. Et si on commençait ?
nternet, comme je le disais dans buté grâce à la diffusion sur un quel-
l’introduction, est un outil formidable. conque réseau peer-to-peer de leur
Je ne suis bien sûr pas le seul à avoir re- maquette ; de grands groupes orches-
marqué que dès qu’une invention peut trant même discrètement ce genre de
rapporter de l’argent, elle est bien vite “fuite” pour faire un coup de pub sur Science du buzz web
utilisée à des fins commerciales, même leur prochain album. Le groupe Nine Inch
si son but premier ne l’était pas. Il est un fait que le web est un outil de Nails (www.nin.com), a
Et donc, Internet a été le synonyme communication (et donc de pub) sans volontairement “perdu” une
d’un bond en avant pour bien des sec- frontière, où des stars se font et se dé- clé USB contenant une copie
teurs, dont le cinéma, le piratage...et font chaque jour. du clip de leur futur single
la musique. Mais si les grands groupes peuvent lors d’un concert en mars
facilement se payer des sites internet 2007.
Progressivement, tous les groupes
“connus” de la planète ont compris (ou conçus par de grandes boites renom- Ce sont eux aussi qui
plutôt leurs agents de communication) mées avec des animations flash hautes permettent à leurs fans de
qu’il leur fallait être présents sur Inter- en couleurs et des campagnes marke- télécharger les sources de
net. ting Internet impressionantes, pour leurs morceaux au format
les petits groupes, la réalité est toute GarageBand afin qu’ils créent
Le web progressant à grand pas, de autre. leurs propres remixes.
newsgroup en forums et de chat en
youtube et consors, les petits groupes Intéressons-nous donc aux possibili-
s’y sont mis eux aussi. tés offertes aux petits groupes, qui,
conscients des potentiels d’Internet, se
Sur Internet, on peut se faire beaucoup décident à essayer de s’y montrer en
de pub, et surtout pour pas cher. se créant un site.
Bien des groupes en ont profité, racon-
tant à qui veut l’entendre qu’ils ont dé-
MySpace et cie des défauts, des sites communautaires
pour les groupes.
le tout-fait pseudo-communautaire
6.5 La communauté
Ce projet, que j’ai vaguement abordé
au début de cet ouvrage, est l’un de
ceux qui me tient le plus à coeur une
fois que l’application aura pris un peu
d’ampleur : créer un site communau-
taire, réunissant les groupes utilisant
mon moteur de site, afin de mettre en
commun leurs news, leurs agendas
et morceaux, pour créer une commu-
nauté de groupes apte à se trouver des
u moment où je rédige ces lignes, La prochaine grande aventure, ce sera
fish in a pan est presque terminé. Il la release de fish in a pan, en juillet.
reste quelques bug à corriger. En regar- Sortir mon poisson de sa poêle et le re-
dant ma table de nuit où se trouve mon lacher dans les eaux troubles du net.
cahier à idées, dans les pages duquel la Espérons juste qu’il n’ait pas cuit trop
première idée concernant fish in a pan longtemps...
fut écrite, bien, bien avant de taper la
première ligne de code, je ne suis pas
peu fier du chemin parcouru.
Entre les premières lignes de code,
tapées en janvier 2007, l’abandon en
mars, la renaissance du code sous une
autre forme en fin avril et les derniers « Quelque part, dans un autre monde loin du
boulons à serrer, il y a eu beaucoup de Disque, quelqu’un empoigna d’une main hésitante
questions, d’idées idiotes tombées à un instrument dont la musique fit écho au rythme
l’eau, de grandes idées bien trop gran- qui lui soûlait l’âme.
des pour être reprises et de petites
idées anodines qui sont toujours écrites Elle ne mourra jamais.
à droite à gauche, dans mon fameux Elle est là et bien là. »
cahier ou sur le gigantesque poster col-
lé sur le mur de ma chambre qui m’a Accros du roc, Terry Pratchett
servi de roadmap, rempli de gribouillis,
de ratures et de petits “OK” verts au fur
et à mesure de l’avancée des fonctions
à inclure dans fish in a pan.
Bibliographie
Collectif, article “Myspace” sur Wikipédia, http://fr.wikipedia.org/wiki/Myspace
(consulté le 12 mai 2007)
Collectif, article “KISS (principe)” sur Wikipédia, http://fr.wikipedia.org/wiki/KISS-
principe (consulté le 15 mai 2007)
Collectif, article “Modèle-Vue-Contrôleur” sur Wikipédia, http://fr.wikipedia.org/
wiki/MVC (consulté le 11 mai 2007)
Collectif, article “Test de Turing” sur Wikipédia, http://fr.wikipedia.org/wiki/Test_de_
Turing (consulté le 20 mai 2007)
Collectif, article “Captcha” sur Wikipédia, http://fr.wikipedia.org/wiki/Captcha
(consulté le 20 mai 2007)
Références
WIEDEMANN Julius (éd.), Web Design : Music Sites, Taschen, coll. Icons, 2006
WIEDEMANN Julius (éd.), Web Design : Studios, Taschen, coll. Icons, 2006
GOTO Kelly & COTLER Emily, [Re]design web [2.0] Conduite de projet, Eyrolles,
2005
PORTENEUVE Christophe, Bien développer pour le Web 2.0, Eyerolles, 2006
Annexe 1 : Cahier des charges original
2 3
Cahier des charges
Notes
le
système sh in a pan sera
codé de manière a être fa-
cilement adaptable en de
multiples langues. Lors de
la sortie du projet, la langue
française sera la seule dispo-
nible, mais la langue anglai-
se rejoindra très vite cette
première.
un système
basé sur la technologie rss
4
Annexe 2 : Code de l’objet Element
<?php
class Element {
// Constructeur
function Element($table=NULL, $id=NULL) {
if( !empty($table) && is_numeric($id) ) {
$this->o_table = BDD_PREFIX.$table;
$this->o_tableName = $table;
$this->o_idPrefix = substr($table, 0, -1);
$this->o_id = $id;
$this->load($id);
}
} // Element
// fonction load, charge un rang de la db (identifié par un id) dans l’objet
function load($id) {
if( !$id ) return false;
$request = ”SELECT * FROM ”.$this->o_table.” WHERE ”.$this->o_idPrefix.”_id =
‘”.$id.”’”;
$this->o_loadRequest = $request;
$data = mysql_query($request);
if( !$data ) { return false; }
while( $current = @mysql_fetch_assoc($data) ) {
$array[] = array_map(”stripslashes”, $current);
}
// variables de l’utilisateur
foreach($array[0] as $key=>$value) {
$this->$key = $value;
}
$this->o_id = $id;
} // load
(suite du code page suivante)
<?php
class Config {
// Constructeur
function Config() {
$this->o_table = BDD_PREFIX.»config»;
$configData = Multiple::parseRequest(«SELECT * FROM «.$this->o_table.»»);
foreach($configData as $param) {
$this->$param[«config_key»] = $param[«config_value»];
}
} // Config
// fonction save, sauve le contenu de l’objet dans la db
function save() {
// récupération des paramètres de l’objet
$properties = get_object_vars($this);
foreach($properties as $key=>$value) {
if( substr($key, 0, 2) != «o_» ) {
$values[] = «(‘».$key.»’, ‘».$value.»’)»;
}
}
$valuesForRequest = implode(«, «, $values);
// construction de la requête
$request = «REPLACE INTO «.$this->o_table.» (config_key, config_value) VALUES
«.$valuesForRequest.»»;
return mysql_query( $request );
} // save
<?php
class Multiple {
// pas de constructeur
// ----------------------------------------
// --- fonctions de requêtes
// getTagboardMessages
function getTagboardMessages($begin=0, $limit=50) {
$request = ”SELECT tb.* , usr.surnom AS msg_user FROM ”.BDD_PREFIX.”boardmsgs tb LEFT
JOIN ”.BDD_PREFIX.”users usr USING ( user_id ) WHERE msg_type = ‘msg’ ORDER BY tb.msg_date DESC
LIMIT ”.$begin.”, ”.$limit.””;
return Multiple::parseRequest($request, true);
} // getTagboardMessages
// getTagboardNotifs
function getTagboardNotifs($begin=0, $limit=200) {
$request = ”SELECT tb.* , usr.surnom AS msg_user FROM ”.BDD_PREFIX.”boardmsgs tb LEFT
JOIN ”.BDD_PREFIX.”users usr USING ( user_id ) WHERE msg_type <> ‘msg’ ORDER BY tb.msg_date DESC
LIMIT «.$begin.”, ”.$limit.””;
return Multiple::parseRequest($request, true);
} // getTagboardNotifs
// getMembers
function getMembers() {
$request = ”SELECT usr.* FROM ”.BDD_PREFIX.”users usr WHERE group_members = 1 ORDER
BY usr.display_order ASC”;
return Multiple::parseRequest($request, true);
} // getMembers
// getUsers
function getUsers() {
$request = ”SELECT usr.* FROM ”.BDD_PREFIX.”users usr WHERE group_members = 0 ORDER
BY usr.display_order ASC”;
return Multiple::parseRequest($request, true);
} // getUsers
// getLyrics
function getLyrics() {
$request = ”SELECT * FROM ”.BDD_PREFIX.”lyrics ORDER BY lyric_display_order ASC”;
return Multiple::parseRequest($request, true);
} // getLyrics
// getDiscs
function getDiscs() {
$request = ”SELECT dsc.*, COUNT(sng.song_id) AS nbrSongs FROM ”.BDD_PREFIX.”discs dsc
LEFT JOIN ”.BDD_PREFIX.”songs sng ON( dsc.disc_id = sng.song_disc_id ) GROUP BY dsc.disc_id ORDER
BY disc_display_order ASC”;
return Multiple::parseRequest($request, true);
} // getDiscs
// getSongs
function getSongs( $discId ) {
$request = ”SELECT * FROM ”.BDD_PREFIX.”songs WHERE ‘”.$discId.”’ = song_disc_id
ORDER BY song_disc_cd_order ASC, song_disc_order ASC”;
$songs = Multiple::parseRequest($request, true);
if( $songs ) {
$newSongs = array();
foreach( $songs as $sng ) {
$newSongs[ $sng[”song_disc_cd_order”] ][ $sng[”song_disc_order”] ] =
$sng;
}
}
return $newSongs;
} // getSongs
// getSongByTrackNum
function getSongByTrackNum( $discId, $discNumber, $songNumber ) {
$request = ”SELECT song_id FROM ”.BDD_PREFIX.”songs WHERE ‘”.$discId.”’ = song_disc_
id AND song_disc_cd_order = ‘”.$discNumber.”’ AND song_disc_order = ‘”.$songNumber.”’ LIMIT 0,1”;
$data = Multiple::parseRequest($request);
return new Element(”songs”, intval( $data[”song_id”] ));
} // getSongByTrackNum
// getAudio
function getAudio() {
$request = ”SELECT * FROM ”.BDD_PREFIX.”medias ORDER BY media_display_order ASC”;
return Multiple::parseRequest($request, true);
} // getAudio
// getVideo
function getVideo() {
$request = ”SELECT * FROM ”.BDD_PREFIX.”videos ORDER BY video_display_order ASC”;
return Multiple::parseRequest($request, true);
} // getVideo
// getNews
function getNews() {
$request = ”SELECT * FROM ”.BDD_PREFIX.”news ORDER BY new_date DESC”;
return Multiple::parseRequest($request, true);
} // getNews
// getEvents
function getEvents() {
$request = ”SELECT * FROM ”.BDD_PREFIX.”events ORDER BY event_date DESC”;
return Multiple::parseRequest($request, true);
} // getEvents
// getLivre
function getLivre() {
$request = ”SELECT * FROM ”.BDD_PREFIX.”livres ORDER BY livre_date DESC”;
return Multiple::parseRequest($request, true);
} // getLivre
// getContacts
function getContacts() {
$request = ”SELECT * FROM ”.BDD_PREFIX.”contacts ORDER BY contact_date DESC”;
return Multiple::parseRequest($request, true);
} // getContacts
// getLinks
function getLinks() {
$request = ”SELECT * FROM ”.BDD_PREFIX.”links ORDER BY link_display_order ASC”;
return Multiple::parseRequest($request, true);
} // getLinks
// getArticles
function getArticles( $byCat=false ) {
if( $byCat ) {
$filter = ”WHERE art.categorie_id = ‘”.$byCat.”’”;
}
$request = ”SELECT art.*, COUNT(com.comment_id) AS comNbr, usr.surnom AS author,
cat.categorie_name FROM ”.BDD_PREFIX.”articles art LEFT JOIN ”.BDD_PREFIX.”comments com ON com.
article_id = art.article_id LEFT JOIN ”.BDD_PREFIX.”users usr ON usr.user_id = art.article_author
LEFT JOIN ”.BDD_PREFIX.”categories cat ON cat.categorie_id = art.categorie_id ”.$filter.” GROUP BY
art.article_id ORDER BY article_date DESC”;
return Multiple::parseRequest($request, true);
} // getArticles
// getCategories
function getCategories() {
$request = ”SELECT cat.*, COUNT(art.article_id) as artNbr FROM ”.BDD_
PREFIX.”categories cat LEFT JOIN ”.BDD_PREFIX.”articles art USING(categorie_id) GROUP BY
categorie_id ORDER BY categorie_name ASC”;
return Multiple::parseRequest($request, true);
} // getCategories
// getComments
function getComments( $art=false ) {
if( is_numeric($art) ) {
$filter = ”WHERE article_id = ‘”.intval($art).”’”;
}
$request = ”SELECT * FROM «.BDD_PREFIX.”comments ”.$filter.” ORDER BY comment_date
DESC”;
return Multiple::parseRequest($request, true);
} // getComments
// getFolders
function getFolders( $public=false ) {
if( $public ) {
$filter = ”WHERE folder_private = 0”;
}
$request = ”SELECT fld.*, COUNT(pto.photo_id) AS nbrPhotos FROM ”.BDD_PREFIX.”folders
fld LEFT JOIN ”.BDD_PREFIX.”photos pto USING(folder_id) ”.$filter.” GROUP BY folder_id ORDER BY
folder_private DESC, folder_display_order ASC”;
return Multiple::parseRequest($request, true);
} // getFolders
// getPhotos
function getPhotos( $id ) {
$request = ”SELECT * FROM ”.BDD_PREFIX.”photos WHERE folder_id = ‘”.$id.”’ ORDER BY
photo_display_order ASC”;
return Multiple::parseRequest($request, true);
} // getPhotos
(suite du code à la page suivante)
// ----------------------------------------
// --- fonctions utilitaires
<?php
// inclusion noyau
require_once(”../core/core_admin.php”);
session_start();
// action à effectuer
switch( $_GET[”action”] ) {
case ”confirmDelete”:
$delNews = new Element(”news”, intval( $_POST[”new_id”] ) );
if( isset( $_POST[”reset”] ) ) {
$smarty->assign(”news”, Multiple::getNews() );
$smarty->assign(”action”, ”list”);
break;
}
if( !$delNews->delete() ) {
$smarty->assign(”error”, ”cantSuppressNews”);
}
$smarty->assign(”news”, Multiple::getNews() );
$smarty->assign(”action”, ”list”);
break;
case ”delete”:
$delNews = new Element(”news”, intval($_GET[”id”]) );
if( !$delNews ) {
$smarty->assign(”error”, ”news_dontExists”);
$smarty->assign(”news”, Multiple::getNews() );
$smarty->assign(”action”, ”list”);
} else {
$smarty->assign(”newsData”, $delNews);
$smarty->assign(”action”, ”delete”);
}
break;
case ”addSubmit”:
if( empty($_POST[”new_title”]) || empty($_POST[”new_description”]) ) {
$smarty->assign(”error”, ”emptyForm”);
$smarty->assign(”action”, ”add”);
} else {
$tempNews = new Element();
$tempNews->o_table = BDD_PREFIX.”news”;
$tempNews->o_idPrefix = ”new”;
if( !$tempNews ) {
$smarty->assign(”error”, ”saveError”);
$smarty->assign(”news”, Multiple::getNews() );
$smarty->assign(”action”, ”list”);
} else {
$tempNews->new_title = str_entities( $_POST[”new_title”] );
$tempNews->new_date = ””.intval( $_POST[”new_date_Year”] ).”-
”.intval( $_POST[”new_date_Month”] ).”-”.intval( $_POST[”new_date_Day”] );
$tempNews->new_date_expiration = ””.intval( $_POST[”new_date_
expiration_Year”] ).”-”.intval( $_POST[”new_date_expiration_Month”] ).”-”.intval( $_POST[”new_
date_expiration_Day”] );
$tempNews->new_description = str_entities( $_POST[”new_description”] );
if( !$tempNews->save() ) {
$smarty->assign(”error”, ”saveError”);
$smarty->assign(”newsData”, $tempNews );
$smarty->assign(”action”, ”edit”);
} else {
$smarty->assign(”news”, Multiple::getNews() );
$smarty->assign(”action”, ”list”);
}
}
}
break;
case ”add”:
$smarty->assign(”action”, ”add”);
break;
// affichage
$smarty->assign(”PageScriptFile”, ”admin_news”);
$smarty->assign(”activePage”, ”site”);
$smarty->assign(”activeUnder”, ”news”);
$smarty->display(”admin_news.tpl”);
?>
Annexe 6 : Captures d’écran
Les captures d’écran ont été réalisées avec le navigateur Firefox 2.0.0.3 sur Mac
OS 10.4.9
Capture n°1
Chat privé et son formulaire.
Capture n°2
Module de gestion des
membres
Capture n°3
Module des photos :
organisation des photos
Capture n°4
Edition d’une vidéo importée
de YouTube
ish in a pan est un CMS (Content Ma- ish in a pan is a CMS (Content Mana-
nagement System - Système de gestion gement System) which easily allows to
de contenu) qui permet de facilement create and to keep updated a website
créer et maintenir à jour un site dédié dedicated to a music band with all the
à un groupe de musique, avec tous les appropriated functions: media, journal,
fonctionnalités appropriées : gestion tour dates management and so on.
de médias, d’un agenda, d’un livre d’or This project, which was first created for
et bien d’autres choses. an egocentric purpose (the manage-
Ce projet, qui a la base était une pro- ment of my band website), slowly turns
duction égoïste et destinée à ne servir to become an open and online project
qu’à un seul site et un seul groupe de so that all bands could use it freely wi-
musique (le mien), s’est doucement thout charges. The main goal is to help
changé en un projet ouvert et destiné those bands which didn’t have time or
à être publié sur internet, pour être uti- skills enough to manage their music,
lisée de manière libre et gratuite par their members and their website in the
tous les groupes en manque de temps same time.
et de compétences pour pouvoir se do- From the hook to the plate the docu-
ter d’un site web facile à maintenir en ment you are holding in your hands is
vie en même temps que le groupe dont going to tell you everything about this
il parle. weird fish which has been frying slowly
De la préparation du hameçon à la fina- in its pan from nearly one year...
lisation du projet, le document que vous
tenez dans les mains vous dira tout sur
cet étrange poisson qui frit doucement
dans sa poêle depuis bientôt un an...