3 // export forum posts in RSS 2.0
4 // Author: Jutta Horstmann, data in transit <jh@dataintransit.com>
6 // Based on: export/rss20_tracker.php (by JH), docman/index.php, export/forum.php, forum/forum.php
9 // 31.01.08 JH error handling & display for valid groups with no forums
10 // and invalid group_ids /forum_ids parameters (see mail CP 30.01.08)
12 // TO DO: Translations for error messages
14 // Keep in mind to write "&" in URLs as & in RSS feeds
17 // Params in calling URL:
18 // group_ids (0 - x group ids, separated by "+"), optional, default: not set
19 // forum_ids (0 - x forum ids, separated by "+"), optional, default: not set
20 // number (no. of feed items), optional, default: 10
21 // item (feed variant, items should be thread headings or postings), optional, default:thread
22 // none: 10 last threads of evolvis as a whole
25 require_once '../env.inc.php';
26 require_once $gfwww.'include/pre.php';
27 require_once $gfwww.'export/rss_utils.inc';
28 require_once $gfcommon.'forum/Forum.class.php';
29 require_once $gfcommon.'forum/ForumFactory.class.php';
30 require_once $gfcommon.'forum/ForumMessage.class.php';
31 require_once $gfcommon.'forum/ForumMessageFactory.class.php';
54 $max_number_items = 100;
60 // ----------------------- check and extract params in GET ----------------------------
62 //--- filter by group_ids - resolve them to forums ---
63 if (isset($_GET['group_ids'])&&!empty($_GET['group_ids'])) {
64 //explode: http changes "+" to " "
65 $group_ids = array_unique(array_merge($group_ids, explode(" ",$_GET['group_ids'])));
67 //loop through group_ids
68 for ($i=0; $i<count($group_ids);$i++){
69 if (is_numeric($group_ids[$i])) {
70 $group =& group_get_object($group_ids[$i]);
71 //does group exist? do we get an object? is group public? does it use forums?
72 if ($group && is_object($group) && !$group->isError()
73 && $group->isPublic() && $group->usesForum()){
75 //valid forums from forum_ids param (needed for feed title)
78 //this groups' forums in array (code based on forum/index.php)
79 $ff=new ForumFactory($group);
80 if ($ff &&is_object($ff) && !$ff->isError()) {
81 $farr = array_merge($farr, $ff->getForums());
82 if (count($farr) < 1) {
83 error_log(_("Forum RSS: No forums found"),0);
86 else error_log("Forum RSS: ForumFactory error: ".$ff->getErrorMessage()." - No forums for group ".$group->getPublicName(),0);
88 else error_log("Forum RSS: group object error",0);
90 else error_log("Forum RSS: invalid group_ids param: ".$group_ids[$i],0);
94 // ----------- add forums called by forum_ids param, if any ------------
95 if (isset($_GET['forum_ids']) && !empty($_GET['forum_ids'])) {
96 //explode: http changes "+" to " "
97 $forum_ids = array_unique(explode(' ',$_GET['forum_ids']));
99 foreach ($forum_ids as $fid){
100 //we got strings from explode(), cast them to int (if possible)
103 if (is_numeric($fid)) {
104 //based on code from forum/forum.php: Get the group_id based on this forum_id
105 $result=db_query_params('SELECT group_id FROM forum_group_list
106 WHERE group_forum_id=$1',
108 if ($result && db_numrows($result) >= 1) {
109 $forum_group_id=db_result($result,0,'group_id');
111 $g =& group_get_object($forum_group_id);
112 if ($g && is_object($g) && !$g->isError() && $g->isPublic() && $g->usesForum()) {
113 $f=new Forum($g,$fid);
115 if ($f && is_object($f) && !$f->isError() && $f->isPublic()) {
116 //add group to group array, forum to forum array
119 //valid forums from forum_ids param (needed for feed title)
122 else error_log("Forum RSS: forum object error",0);
124 else error_log("Forum RSS: forum group oject error",0);
125 }//there is a db result
126 else error_log("Forum RSS: no forum group in DB",0);
127 }//url param is valid (numeric)
128 else error_log("Forum RSS: invalid forum_ids param",0);
133 //if forum_ids specifies forums contained also in group_ids: drop duplicates
134 //does not filter groups by forums!
136 //merge $forums and $farr
137 $forums = array_merge($farr, $forums);
139 $forums = object_array_unique($forums);
140 $groups = object_array_unique($groups);
142 $n_forums = count($forums);
143 $n_groups = count($groups);
145 // ----------------------- error cases ---------------------
146 $error_no_messages = false;
147 //there were filter parameters but they were invalid or
148 //there were valid group_ids, but they contained no forums
150 if (($n_groups == 0 && count($_GET['group_ids'])>0) ||
151 ($n_forums == 0 && count($_GET['forum_ids'])>0) ||
152 ($n_groups > 0 && $n_forums == 0)){
153 $error_no_messages = "No forum messages found. Please check for invalid parameters and if the project(s) contain public forums.";
158 //-------------------- other parameters --------------------
160 if (isset($_GET['number']) && !empty($_GET['number']) &&
161 is_numeric($_GET['number']) && $_GET['number']>0) {
162 $number_items = $_GET['number'];
163 if ($number_items > $max_number_items) $number_items = $max_number_items;
167 if (isset($_GET['item']) && !empty($_GET['item']) && ($_GET['item'] == "posting")) {
168 $show_threads = false;
170 else $where_threads = " AND is_followup_to=0";
173 // ------------- general settings and defaults for filtered and non-filtered feeds -------------
174 $feed_title_desc = $show_threads ? "Current threads" : "Recent postings";
175 $feed_title = forge_get_config('forge_name')." Forums: ".$feed_title_desc; //all site's forums
176 $feed_link = "http://".forge_get_config('web_host');
177 $feed_desc = forge_get_config('forge_name')." Forums";
180 // -------------for filtered feeds - set feed title, link and description-------------
182 //more than one group and/or multiple forums -> title is "Selected Evolvis Forums..."; link is default
183 if ($n_groups>1 || $n_forums>0) {
184 $feed_title = "Selected ".$feed_title;
185 if ($debug) error_log ("Forum RSS: g: ".$n_groups." f: ".$n_forums,0);
187 //one group and no forum param -> Groupname in feed title; link to group
188 if ($n_groups == 1 && $n_forum_ids == 0){
189 $feed_title = $groups[0]->getPublicName()." Forums: ".$feed_title_desc;
190 $feed_link = $feed_link . "/forum/?group_id=".$groups[0]->getID();
191 $feed_desc = $groups[0]->getDescription(); //Feed desc = project desc
193 //one forum and no (valid) group param
194 //-> forum's group name and forum name in feed title; link to forum
195 if ($n_forum_ids == 1 && $n_group_ids == 0){
196 $forum_group = $forums[0]->getGroup();
198 $feed_title = $forum_group->getPublicName().' - "' .$forums[0]->getName().'" forum: '.
200 $feed_link = $feed_link . "/forum/forum.php?forum_id=".$forums[0]->getID();
201 $feed_desc = $forums[0]->getDescription();
204 // --------------------------- build the feed -------------------------------
206 beginForumFeed($feed_title, $feed_link, $feed_desc);
208 // ----------------- collect the messages -----------
210 //only if no $error_no_messages
211 if (!$error_no_messages){
212 //messages to be displayed
213 $rss_messages = array();
216 $qpa = db_construct_qpa () ;
217 $qpa = db_construct_qpa ($qpa, 'SELECT f.group_forum_id AS group_forum_id,
218 f.msg_id AS msg_id, f.subject AS subject, f.most_recent_date AS most_recent_date,
219 f.has_followups, f.thread_id,
220 u.realname AS user_realname,
221 g.group_id AS group_id, g.group_name as group_name,
222 fg.forum_name as forum_name, fg.description AS forum_desc
223 FROM forum f,users u, groups g,forum_group_list fg
224 WHERE f.posted_by=u.user_id
225 AND g.group_id = fg.group_id
226 AND f.group_forum_id = fg.group_forum_id
230 AND fg.is_public=1 ',
234 $qpa = db_construct_qpa ($qpa, 'AND (') ;
235 foreach ($forums as $f){
236 $qpa = db_construct_qpa ($qpa, 'f.group_forum_id = $1',
237 array ($f->getID())) ;
239 if ($cnt < $n_forums) {
240 $qpa = db_construct_qpa ($qpa, ' OR ') ;
243 $qpa = db_construct_qpa ($qpa, ') ') ;
246 $qpa = db_construct_qpa ($qpa, 'ORDER BY f.most_recent_date DESC LIMIT $1',
247 array ($number_items)) ;
249 $res_msg = db_query_qpa($qpa);
250 if (!$res_msg || db_numrows($res_msg) < 1) {
251 error_log(_("Forum RSS: Forum not found: ").' '.db_error(),0);
253 if ($debug) error_log("Forum RSS: Error",0);
256 while ($row_msg = db_fetch_array($res_msg)) {
257 //get thread name for posting
258 $res_thread = db_query_params('SELECT subject FROM forum WHERE is_followup_to=0 AND thread_id = $1',
259 array ($row_msg['thread_id']));
260 $row_thread = db_fetch_array($res_thread);
261 if (!$res_thread || db_numrows($res_thread) != 1) {
262 error_log("Forum RSS: Could not get thread subject to thread-ID ".$row_msg['thread_id'],0);
264 //category: Project name - Forum Name - Thread Name
265 $item_cat = $row_msg['group_name']." - ".$row_msg['forum_name']." -- ".$row_thread['subject'];
266 writeForumFeed($row_msg, $item_cat);
268 }//end no $error_no_messages
270 displayError($error_no_messages);
276 //*********************** HELPER FUNCTIONS ***************************************
277 function beginForumFeed($feed_title, $feed_link, $feed_desc) {
279 header("Content-Type: text/xml");
280 print '<?xml version="1.0" encoding="UTF-8"?>
283 print " <channel>\n";
284 print " <title>".$feed_title."</title>\n";
285 print " <link>".$feed_link."</link>\n";
286 print " <description>".$feed_desc."</description>\n";
287 print " <language>en-us</language>\n";
288 print " <copyright>Copyright 2000-".date("Y")." ".forge_get_config('forge_name')."</copyright>\n";
289 print " <webMaster>".forge_get_config('admin_email')."</webMaster>\n";
290 print " <lastBuildDate>".gmdate('D, d M Y G:i:s',time())." GMT</lastBuildDate>\n";
291 print " <docs>http://blogs.law.harvard.edu/tech/rss</docs>\n";
293 print " <url>http://".forge_get_config('web_host')."/images/bflogo-88.png</url>\n";
294 print " <title>".forge_get_config('forge_name')." Developer</title>\n";
295 print " <link>http://".forge_get_config('web_host')."/</link>\n";
296 print " <width>124</width>\n";
297 print " <heigth>32</heigth>\n";
301 function writeForumFeed($msg, $item_cat){
302 global $show_threads;
304 $link = "forum/message.php?msg_id=".$msg['msg_id'];
306 //------------ build one feed item ------------
308 print " <title>".$msg['subject']."</title>\n";
309 print " <link>http://".forge_get_config('web_host')."/".$link."</link>\n";
310 print " <category>".$item_cat."</category>\n";
311 //print " <description>".rss_description($item_desc)."</description>\n";
312 print " <author>".$msg['user_realname']."</author>\n";
313 //print " <comment></comment>\n";
314 print " <pubDate>".gmdate('D, d M Y G:i:s',$msg['most_recent_date'])." GMT</pubDate>\n";
315 //print " <guid></guid>\n";
321 function displayError($errorMessage) {
322 print " <title>Error</title>".
323 "<description>".rss_description($errorMessage)."</description>";
327 print '</channel></rss>';
331 function endOnError($errorMessage) {
332 displayError($errorMessage);
336 //function taken from here http://de3.php.net/manual/de/function.array-unique.php#75307
337 function object_array_unique($array, $keep_key_assoc = false)
339 $duplicate_keys = array();
342 foreach ($array as $key=>$val)
344 // convert objects to arrays, in_array() does not support objects
348 if (!in_array($val, $tmp))
351 $duplicate_keys[] = $key;
354 foreach ($duplicate_keys as $key)
357 return $keep_key_assoc ? $array : array_values($array);