* (avec quelques bouts de code "empruntés" au projet SMOB (fonctions sen_data(), twitter_post(), curl_get())) * * Licence GPL - Version 0.1 dév : première version de développement TODO : - ??' gérer les cas où on a plusieurs comptes twitter - ??' gérer la langue ? - ??' gérer la timezone ? - ??' gérer le paramétrage des serveurs SMOB - attention un effacement efface également tous les doublons ! TODO en question : - permettre de reposter un message ? - gérer le cas où aucun serveur n'est spécifié Usage : {{smob}} dans une page correspondant à un utilisateur ou {{smob user="TelUser"}} */ // Vérification de sécurité if (!defined("WIKINI_VERSION")) { die ("accès direct interdit"); } if(!function_exists("curl_init")) { die ("cURL n'est pas disponible."); } // Déclarations // TODO : Déclarer une constante dans le fichier des constantes ? if (!defined("WN_USER_DATA_RDF_HANDLER")) define("WN_USER_DATA_RDF_HANDLER", "userdata"); // --------------------------------------------- Action proprement dite class ActionSmob extends WikiniAction { function PerformAction($args) { $wiki = &$this->wiki; $array_user = $wiki->GetUser(); // Renvoie le nom de l'utilisateur courrant si connecté $current_user = isset($array_user["name"]) ? $array_user["name"] : ''; $currentPage = $wiki->tag; $r = ""; // Si un utilisateur est spécifié comme argument if(isset($args["user"])) { if($wiki->LoadUser($args["user"])) { $suser = $wiki->GetUser($args["user"]); $smob_user = $suser["name"]; } else echo "..."; } // Sinon on regarde si l'action est utilisée dans la page d'un utilisateur else if($wiki->LoadUser($currentPage)) { $smob_user = $currentPage; } // Sinon on prend comme utilisateur l'utilisateur courrant else if($current_user) { $smob_user = $current_user; } if (!$smob_user) { echo "Impossible d'utiliser cette action. Il faut :". "" . "
"; return; } $subject = $smob_user; $property = "http://www.wikini.net/_vocabulary/smobContent"; $value = isset($_GET['value']) ? $_GET['value'] : ""; $value = isset($_POST['value']) ? $_POST['value'] : $value; $lang = isset($_GET['lang']) ? $_GET['lang'] : ""; $lang = isset($_POST['lang']) ? $_POST['lang'] : $lang; $comment = isset($_GET['comment']) ? $_GET['comment'] : ""; $comment = isset($_POST['comment']) ? $_POST['comment'] : $comment; //$twitter_user = "CharlesNepote"; //$twitter_pass = "..."; $servers = array( 'http://smob.sioc-project.org/server' => '', 'http://microplanet.sioc-project.org/' => '', 'http://smob.websemantique.org' => '', //'http://localhost/smob/server' => '', );/**/ // --------------------------------- Sauve les triplets if($property && $value) { $error_code = $wiki->InsertTriple($subject, $property, $value, "", "", "", "", false); //echo $error_code; /*if($error_code == "0") $wiki->Redirect($wiki->Href()); else echo "InsertTriple erreur : " . $error_code ." - " . $subject . " -> " . $property . " -> " . $value;*/ } // --------------------------------- Publication du message if($value) { // http://code.google.com/p/smob/source/browse/trunk/client/publish/index.php $content = $value; // We know what to quote better than you PHP, thank you very much: if(get_magic_quotes_gpc()) $content = stripslashes($content); print "

Publishing your message...

