3 * http://fusionforge.org/
5 * This file is part of FusionForge. FusionForge is free software;
6 * you can redistribute it and/or modify it under the terms of the
7 * GNU General Public License as published by the Free Software
8 * Foundation; either version 2 of the Licence, or (at your option)
11 * FusionForge is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License along
17 * with FusionForge; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
22 // export forum posts in RSS 2.0
23 // Author: Jutta Horstmann, data in transit <jh@dataintransit.com>
25 // Based on: export/rss20_tracker.php (by JH), docman/index.php, export/forum.php, forum/forum.php
27 // Date Author Comment
28 // 31.01.08 JH error handling & display for valid groups with no forums
29 // and invalid group_ids /forum_ids parameters (see mail CP 30.01.08)
31 // TO DO: Translations for error messages
33 // Keep in mind to write "&" in URLs as & in RSS feeds
36 // Params in calling URL:
37 // group_ids (0 - x group ids, separated by "+"), optional, default: not set
38 // forum_ids (0 - x forum ids, separated by "+"), optional, default: not set
39 // number (no. of feed items), optional, default: 10
40 // item (feed variant, items should be thread headings or postings), optional, default:thread
41 // none: 10 last threads of evolvis as a whole
44 require_once '../env.inc.php';
45 require_once $gfcommon.'include/pre.php';
46 require_once $gfwww.'export/rss_utils.inc';
47 require_once $gfcommon.'forum/Forum.class.php';
48 require_once $gfcommon.'forum/ForumFactory.class.php';
49 require_once $gfcommon.'forum/ForumMessage.class.php';
50 require_once $gfcommon.'forum/ForumMessageFactory.class.php';
73 $max_number_items = 100;
79 // ----------------------- check and extract params in GET ----------------------------
81 //--- filter by group_ids - resolve them to forums ---
82 if (isset($_GET['group_ids'])&&!empty($_GET['group_ids'])) {
83 //explode: http changes "+" to " "
84 $group_ids = array_unique(array_merge($group_ids, explode(" ",$_GET['group_ids'])));
86 //loop through group_ids
87 for ($i=0; $i<count($group_ids);$i++){
88 if (is_numeric($group_ids[$i])) {
89 $group =& group_get_object($group_ids[$i]);
90 //does group exist? do we get an object? is group public? does it use forums?
91 if ($group && is_object($group) && !$group->isError()
92 && $group->isPublic() && $group->usesForum()){
94 //valid forums from forum_ids param (needed for feed title)
97 //this groups' forums in array (code based on forum/index.php)
98 $ff=new ForumFactory($group);
99 if ($ff &&is_object($ff) && !$ff->isError()) {
100 $farr = array_merge($farr, $ff->getForums());
101 if (count($farr) < 1) {
102 error_log(_("Forum RSS: No forums found"),0);
105 else error_log("Forum RSS: ForumFactory error: ".$ff->getErrorMessage()." - No forums for group ".$group->getPublicName(),0);
107 else error_log("Forum RSS: group object error",0);
109 else error_log("Forum RSS: invalid group_ids param: ".$group_ids[$i],0);
113 // ----------- add forums called by forum_ids param, if any ------------
114 if (isset($_GET['forum_ids']) && !empty($_GET['forum_ids'])) {
115 //explode: http changes "+" to " "
116 $forum_ids = array_unique(explode(' ',$_GET['forum_ids']));
118 foreach ($forum_ids as $fid){
119 //we got strings from explode(), cast them to int (if possible)
122 if (is_numeric($fid)) {
123 //based on code from forum/forum.php: Get the group_id based on this forum_id
124 $result=db_query_params('SELECT group_id FROM forum_group_list
125 WHERE group_forum_id=$1',
127 if ($result && db_numrows($result) >= 1) {
128 $forum_group_id=db_result($result,0,'group_id');
130 $g =& group_get_object($forum_group_id);
131 if ($g && is_object($g) && !$g->isError() && $g->isPublic() && $g->usesForum()) {
132 $f=new Forum($g,$fid);
134 if ($f && is_object($f) && !$f->isError() && $f->isPublic()) {
135 //add group to group array, forum to forum array
138 //valid forums from forum_ids param (needed for feed title)
141 else error_log("Forum RSS: forum object error",0);
143 else error_log("Forum RSS: forum group oject error",0);
144 }//there is a db result
145 else error_log("Forum RSS: no forum group in DB",0);
146 }//url param is valid (numeric)
147 else error_log("Forum RSS: invalid forum_ids param",0);
152 //if forum_ids specifies forums contained also in group_ids: drop duplicates
153 //does not filter groups by forums!
155 //merge $forums and $farr
156 $forums = array_merge($farr, $forums);
158 $forums = object_array_unique($forums);
159 $groups = object_array_unique($groups);
161 $n_forums = count($forums);
162 $n_groups = count($groups);
164 // ----------------------- error cases ---------------------
165 $error_no_messages = false;
166 //there were filter parameters but they were invalid or
167 //there were valid group_ids, but they contained no forums
169 if (($n_groups == 0 && isset($_GET['group_ids']) && count($_GET['group_ids'])>0) ||
170 ($n_forums == 0 && isset($_GET['forum_ids']) && count($_GET['forum_ids'])>0) ||
171 ($n_groups > 0 && $n_forums == 0)){
172 $error_no_messages = "No forum messages found. Please check for invalid parameters and if the project(s) contain public forums.";
177 //-------------------- other parameters --------------------
179 if (isset($_GET['number']) && !empty($_GET['number']) &&
180 is_numeric($_GET['number']) && $_GET['number']>0) {
181 $number_items = $_GET['number'];
182 if ($number_items > $max_number_items) $number_items = $max_number_items;
186 if (isset($_GET['item']) && !empty($_GET['item']) && ($_GET['item'] == "posting")) {
187 $show_threads = false;
189 else $where_threads = " AND is_followup_to=0";
192 // ------------- general settings and defaults for filtered and non-filtered feeds -------------
193 $feed_title_desc = $show_threads ? "Current threads" : "Recent postings";
194 $feed_title = forge_get_config('forge_name')." Forums: ".$feed_title_desc; //all site's forums
195 $feed_link = "http://".forge_get_config('web_host');
196 $feed_desc = forge_get_config('forge_name')." Forums";
199 // -------------for filtered feeds - set feed title, link and description-------------
201 //more than one group and/or multiple forums -> title is "Selected Evolvis Forums..."; link is default
202 if ($n_groups>1 || $n_forums>0) {
203 $feed_title = "Selected ".$feed_title;
204 if ($debug) error_log ("Forum RSS: g: ".$n_groups." f: ".$n_forums,0);
206 //one group and no forum param -> Groupname in feed title; link to group
207 if ($n_groups == 1 && $n_forum_ids == 0){
208 $feed_title = $groups[0]->getPublicName()." Forums: ".$feed_title_desc;
209 $feed_link = $feed_link . "/forum/?group_id=".$groups[0]->getID();
210 $feed_desc = $groups[0]->getDescription(); //Feed desc = project desc
212 //one forum and no (valid) group param
213 //-> forum's group name and forum name in feed title; link to forum
214 if ($n_forum_ids == 1 && $n_group_ids == 0){
215 $forum_group = $forums[0]->getGroup();
217 $feed_title = $forum_group->getPublicName().' - "' .$forums[0]->getName().'" forum: '.
219 $feed_link = $feed_link . "/forum/forum.php?forum_id=".$forums[0]->getID();
220 $feed_desc = $forums[0]->getDescription();
223 // --------------------------- build the feed -------------------------------
225 beginForumFeed($feed_title, $feed_link, $feed_desc);
227 // ----------------- collect the messages -----------
229 //only if no $error_no_messages
230 if (!$error_no_messages){
231 //messages to be displayed
232 $rss_messages = array();
235 $qpa = db_construct_qpa () ;
236 $qpa = db_construct_qpa ($qpa, 'SELECT f.group_forum_id AS group_forum_id,
237 f.msg_id AS msg_id, f.subject AS subject, f.most_recent_date AS most_recent_date,
238 f.has_followups, f.thread_id,
239 u.realname AS user_realname,
240 g.group_id AS group_id, g.group_name as group_name,
241 fg.forum_name as forum_name, fg.description AS forum_desc
242 FROM forum f,users u, groups g,forum_group_list fg
243 WHERE f.posted_by=u.user_id
244 AND g.group_id = fg.group_id
245 AND f.group_forum_id = fg.group_forum_id
251 $qpa = db_construct_qpa ($qpa, 'AND (') ;
252 foreach ($forums as $f){
253 $qpa = db_construct_qpa ($qpa, 'f.group_forum_id = $1',
254 array ($f->getID())) ;
256 if ($cnt < $n_forums) {
257 $qpa = db_construct_qpa ($qpa, ' OR ') ;
260 $qpa = db_construct_qpa ($qpa, ') ') ;
263 $qpa = db_construct_qpa ($qpa, 'ORDER BY f.most_recent_date DESC LIMIT $1',
264 array ($number_items)) ;
266 $res_msg = db_query_qpa($qpa);
268 error_log(_("Forum RSS: Forum not found: ").' '.db_error(),0);
271 while ($row_msg = db_fetch_array($res_msg)) {
272 if (!forge_check_perm('forum',$row_msg['group_forum_id'],'read')) {
275 //get thread name for posting
276 $res_thread = db_query_params('SELECT subject FROM forum WHERE is_followup_to=0 AND thread_id = $1',
277 array ($row_msg['thread_id']));
278 $row_thread = db_fetch_array($res_thread);
279 if (!$res_thread || db_numrows($res_thread) != 1) {
280 error_log("Forum RSS: Could not get thread subject to thread-ID ".$row_msg['thread_id'],0);
282 //category: Project name - Forum Name - Thread Name
283 $item_cat = $row_msg['group_name']." - ".$row_msg['forum_name']." -- ".$row_thread['subject'];
284 writeForumFeed($row_msg, $item_cat);
286 }//end no $error_no_messages
288 displayError($error_no_messages);
294 //*********************** HELPER FUNCTIONS ***************************************
295 function beginForumFeed($feed_title, $feed_link, $feed_desc) {
297 header("Content-Type: text/xml");
298 print '<?xml version="1.0" encoding="UTF-8"?>
301 print " <channel>\n";
302 print " <title>".$feed_title."</title>\n";
303 print " <link>".$feed_link."</link>\n";
304 print " <description>".$feed_desc."</description>\n";
305 print " <language>en-us</language>\n";
306 print " <copyright>Copyright 2000-".date("Y")." ".forge_get_config('forge_name')."</copyright>\n";
307 print " <webMaster>".forge_get_config('admin_email')."</webMaster>\n";
308 print " <lastBuildDate>".gmdate('D, d M Y G:i:s',time())." GMT</lastBuildDate>\n";
309 print " <docs>http://blogs.law.harvard.edu/tech/rss</docs>\n";
311 print " <url>http://".forge_get_config('web_host')."/images/bflogo-88.png</url>\n";
312 print " <title>".forge_get_config('forge_name')." Developer</title>\n";
313 print " <link>http://".forge_get_config('web_host')."/</link>\n";
314 print " <width>124</width>\n";
315 print " <heigth>32</heigth>\n";
319 function writeForumFeed($msg, $item_cat){
320 global $show_threads;
322 $link = "forum/message.php?msg_id=".$msg['msg_id'];
324 //------------ build one feed item ------------
326 print " <title>".$msg['subject']."</title>\n";
327 print " <link>http://".forge_get_config('web_host')."/".$link."</link>\n";
328 print " <category>".$item_cat."</category>\n";
329 //print " <description>".rss_description($item_desc)."</description>\n";
330 print " <author>".$msg['user_realname']."</author>\n";
331 //print " <comment></comment>\n";
332 print " <pubDate>".gmdate('D, d M Y G:i:s',$msg['most_recent_date'])." GMT</pubDate>\n";
333 //print " <guid></guid>\n";
339 function displayError($errorMessage) {
340 print " <title>Error</title>".
341 "<description>".rss_description($errorMessage)."</description>";
345 print '</channel></rss>';
349 function endOnError($errorMessage) {
350 displayError($errorMessage);
354 //function taken from here http://de3.php.net/manual/de/function.array-unique.php#75307
355 function object_array_unique($array, $keep_key_assoc = false)
357 $duplicate_keys = array();
360 foreach ($array as $key=>$val)
362 // convert objects to arrays, in_array() does not support objects
366 if (!in_array($val, $tmp))
369 $duplicate_keys[] = $key;
372 foreach ($duplicate_keys as $key)
375 return $keep_key_assoc ? $array : array_values($array);