* @author Uldis Bojars (adaptation to PHP4) * @author Thomas Schandl (addition of SIOCThread) * @author Fabrizio Orlandi (addition of SIOCWIki SIOCWikiArticle SIOCCategory) * * @phpcs:disable PSR1.Classes.ClassDeclaration.MultipleClasses */ const AUTHORS_NODE = 'authors'; const EXPORTER_URL = 'http://wiki.sioc-project.org/index.php/PHPExportAPI'; const EXPORTER_VERSION = '1.01'; /** * Main exporter class. * * Generates RDF/XML content of SIOC export. * - Sets up parameters for generating RDF/XML * - Sets up parameters for SIOC URL generation */ class SIOCExporter { public $profile_url; private $title; private $blog_url; private $sioc_url; private $encoding; private $generator; private $urlseparator; private $urlequal; private $url4type; // e.g. type or sioc_type private $url4id; // TS e. g. id or sioc_id private $url4page; // TS: if true: appends the "type" of a class to the url4id in order to compose the string for the "id part" // of the siocURL. e. g. for a forum that could produce "forum_id=" or "forum_sioc_id=" private $url_usetype; private $url_suffix; // TS: custom parameter to be appended at the end of a siocURL private $type_table; private $ignore_suffix; // TS: for types in this table the url_suffix won't be appended to their siocURL private $export_email; private $objects; public function __construct() { $this->urlseparator = '&'; $this->urlequal = '='; $this->url4type = 'type'; $this->url4id = 'id'; $this->url4page = 'page'; $this->url_usetype = true; $this->url_suffix = ''; $this->type_table = array(); $this->ignore_suffix = array(); $this->export_email = false; $this->encoding = 'UTF-8'; $this->objects = array(); } public function setURLParameters( $type = 'type', $id = 'id', $page = 'page', $url_usetype = true, $urlseparator = '&', $urlequal = '=', $suffix = '' ) { $this->urlseparator = $urlseparator; $this->urlequal = $urlequal; $this->url4type = $type; $this->url4id = $id; $this->url4page = $page; $this->url_usetype = $url_usetype; $this->url_suffix = $suffix; } public function setParameters($title, $url, $sioc_url, $encoding, $generator, $export_email = false) { $this->title = $title; $this->blog_url = $url; $this->sioc_url = $sioc_url; $this->encoding = $encoding; $this->generator = $generator; $this->export_email = $export_email; } // Assigns some objects to the exporter public function addObject(&$obj) { $this->objects[] = &$obj; } // TS: Used to replace url4id in the siocURL for a given type (site, forum, etc.) with a // parameter ($name) of your choice // E.g. b2evo exporter uses "blog=" instead of "sioc_id=" in the siocURL of a forum public function setURLTypeParm($type, $name) { $this->type_table[$type] = $name; } public function setSuffixIgnore($type) { $this->ignore_suffix[$type] = 1; } public function siocURL($type, $id, $page = "") { $type_part = $this->url4type . $this->urlequal . $type; if ($id) { if (isset($this->type_table[$type])) { $myID = $this->type_table[$type]; } else { $myID = (($this->url_usetype) ? $type . '_' : '') . $this->url4id; } $id_part = $this->urlseparator . $myID . $this->urlequal . $id; } else { $id_part = ''; } ($page) ? $page_part = $this->urlseparator . $this->url4page . $this->urlequal . $page : $page_part = ''; ($this->url_suffix && !isset($this->ignore_suffix[$type])) ? $suffix = $this->urlseparator . $this->url_suffix : $suffix = ''; $siocURL = $this->sioc_url . $type_part . $id_part . $page_part . $suffix; return clean($siocURL, true); } public function export($rdf_content = '') { header('Content-Type: application/rdf+xml; charset=' . $this->encoding, true, 200); echo $this->makeRDF($rdf_content); } public function makeRDF($rdf_content = '') { $rdf = 'encoding . '" ?>' . "\n"; $rdf .= ' "' . clean($this->title) . '" (SIOC profile) ' . "\n"; if ($rdf_content) { $rdf .= $rdf_content; } if (count($this->objects)) { foreach ($this->objects as $object) { if ($object) { $rdf .= $object->getContent($this); } } } $rdf .= "\n"; return $rdf; } } /** * Generic SIOC Object * * All SIOC objects are derived from this. */ class SIOCObject { protected $note = ''; public function addNote($note) { $this->note = $note; } public function getContent(&$exp): string { $rdf = "\n"; $rdf .= " Generic SIOC Object\n"; $rdf .= "\n"; return $rdf; } } /** * SIOC::Site object * * Contains information about main SIOC page including: * - site description * - list of forums * - list of users */ class SIOCSite extends SIOCObject { private $type = 'site'; private $url; private $name; private $description; private $forums; private $users; private $page; private $next_users; private $next_forums; private $usergroup_uri; public function __construct($url, $name, $description, $page = '', $usergroup_uri = '') { $this->url = $url; $this->name = $name; $this->description = $description; $this->forums = array(); $this->users = array(); $this->page = $page; $this->next_users = false; $this->next_forums = false; $this->usergroup_uri = $usergroup_uri; } public function addForum($id, $url) { $this->forums[$id] = $url; } public function addUser($id, $url) { $this->users[$id] = $url; } public function setNextPageUsers($next) { $this->next_users = $next; } public function setNextPageForums($next) { $this->next_forums = $next; } public function getContent(&$exp): string { $rdf = "url) . "\">\n"; $rdf .= " " . clean($this->name) . "\n"; $rdf .= " " . clean($this->description) . "\n"; $rdf .= " url) . "\"/>\n"; if ($this->forums) { foreach ($this->forums as $id => $url) { $rdf .= " \n"; } } if ($this->next_forums) { $rdf .= " siocURL('site', "", $this->page + 1) . "\"/>\n"; } if ($this->usergroup_uri) { $rdf .= " usergroup_uri . "\"/>\n"; } else { $rdf .= " \n"; } $rdf .= "\n"; // Forums if ($this->forums) { $rdf .= "\n"; foreach ($this->forums as $id => $url) { $rdf .= '\n"; $rdf .= " \n"; $rdf .= " siocURL('forum', $id) . "\"/>\n"; $rdf .= "\n"; } } // Usergroup if ($this->users) { $rdf .= "\n"; if ($this->usergroup_uri) { $rdf .= '\n"; } else { $rdf .= '\n"; } $rdf .= " Authors for \"" . clean($this->name) . "\"\n"; foreach ($this->users as $id => $url) { $rdf .= " \n"; $rdf .= " \n"; $rdf .= " siocURL('user', $id) . "\"/>\n"; $rdf .= " \n"; $rdf .= " \n"; } if ($this->next_users) { $rdf .= " siocURL('site', "", $this->page + 1) . "\"/>\n"; } $rdf .= "\n"; } return $rdf; } } // Export detaille d'un utilisateur /** * SIOC::User object * * Contains user profile information */ class SIOCUser extends SIOCObject { private $type = 'user'; private $id; private $nick; private $uri; private $name; private $email; private $sha1; private $homepage; private $foaf_uri; private $role; private $sioc_url; private $foaf_url; public function __construct( $id, $uri, $name, $email, $homepage = '', $foaf_uri = '', $role = false, $nick = '', $sioc_url = '', $foaf_url = '' ) { $this->id = $id; $this->uri = $uri; $this->name = $name; if (preg_match_all('/^.+@.+\..+$/Ui', $email, $check, PREG_SET_ORDER)) { if (preg_match_all('/^mailto:(.+@.+\..+$)/Ui', $email, $matches, PREG_SET_ORDER)) { $this->email = $email; $this->sha1 = sha1($email); } else { $this->email = "mailto:" . $email; $this->sha1 = sha1("mailto:" . $email); } } $this->homepage = $homepage; $this->foaf_uri = $foaf_uri; $this->_url = $foaf_uri; $this->role = $role; $this->nick = $nick; $this->foaf_url = $foaf_url; $this->sioc_url = $sioc_url; } public function getContent(&$exp): string { $rdf = "foaf_uri) . "\">\n"; if ($this->name) { $rdf .= " " . $this->name . "\n"; } if ($this->email) { $rdf .= " " . $this->sha1 . "\n"; } if ($this->foaf_url) { $rdf .= " foaf_url . "\"/>\n"; } $rdf .= " \n"; $rdf .= " uri) . "\">\n"; if ($this->nick) { $rdf .= " " . $this->nick . "\n"; } if ($this->email) { if ($exp->_export_email) { $rdf .= " email . "\"/>\n"; } $rdf .= " " . $this->sha1 . "\n"; } if ($this->role) { $rdf .= " \n"; $rdf .= " \n"; $rdf .= " " . $this->role . "\n"; $rdf .= " \n"; $rdf .= " \n"; } if ($this->sioc_url) { $rdf .= " sioc_url . "\"/>\n"; } $rdf .= " \n"; $rdf .= " \n"; $rdf .= "\n"; return $rdf; } } // Export detaille d'un utilisateur /** * SIOC::Thread object * * Contains information about a SIOC Thread in a SIOC Forum * - list of posts in that thread */ class SIOCThread extends SIOCObject { private $type = 'thread'; private $id; private $url; private $page; private $posts; private $next; private $views; private $tags; private $related; private $title; private $created; private $parents; /** * @var mixed|string */ private $subject; public function __construct($id, $url, $page, $views = '', $tags = array(), $subject = '', $created = '') { $this->id = $id; $this->url = $url; $this->page = $page; $this->posts = array(); $this->next = false; $this->views = $views; $this->tags = $tags; $this->related = array(); $this->subject = $subject; $this->created = $created; } public function addPost($id, $url, $prev = '', $next = '') { $this->posts[$id] = array("url" => $url, "prev" => $prev, "next" => $next); } // add links to things that are similar to this via sioc:related_to public function addRelated($id, $url) { $this->related[$id] = $url; } public function setNextPage($next) { $this->next = $next; } public function addParentForum($id, $url) { $this->parents[$id] = $url; } public function getContent(&$exp): string { $rdf = '\n"; $rdf .= " url) . "\"/>\n"; if ($this->views) { $rdf .= " " . $this->views . "\n"; } if ($this->note) { $rdf .= " " . $this->note . "\n"; } if ($this->subject) { $rdf .= " " . $this->subject . "\n"; } if ($this->created) { $rdf .= " " . $this->created . "\n"; } if ($this->parents) { foreach ($this->parents as $id => $uri) { $rdf .= " \n"; $rdf .= " \n"; $rdf .= " siocURL('forum', $id) . "\"/>\n"; $rdf .= " \n"; $rdf .= " \n"; } } // here the tags are just used as keywords for dc:subject if ($this->tags) { foreach ($this->tags as $id => $tag) { $rdf .= " " . $tag . "\n"; } } // here the tags are used by creating a tag object with a blank node, with the keyword as moat:name - if you // use this insert prefixes for moat and tags // if ($this->tags) { // $i=1; // foreach ($this->tags as $id => $tag) { // $rdf .= " \n"; // $rdf .= " \n"; // // actually, the best way is to have 'reference URIs' for tags, e.g. URIs for all the platform // (http://tags.example.org/tag/soccer // $rdf .= " " . $tag . "\n"; // $rdf .= " \n"; // $rdf .= " \n"; // $i++; // } // } // here the tags are used are used for sioc:topic, each topic needs to have a URI /*if($this->tags) { foreach($this->tags as $url=>$topic) { $rdf .= " \n"; } } */ if ($this->related) { foreach ($this->related as $id => $url) { $rdf .= " \n"; $rdf .= " \n"; $rdf .= " \n"; // todo - each topic needs to have a URI } } if ($this->posts) { foreach ($this->posts as $id => $data) { $rdf .= " \n"; $rdf .= " \n"; $rdf .= " siocURL('post', $id) . "\"/>\n"; if ($data[prev]) { $rdf .= " \n"; } if ($data[next]) { $rdf .= " \n"; } $rdf .= " \n"; $rdf .= " \n"; } } if ($this->next) { $rdf .= "\rsiocURL('thread', $this->id, $this->page + 1) . "\"/>\n"; } $rdf .= "\n"; return $rdf; } } // Export d'un forum avec une liste de posts -variable (next with seeAlso) /** * SIOC::Forum object * * Contains information about SIOC Forum (blog, ...): * - description of a forum * - list of posts within a forum [partial, paged] */ class SIOCForum extends SIOCObject { private $type = 'forum'; private $id; private $url; private $page; private $posts; private $next; private $blog_title; private $description; private $threads; private $parents; private $creator; private $administrator; /** * @var array|mixed */ private $links; public function __construct( $id, $url, $page, $title = '', $descr = '', $type = 'sioc:Forum', $creator = '', $admin = '', $links = array() ) { $this->id = $id; $this->url = $url; $this->page = $page; $this->posts = array(); $this->next = false; $this->blog_title = $title; $this->description = $descr; $this->threads = array(); $this->parents = array(); $this->_type = $type; $this->creator = $creator; $this->administrator = $admin; $this->links = $links; } public function addPost($id, $url) { $this->posts[$id] = $url; } public function addThread($id, $url) { $this->threads[$id] = $url; } public function addParentForum($id, $url) { $this->parents[$id] = $url; } public function setNextPage($next) { $this->next = $next; } public function getContent(&$exp): string { $rdf = '<' . $this->_type . ' rdf:about="' . clean($this->url) . "\">\n"; if ($this->_type != 'sioc:Forum') { $rdf .= " \n"; } $rdf .= " url) . "\"/>\n"; if ($this->blog_title) { $rdf .= " " . $this->blog_title . "\n"; } if ($this->description) { $rdf .= " " . $this->description . "\n"; } if ($this->note) { $rdf .= " " . $this->note . "\n"; } if ($this->parents) { foreach ($this->parents as $id => $uri) { $rdf .= " \n"; $rdf .= " \n"; $rdf .= " siocURL('forum', $id) . "\"/>\n"; $rdf .= " \n"; $rdf .= " \n"; } } if ($this->threads) { foreach ($this->threads as $id => $uri) { $rdf .= " \n"; $rdf .= " \n"; $rdf .= " siocURL('thread', $id) . "\"/>\n"; $rdf .= " \n"; $rdf .= " \n"; } } if ($this->posts) { foreach ($this->posts as $id => $url) { $rdf .= " \n"; $rdf .= " \n"; $rdf .= " siocURL('post', $id) . "\"/>\n"; $rdf .= " \n"; $rdf .= " \n"; } } if ($this->creator) { if ($this->creator->_id) { $rdf .= " \n"; $rdf .= " creator->_uri) . "\">\n"; if ($this->creator->_sioc_url) { $rdf .= " creator->_sioc_url . "\"/>\n"; } else { $rdf .= " siocURL( 'user', $this->creator->_id ) . "\"/>\n"; } $rdf .= " \n"; $rdf .= " \n"; $rdf .= " \n"; $rdf .= " creator->_foaf_uri) . "\">\n"; if ($this->creator->_foaf_url) { $rdf .= " creator->_foaf_url . "\"/>\n"; } else { $rdf .= " siocURL( 'user', $this->creator->_id ) . "\"/>\n"; } $rdf .= " \n"; $rdf .= " \n"; } else { $rdf .= " \n"; $rdf .= " creator->_name) { $rdf .= " foaf:name=\"" . $this->creator->_name . "\""; } if ($this->creator->_sha1) { $rdf .= " foaf:mbox_sha1sum=\"" . $this->creator->_sha1 . "\""; } if ($this->creator->_name) { $rdf .= ">\ncreator->_homepage . "\"/>\n\n"; } else { $rdf .= "/>\n"; } $rdf .= " \n"; } } if ($this->administrator) { if ($this->administrator->_id) { $rdf .= " \n"; $rdf .= " administrator->_uri) . "\">\n"; if ($this->administrator->_sioc_url) { $rdf .= " administrator->_sioc_url . "\"/>\n"; } else { $rdf .= " siocURL( 'user', $this->administrator->_id ) . "\"/>\n"; } $rdf .= " \n"; $rdf .= " \n"; } } if ($this->links) { foreach ($this->links as $url => $link) { $rdf .= " \n"; } } if ($this->next) { $rdf .= "\rsiocURL('forum', $this->id, $this->page + 1) . "\"/>\n"; } $rdf .= "_type . ">"; return $rdf; } } /** * SIOC::Post object * * Contains information about a post */ class SIOCPost extends SIOCObject { private $type = 'post'; private $url; private $subject; private $content; private $encoded; private $creator; private $created; private $updated; private $topics; private $links; private $comments; private $reply_of; private $has_part; public function __construct( $url, $subject, $content, $encoded, $creator, $created, $updated = "", $topics = array(), $links = array(), $type = 'sioc:Post', $has_part = array() ) { $this->url = $url; $this->subject = $subject; $this->content = $content; $this->encoded = $encoded; $this->creator = $creator; $this->created = $created; $this->updated = $updated; $this->topics = $topics; $this->links = $links; $this->comments = array(); $this->reply_of = array(); $this->_type = $type; $this->has_part = $has_part; } public function addComment($id, $url) { $this->comments[$id] = $url; } public function addReplyOf($id, $url) { $this->reply_of[$id] = $url; } public function getContent(&$exp): string { $rdf = '<' . $this->_type . " rdf:about=\"" . clean($this->url) . "\">\n"; if ($this->_type != 'sioc:Post') { $rdf .= " \n"; } if ($this->subject) { $rdf .= " " . $this->subject . "\n"; } if ($this->creator) { if ($this->creator->_id) { $rdf .= " \n"; $rdf .= " creator->_uri) . "\">\n"; if ($this->creator->_sioc_url) { $rdf .= " creator->_sioc_url . "\"/>\n"; } else { $rdf .= " siocURL( 'user', $this->creator->_id ) . "\"/>\n"; } $rdf .= " \n"; $rdf .= " \n"; $rdf .= " \n"; $rdf .= " creator->_foaf_uri) . "\">\n"; if ($this->creator->_foaf_url) { $rdf .= " creator->_foaf_url . "\"/>\n"; } else { $rdf .= " siocURL( 'user', $this->creator->_id ) . "\"/>\n"; } $rdf .= " \n"; $rdf .= " \n"; } else { $rdf .= " \n"; $rdf .= " creator->_name) { $rdf .= " foaf:name=\"" . $this->creator->_name . "\""; } if ($this->creator->_sha1) { $rdf .= " foaf:mbox_sha1sum=\"" . $this->creator->_sha1 . "\""; } if ($this->creator->_name) { $rdf .= ">\ncreator->_homepage . "\"/>\n\n"; } else { $rdf .= "/>\n"; } $rdf .= " \n"; } } $rdf .= " " . $this->created . "\n"; if ($this->updated and ($this->created != $this->updated)) { $rdf .= " " . $this->updated . "\n"; } $rdf .= " " . pureContent($this->content) . "\n"; $rdf .= " encoded . "]]>\n"; if ($this->topics) { foreach ($this->topics as $url => $topic) { $rdf .= " \n"; } } if ($this->links) { foreach ($this->links as $url => $link) { $rdf .= " \n"; } } if ($this->has_part) { foreach ($this->has_part as $id => $url) { $rdf .= " \n"; $rdf .= " \n"; $rdf .= " \n"; } } if ($this->reply_of) { foreach ($this->reply_of as $id => $url) { $rdf .= " \n"; $rdf .= " \n"; $rdf .= " siocURL('post', $id) . "\"/>\n"; $rdf .= " \n"; $rdf .= " \n"; } } if ($this->comments) { foreach ($this->comments as $id => $url) { $rdf .= " \n"; $rdf .= " \n"; // if($comments->f('comment_trackback')) $rdf .= " " // . POST_TRACKBACK . "\n"; // else $rdf .= " " . POST_COMMENT . "\n"; $rdf .= " siocURL('comment', $id) . "\"/>\n"; $rdf .= " \n"; $rdf .= " \n"; } } $rdf .= "_type . ">\n"; return $rdf; } } /** * SIOC::WikiArticle object * * Contains information about a wiki article */ class SIOCWikiArticle extends SIOCObject { private $type = 'sioct:WikiArticle'; private $url; private $api = null; private $subject; private $redirpage; private $creator; private $created; private $topics; private $links; private $ext_links; private $previous_version; private $next_version; private $latest_version; private $has_discussion; private $has_container; public function __construct( $url, $api, $subject, $redir, $user, $created, $prev_vers, $next_vers, $latest_vers, $has_discuss, $container, $topics = array(), $links = array(), $ext_links = array(), $type = 'sioct:WikiArticle' ) { $this->url = $url; $this->api = $api; $this->subject = $subject; $this->redirpage = $redir; $this->creator = $user; $this->created = $created; $this->topics = $topics; $this->links = $links; $this->ext_links = $ext_links; $this->_type = $type; $this->previous_version = $prev_vers; $this->next_version = $next_vers; $this->latest_version = $latest_vers; $this->has_discussion = $has_discuss; $this->has_container = $container; } public function getContent(&$exp): string { $rdf = '<' . $this->_type . " rdf:about=\"" . clean($this->url) . "\">\n"; if ($this->subject) { $rdf .= " " . clean($this->subject) . "\n"; if (strcmp($this->has_container, 'http://en.wikipedia.org') === 0) { $rdf .= " subject ) . "\"/>\n"; } } if ($this->creator->_nick) { /*if ($this->creator->id) { $rdf .= " \n"; $rdf .= " creator->uri) ."\">\n"; if($this->creator->sioc_url) { $rdf .= " creator->sioc_url ."\"/>\n"; } else $rdf .= " siocURL('user', $this->creator->id) . "\"/>\n"; $rdf .= " \n"; $rdf .= " \n"; $rdf .= " \n"; $rdf .= " creator->foaf_uri) ."\">\n"; if($this->creator->foaf_url) { $rdf .= " creator->foaf_url ."\"/>\n"; } else $rdf .= " siocURL('user', $this->creator->id) . "\"/>\n"; $rdf .= " \n"; $rdf .= " \n"; } else {*/ $rdf .= " \n"; $rdf .= " creator->_uri) . "\">\n"; $rdf .= " created) { $rdf .= " " . $this->created . "\n"; } if (is_array($this->topics)) { foreach ($this->topics as $topic => $url) { $rdf .= " \n"; $rdf .= " \n"; $rdf .= " has_discussion) . "\">\n"; $rdf .= " url = $url; $this->type = $type; } public function getContent(&$exp): string { $rdf = '<' . $this->type . " rdf:about=\"" . clean($this->url) . "\"/>\n"; return $rdf; } } /** * SIOC::Category object * * Contains information about the category which is object of the sioc:topic property */ class SIOCCategory extends SIOCObject { private $url; private $type; public function __construct($url, $type = 'sioct:Category') { $this->url = $url; $this->type = $type; } public function getContent(&$exp): string { $rdf = '<' . $this->type . " rdf:about=\"" . clean($this->url) . "\"/>\n"; return $rdf; } } /** * "Clean" text * * Transforms text so that it can be safely put into XML markup */ if (!function_exists('clean')) { function clean($text, $url = false) { # return htmlentities( $text ); # return htmlentities2( $text ); // double encoding is preventable now // $text = htmlspecialchars_decode($text, ENT_COMPAT); if ($url) { $text = str_replace('&', '&', $text); } return htmlspecialchars($text, ENT_COMPAT, 'UTF-8'); } } /** * HTML Entities 2 * * Same a HTMLEntities, but avoids double-encoding of entities */ if (!function_exists('htmlentities2')) { function htmlentities2($myHTML) { $translation_table = get_html_translation_table(HTML_ENTITIES, ENT_QUOTES); $translation_table[chr(38)] = '&'; return preg_replace( "/&(?![A-Za-z]{0,4}\w{2,3};|#[0-9]{2,3};)/", "&", strtr($myHTML, $translation_table) ); //return htmlentities(strtr(str_replace(' ', '%20', $myHTML), $translation_table)); } } /** * pureContent * * Prepares text-only representation of HTML content */ if (!function_exists('pureContent')) { function pureContent($content) { // Remove HTML tags // May add more cleanup code later, if validation errors are found return strip_tags($content); } }