\n"; // date('c') isn't implemented by PHP4: // $ts = date('Y-m-d\TH:i:s'). substr_replace(date('O'),':',3,0); // Donne : 2008-05-26T16:09:13+02:00 // Construction de l'adresse d'appel du message au format RDF // ATTENTION : la date est actuellement sauvée dans la base à l'aide // de la fonction now() de MYSQL => donne "2008-05-26 17:29:37" //$date = $_GET["date"]; $sql = 'SELECT * FROM ' . $wiki->GetConfigValue('table_prefix') . 'triples ' . 'WHERE resource = "' . addslashes($subject) . '" ' . 'AND property = "' . addslashes("http://www.wikini.net/_vocabulary/smobContent") . '" ' . 'ORDER BY time DESC'; //. 'AND time = "' . $date . '"'; //echo $sql; $result = $wiki->LoadSingle($sql); //print_r($result); /* Array ( [id] => 53 [time] => 2008-05-27 22:38:22 [user] => CharlesNepote [resource] => CharlesNepote [property] => http://www.wikini.net/_vocabulary/smobContent [value] => dfjks jfksd fjkjsdi [lang] => [comment] => )*/ // URL du fichier SIOC. http://example.org/wakka.php?wiki=TelUser/smob&date=2008-05-27T22:38:22 $rdf_file = $wiki->Href("smob", $subject) . '&date=' . str_replace(" ", "T", $result["time"]); // Construction de l'URL et de l'URI de la personne au format FOAF $foaf_url = $wiki->Href("userdata", $subject); $foaf_uri = $wiki->Href("userdata", $subject) . "#me"; // Publie l'URL du fichier RDF généré à destination de chaque agrégateur SMOB print "\n"; } // --------------------------------- Efface les triplets if(isset($_POST["del-property"])) { $error_code = $wiki->DeleteTriple($subject, $_POST["del-property"], $_POST["del-value"], "", ""); // TODO : modifier la méthode DeleteTriple pour qu'elle renvoie un résultat /*if($error_code == "0") $wiki->Redirect($wiki->Href()); else echo "erreur : " . $error_code ." - " . $tag . " -> " . $property . " -> " . $value;*/ $wiki->Redirect($wiki->Href()); } // --------------------------------- Affiche les propriétés existantes $r .= "\n\n"; $r .= '
' . "\n"; // TODO / FIXME : à terme, passer \n"; // --- Recherche et affiche tous les triplets relatifs à cette URI $triples = $wiki->GetMatchingTriples($subject, $property); usort($triples, array($this,"compare")); $r .= '

Gazouillis de ' . $wiki->Link($subject) . '. [rdf]

