| 1 |
<?php
|
| 2 |
// $Id: sioc.module,v 1.33 2008/01/22 11:59:50 terraces Exp $
|
| 3 |
|
| 4 |
/**
|
| 5 |
* @file
|
| 6 |
* Module that allows content to be exported using the SIOC format from the site.
|
| 7 |
*/
|
| 8 |
|
| 9 |
/**
|
| 10 |
* Implementation of hook_help().
|
| 11 |
*/
|
| 12 |
function sioc_help($section) {
|
| 13 |
switch ($section) {
|
| 14 |
case 'admin/help#sioc':
|
| 15 |
$output = t("
|
| 16 |
<h3>SIOC</h3>
|
| 17 |
<p>This module is an exporter for SIOC (Semantically-Interlinked Online Community)
|
| 18 |
metadata. When browsing nodes or comments in forums or blogs, you will see SIOC
|
| 19 |
links on the menu which will bring you to the corresponding metadata export.</p>");
|
| 20 |
return $output;
|
| 21 |
case 'admin/modules#description':
|
| 22 |
return t("Enables your site to export metadata for the Semantic Web using SIOC.");
|
| 23 |
}
|
| 24 |
}
|
| 25 |
|
| 26 |
/**
|
| 27 |
* Implementation of hook_menu().
|
| 28 |
*/
|
| 29 |
function sioc_menu($may_cache) {
|
| 30 |
$items = array();
|
| 31 |
|
| 32 |
if (!$may_cache) {
|
| 33 |
sioc_autodiscovery();
|
| 34 |
doap_autodiscovery();
|
| 35 |
if (arg(1) == 'blog' && is_numeric(arg(2))) {
|
| 36 |
$items[] = array('path' => 'sioc/blog/'. arg(2), 'title' => t('sioc forum'),
|
| 37 |
'callback' => 'sioc_page',
|
| 38 |
'access' => TRUE,
|
| 39 |
'weight' => '9',
|
| 40 |
'type' => MENU_CALLBACK);
|
| 41 |
}
|
| 42 |
elseif (arg(1) == 'forum' && is_numeric(arg(2))) {
|
| 43 |
$items[] = array('path' => 'sioc/forum/'. arg(2), 'title' => t('sioc forum'),
|
| 44 |
'callback' => 'sioc_page',
|
| 45 |
'access' => TRUE,
|
| 46 |
'weight' => '9',
|
| 47 |
'type' => MENU_CALLBACK); }
|
| 48 |
elseif (arg(1) == 'node' && is_numeric(arg(2))) {
|
| 49 |
$items[] = array('path' => 'sioc/node/'. arg(2), 'title' => t('sioc post'),
|
| 50 |
'callback' => 'sioc_page',
|
| 51 |
'access' => node_access('view', node_load(array('nid' => arg(2)))),
|
| 52 |
'weight' => '9',
|
| 53 |
'type' => MENU_CALLBACK);
|
| 54 |
}
|
| 55 |
elseif (arg(1) == 'story' && is_numeric(arg(2))) {
|
| 56 |
$items[] = array('path' => 'sioc/node/'. arg(2), 'title' => t('sioc story'),
|
| 57 |
'callback' => 'sioc_page',
|
| 58 |
'access' => node_access('view', node_load(array('nid' => arg(2)))),
|
| 59 |
'weight' => '9',
|
| 60 |
'type' => MENU_CALLBACK);
|
| 61 |
}
|
| 62 |
elseif (arg(1) == 'user' && is_numeric(arg(2))) {
|
| 63 |
$items[] = array('path' => 'sioc/user/'. arg(2), 'title' => t('sioc user'),
|
| 64 |
'callback' => 'sioc_page',
|
| 65 |
'access' => TRUE,
|
| 66 |
'weight' => '9',
|
| 67 |
'type' => MENU_CALLBACK);
|
| 68 |
}
|
| 69 |
elseif (arg(1) == 'site') {
|
| 70 |
$items[] = array('path' => 'sioc/site', 'title' => t('sioc site'),
|
| 71 |
'callback' => 'sioc_page',
|
| 72 |
'access' => TRUE,
|
| 73 |
'weight' => '9',
|
| 74 |
'type' => MENU_CALLBACK);
|
| 75 |
}
|
| 76 |
else {
|
| 77 |
$items[] = array('path' => 'sioc', 'title' => t('sioc'),
|
| 78 |
'callback' => 'sioc_page',
|
| 79 |
'access' => TRUE,
|
| 80 |
'weight' => '9',
|
| 81 |
'type' => MENU_CALLBACK);
|
| 82 |
}
|
| 83 |
}
|
| 84 |
return $items;
|
| 85 |
}
|
| 86 |
|
| 87 |
/**
|
| 88 |
* Menu callback; provides the main page of the administration section.
|
| 89 |
*/
|
| 90 |
function sioc_page() {
|
| 91 |
switch (arg(1)) {
|
| 92 |
case 'blog':
|
| 93 |
export_sioc_forum(arg(1), arg(2), NULL, arg(3), arg(4));
|
| 94 |
return;
|
| 95 |
case 'comment':
|
| 96 |
export_sioc_post(arg(1), NULL, arg(2), arg(3), arg(4));
|
| 97 |
return;
|
| 98 |
case 'forum':
|
| 99 |
export_sioc_forum(arg(1), NULL, arg(2), arg(3), arg(4));
|
| 100 |
return;
|
| 101 |
case 'node':
|
| 102 |
export_sioc_post(arg(1), arg(2), NULL, arg(3), arg(4));
|
| 103 |
return;
|
| 104 |
case 'stories':
|
| 105 |
export_sioc_forum(arg(1), arg(2), NULL, arg(3), arg(4));
|
| 106 |
return;
|
| 107 |
case 'role':
|
| 108 |
export_sioc_role(arg(2));
|
| 109 |
return;
|
| 110 |
case 'user':
|
| 111 |
export_sioc_user(arg(2));
|
| 112 |
return;
|
| 113 |
case 'site':
|
| 114 |
export_sioc_site(arg(2), arg(3));
|
| 115 |
return;
|
| 116 |
default:
|
| 117 |
print theme('page', sioc_page_default(), '');
|
| 118 |
return;
|
| 119 |
}
|
| 120 |
}
|
| 121 |
|
| 122 |
function sioc_page_default() {
|
| 123 |
$output = t("<p>This module is an exporter for SIOC (Semantically-Interlinked Online
|
| 124 |
Community) metadata. For more information, see
|
| 125 |
<a href=\"http://sioc-project.org/\">sioc-project.org</a>.</p>\n
|
| 126 |
<p>When browsing nodes or comments in forums or blogs, you will see links to SIOC
|
| 127 |
metadata on the menu (e.g. \"sioc forum\", \"sioc post\") which will bring you to
|
| 128 |
the corresponding metadata export for that item.</p>\n
|
| 129 |
<p>You can begin by viewing <a href=\"sioc/site\">metadata about this site</a>.</p>");
|
| 130 |
return $output;
|
| 131 |
}
|
| 132 |
|
| 133 |
/**
|
| 134 |
* Displays a SIOC export containing recent posts from a user's blog.
|
| 135 |
*/
|
| 136 |
function export_sioc_forum($type, $uid = 0, $tid = 0, $start = 0, $limit = 15) {
|
| 137 |
|
| 138 |
$resources = array();
|
| 139 |
|
| 140 |
if (!is_numeric($uid)) { $uid = "0"; }
|
| 141 |
if (!is_numeric($tid)) { $tid = "0"; }
|
| 142 |
if (!is_numeric($start)) { $start = "0"; }
|
| 143 |
if (!is_numeric($limit)) { $limit = "15"; }
|
| 144 |
|
| 145 |
if ($type == "blog") {
|
| 146 |
$account = user_load(array('uid' => $uid, 'status' => 1));
|
| 147 |
$result = db_query_range('SELECT n.nid, n.title, n.teaser, n.created, u.name, u.uid FROM {node} n INNER JOIN {users} u ON n.uid = u.uid WHERE n.type = "'.$type.'" AND u.uid = %d AND n.status = 1 ORDER BY n.created DESC', $uid, $start, $limit);
|
| 148 |
|
| 149 |
// A link to this blog
|
| 150 |
$resources[] = array(
|
| 151 |
'property' => 'sioc:link',
|
| 152 |
'label' => $account->name ."'s Blog",
|
| 153 |
'resource' => url("blog/$uid", NULL, NULL, 1)
|
| 154 |
);
|
| 155 |
}
|
| 156 |
elseif(type=="stories") {
|
| 157 |
$result = db_query_range('SELECT n.nid, n.title, n.teaser, n.created, u.name, u.uid FROM {node} n INNER JOIN {users} u ON n.uid = u.uid WHERE n.type = "'.$type.'" AND u.uid = %d AND n.status = 1 ORDER BY n.created DESC', $uid, $start, $limit);
|
| 158 |
// A link to the stories
|
| 159 |
$resources[] = array(
|
| 160 |
'property' => 'sioc:link',
|
| 161 |
'label' => "SITE NAME Forum",
|
| 162 |
'resource' => url("", NULL, "stories", 1)
|
| 163 |
);
|
| 164 |
|
| 165 |
}
|
| 166 |
elseif ($type == "forum") {
|
| 167 |
$term = db_fetch_object(db_query('SELECT * FROM {term_data} WHERE tid = %d', $tid));
|
| 168 |
|
| 169 |
// A link to this forum
|
| 170 |
$resources[] = array(
|
| 171 |
'property' => 'sioc:link',
|
| 172 |
'label' => $term->name ." Forum",
|
| 173 |
'resource' => url("forum/$tid", NULL, NULL, 1)
|
| 174 |
);
|
| 175 |
|
| 176 |
// The subject(s) of this forum
|
| 177 |
$resources[] = array(
|
| 178 |
'property' => 'sioc:topic',
|
| 179 |
'label' => $term->name,
|
| 180 |
'resource' => url("taxonomy/term/$term->tid", NULL, NULL, 1)
|
| 181 |
);
|
| 182 |
|
| 183 |
// Find the children of this forum
|
| 184 |
// $childs = db_query('SELECT DISTINCT th.tid AS tid, th.parent AS parent, td.name AS name FROM {term_hierarchy} th, {term_data} td, {forum} f WHERE f.tid = th.parent AND td.tid = th.tid AND th.parent = %d', $tid);
|
| 185 |
$childs = taxonomy_get_tree(_forum_get_vid(), $tid);
|
| 186 |
if ($childs) {
|
| 187 |
foreach ($childs as $child) {
|
| 188 |
$resources[] = array(
|
| 189 |
'property' => 'sioc:parent_of',
|
| 190 |
'label' => $child->name,
|
| 191 |
'resource' => url("sioc/forum/".$child->tid, NULL, NULL, 1),
|
| 192 |
'class' => 'Forum',
|
| 193 |
'about' => url("forum/".$child->tid, NULL, NULL, 1)
|
| 194 |
);
|
| 195 |
}
|
| 196 |
}
|
| 197 |
|
| 198 |
$result = db_query_range('SELECT n.nid, n.title, n.teaser, n.created, t.name, t.tid FROM {node} n INNER JOIN {forum} f ON n.nid = f.nid LEFT JOIN {term_data} t ON t.tid = f.tid WHERE n.type = "'.$type.'" AND t.tid = %d AND n.status = 1 ORDER BY n.created DESC', $tid, $start, $limit);
|
| 199 |
}
|
| 200 |
|
| 201 |
// $limit posts that this forum contains
|
| 202 |
$nodes = $result;
|
| 203 |
|
| 204 |
// If no nodes exist, get some default ones
|
| 205 |
if (!$nodes) {
|
| 206 |
$nodes = db_query_range('SELECT n.nid, n.title FROM {node} n WHERE n.promote = 1 AND n.status = 1 ORDER BY n.created DESC', $start, $limit);
|
| 207 |
}
|
| 208 |
|
| 209 |
$posts_counter = 0;
|
| 210 |
|
| 211 |
while ($node = db_fetch_object($nodes)) {
|
| 212 |
$posts_counter++;
|
| 213 |
if(node_access('view', node_load(array('nid' => $node->nid)))) {
|
| 214 |
$resources[] = array(
|
| 215 |
'property' => 'sioc:container_of',
|
| 216 |
'label' => check_plain(strip_tags($node->title)),
|
| 217 |
'resource' => url("sioc/node/".$node->nid, NULL, NULL, 1),
|
| 218 |
'class' => 'Post',
|
| 219 |
'about' => url("node/".$node->nid, NULL, NULL, 1)
|
| 220 |
);
|
| 221 |
}
|
| 222 |
}
|
| 223 |
|
| 224 |
if ($type == "blog") {
|
| 225 |
if ($posts_counter >= $limit) {
|
| 226 |
$resources[] = array(
|
| 227 |
'property' => 'rdfs:seeAlso',
|
| 228 |
'label' => "Posts ".($start+$limit)." to ".($start+2*$limit),
|
| 229 |
'resource' => url("sioc/blog/".$uid."/".($start+$limit)."/".$limit, NULL, NULL, 1)
|
| 230 |
);
|
| 231 |
}
|
| 232 |
|
| 233 |
$output .= output_sioc_concept(
|
| 234 |
"sioc:Forum",
|
| 235 |
url("blog/".$uid, NULL, NULL, 1),
|
| 236 |
array(
|
| 237 |
'dc:title' => $account->name ."'s Blog",
|
| 238 |
'dc:description' => $account->name ."'s Blog at ".variable_get('site_name', 'drupal'),
|
| 239 |
),
|
| 240 |
$resources
|
| 241 |
);
|
| 242 |
}
|
| 243 |
elseif ($type == "forum") {
|
| 244 |
if ($posts_counter >= $limit) {
|
| 245 |
$resources[] = array(
|
| 246 |
'property' => 'rdfs:seeAlso',
|
| 247 |
'label' => "Posts ".($start+$limit)." to ".($start+2*$limit),
|
| 248 |
'resource' => url("sioc/forum/".$tid."/".($start+$limit)."/".$limit, NULL, NULL, 1)
|
| 249 |
);
|
| 250 |
}
|
| 251 |
|
| 252 |
$output .= output_sioc_concept(
|
| 253 |
"sioc:Forum",
|
| 254 |
url("forum/".$tid, NULL, NULL, 1),
|
| 255 |
array(
|
| 256 |
'dc:title' => $term->name." Forum",
|
| 257 |
'dc:description' => $term->name ." Forum at ".variable_get('site_name', 'drupal'),
|
| 258 |
),
|
| 259 |
$resources,
|
| 260 |
$subject
|
| 261 |
);
|
| 262 |
}
|
| 263 |
elseif ($type =="stories" ){
|
| 264 |
$stories_counter = db_result(db_query('SELECT COUNT(*) as count from {node} where type=\'story\''));
|
| 265 |
if ($stories_counter >= $limit) {
|
| 266 |
$resources[] = array(
|
| 267 |
'property' => 'rdfs:seeAlso',
|
| 268 |
'label' => "Stories ".($start+$limit)." to ".($start+2*$limit),
|
| 269 |
'resource' => url("sioc/stories/".$uid."/".($start+$limit)."/".$limit, NULL, NULL, 1)
|
| 270 |
);
|
| 271 |
}
|
| 272 |
$output .= output_sioc_concept(
|
| 273 |
"sioc:Forum",
|
| 274 |
url("".$uid, NULL, "stories", 1),
|
| 275 |
array(
|
| 276 |
'dc:title' => "Blog title",
|
| 277 |
'dc:description' => "Stories at ".variable_get('site_name', 'drupal'),
|
| 278 |
),
|
| 279 |
$resources
|
| 280 |
);
|
| 281 |
print $output;
|
| 282 |
}
|
| 283 |
|
| 284 |
}
|
| 285 |
|
| 286 |
/**
|
| 287 |
* Displays a SIOC export containing details about a post and its replies.
|
| 288 |
*/
|
| 289 |
function export_sioc_post($type, $nid = 0, $cid = 0, $start = 0, $limit = 15) {
|
| 290 |
|
| 291 |
$resources = array();
|
| 292 |
|
| 293 |
if (!is_numeric($nid)) { $nid = "0"; }
|
| 294 |
if (!is_numeric($cid)) { $cid = "0"; }
|
| 295 |
if (!is_numeric($start)) { $start = "0"; }
|
| 296 |
if (!is_numeric($limit)) { $limit = "15"; }
|
| 297 |
|
| 298 |
$replies_counter = 0;
|
| 299 |
|
| 300 |
if ($type == "node" || $type == "story") {
|
| 301 |
//$node = db_fetch_object(db_query('SELECT * FROM {node} n WHERE nid = %d', $nid));
|
| 302 |
$node = node_load($nid);//db_fetch_object(db_query('SELECT * FROM {node_revisions} n WHERE nid = %d order by timestamp desc limit 1', $nid));
|
| 303 |
$node_filtered_content = check_markup($node->body,$node->format,FALSE);
|
| 304 |
|
| 305 |
$answers = db_query_range('SELECT * FROM {comments} c WHERE nid = %d AND LENGTH(thread) = 2 ORDER BY timestamp', $nid, $start, $limit);
|
| 306 |
$link = url("node/$nid", NULL, NULL, 1);
|
| 307 |
$uid = $node->uid;
|
| 308 |
$resources[] = array(
|
| 309 |
'property' => 'sioc:link',
|
| 310 |
'label' => check_plain(strip_tags($node->title)),
|
| 311 |
'resource' => $link
|
| 312 |
);
|
| 313 |
}
|
| 314 |
elseif ($type == "comment") {
|
| 315 |
$comment = db_fetch_object(db_query('SELECT * FROM {comments} WHERE cid = %d', $cid));
|
| 316 |
$thread = rtrim($comment->thread, '/');
|
| 317 |
// $answers = db_query_range('SELECT * FROM {comments} c WHERE nid = %d AND LOCATE("%s", thread) = 1 AND LENGTH(thread) = LENGTH("%s") + 3 ORDER BY timestamp', $comment->nid, $thread, $thread, $start, $limit);
|
| 318 |
$answers = db_query_range('SELECT * FROM {comments} c WHERE pid = %d ORDER BY timestamp', $comment->cid, $start, $limit);
|
| 319 |
$link = url("node/".$comment->nid."#comment-".$comment->cid, NULL, NULL, 1);
|
| 320 |
$nid = $comment->nid;
|
| 321 |
$uid = $comment->uid;
|
| 322 |
$resources[] = array(
|
| 323 |
'property' => 'sioc:link',
|
| 324 |
'label' => check_plain(strip_tags($comment->subject)),
|
| 325 |
'resource' => $link
|
| 326 |
);
|
| 327 |
}
|
| 328 |
|
| 329 |
// Get the subject(s) for this post (node or parent node of comments)
|
| 330 |
$term_nodes = db_query('SELECT tn.tid AS tid, td.name AS name FROM {term_node} tn, {term_data} td WHERE td.tid = tn.tid AND tn.nid = %d', $nid);
|
| 331 |
while ($term_node = db_fetch_object($term_nodes)) {
|
| 332 |
$resources[] = array(
|
| 333 |
'property' => 'sioc:topic',
|
| 334 |
'label' => $term_node->name,
|
| 335 |
'resource' => url("taxonomy/term/$term_node->tid", NULL, NULL, 1)
|
| 336 |
);
|
| 337 |
}
|
| 338 |
if (module_exists('moat')) {
|
| 339 |
$uris = moat_get_uris($nid);
|
| 340 |
if($uris) {
|
| 341 |
foreach($uris as $uri) {
|
| 342 |
$resources[] = array(
|
| 343 |
'property' => 'sioc:topic',
|
| 344 |
'resource' => $uri,
|
| 345 |
);
|
| 346 |
}
|
| 347 |
}
|
| 348 |
}
|
| 349 |
|
| 350 |
// Get the creator of the post
|
| 351 |
$account = user_load(array('uid' => $uid, 'status' => 1));
|
| 352 |
$resources[] = array(
|
| 353 |
'property' => 'sioc:has_creator',
|
| 354 |
'resource' => url("sioc/user/$uid#user", NULL, NULL, 1),
|
| 355 |
'seeAlso' => url("sioc/user/$uid", NULL, NULL, 1),
|
| 356 |
);
|
| 357 |
if (module_exists('foaf')) {
|
| 358 |
$resources[] = array(
|
| 359 |
'property' => 'foaf:maker',
|
| 360 |
'resource' => url("foaf/$uid#_$uid", NULL, NULL, 1),
|
| 361 |
'seeAlso' => url("foaf/$uid", NULL, NULL, 1),
|
| 362 |
);
|
| 363 |
}
|
| 364 |
|
| 365 |
// The replies to this post
|
| 366 |
while ($answer = db_fetch_object($answers)) {
|
| 367 |
$replies_counter++;
|
| 368 |
|
| 369 |
$resources[] = array(
|
| 370 |
'property' => 'sioc:has_reply',
|
| 371 |
'label' => $answer->subject,
|
| 372 |
'resource' => url("sioc/comment/".$answer->cid, NULL, NULL, 1),
|
| 373 |
'class' => 'Post',
|
| 374 |
'about' => url("node/".$answer->nid."#comment-".$answer->cid, NULL, NULL, 1)
|
| 375 |
);
|
| 376 |
}
|
| 377 |
|
| 378 |
if ($type == "node" || $type == "story") {
|
| 379 |
if ($replies_counter >= $limit) {
|
| 380 |
$resources[] = array(
|
| 381 |
'property' => 'rdfs:seeAlso',
|
| 382 |
'label' => "Replies ".($start+$limit)." to ".($start+2*$limit),
|
| 383 |
'resource' => url("sioc/node/".$nid."/".($start+$limit)."/".$limit, NULL, NULL, 1)
|
| 384 |
);
|
| 385 |
}
|
| 386 |
|
| 387 |
$w3c_dtf_date_created = preg_replace("/(\+|\-)([0-9]{2})([0-9]{2})/","$1$2:$3", date("O", $node->created));
|
| 388 |
$date_created = date("Y-m-d", $node->created)."T".date("H:i:s", $node->created).$w3c_dtf_date_created;
|
| 389 |
$w3c_dtf_date_changed = preg_replace("/(\+|\-)([0-9]{2})([0-9]{2})/","$1$2:$3", date("O", $node->changed));
|
| 390 |
$date_changed = date("Y-m-d", $node->changed)."T".date("H:i:s", $node->changed).$w3c_dtf_date_changed;
|
| 391 |
#print check_markup($node->body, 4);
|
| 392 |
$output .= output_sioc_concept(
|
| 393 |
"sioc:Post",
|
| 394 |
url("node/".$nid, NULL, NULL, 1),
|
| 395 |
array(
|
| 396 |
'dc:title' => check_plain(strip_tags($node->title)),
|
| 397 |
'sioc:content' => $node_filtered_content, //check_plain, strip_tags, check_filter
|
| 398 |
'dcterms:created' => $date_created,
|
| 399 |
'dcterms:modified' => $date_changed
|
| 400 |
),
|
| 401 |
$resources
|
| 402 |
);
|
| 403 |
}
|
| 404 |
elseif ($type == "comment") {
|
| 405 |
if ($replies_counter >= $limit) {
|
| 406 |
$resources[] = array(
|
| 407 |
'property' => 'rdfs:seeAlso',
|
| 408 |
'label' => "Replies ".($start+$limit)." to ".($start+2*$limit),
|
| 409 |
'resource' => url("sioc/comment/".$cid."/".($start+$limit), NULL, NULL, 1)
|
| 410 |
);
|
| 411 |
}
|
| 412 |
|
| 413 |
$w3c_dtf_date_created = preg_replace("/(\+|\-)([0-9]{2})([0-9]{2})/","$1$2:$3", date("O", $comment->timestamp));
|
| 414 |
$date_created = date("Y-m-d", $comment->timestamp)."T".date("H:i:s", $comment->timestamp).$w3c_dtf_date_created;
|
| 415 |
|
| 416 |
$output .= output_sioc_concept(
|
| 417 |
"sioc:Post",
|
| 418 |
url("node/".$nid."#comment-".$cid, NULL, NULL, 1),
|
| 419 |
array(
|
| 420 |
'dc:title' => check_plain(strip_tags($comment->subject)),
|
| 421 |
'dc:description' => check_plain(strip_tags($comment->comment)),
|
| 422 |
'dcterms:created' => $date_created
|
| 423 |
),
|
| 424 |
$resources
|
| 425 |
);
|
| 426 |
}
|
| 427 |
}
|
| 428 |
|
| 429 |
/**
|
| 430 |
* Displays a SIOC export containing details about a role.
|
| 431 |
*/
|
| 432 |
function export_sioc_role($rid = 0) {
|
| 433 |
|
| 434 |
if (!is_numeric($rid)) { $rid = "0"; }
|
| 435 |
|
| 436 |
$role = db_fetch_object(db_query("SELECT r.name AS name, p.perm AS perm FROM {users_roles} ur, {role} r, {permission} p WHERE ur.rid = %d AND ur.rid = r.rid AND r.rid = p.rid GROUP BY r.rid", $rid));
|
| 437 |
|
| 438 |
if (!$role->perm) { $role = db_fetch_object(db_query("SELECT r.name AS name, \"no permissions\" AS perm FROM {users_roles} ur, {role} r WHERE ur.rid = %d AND ur.rid = r.rid GROUP BY r.rid", $rid)); }
|
| 439 |
|
| 440 |
$output .= output_sioc_concept(
|
| 441 |
"sioc:Role",
|
| 442 |
url("sioc/role/".$rid, NULL, NULL, 1),
|
| 443 |
array(
|
| 444 |
'sioc:name' => check_plain(strip_tags($role->name)),
|
| 445 |
'dc:description' => check_plain(strip_tags($role->perm))
|
| 446 |
),
|
| 447 |
array()
|
| 448 |
);
|
| 449 |
}
|
| 450 |
|
| 451 |
/**
|
| 452 |
* Displays a SIOC export containing details about the site.
|
| 453 |
*/
|
| 454 |
function export_sioc_site($start = 0, $limit = 15) {
|
| 455 |
|
| 456 |
$resources = array();
|
| 457 |
|
| 458 |
if (!is_numeric($start)) { $start = "0"; }
|
| 459 |
if (!is_numeric($limit)) { $limit = "15"; }
|
| 460 |
|
| 461 |
$forums_counter = 0;
|
| 462 |
$blogs_counter = 0;
|
| 463 |
$stories_counter = db_result(db_query('SELECT COUNT(*) as count from {node} where type=\'story\''));
|
| 464 |
// $forums = db_query_range('SELECT td.tid AS tid, td.name AS name FROM {term_hierarchy} th, {term_data} td, {forum} f WHERE f.tid = td.tid AND th.tid = td.tid AND th.parent = 0 GROUP BY f.tid ORDER BY f.tid', $start, $limit);
|
| 465 |
$forums = db_query_range('SELECT td.tid AS tid, td.name AS name FROM {term_hierarchy} th, {term_data} td, {vocabulary_node_types} v WHERE v.vid = td.vid AND v.type = "forum" AND th.tid = td.tid AND th.parent = 0 ORDER BY td.tid', $start, $limit);
|
| 466 |
|
| 467 |
while ($forum = db_fetch_object($forums)) {
|
| 468 |
$forums_counter++;
|
| 469 |
|
| 470 |
$resources[] = array(
|
| 471 |
'property' => 'sioc:host_of',
|
| 472 |
'label' => $forum->name." Forum",
|
| 473 |
'resource' => url("sioc/forum/".$forum->tid, NULL, NULL, 1),
|
| 474 |
'class' => 'Forum',
|
| 475 |
'about' => url("forum/".$forum->tid, NULL, NULL, 1)
|
| 476 |
);
|
| 477 |
}
|
| 478 |
|
| 479 |
$blogs = db_query_range('SELECT u.name AS name, u.uid AS uid FROM {users} u, {node} n WHERE n.type = "blog" AND n.uid = u.uid GROUP BY u.uid ORDER BY u.uid', $start, $limit);
|
| 480 |
|
| 481 |
while ($blog = db_fetch_object($blogs)) {
|
| 482 |
$blogs_counter++;
|
| 483 |
$resources[] = array(
|
| 484 |
'property' => 'sioc:host_of',
|
| 485 |
'label' => $blog->name."'s Blog",
|
| 486 |
'resource' => url("sioc/blog/".$blog->uid, NULL, NULL, 1),
|
| 487 |
'class' => 'Forum',
|
| 488 |
'about' => url("blog/".$blog->uid, NULL, NULL, 1)
|
| 489 |
);
|
| 490 |
}
|
| 491 |
|
| 492 |
$site = array(
|
| 493 |
'name' => variable_get('site_name', 'drupal') .' - '. variable_get('site_slogan', ''),
|
| 494 |
'link' => url("", NULL, NULL, 1),
|
| 495 |
'description' => variable_get('site_mission', '')
|
| 496 |
);
|
| 497 |
|
| 498 |
$resources[] = array(
|
| 499 |
'property' => 'sioc:link',
|
| 500 |
'label' => check_plain(strip_tags($site['name'])),
|
| 501 |
'resource' => check_plain(strip_tags($site['link']))
|
| 502 |
);
|
| 503 |
|
| 504 |
//add a forum for the stories
|
| 505 |
//if no forums and no blogs but there are stories
|
| 506 |
//this site must be a single-user blog
|
| 507 |
if($stories_counter > 0){// && blogs_counter==0 && forums_counter==0){
|
| 508 |
// should we create this container for stories even if there are blogs and forums?
|
| 509 |
$resources[] = array(
|
| 510 |
'property' => 'sioc:host_of',
|
| 511 |
'label' => "Stories at ".$site['name'],
|
| 512 |
'resource' => url("sioc/stories", NULL, NULL, 1),
|
| 513 |
'class' => 'Forum',
|
| 514 |
'about' => url("", NULL, "stories", 1)
|
| 515 |
);
|
| 516 |
}
|
| 517 |
if (($blogs_counter >= $limit) || ($forums_counter >= $limit)) {
|
| 518 |
$resources[] = array(
|
| 519 |
'property' => 'rdfs:seeAlso',
|
| 520 |
'label' => "Forums and/or Blogs ".($start+$limit)." to ".($start+2*$limit),
|
| 521 |
'resource' => url("sioc/site/".($start+$limit)."/".$limit, NULL, NULL, 1)
|
| 522 |
);
|
| 523 |
}
|
| 524 |
|
| 525 |
$output .= output_sioc_concept(
|
| 526 |
"sioc:Site",
|
| 527 |
url("", NULL, NULL, 1),
|
| 528 |
array(
|
| 529 |
'dc:title' => check_plain(strip_tags($site['name'])),
|
| 530 |
'dc:description' => check_plain(strip_tags($site['description']))
|
| 531 |
),
|
| 532 |
$resources
|
| 533 |
);
|
| 534 |
//print "CCC $stories_counter $forums_counter $blogs_counter";
|
| 535 |
}
|
| 536 |
|
| 537 |
/**
|
| 538 |
* Displays a SIOC export containing details about a user.
|
| 539 |
*/
|
| 540 |
function export_sioc_user($uid = 0) {
|
| 541 |
global $user;
|
| 542 |
|
| 543 |
if ($uid) {
|
| 544 |
$account = user_load(array('uid' => $uid, 'status' => 1));
|
| 545 |
}
|
| 546 |
else {
|
| 547 |
$account = $user;
|
| 548 |
}
|
| 549 |
|
| 550 |
$link = url("user/".$account->uid, NULL, NULL, 1);
|
| 551 |
|
| 552 |
$resources[] = array(
|
| 553 |
'property' => 'sioc:link',
|
| 554 |
'label' => $account->name,
|
| 555 |
'resource' => $link
|
| 556 |
);
|
| 557 |
|
| 558 |
$roles = db_query("SELECT r.name AS name, r.rid AS rid FROM {users_roles} ur, {role} r WHERE ur.uid = %d AND ur.rid = r.rid", $account->uid);
|
| 559 |
|
| 560 |
while ($role = db_fetch_object($roles)) {
|
| 561 |
|
| 562 |
$resources[] = array(
|
| 563 |
'property' => 'sioc:has_function',
|
| 564 |
'label' => $role->name,
|
| 565 |
'resource' => url("sioc/role/".$role->rid, NULL, NULL, 1),
|
| 566 |
'class' => 'Role',
|
| 567 |
'about' => url("role/".$role->rid, NULL, NULL, 1)
|
| 568 |
);
|
| 569 |
}
|
| 570 |
|
| 571 |
$output .= output_sioc_concept(
|
| 572 |
"sioc:User",
|
| 573 |
url("user/".$uid, NULL, NULL, 1),
|
| 574 |
array(
|
| 575 |
'sioc:name' => check_plain(strip_tags($account->name)),
|
| 576 |
'dc:description' => check_plain(strip_tags($account->signature)),
|
| 577 |
'sioc:email_sha1' => check_plain(strip_tags(sha1($account->email)))
|
| 578 |
),
|
| 579 |
$resources
|
| 580 |
);
|
| 581 |
}
|
| 582 |
|
| 583 |
/**
|
| 584 |
* Output a SIOC concept.
|
| 585 |
*
|
| 586 |
* Arbitrary elements may be added using the $literals or $resources associative arrays.
|
| 587 |
* $resources is an array of arrays. Each $resource has property, label and resource.
|
| 588 |
*/
|
| 589 |
function output_sioc_concept($concept_name, $html_url, $literals = array(), $resources = array()) {
|
| 590 |
$output = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n";
|
| 591 |
$output .= "<rdf:RDF\r\n";
|
| 592 |
$output .= " xmlns:rdf=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\"\r\n";
|
| 593 |
$output .= " xmlns:rdfs=\"http://www.w3.org/2000/01/rdf-schema#\"\r\n";
|
| 594 |
$output .= " xmlns:sioc=\"http://rdfs.org/sioc/ns#\"\r\n";
|
| 595 |
$output .= " xmlns:sioct=\"http://rdfs.org/sioc/types#\"\r\n";
|
| 596 |
$output .= " xmlns:dc=\"http://purl.org/dc/elements/1.1/\"\r\n";
|
| 597 |
$output .= " xmlns:dcterms=\"http://purl.org/dc/terms/\"\r\n";
|
| 598 |
$output .= " xmlns:admin=\"http://webns.net/mvcb/\"\r\n";
|
| 599 |
$output .= " xmlns:foaf=\"http://xmlns.com/foaf/0.1/\">\r\n";
|
| 600 |
|
| 601 |
$output .= "<foaf:Document rdf:about=''>\n";
|
| 602 |
$output .= " <dc:title>SIOC profile for '".$conf['site_name']."'</dc:title>\n";
|
| 603 |
$output .= " <dc:description>A SIOC profile describes the structure and contents of a community site (e.g., weblog) in a machine processable form. For more information refer to the <a href="http://rdfs.org/sioc">SIOC project page</a></dc:description>\n";
|
| 604 |
if($concept_name == 'sioc:User') $output .= " <foaf:primaryTopic rdf:resource=\"#user\"/>\n";
|
| 605 |
else $output .= " <foaf:primaryTopic rdf:resource=\"$html_url\"/>\n";
|
| 606 |
$output .= " <admin:generatorAgent rdf:resource=\"http://drupal.org/project/sioc\"/>\n";
|
| 607 |
$output .= "</foaf:Document>\n";
|
| 608 |
|
| 609 |
$output .= "<$concept_name";
|
| 610 |
if($concept_name == 'sioc:User') $output .= " rdf:ID=\"user\"";
|
| 611 |
else $output .= " rdf:about=\"$html_url\"";
|
| 612 |
$output .= ">\n";
|
| 613 |
foreach ($literals as $key => $value) {
|
| 614 |
if (substr($value, 0, 9) == '<![CDATA[') {
|
| 615 |
$output .= " <". $key .">". $value ."</$key>\n";
|
| 616 |
}
|
| 617 |
else {
|
| 618 |
if ($value) { $output .= " <". $key .">". check_plain(strip_tags($value)) ."</$key>\n"; }
|
| 619 |
}
|
| 620 |
}
|
| 621 |
foreach ($resources as $resource) {
|
| 622 |
if (!$resource['class']) {
|
| 623 |
$output .= " <".$resource['property']." ";
|
| 624 |
$output .= "rdf:resource=\"".$resource['resource']."\" ";
|
| 625 |
if($resource['label']) $output .= "rdfs:label=\"".$resource['label']."\" ";
|
| 626 |
if($resource['seeAlso']) $output .= "rdfs:seeAlso=\"".$resource['seeAlso']."\" ";
|
| 627 |
$output .= "/>\n";
|
| 628 |
}
|
| 629 |
else {
|
| 630 |
$output .= " <".$resource['property'].">\n";
|
| 631 |
$output .= " <sioc:".$resource['class']." rdf:about=\"".$resource['about']."\">\n";
|
| 632 |
$output .= " <rdfs:label><![CDATA[".$resource['label']."]]></rdfs:label>\n";
|
| 633 |
$output .= " <rdfs:seeAlso rdf:resource=\"".$resource['resource']."\" />\n";
|
| 634 |
$output .= " </sioc:".$resource['class'].">\n";
|
| 635 |
$output .= " </".$resource['property'].">\n";
|
| 636 |
}
|
| 637 |
}
|
| 638 |
$output .= "</$concept_name>\n";
|
| 639 |
$output .= "</rdf:RDF>\n";
|
| 640 |
drupal_set_header('Content-Type: application/rdf+xml; charset=utf-8');
|
| 641 |
print $output;
|
| 642 |
}
|
| 643 |
|
| 644 |
/**
|
| 645 |
* Add SIOC auto discovery link in the header
|
| 646 |
*/
|
| 647 |
function sioc_autodiscovery() {
|
| 648 |
if (arg(0)=='node' && is_numeric($id=arg(1))) $type = "node/$id";
|
| 649 |
else if (arg(0)=='comment' && is_numeric($id=arg(2))) $type = "node/$id";
|
| 650 |
else if (arg(0)=='user' && $id=arg(1)) $type = "user/$id";
|
| 651 |
else if (arg(0)=='blog' && $id=arg(1)) $type = "forum/$id";
|
| 652 |
else $type = 'site';
|
| 653 |
drupal_set_html_head('<link rel="media" type="application/rdf+xml" title="SIOC" href="'.url("sioc/$type", NULL, NULL, 1).'"/>');
|
| 654 |
}
|
| 655 |
|
| 656 |
/**
|
| 657 |
* Extract HTML A tags of type "application/rdf+xml"
|
| 658 |
* and reformat them as RDF autodiscovery links
|
| 659 |
*/
|
| 660 |
function extractLinks( $html ) {
|
| 661 |
$rdf = '';
|
| 662 |
preg_match_all ('/<a\b([^>]+)>(.*?)<\/a>/ims', $html, $out, PREG_SET_ORDER);
|
| 663 |
foreach ($out as $val) {
|
| 664 |
if ( preg_match ( '/href\s*=\s*"([^"]*)"/ims', $val[1], $anchor ) ) {
|
| 665 |
if ( preg_match( '/type\s*=\s*"application\/rdf\+xml/i', $val[1]) ) {
|
| 666 |
preg_match( '/title\s*=\s*"([^"]*)"/ims', $val[1], $title );
|
| 667 |
// If type="application/rdf+xml":
|
| 668 |
// create autodiscovery link in <HEAD> with same HREF and same TITLE
|
| 669 |
$rdf .= '<link rel="media" type="application/rdf+xml" title="' . $title[1] . '" href="' . trim($anchor[1]) . '"/>' . "\n";
|
| 670 |
}
|
| 671 |
}
|
| 672 |
}
|
| 673 |
return $rdf;
|
| 674 |
}
|
| 675 |
|
| 676 |
|
| 677 |
/**
|
| 678 |
* Extract and add DOAP autodiscovery link
|
| 679 |
*/
|
| 680 |
function doap_autodiscovery() {
|
| 681 |
if (arg(0)=='node' && is_numeric($id=arg(1))) $type = "node/$id";
|
| 682 |
else return;
|
| 683 |
|
| 684 |
$node = db_fetch_object(db_query('SELECT DISTINCT body FROM {node} n, {node_revisions} r WHERE n.vid = r.vid AND n.nid = %d', $id));
|
| 685 |
|
| 686 |
if ( ($doap = extractLinks( $node->body )) != '')
|
| 687 |
drupal_set_html_head( $doap );
|
| 688 |
}
|
| 689 |
?>
|