phpBB
Statistics
| Revision:

root / branches / phpBB-3_0_0 / phpBB / feed.php

History | View | Annotate | Download (38.3 kB)

1
<?php
2
/**
3
* @package phpBB3
4
* @version $Id: feed.php 11387 2011-08-26 10:00:08Z git-gate $
5
* @copyright (c) 2009 phpBB Group
6
* @license http://opensource.org/licenses/gpl-license.php GNU Public License
7
*
8
* Idea and original RSS Feed 2.0 MOD (Version 1.0.8/9) by leviatan21
9
* Original MOD: http://www.phpbb.com/community/viewtopic.php?f=69&t=1214645
10
* MOD Author Profile: http://www.phpbb.com/community/memberlist.php?mode=viewprofile&u=345763
11
* MOD Author Homepage: http://www.mssti.com/phpbb3/
12
*
13
**/
14
15
/**
16
* @ignore
17
**/
18
define('IN_PHPBB', true);
19
$phpbb_root_path = (defined('PHPBB_ROOT_PATH')) ? PHPBB_ROOT_PATH : './';
20
$phpEx = substr(strrchr(__FILE__, '.'), 1);
21
include($phpbb_root_path . 'common.' . $phpEx);
22
23
if (!$config['feed_enable'])
24
{
25
        trigger_error('NO_FEED_ENABLED');
26
}
27
28
// Start session
29
$user->session_begin();
30
31
if (!empty($config['feed_http_auth']) && request_var('auth', '') == 'http')
32
{
33
        phpbb_http_login(array(
34
                'auth_message'        => 'Feed',
35
                'viewonline'        => request_var('viewonline', true),
36
        ));
37
}
38
39
$auth->acl($user->data);
40
$user->setup();
41
42
// Initial var setup
43
$forum_id        = request_var('f', 0);
44
$topic_id        = request_var('t', 0);
45
$mode                = request_var('mode', '');
46
47
// We do not use a template, therefore we simply define the global template variables here
48
$global_vars = $item_vars = array();
49
$feed_updated_time = 0;
50
51
// Generate params array for use in append_sid() to correctly link back to this page
52
$params = false;
53
if ($forum_id || $topic_id || $mode)
54
{
55
        $params = array(
56
                'f'                => ($forum_id) ? $forum_id : NULL,
57
                't'                => ($topic_id) ? $topic_id : NULL,
58
                'mode'        => ($mode) ? $mode : NULL,
59
        );
60
}
61
62
// This boards URL
63
$board_url = generate_board_url();
64
65
// Get correct feed object
66
$feed = phpbb_feed_factory::init($mode, $forum_id, $topic_id);
67
68
// No feed found
69
if ($feed === false)
70
{
71
        trigger_error('NO_FEED');
72
}
73
74
// Open Feed
75
$feed->open();
76
77
// Iterate through items
78
while ($row = $feed->get_item())
79
{
80
        // BBCode options to correctly disable urls, smilies, bbcode...
81
        if ($feed->get('options') === NULL)
82
        {
83
                // Allow all combinations
84
                $options = 7;
85
86
                if ($feed->get('enable_bbcode') !== NULL && $feed->get('enable_smilies') !== NULL && $feed->get('enable_magic_url') !== NULL)
87
                {
88
                        $options = (($row[$feed->get('enable_bbcode')]) ? OPTION_FLAG_BBCODE : 0) + (($row[$feed->get('enable_smilies')]) ? OPTION_FLAG_SMILIES : 0) + (($row[$feed->get('enable_magic_url')]) ? OPTION_FLAG_LINKS : 0);
89
                }
90
        }
91
        else
92
        {
93
                $options = $row[$feed->get('options')];
94
        }
95
96
        $title = (isset($row[$feed->get('title')]) && $row[$feed->get('title')] !== '') ? $row[$feed->get('title')] : ((isset($row[$feed->get('title2')])) ? $row[$feed->get('title2')] : '');
97
98
        $published = ($feed->get('published') !== NULL) ? (int) $row[$feed->get('published')] : 0;
99
        $updated = ($feed->get('updated') !== NULL) ? (int) $row[$feed->get('updated')] : 0;
100
101
        $item_row = array(
102
                'author'                => ($feed->get('creator') !== NULL) ? $row[$feed->get('creator')] : '',
103
                'published'                => ($published > 0) ? feed_format_date($published) : '',
104
                'updated'                => ($updated > 0) ? feed_format_date($updated) : '',
105
                'link'                        => '',
106
                'title'                        => censor_text($title),
107
                'category'                => ($config['feed_item_statistics'] && !empty($row['forum_id'])) ? $board_url . '/viewforum.' . $phpEx . '?f=' . $row['forum_id'] : '',
108
                'category_name'        => ($config['feed_item_statistics'] && isset($row['forum_name'])) ? $row['forum_name'] : '',
109
                'description'        => censor_text(feed_generate_content($row[$feed->get('text')], $row[$feed->get('bbcode_uid')], $row[$feed->get('bitfield')], $options)),
110
                'statistics'        => '',
111
        );
112
113
        // Adjust items, fill link, etc.
114
        $feed->adjust_item($item_row, $row);
115
116
        $item_vars[] = $item_row;
117
118
        $feed_updated_time = max($feed_updated_time, $published, $updated);
119
}
120
121
// If we do not have any items at all, sending the current time is better than sending no time.
122
if (!$feed_updated_time)
123
{
124
        $feed_updated_time = time();
125
}
126
127
// Some default assignments
128
// FEED_IMAGE is not used (atom)
129
$global_vars = array_merge($global_vars, array(
130
        'FEED_IMAGE'                        => ($user->img('site_logo', '', false, '', 'src')) ? $board_url . '/' . substr($user->img('site_logo', '', false, '', 'src'), strlen($phpbb_root_path)) : '',
131
        'SELF_LINK'                                => feed_append_sid('/feed.' . $phpEx, $params),
132
        'FEED_LINK'                                => $board_url . '/index.' . $phpEx,
133
        'FEED_TITLE'                        => $config['sitename'],
134
        'FEED_SUBTITLE'                        => $config['site_desc'],
135
        'FEED_UPDATED'                        => feed_format_date($feed_updated_time),
136
        'FEED_LANG'                                => $user->lang['USER_LANG'],
137
        'FEED_AUTHOR'                        => $config['sitename'],
138
));
139
140
$feed->close();
141
142
// Output page
143
144
// gzip_compression
145
if ($config['gzip_compress'])
146
{
147
        if (@extension_loaded('zlib') && !headers_sent())
148
        {
149
                ob_start('ob_gzhandler');
150
        }
151
}
152
153
// IF debug extra is enabled and admin want to "explain" the page we need to set other headers...
154
if (defined('DEBUG_EXTRA') && request_var('explain', 0) && $auth->acl_get('a_'))
155
{
156
        header('Content-type: text/html; charset=UTF-8');
157
        header('Cache-Control: private, no-cache="set-cookie"');
158
        header('Expires: 0');
159
        header('Pragma: no-cache');
160
161
        $mtime = explode(' ', microtime());
162
        $totaltime = $mtime[0] + $mtime[1] - $starttime;
163
164
        if (method_exists($db, 'sql_report'))
165
        {
166
                $db->sql_report('display');
167
        }
168
169
        garbage_collection();
170
        exit_handler();
171
}
172
173
header("Content-Type: application/atom+xml; charset=UTF-8");
174
header("Last-Modified: " . gmdate('D, d M Y H:i:s', $feed_updated_time) . ' GMT');
175
176
if (!empty($user->data['is_bot']))
177
{
178
        // Let reverse proxies know we detected a bot.
179
        header('X-PHPBB-IS-BOT: yes');
180
}
181
182
echo '<?xml version="1.0" encoding="UTF-8"?>' . "\n";
183
echo '<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="' . $global_vars['FEED_LANG'] . '">' . "\n";
184
echo '<link rel="self" type="application/atom+xml" href="' . $global_vars['SELF_LINK'] . '" />' . "\n\n";
185
186
echo (!empty($global_vars['FEED_TITLE'])) ? '<title>' . $global_vars['FEED_TITLE'] . '</title>' . "\n" : '';
187
echo (!empty($global_vars['FEED_SUBTITLE'])) ? '<subtitle>' . $global_vars['FEED_SUBTITLE'] . '</subtitle>' . "\n" : '';
188
echo (!empty($global_vars['FEED_LINK'])) ? '<link href="' . $global_vars['FEED_LINK'] .'" />' . "\n" : '';
189
echo '<updated>' . $global_vars['FEED_UPDATED'] . '</updated>' . "\n\n";
190
191
echo '<author><name><![CDATA[' . $global_vars['FEED_AUTHOR'] . ']]></name></author>' . "\n";
192
echo '<id>' . $global_vars['SELF_LINK'] . '</id>' . "\n";
193
194
foreach ($item_vars as $row)
195
{
196
        echo '<entry>' . "\n";
197
198
        if (!empty($row['author']))
199
        {
200
                echo '<author><name><![CDATA[' . $row['author'] . ']]></name></author>' . "\n";
201
        }
202
203
        echo '<updated>' . ((!empty($row['updated'])) ? $row['updated'] : $row['published']) . '</updated>' . "\n";
204
205
        if (!empty($row['published']))
206
        {
207
                echo '<published>' . $row['published'] . '</published>' . "\n";
208
        }
209
210
        echo '<id>' . $row['link'] . '</id>' . "\n";
211
        echo '<link href="' . $row['link'] . '"/>' . "\n";
212
        echo '<title type="html"><![CDATA[' . $row['title'] . ']]></title>' . "\n\n";
213
214
        if (!empty($row['category']) && isset($row['category_name']) && $row['category_name'] !== '')
215
        {
216
                echo '<category term="' . $row['category_name'] . '" scheme="' . $row['category'] . '" label="' . $row['category_name'] . '"/>' . "\n";
217
        }
218
219
        echo '<content type="html" xml:base="' . $row['link'] . '"><![CDATA[' . "\n";
220
        echo $row['description'];
221
222
        if (!empty($row['statistics']))
223
        {
224
                echo '<p>' . $user->lang['STATISTICS'] . ': ' . $row['statistics'] . '</p>';
225
        }
226
227
        echo '<hr />' . "\n" . ']]></content>' . "\n";
228
        echo '</entry>' . "\n";
229
}
230
231
echo '</feed>';
232
233
garbage_collection();
234
exit_handler();
235
236
/**
237
* Run links through append_sid(), prepend generate_board_url() and remove session id
238
**/
239
function feed_append_sid($url, $params)
240
{
241
        global $board_url;
242
243
        return append_sid($board_url . $url, $params, true, '');
244
}
245
246
/**
247
* Generate ISO 8601 date string (RFC 3339)
248
**/
249
function feed_format_date($time)
250
{
251
        static $zone_offset;
252
        static $offset_string;
253
254
        if (empty($offset_string))
255
        {
256
                global $user;
257
258
                $zone_offset = (int) $user->timezone + (int) $user->dst;
259
260
                $sign = ($zone_offset < 0) ? '-' : '+';
261
                $time_offset = abs($zone_offset);
262
263
                $offset_seconds        = $time_offset % 3600;
264
                $offset_minutes        = $offset_seconds / 60;
265
                $offset_hours        = ($time_offset - $offset_seconds) / 3600;
266
267
                $offset_string        = sprintf("%s%02d:%02d", $sign, $offset_hours, $offset_minutes);
268
        }
269
270
        return gmdate("Y-m-d\TH:i:s", $time + $zone_offset) . $offset_string;
271
}
272
273
/**
274
* Generate text content
275
**/
276
function feed_generate_content($content, $uid, $bitfield, $options)
277
{
278
        global $user, $config, $phpbb_root_path, $phpEx, $board_url;
279
280
        if (empty($content))
281
        {
282
                return '';
283
        }
284
285
        // Prepare some bbcodes for better parsing
286
        $content        = preg_replace("#\[quote(=&quot;.*?&quot;)?:$uid\]\s*(.*?)\s*\[/quote:$uid\]#si", "[quote$1:$uid]<br />$2<br />[/quote:$uid]", $content);
287
288
        $content = generate_text_for_display($content, $uid, $bitfield, $options);
289
290
        // Add newlines
291
        $content = str_replace('<br />', '<br />' . "\n", $content);
292
293
        // Convert smiley Relative paths to Absolute path, Windows style
294
        $content = str_replace($phpbb_root_path . $config['smilies_path'], $board_url . '/' . $config['smilies_path'], $content);
295
296
        // Remove "Select all" link and mouse events
297
        $content = str_replace('<a href="#" onclick="selectCode(this); return false;">' . $user->lang['SELECT_ALL_CODE'] . '</a>', '', $content);
298
        $content = preg_replace('#(onkeypress|onclick)="(.*?)"#si', '', $content);
299
300
        // Firefox does not support CSS for feeds, though
301
302
        // Remove font sizes
303
//        $content = preg_replace('#<span style="font-size: [0-9]+%; line-height: [0-9]+%;">([^>]+)</span>#iU', '\1', $content);
304
305
        // Make text strong :P
306
//        $content = preg_replace('#<span style="font-weight: bold?">(.*?)</span>#iU', '<strong>\1</strong>', $content);
307
308
        // Italic
309
//        $content = preg_replace('#<span style="font-style: italic?">([^<]+)</span>#iU', '<em>\1</em>', $content);
310
311
        // Underline
312
//        $content = preg_replace('#<span style="text-decoration: underline?">([^<]+)</span>#iU', '<u>\1</u>', $content);
313
314
        // Remove embed Windows Media Streams
315
        $content        = preg_replace( '#<\!--\[if \!IE\]>-->([^[]+)<\!--<!\[endif\]-->#si', '', $content);
316
317
        // Do not use &lt; and &gt;, because we want to retain code contained in [code][/code]
318
319
        // Remove embed and objects
320
        $content        = preg_replace( '#<(object|embed)(.*?) (value|src)=(.*?) ([^[]+)(object|embed)>#si',' <a href=$4 target="_blank"><strong>$1</strong></a> ',$content);
321
322
        // Remove some specials html tag, because somewhere there are a mod to allow html tags ;)
323
        $content        = preg_replace( '#<(script|iframe)([^[]+)\1>#siU', ' <strong>$1</strong> ', $content);
324
325
        // Remove Comments from inline attachments [ia]
326
        $content        = preg_replace('#<div class="(inline-attachment|attachtitle)">(.*?)<!-- ia(.*?) -->(.*?)<!-- ia(.*?) -->(.*?)</div>#si','$4',$content);
327
328
        // Replace some entities with their unicode counterpart
329
        $entities = array(
330
                '&nbsp;'        => "\xC2\xA0",
331
                '&bull;'        => "\xE2\x80\xA2",
332
                '&middot;'        => "\xC2\xB7",
333
                '&copy;'        => "\xC2\xA9",
334
        );
335
336
        $content = str_replace(array_keys($entities), array_values($entities), $content);
337
338
        // Remove CDATA blocks. ;)
339
        $content = preg_replace('#\<\!\[CDATA\[(.*?)\]\]\>#s', '', $content);
340
341
        // Other control characters
342
        $content = preg_replace('#(?:[\x00-\x1F\x7F]+|(?:\xC2[\x80-\x9F])+)#', '', $content);
343
344
        return $content;
345
}
346
347
/**
348
* Factory class to return correct object
349
* @package phpBB3
350
*/
351
class phpbb_feed_factory
352
{
353
        /**
354
        * Return correct object for specified mode
355
        *
356
        * @param string        $mode                The feeds mode.
357
        * @param int        $forum_id        Forum id specified by the script if forum feed provided.
358
        * @param int        $topic_id        Topic id specified by the script if topic feed provided.
359
        *
360
        * @return object        Returns correct feeds object for specified mode.
361
        */
362
        function init($mode, $forum_id, $topic_id)
363
        {
364
                global $config;
365
366
                switch ($mode)
367
                {
368
                        case 'forums':
369
                                if (!$config['feed_overall_forums'])
370
                                {
371
                                        return false;
372
                                }
373
374
                                return new phpbb_feed_forums();
375
                        break;
376
377
                        case 'topics':
378
                        case 'topics_new':
379
                                if (!$config['feed_topics_new'])
380
                                {
381
                                        return false;
382
                                }
383
384
                                return new phpbb_feed_topics();
385
                        break;
386
387
                        case 'topics_active':
388
                                if (!$config['feed_topics_active'])
389
                                {
390
                                        return false;
391
                                }
392
393
                                return new phpbb_feed_topics_active();
394
                        break;
395
396
                        case 'news':
397
                                global $db;
398
399
                                // Get at least one news forum
400
                                $sql = 'SELECT forum_id
401
                                        FROM ' . FORUMS_TABLE . '
402
                                        WHERE ' . $db->sql_bit_and('forum_options', FORUM_OPTION_FEED_NEWS, '<> 0');
403
                                $result = $db->sql_query_limit($sql, 1, 0, 600);
404
                                $s_feed_news = (int) $db->sql_fetchfield('forum_id');
405
                                $db->sql_freeresult($result);
406
407
                                if (!$s_feed_news)
408
                                {
409
                                        return false;
410
                                }
411
412
                                return new phpbb_feed_news();
413
                        break;
414
415
                        default:
416
                                if ($topic_id && $config['feed_topic'])
417
                                {
418
                                        return new phpbb_feed_topic($topic_id);
419
                                }
420
                                else if ($forum_id && $config['feed_forum'])
421
                                {
422
                                        return new phpbb_feed_forum($forum_id);
423
                                }
424
                                else if ($config['feed_overall'])
425
                                {
426
                                        return new phpbb_feed_overall();
427
                                }
428
429
                                return false;
430
                        break;
431
                }
432
        }
433
}
434
435
/**
436
* Base class with some generic functions and settings.
437
*
438
* @package phpBB3
439
*/
440
class phpbb_feed_base
441
{
442
        /**
443
        * SQL Query to be executed to get feed items
444
        */
445
        var $sql = array();
446
447
        /**
448
        * Keys specified for retrieval of title, content, etc.
449
        */
450
        var $keys = array();
451
452
        /**
453
        * Number of items to fetch. Usually overwritten by $config['feed_something']
454
        */
455
        var $num_items = 15;
456
457
        /**
458
        * Separator for title elements to separate items (for example forum / topic)
459
        */
460
        var $separator = "\xE2\x80\xA2"; // &bull;
461
462
        /**
463
        * Separator for the statistics row (Posted by, post date, replies, etc.)
464
        */
465
        var $separator_stats = "\xE2\x80\x94"; // &mdash;
466
467
        /**
468
        * Constructor
469
        */
470
        function phpbb_feed_base()
471
        {
472
                global $config;
473
474
                $this->set_keys();
475
476
                // Allow num_items to be string
477
                if (is_string($this->num_items))
478
                {
479
                        $this->num_items = (int) $config[$this->num_items];
480
481
                        // A precaution
482
                        if (!$this->num_items)
483
                        {
484
                                $this->num_items = 10;
485
                        }
486
                }
487
        }
488
489
        /**
490
        * Set keys.
491
        */
492
        function set_keys()
493
        {
494
        }
495
496
        /**
497
        * Open feed
498
        */
499
        function open()
500
        {
501
        }
502
503
        /**
504
        * Close feed
505
        */
506
        function close()
507
        {
508
                global $db;
509
510
                if (!empty($this->result))
511
                {
512
                        $db->sql_freeresult($this->result);
513
                }
514
        }
515
516
        /**
517
        * Set key
518
        */
519
        function set($key, $value)
520
        {
521
                $this->keys[$key] = $value;
522
        }
523
524
        /**
525
        * Get key
526
        */
527
        function get($key)
528
        {
529
                return (isset($this->keys[$key])) ? $this->keys[$key] : NULL;
530
        }
531
532
        function get_readable_forums()
533
        {
534
                global $auth;
535
                static $forum_ids;
536
537
                if (!isset($forum_ids))
538
                {
539
                        $forum_ids = array_keys($auth->acl_getf('f_read', true));
540
                }
541
542
                return $forum_ids;
543
        }
544
545
        function get_moderator_approve_forums()
546
        {
547
                global $auth;
548
                static $forum_ids;
549
550
                if (!isset($forum_ids))
551
                {
552
                        $forum_ids = array_keys($auth->acl_getf('m_approve', true));
553
                }
554
555
                return $forum_ids;
556
        }
557
558
        function is_moderator_approve_forum($forum_id)
559
        {
560
                static $forum_ids;
561
562
                if (!isset($forum_ids))
563
                {
564
                        $forum_ids = array_flip($this->get_moderator_approve_forums());
565
                }
566
567
                if (!$forum_id)
568
                {
569
                        // Global announcement, your a moderator in any forum than it's okay.
570
                        return (!empty($forum_ids)) ? true : false;
571
                }
572
573
                return (isset($forum_ids[$forum_id])) ? true : false;
574
        }
575
576
        function get_excluded_forums()
577
        {
578
                global $db, $cache;
579
                static $forum_ids;
580
581
                // Matches acp/acp_board.php
582
                $cache_name        = 'feed_excluded_forum_ids';
583
584
                if (!isset($forum_ids) && ($forum_ids = $cache->get('_' . $cache_name)) === false)
585
                {
586
                        $sql = 'SELECT forum_id
587
                                FROM ' . FORUMS_TABLE . '
588
                                WHERE ' . $db->sql_bit_and('forum_options', FORUM_OPTION_FEED_EXCLUDE, '<> 0');
589
                        $result = $db->sql_query($sql);
590
591
                        $forum_ids = array();
592
                        while ($forum_id = (int) $db->sql_fetchfield('forum_id'))
593
                        {
594
                                $forum_ids[$forum_id] = $forum_id;
595
                        }
596
                        $db->sql_freeresult($result);
597
598
                        $cache->put('_' . $cache_name, $forum_ids);
599
                }
600
601
                return $forum_ids;
602
        }
603
604
        function is_excluded_forum($forum_id)
605
        {
606
                $forum_ids = $this->get_excluded_forums();
607
608
                return isset($forum_ids[$forum_id]) ? true : false;
609
        }
610
611
        function get_passworded_forums()
612
        {
613
                global $user;
614
615
                return $user->get_passworded_forums();
616
        }
617
618
        function get_item()
619
        {
620
                global $db, $cache;
621
                static $result;
622
623
                if (!isset($result))
624
                {
625
                        if (!$this->get_sql())
626
                        {
627
                                return false;
628
                        }
629
630
                        // Query database
631
                        $sql = $db->sql_build_query('SELECT', $this->sql);
632
                        $result = $db->sql_query_limit($sql, $this->num_items);
633
                }
634
635
                return $db->sql_fetchrow($result);
636
        }
637
638
        function user_viewprofile($row)
639
        {
640
                global $phpEx, $user;
641
642
                $author_id = (int) $row[$this->get('author_id')];
643
644
                if ($author_id == ANONYMOUS)
645
                {
646
                        // Since we cannot link to a profile, we just return GUEST
647
                        // instead of $row['username']
648
                        return $user->lang['GUEST'];
649
                }
650
651
                return '<a href="' . feed_append_sid('/memberlist.' . $phpEx, 'mode=viewprofile&amp;u=' . $author_id) . '">' . $row[$this->get('creator')] . '</a>';
652
        }
653
}
654
655
/**
656
* Abstract class for post based feeds
657
*
658
* @package phpBB3
659
*/
660
class phpbb_feed_post_base extends phpbb_feed_base
661
{
662
        var $num_items = 'feed_limit_post';
663
664
        function set_keys()
665
        {
666
                $this->set('title',                'post_subject');
667
                $this->set('title2',        'topic_title');
668
669
                $this->set('author_id',        'user_id');
670
                $this->set('creator',        'username');
671
                $this->set('published',        'post_time');
672
                $this->set('updated',        'post_edit_time');
673
                $this->set('text',                'post_text');
674
675
                $this->set('bitfield',        'bbcode_bitfield');
676
                $this->set('bbcode_uid','bbcode_uid');
677
678
                $this->set('enable_bbcode',                'enable_bbcode');
679
                $this->set('enable_smilies',        'enable_smilies');
680
                $this->set('enable_magic_url',        'enable_magic_url');
681
        }
682
683
        function adjust_item(&$item_row, &$row)
684
        {
685
                global $phpEx, $config, $user;
686
687
                $item_row['link'] = feed_append_sid('/viewtopic.' . $phpEx, "t={$row['topic_id']}&amp;p={$row['post_id']}#p{$row['post_id']}");
688
689
                if ($config['feed_item_statistics'])
690
                {
691
                        $item_row['statistics'] = $user->lang['POSTED'] . ' ' . $user->lang['POST_BY_AUTHOR'] . ' ' . $this->user_viewprofile($row)
692
                                . ' ' . $this->separator_stats . ' ' . $user->format_date($row[$this->get('published')])
693
                                . (($this->is_moderator_approve_forum($row['forum_id']) && !$row['post_approved']) ? ' ' . $this->separator_stats . ' ' . $user->lang['POST_UNAPPROVED'] : '');
694
                }
695
        }
696
}
697
698
/**
699
* Abstract class for topic based feeds
700
*
701
* @package phpBB3
702
*/
703
class phpbb_feed_topic_base extends phpbb_feed_base
704
{
705
        var $num_items = 'feed_limit_topic';
706
707
        function set_keys()
708
        {
709
                $this->set('title',                'topic_title');
710
                $this->set('title2',        'forum_name');
711
712
                $this->set('author_id',        'topic_poster');
713
                $this->set('creator',        'topic_first_poster_name');
714
                $this->set('published',        'post_time');
715
                $this->set('updated',        'post_edit_time');
716
                $this->set('text',                'post_text');
717
718
                $this->set('bitfield',        'bbcode_bitfield');
719
                $this->set('bbcode_uid','bbcode_uid');
720
721
                $this->set('enable_bbcode',                'enable_bbcode');
722
                $this->set('enable_smilies',        'enable_smilies');
723
                $this->set('enable_magic_url',        'enable_magic_url');
724
        }
725
726
        function adjust_item(&$item_row, &$row)
727
        {
728
                global $phpEx, $config, $user;
729
730
                $item_row['link'] = feed_append_sid('/viewtopic.' . $phpEx, 't=' . $row['topic_id'] . '&amp;p=' . $row['post_id'] . '#p' . $row['post_id']);
731
732
                if ($config['feed_item_statistics'])
733
                {
734
                        $item_row['statistics'] = $user->lang['POSTED'] . ' ' . $user->lang['POST_BY_AUTHOR'] . ' ' . $this->user_viewprofile($row)
735
                                . ' ' . $this->separator_stats . ' ' . $user->format_date($row[$this->get('published')])
736
                                . ' ' . $this->separator_stats . ' ' . $user->lang['REPLIES'] . ' ' . (($this->is_moderator_approve_forum($row['forum_id'])) ? $row['topic_replies_real'] : $row['topic_replies'])
737
                                . ' ' . $this->separator_stats . ' ' . $user->lang['VIEWS'] . ' ' . $row['topic_views']
738
                                . (($this->is_moderator_approve_forum($row['forum_id']) && ($row['topic_replies_real'] != $row['topic_replies'])) ? ' ' . $this->separator_stats . ' ' . $user->lang['POSTS_UNAPPROVED'] : '');
739
                }
740
        }
741
}
742
743
/**
744
* Board wide feed (aka overall feed)
745
*
746
* This will give you the newest {$this->num_items} posts
747
* from the whole board.
748
*
749
* @package phpBB3
750
*/
751
class phpbb_feed_overall extends phpbb_feed_post_base
752
{
753
        function get_sql()
754
        {
755
                global $auth, $db;
756
757
                $forum_ids = array_diff($this->get_readable_forums(), $this->get_excluded_forums(), $this->get_passworded_forums());
758
                if (empty($forum_ids))
759
                {
760
                        return false;
761
                }
762
763
                // Add global forum id
764
                $forum_ids[] = 0;
765
766
                // m_approve forums
767
                $fid_m_approve = $this->get_moderator_approve_forums();
768
                $sql_m_approve = (!empty($fid_m_approve)) ? 'OR ' . $db->sql_in_set('forum_id', $fid_m_approve) : '';
769
770
                // Determine topics with recent activity
771
                $sql = 'SELECT topic_id, topic_last_post_time
772
                        FROM ' . TOPICS_TABLE . '
773
                        WHERE ' . $db->sql_in_set('forum_id', $forum_ids) . '
774
                                AND topic_moved_id = 0
775
                                AND (topic_approved = 1
776
                                        ' . $sql_m_approve . ')
777
                        ORDER BY topic_last_post_time DESC';
778
                $result = $db->sql_query_limit($sql, $this->num_items);
779
780
                $topic_ids = array();
781
                $min_post_time = 0;
782
                while ($row = $db->sql_fetchrow())
783
                {
784
                        $topic_ids[] = (int) $row['topic_id'];
785
786
                        $min_post_time = (int) $row['topic_last_post_time'];
787
                }
788
                $db->sql_freeresult($result);
789
790
                if (empty($topic_ids))
791
                {
792
                        return false;
793
                }
794
795
                // Get the actual data
796
                $this->sql = array(
797
                        'SELECT'        =>        'f.forum_id, f.forum_name, ' .
798
                                                        'p.post_id, p.topic_id, p.post_time, p.post_edit_time, p.post_approved, p.post_subject, p.post_text, p.bbcode_bitfield, p.bbcode_uid, p.enable_bbcode, p.enable_smilies, p.enable_magic_url, ' .
799
                                                        'u.username, u.user_id',
800
                        'FROM'                => array(
801
                                USERS_TABLE                => 'u',
802
                                POSTS_TABLE                => 'p',
803
                        ),
804
                        'LEFT_JOIN'        => array(
805
                                array(
806
                                        'FROM'        => array(FORUMS_TABLE        => 'f'),
807
                                        'ON'        => 'f.forum_id = p.forum_id',
808
                                ),
809
                        ),
810
                        'WHERE'                => $db->sql_in_set('p.topic_id', $topic_ids) . '
811
                                                        AND (p.post_approved = 1
812
                                                                ' . str_replace('forum_id', 'p.forum_id', $sql_m_approve) . ')
813
                                                        AND p.post_time >= ' . $min_post_time . '
814
                                                        AND u.user_id = p.poster_id',
815
                        'ORDER_BY'        => 'p.post_time DESC',
816
                );
817
818
                return true;
819
        }
820
821
        function adjust_item(&$item_row, &$row)
822
        {
823
                parent::adjust_item($item_row, $row);
824
825
                $item_row['title'] = (isset($row['forum_name']) && $row['forum_name'] !== '') ? $row['forum_name'] . ' ' . $this->separator . ' ' . $item_row['title'] : $item_row['title'];
826
        }
827
}
828
829
/**
830
* Forum feed
831
*
832
* This will give you the last {$this->num_items} posts made
833
* within a specific forum.
834
*
835
* @package phpBB3
836
*/
837
class phpbb_feed_forum extends phpbb_feed_post_base
838
{
839
        var $forum_id                = 0;
840
        var $forum_data                = array();
841
842
        function phpbb_feed_forum($forum_id)
843
        {
844
                parent::phpbb_feed_base();
845
846
                $this->forum_id = (int) $forum_id;
847
        }
848
849
        function open()
850
        {
851
                global $db, $auth;
852
853
                // Check if forum exists
854
                $sql = 'SELECT forum_id, forum_name, forum_password, forum_type, forum_options
855
                        FROM ' . FORUMS_TABLE . '
856
                        WHERE forum_id = ' . $this->forum_id;
857
                $result = $db->sql_query($sql);
858
                $this->forum_data = $db->sql_fetchrow($result);
859
                $db->sql_freeresult($result);
860
861
                if (empty($this->forum_data))
862
                {
863
                        trigger_error('NO_FORUM');
864
                }
865
866
                // Forum needs to be postable
867
                if ($this->forum_data['forum_type'] != FORUM_POST)
868
                {
869
                        trigger_error('NO_FEED');
870
                }
871
872
                // Make sure forum is not excluded from feed
873
                if (phpbb_optionget(FORUM_OPTION_FEED_EXCLUDE, $this->forum_data['forum_options']))
874
                {
875
                        trigger_error('NO_FEED');
876
                }
877
878
                // Make sure we can read this forum
879
                if (!$auth->acl_get('f_read', $this->forum_id))
880
                {
881
                        trigger_error('SORRY_AUTH_READ');
882
                }
883
884
                // Make sure forum is not passworded or user is authed
885
                if ($this->forum_data['forum_password'])
886
                {
887
                        $forum_ids_passworded = $this->get_passworded_forums();
888
889
                        if (isset($forum_ids_passworded[$this->forum_id]))
890
                        {
891
                                trigger_error('SORRY_AUTH_READ');
892
                        }
893
894
                        unset($forum_ids_passworded);
895
                }
896
        }
897
898
        function get_sql()
899
        {
900
                global $auth, $db;
901
902
                $m_approve = ($auth->acl_get('m_approve', $this->forum_id)) ? true : false;
903
                $forum_ids = array(0, $this->forum_id);
904
905
                // Determine topics with recent activity
906
                $sql = 'SELECT topic_id, topic_last_post_time
907
                        FROM ' . TOPICS_TABLE . '
908
                        WHERE ' . $db->sql_in_set('forum_id', $forum_ids) . '
909
                                AND topic_moved_id = 0
910
                                ' . ((!$m_approve) ? 'AND topic_approved = 1' : '') . '
911
                        ORDER BY topic_last_post_time DESC';
912
                $result = $db->sql_query_limit($sql, $this->num_items);
913
914
                $topic_ids = array();
915
                $min_post_time = 0;
916
                while ($row = $db->sql_fetchrow())
917
                {
918
                        $topic_ids[] = (int) $row['topic_id'];
919
920
                        $min_post_time = (int) $row['topic_last_post_time'];
921
                }
922
                $db->sql_freeresult($result);
923
924
                if (empty($topic_ids))
925
                {
926
                        return false;
927
                }
928
929
                $this->sql = array(
930
                        'SELECT'        =>        'p.post_id, p.topic_id, p.post_time, p.post_edit_time, p.post_approved, p.post_subject, p.post_text, p.bbcode_bitfield, p.bbcode_uid, p.enable_bbcode, p.enable_smilies, p.enable_magic_url, ' .
931
                                                        'u.username, u.user_id',
932
                        'FROM'                => array(
933
                                POSTS_TABLE                => 'p',
934
                                USERS_TABLE                => 'u',
935
                        ),
936
                        'WHERE'                => $db->sql_in_set('p.topic_id', $topic_ids) . '
937
                                                        ' . ((!$m_approve) ? 'AND p.post_approved = 1' : '') . '
938
                                                        AND p.post_time >= ' . $min_post_time . '
939
                                                        AND p.poster_id = u.user_id',
940
                        'ORDER_BY'        => 'p.post_time DESC',
941
                );
942
943
                return true;
944
        }
945
946
        function adjust_item(&$item_row, &$row)
947
        {
948
                parent::adjust_item($item_row, $row);
949
950
                $item_row['title'] = (isset($row['forum_name']) && $row['forum_name'] !== '') ? $row['forum_name'] . ' ' . $this->separator . ' ' . $item_row['title'] : $item_row['title'];
951
        }
952
953
        function get_item()
954
        {
955
                return ($row = parent::get_item()) ? array_merge($this->forum_data, $row) : $row;
956
        }
957
}
958
959
/**
960
* Topic feed for a specific topic
961
*
962
* This will give you the last {$this->num_items} posts made within this topic.
963
*
964
* @package phpBB3
965
*/
966
class phpbb_feed_topic extends phpbb_feed_post_base
967
{
968
        var $topic_id                = 0;
969
        var $forum_id                = 0;
970
        var $topic_data                = array();
971
972
        function phpbb_feed_topic($topic_id)
973
        {
974
                parent::phpbb_feed_base();
975
976
                $this->topic_id = (int) $topic_id;
977
        }
978
979
        function open()
980
        {
981
                global $auth, $db, $user;
982
983
                $sql = 'SELECT f.forum_options, f.forum_password, t.topic_id, t.forum_id, t.topic_approved, t.topic_title, t.topic_time, t.topic_views, t.topic_replies, t.topic_type
984
                        FROM ' . TOPICS_TABLE . ' t
985
                        LEFT JOIN ' . FORUMS_TABLE . ' f
986
                                ON (f.forum_id = t.forum_id)
987
                        WHERE t.topic_id = ' . $this->topic_id;
988
                $result = $db->sql_query($sql);
989
                $this->topic_data = $db->sql_fetchrow($result);
990
                $db->sql_freeresult($result);
991
992
                if (empty($this->topic_data))
993
                {
994
                        trigger_error('NO_TOPIC');
995
                }
996
997
                if ($this->topic_data['topic_type'] == POST_GLOBAL)
998
                {
999
                        // We need to find at least one postable forum where feeds are enabled,
1000
                        // that the user can read and maybe also has approve permissions.
1001
                        $in_fid_ary = $this->get_readable_forums();
1002
1003
                        if (empty($in_fid_ary))
1004
                        {
1005
                                // User cannot read any forums
1006
                                trigger_error('SORRY_AUTH_READ');
1007
                        }
1008
1009
                        if (!$this->topic_data['topic_approved'])
1010
                        {
1011
                                // Also require m_approve
1012
                                $in_fid_ary = array_intersect($in_fid_ary, $this->get_moderator_approve_forums());
1013
1014
                                if (empty($in_fid_ary))
1015
                                {
1016
                                        trigger_error('SORRY_AUTH_READ');
1017
                                }
1018
                        }
1019
1020
                        // Diff excluded forums
1021
                        $in_fid_ary = array_diff($in_fid_ary, $this->get_excluded_forums());
1022
1023
                        if (empty($in_fid_ary))
1024
                        {
1025
                                trigger_error('SORRY_AUTH_READ');
1026
                        }
1027
1028
                        // Also exclude passworded forums
1029
                        $in_fid_ary = array_diff($in_fid_ary, $this->get_passworded_forums());
1030
1031
                        if (empty($in_fid_ary))
1032
                        {
1033
                                trigger_error('SORRY_AUTH_READ');
1034
                        }
1035
1036
                        $sql = 'SELECT forum_id, left_id
1037
                                FROM ' . FORUMS_TABLE . '
1038
                                WHERE forum_type = ' . FORUM_POST . '
1039
                                        AND ' . $db->sql_in_set('forum_id', $in_fid_ary) . '
1040
                                ORDER BY left_id ASC';
1041
                        $result = $db->sql_query_limit($sql, 1);
1042
                        $this->forum_data = $db->sql_fetchrow($result);
1043
                        $db->sql_freeresult($result);
1044
1045
                        if (empty($this->forum_data))
1046
                        {
1047
                                // No forum found.
1048
                                trigger_error('SORRY_AUTH_READ');
1049
                        }
1050
1051
                        unset($in_fid_ary);
1052
                }
1053
                else
1054
                {
1055
                        $this->forum_id = (int) $this->topic_data['forum_id'];
1056
1057
                        // Make sure topic is either approved or user authed
1058
                        if (!$this->topic_data['topic_approved'] && !$auth->acl_get('m_approve', $this->forum_id))
1059
                        {
1060
                                trigger_error('SORRY_AUTH_READ');
1061
                        }
1062
1063
                        // Make sure forum is not excluded from feed
1064
                        if (phpbb_optionget(FORUM_OPTION_FEED_EXCLUDE, $this->topic_data['forum_options']))
1065
                        {
1066
                                trigger_error('NO_FEED');
1067
                        }
1068
1069
                        // Make sure we can read this forum
1070
                        if (!$auth->acl_get('f_read', $this->forum_id))
1071
                        {
1072
                                trigger_error('SORRY_AUTH_READ');
1073
                        }
1074
1075
                        // Make sure forum is not passworded or user is authed
1076
                        if ($this->topic_data['forum_password'])
1077
                        {
1078
                                $forum_ids_passworded = $this->get_passworded_forums();
1079
1080
                                if (isset($forum_ids_passworded[$this->forum_id]))
1081
                                {
1082
                                        trigger_error('SORRY_AUTH_READ');
1083
                                }
1084
1085
                                unset($forum_ids_passworded);
1086
                        }
1087
                }
1088
        }
1089
1090
        function get_sql()
1091
        {
1092
                global $auth, $db;
1093
1094
                $this->sql = array(
1095
                        'SELECT'        =>        'p.post_id, p.post_time, p.post_edit_time, p.post_approved, p.post_subject, p.post_text, p.bbcode_bitfield, p.bbcode_uid, p.enable_bbcode, p.enable_smilies, p.enable_magic_url, ' .
1096
                                                        'u.username, u.user_id',
1097
                        'FROM'                => array(
1098
                                POSTS_TABLE                => 'p',
1099
                                USERS_TABLE                => 'u',
1100
                        ),
1101
                        'WHERE'                => 'p.topic_id = ' . $this->topic_id . '
1102
                                                                ' . ($this->forum_id && !$auth->acl_get('m_approve', $this->forum_id) ? 'AND p.post_approved = 1' : '') . '
1103
                                                                AND p.poster_id = u.user_id',
1104
                        'ORDER_BY'        => 'p.post_time DESC',
1105
                );
1106
1107
                return true;
1108
        }
1109
1110
        function get_item()
1111
        {
1112
                return ($row = parent::get_item()) ? array_merge($this->topic_data, $row) : $row;
1113
        }
1114
}
1115
1116
/**
1117
* 'All Forums' feed
1118
*
1119
* This will give you a list of all postable forums where feeds are enabled
1120
* including forum description, topic stats and post stats
1121
*
1122
* @package phpBB3
1123
*/
1124
class phpbb_feed_forums extends phpbb_feed_base
1125
{
1126
        var $num_items        = 0;
1127
1128
        function set_keys()
1129
        {
1130
                $this->set('title',                'forum_name');
1131
                $this->set('text',                'forum_desc');
1132
                $this->set('bitfield',        'forum_desc_bitfield');
1133
                $this->set('bbcode_uid','forum_desc_uid');
1134
                $this->set('updated',        'forum_last_post_time');
1135
                $this->set('options',        'forum_desc_options');
1136
        }
1137
1138
        function get_sql()
1139
        {
1140
                global $auth, $db;
1141
1142
                $in_fid_ary = array_diff($this->get_readable_forums(), $this->get_excluded_forums());
1143
                if (empty($in_fid_ary))
1144
                {
1145
                        return false;
1146
                }
1147
1148
                // Build SQL Query
1149
                $this->sql = array(
1150
                        'SELECT'        => 'f.forum_id, f.left_id, f.forum_name, f.forum_last_post_time,
1151
                                                        f.forum_desc, f.forum_desc_bitfield, f.forum_desc_uid, f.forum_desc_options,
1152
                                                        f.forum_topics, f.forum_posts',
1153
                        'FROM'                => array(FORUMS_TABLE => 'f'),
1154
                        'WHERE'                => 'f.forum_type = ' . FORUM_POST . '
1155
                                                        AND ' . $db->sql_in_set('f.forum_id', $in_fid_ary),
1156
                        'ORDER_BY'        => 'f.left_id ASC',
1157
                );
1158
1159
                return true;
1160
        }
1161
1162
        function adjust_item(&$item_row, &$row)
1163
        {
1164
                global $phpEx, $config;
1165
1166
                $item_row['link'] = feed_append_sid('/viewforum.' . $phpEx, 'f=' . $row['forum_id']);
1167
1168
                if ($config['feed_item_statistics'])
1169
                {
1170
                        global $user;
1171
1172
                        $item_row['statistics'] = sprintf($user->lang['TOTAL_TOPICS_OTHER'], $row['forum_topics'])
1173
                                . ' ' . $this->separator_stats . ' ' . sprintf($user->lang['TOTAL_POSTS_OTHER'], $row['forum_posts']);
1174
                }
1175
        }
1176
}
1177
1178
/**
1179
* News feed
1180
*
1181
* This will give you {$this->num_items} first posts
1182
* of all topics in the selected news forums.
1183
*
1184
* @package phpBB3
1185
*/
1186
class phpbb_feed_news extends phpbb_feed_topic_base
1187
{
1188
        function get_news_forums()
1189
        {
1190
                global $db, $cache;
1191
                static $forum_ids;
1192
1193
                // Matches acp/acp_board.php
1194
                $cache_name        = 'feed_news_forum_ids';
1195
1196
                if (!isset($forum_ids) && ($forum_ids = $cache->get('_' . $cache_name)) === false)
1197
                {
1198
                        $sql = 'SELECT forum_id
1199
                                FROM ' . FORUMS_TABLE . '
1200
                                WHERE ' . $db->sql_bit_and('forum_options', FORUM_OPTION_FEED_NEWS, '<> 0');
1201
                        $result = $db->sql_query($sql);
1202
1203
                        $forum_ids = array();
1204
                        while ($forum_id = (int) $db->sql_fetchfield('forum_id'))
1205
                        {
1206
                                $forum_ids[$forum_id] = $forum_id;
1207
                        }
1208
                        $db->sql_freeresult($result);
1209
1210
                        $cache->put('_' . $cache_name, $forum_ids);
1211
                }
1212
1213
                return $forum_ids;
1214
        }
1215
1216
        function get_sql()
1217
        {
1218
                global $auth, $config, $db;
1219
1220
                // Determine forum ids
1221
                $in_fid_ary = array_intersect($this->get_news_forums(), $this->get_readable_forums());
1222
                if (empty($in_fid_ary))
1223
                {
1224
                        return false;
1225
                }
1226
1227
                $in_fid_ary = array_diff($in_fid_ary, $this->get_passworded_forums());
1228
                if (empty($in_fid_ary))
1229
                {
1230
                        return false;
1231
                }
1232
1233
                // Add global forum
1234
                $in_fid_ary[] = 0;
1235
1236
                // We really have to get the post ids first!
1237
                $sql = 'SELECT topic_first_post_id, topic_time
1238
                        FROM ' . TOPICS_TABLE . '
1239
                        WHERE ' . $db->sql_in_set('forum_id', $in_fid_ary) . '
1240
                                AND topic_moved_id = 0
1241
                                AND topic_approved = 1
1242
                        ORDER BY topic_time DESC';
1243
                $result = $db->sql_query_limit($sql, $this->num_items);
1244
1245
                $post_ids = array();
1246
                while ($row = $db->sql_fetchrow($result))
1247
                {
1248
                        $post_ids[] = (int) $row['topic_first_post_id'];
1249
                }
1250
                $db->sql_freeresult($result);
1251
1252
                if (empty($post_ids))
1253
                {
1254
                        return false;
1255
                }
1256
1257
                $this->sql = array(
1258
                        'SELECT'        => 'f.forum_id, f.forum_name,
1259
                                                        t.topic_id, t.topic_title, t.topic_poster, t.topic_first_poster_name, t.topic_replies, t.topic_replies_real, t.topic_views, t.topic_time, t.topic_last_post_time,
1260
                                                        p.post_id, p.post_time, p.post_edit_time, p.post_text, p.bbcode_bitfield, p.bbcode_uid, p.enable_bbcode, p.enable_smilies, p.enable_magic_url',
1261
                        'FROM'                => array(
1262
                                TOPICS_TABLE        => 't',
1263
                                POSTS_TABLE                => 'p',
1264
                        ),
1265
                        'LEFT_JOIN'        => array(
1266
                                array(
1267
                                        'FROM'        => array(FORUMS_TABLE => 'f'),
1268
                                        'ON'        => 'p.forum_id = f.forum_id',
1269
                                ),
1270
                        ),
1271
                        'WHERE'                => 'p.topic_id = t.topic_id
1272
                                                        AND ' . $db->sql_in_set('p.post_id', $post_ids),
1273
                        'ORDER_BY'        => 'p.post_time DESC',
1274
                );
1275
1276
                return true;
1277
        }
1278
}
1279
1280
/**
1281
* New Topics feed
1282
*
1283
* This will give you the last {$this->num_items} created topics
1284
* including the first post.
1285
*
1286
* @package phpBB3
1287
*/
1288
class phpbb_feed_topics extends phpbb_feed_topic_base
1289
{
1290
        function get_sql()
1291
        {
1292
                global $db, $config;
1293
1294
                $forum_ids_read = $this->get_readable_forums();
1295
                if (empty($forum_ids_read))
1296
                {
1297
                        return false;
1298
                }
1299
1300
                $in_fid_ary = array_diff($forum_ids_read, $this->get_excluded_forums(), $this->get_passworded_forums());
1301
                if (empty($in_fid_ary))
1302
                {
1303
                        return false;
1304
                }
1305
1306
                // Add global forum
1307
                $in_fid_ary[] = 0;
1308
1309
                // We really have to get the post ids first!
1310
                $sql = 'SELECT topic_first_post_id, topic_time
1311
                        FROM ' . TOPICS_TABLE . '
1312
                        WHERE ' . $db->sql_in_set('forum_id', $in_fid_ary) . '
1313
                                AND topic_moved_id = 0
1314
                                AND topic_approved = 1
1315
                        ORDER BY topic_time DESC';
1316
                $result = $db->sql_query_limit($sql, $this->num_items);
1317
1318
                $post_ids = array();
1319
                while ($row = $db->sql_fetchrow($result))
1320
                {
1321
                        $post_ids[] = (int) $row['topic_first_post_id'];
1322
                }
1323
                $db->sql_freeresult($result);
1324
1325
                if (empty($post_ids))
1326
                {
1327
                        return false;
1328
                }
1329
1330
                $this->sql = array(
1331
                        'SELECT'        => 'f.forum_id, f.forum_name,
1332
                                                        t.topic_id, t.topic_title, t.topic_poster, t.topic_first_poster_name, t.topic_replies, t.topic_replies_real, t.topic_views, t.topic_time, t.topic_last_post_time,
1333
                                                        p.post_id, p.post_time, p.post_edit_time, p.post_text, p.bbcode_bitfield, p.bbcode_uid, p.enable_bbcode, p.enable_smilies, p.enable_magic_url',
1334
                        'FROM'                => array(
1335
                                TOPICS_TABLE        => 't',
1336
                                POSTS_TABLE                => 'p',
1337
                        ),
1338
                        'LEFT_JOIN'        => array(
1339
                                array(
1340
                                        'FROM'        => array(FORUMS_TABLE => 'f'),
1341
                                        'ON'        => 'p.forum_id = f.forum_id',
1342
                                ),
1343
                        ),
1344
                        'WHERE'                => 'p.topic_id = t.topic_id
1345
                                                        AND ' . $db->sql_in_set('p.post_id', $post_ids),
1346
                        'ORDER_BY'        => 'p.post_time DESC',
1347
                );
1348
1349
                return true;
1350
        }
1351
1352
        function adjust_item(&$item_row, &$row)
1353
        {
1354
                parent::adjust_item($item_row, $row);
1355
1356
                $item_row['title'] = (isset($row['forum_name']) && $row['forum_name'] !== '') ? $row['forum_name'] . ' ' . $this->separator . ' ' . $item_row['title'] : $item_row['title'];
1357
        }
1358
}
1359
1360
/**
1361
* Active Topics feed
1362
*
1363
* This will give you the last {$this->num_items} topics
1364
* with replies made withing the last {$this->sort_days} days
1365
* including the last post.
1366
*
1367
* @package phpBB3
1368
*/
1369
class phpbb_feed_topics_active extends phpbb_feed_topic_base
1370
{
1371
        var $sort_days = 7;
1372
1373
        function set_keys()
1374
        {
1375
                parent::set_keys();
1376
1377
                $this->set('author_id',        'topic_last_poster_id');
1378
                $this->set('creator',        'topic_last_poster_name');
1379
        }
1380
1381
        function get_sql()
1382
        {
1383
                global $db, $config;
1384
1385
                $forum_ids_read = $this->get_readable_forums();
1386
                if (empty($forum_ids_read))
1387
                {
1388
                        return false;
1389
                }
1390
1391
                $in_fid_ary = array_intersect($forum_ids_read, $this->get_forum_ids());
1392
                $in_fid_ary = array_diff($in_fid_ary, $this->get_passworded_forums());
1393
                if (empty($in_fid_ary))
1394
                {
1395
                        return false;
1396
                }
1397
1398
                // Add global forum
1399
                $in_fid_ary[] = 0;
1400
1401
                // Search for topics in last X days
1402
                $last_post_time_sql = ($this->sort_days) ? ' AND topic_last_post_time > ' . (time() - ($this->sort_days * 24 * 3600)) : '';
1403
1404
                // We really have to get the post ids first!
1405
                $sql = 'SELECT topic_last_post_id, topic_last_post_time
1406
                        FROM ' . TOPICS_TABLE . '
1407
                        WHERE ' . $db->sql_in_set('forum_id', $in_fid_ary) . '
1408
                                AND topic_moved_id = 0
1409
                                AND topic_approved = 1
1410
                                ' . $last_post_time_sql . '
1411
                        ORDER BY topic_last_post_time DESC';
1412
                $result = $db->sql_query_limit($sql, $this->num_items);
1413
1414
                $post_ids = array();
1415
                while ($row = $db->sql_fetchrow($result))
1416
                {
1417
                        $post_ids[] = (int) $row['topic_last_post_id'];
1418
                }
1419
                $db->sql_freeresult($result);
1420
1421
                if (empty($post_ids))
1422
                {
1423
                        return false;
1424
                }
1425
1426
                $this->sql = array(
1427
                        'SELECT'        => 'f.forum_id, f.forum_name,
1428
                                                        t.topic_id, t.topic_title, t.topic_replies, t.topic_replies_real, t.topic_views,
1429
                                                        t.topic_last_poster_id, t.topic_last_poster_name, t.topic_last_post_time,
1430
                                                        p.post_id, p.post_time, p.post_edit_time, p.post_text, p.bbcode_bitfield, p.bbcode_uid, p.enable_bbcode, p.enable_smilies, p.enable_magic_url',
1431
                        'FROM'                => array(
1432
                                TOPICS_TABLE        => 't',
1433
                                POSTS_TABLE                => 'p',
1434
                        ),
1435
                        'LEFT_JOIN'        => array(
1436
                                array(
1437
                                        'FROM'        => array(FORUMS_TABLE => 'f'),
1438
                                        'ON'        => 'p.forum_id = f.forum_id',
1439
                                ),
1440
                        ),
1441
                        'WHERE'                => 'p.topic_id = t.topic_id
1442
                                                        AND ' . $db->sql_in_set('p.post_id', $post_ids),
1443
                        'ORDER_BY'        => 'p.post_time DESC',
1444
                );
1445
1446
                return true;
1447
        }
1448
1449
        function get_forum_ids()
1450
        {
1451
                global $db, $cache;
1452
                static $forum_ids;
1453
1454
                $cache_name        = 'feed_topic_active_forum_ids';
1455
1456
                if (!isset($forum_ids) && ($forum_ids = $cache->get('_' . $cache_name)) === false)
1457
                {
1458
                        $sql = 'SELECT forum_id
1459
                                FROM ' . FORUMS_TABLE . '
1460
                                WHERE forum_type = ' . FORUM_POST . '
1461
                                        AND ' . $db->sql_bit_and('forum_options', FORUM_OPTION_FEED_EXCLUDE, '= 0') . '
1462
                                        AND ' . $db->sql_bit_and('forum_flags', log(FORUM_FLAG_ACTIVE_TOPICS, 2), '<> 0');
1463
                        $result = $db->sql_query($sql);
1464
1465
                        $forum_ids = array();
1466
                        while ($forum_id = (int) $db->sql_fetchfield('forum_id'))
1467
                        {
1468
                                $forum_ids[$forum_id] = $forum_id;
1469
                        }
1470
                        $db->sql_freeresult($result);
1471
1472
                        $cache->put('_' . $cache_name, $forum_ids, 180);
1473
                }
1474
1475
                return $forum_ids;
1476
        }
1477
1478
        function adjust_item(&$item_row, &$row)
1479
        {
1480
                parent::adjust_item($item_row, $row);
1481
1482
                $item_row['title'] = (isset($row['forum_name']) && $row['forum_name'] !== '') ? $row['forum_name'] . ' ' . $this->separator . ' ' . $item_row['title'] : $item_row['title'];
1483
        }
1484
}
1485
1486
1487
?>