' . "\n"; $r .= '' . "\n"; foreach($triples as $triple) { if(isset($_GET["delete"]) && $_GET["delete"] == $triple["id"]) { $r .= '' . "\n"; $r .= '' . "\n"; $r .= '' . "\n"; $r .= ''. "\n"; } else $r .= ''. "\n"; $r .= ''; /*$r .= '";*/ $r .= '' . "\n"; $r .= '' . "\n"; if(isset($_GET["delete"]) && $_GET["delete"] == $triple["id"]) { $r .= '' ."\n"; $r .= '' ."\n"; $r .= '' . "\n"; } else { $r .= '' . "\n"; $r .= '' . "\n"; } } $r .= '
' . $triple["time"] . '' . $this->GetRDFSLabel($triple["property"]) . "'; $l = $this->GetRDFSLabel($triple["value"]); $r .= $this->isURI($triple["value"]) ? '' . htmlentities($this->shorten($l)) . '' : htmlentities($this->shorten($l)); $r .= ''; $r .= '[rdf]'; $r .= '' . ''; $r .= '
'; $r .= 'effacer'; $r .= '
' . "\n"; // --------------------------------- Affiche le formulaire de saisie // --- Formulaire 1 si l'utilisateur est identifié if($smob_user == $current_user) { $r .= '
' . "\n"; $r .= '' . "\n"; $r .= '' . "\n"; $r .= '

'; $r .= $subject . " "; $r .= '' . $this->GetRDFSLabel($property) . " "; $r .= '

' . "\n"; $r .= ' ' . "\n"; // Liste des serveurs accessibles foreach($servers as $server => $key) { $r .= '' . $server . '
' ."\n"; } // Si l'utilisateur a déclaré un compte twitter, lui proposer if(isset($twitter_user) && isset($twitter_pass)) { $r .= '' . 'Twitter as ' . $twitter_user . '
' . "\n"; } $r .= '

'; $r .= '' . "\n"; $r .= '[ou voir la Documentation complète]'; $r .= '

' . "\n"; // Liste des serveurs SMOB où l'utilisateur peut publier // Si l'utilisateur a déclaré un compte Twitter $r .= '
' . "\n"; } // --- Fermeture de la boite "smob" $r .= "
\n"; $r .= "\n\n"; // Affichage de la boite return $r; } // Fonctions ------------------------------------------------------------ function twitter_post($content, $user, $pass) { $dest = 'http://twitter.com/statuses/update.xml'; $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $dest); curl_setopt($ch, CURLOPT_HEADER, 0); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_POSTFIELDS, "status=$content&source=smob"); curl_setopt($ch, CURLOPT_USERPWD, "$user:$pass"); $data = curl_exec($ch); curl_close($ch); return $data; } function curl_get($url) { $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_HEADER, 1); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); $response = curl_exec($ch); if ($error = curl_error($ch)) return array("$error.", "", 0); $status_code = curl_getinfo($ch, CURLINFO_HTTP_CODE); $status_line = substr($response, 0, strcspn($response, "\n\r")); $header_size = curl_getinfo($ch, CURLINFO_HEADER_SIZE); $body = substr($response, $header_size); curl_close($ch); return array($body, $status_line, $status_code); } function send_data($url, $server) { global $servers; $key = $servers[$server]; // TODO virer le code en dur $dest = "$server/load/index.php?key=$key&data=".urlencode($url); print "Telling $server"; print " about $url...
\n"; print htmlentities($dest) . "
\n"; print htmlentities(urldecode($url)) . "
\n"; list ($resp, $status, $code) = $this->curl_get($dest); if ($code != 200 && $status) print "$status: "; if (!$resp) { if ($code == 200) print "Done."; else print "No response!"; } print "$resp\n"; } /** * isURI * * @param string $string URI * @return boolean True ou false */ function isURI($string) { if(preg_match("@^https?://[a-z0-9-]+(\.[a-z0-9-]+)*(/[a-z0-9-_\%\?\=\+\&]*)*@", $string)) return true; else return false; } /** * compare triple * Établi une comparaison entre deux chaînes * * @param string $a Première chaîne * @param string $b Deuxième chaîne * @return numeric Rapport de comparaison entre le deux : 0, -1 ou 1 * */ function compare($a, $b) { if ($a['time'] == $b['time']) return 0; return ($this->GetRDFSLabel($a['time']) < $this->GetRDFSLabel($b['time'])) ? 1 : -1; } /** * Retourne le type du sujet * * @param string subject * @return array Tableau contenant les types RDF * */ function GetRDFType($subject) { $wiki = &$this->wiki; // 1. Types définis par WikiNi $user = $wiki->LoadUser($subject); if($user) $return[] = "foaf:person"; // ou plutôt foaf:agent ? $return[] = "rdf:resource"; // 2. Types définis d'après les rdf:type et/ou les autres propriétés // TODO : Lire le fichier RDF avec ARC ? // return $return; } /** * GetPossibleValues * * @param string property Propriété * @return array Tableau des différentes valeurs possibles * */ function GetPossibleValues($property) { $wiki = &$this->wiki; // 0. --- Valeurs particulières codées en dur if($property == "http://www.wikini.net/_vocabulary/hasPrivacySetting") { return array("http://www.wikini.net/_vocabulary/AllowIDValues"); } if($property == "http://www.wikini.net/_vocabulary/knows") { $query = 'SELECT name FROM '.$wiki->GetConfigValue('table_prefix').'users '; $array_user = $wiki->LoadAll($query." ORDER BY name ASC"); foreach($array_user as $user) { $return[] = $wiki->Href(WN_USER_DATA_RDF_HANDLER, $user["name"]) . "#me"; } return $return; }/**/ // 1. --- retrouve les classes de valeurs possibles // 2. --- Propriétés calculées selon des vocabulaires importés (comment ?) } /** * GetRDFSLabel : retourne le label d'une classe, d'une ressource * ou d'une propriété * * @param string $resource Nom de la resource * @param string $lang Langue du label * @return string label dans la langue demandée * */ function GetRDFSLabel($resource, $lang = "fr") { $wiki = &$this->wiki; include("./includes/rdf.php"); $motif = '`^' . addcslashes($wiki->GetConfigValue("base_url"), '?') . WN_TAG_HANDLER_CAPTURE . '(#me)?$`'; if (preg_match($motif, $resource, $matches)) { list(, $page, $method) = $matches; return $page; } else { $return = isset($array_label[$resource][$lang]) ? $array_label[$resource][$lang] : $resource; return $return; } } /** * GetNamespace............. */ /** * shorten * Shorten a string to the given lenght (140 by default) * * @param string $uri URI * @param numeric $lenght Lenght of the returned string * */ function shorten($uri, $lenght = 140) { // Si la longueur ne dépasse pas XX caractères (32 par défaut) if(strlen($uri) < $lenght) return $uri; else { $uri = substr($uri, 0, $lenght) . "[...]"; return $uri; } } } ?>