phpBB
Statistics
| Revision:

root / trunk / phpBB / feed.php

History | View | Annotate | Download (36.4 kB)

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