~azzar1/unity/add-show-desktop-key

« back to all changes in this revision

Viewing changes to www/php/phpBB3/includes/functions_content.php

  • Committer: William Grant
  • Date: 2009-02-23 23:47:02 UTC
  • mfrom: (1099.1.211 new-dispatch)
  • Revision ID: grantw@unimelb.edu.au-20090223234702-db4b1llly46ignwo
Merge from lp:~ivle-dev/ivle/new-dispatch.

Pretty much everything changes. Reread the setup docs. Backup your databases.
Every file is now in a different installed location, the configuration system
is rewritten, the dispatch system is rewritten, URLs are different, the
database is different, worksheets and exercises are no longer on the
filesystem, we use a templating engine, jail service protocols are rewritten,
we don't repeat ourselves, we have authorization rewritten, phpBB is gone,
and probably lots of other things that I cannot remember.

This is certainly the biggest commit I have ever made, and hopefully
the largest I ever will.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
<?php
2
 
/**
3
 
*
4
 
* @package phpBB3
5
 
* @version $Id: functions_content.php,v 1.3 2007/11/18 15:37:17 naderman Exp $
6
 
* @copyright (c) 2005 phpBB Group
7
 
* @license http://opensource.org/licenses/gpl-license.php GNU Public License
8
 
*
9
 
*/
10
 
 
11
 
/**
12
 
* @ignore
13
 
*/
14
 
if (!defined('IN_PHPBB'))
15
 
{
16
 
        exit;
17
 
}
18
 
 
19
 
/**
20
 
* gen_sort_selects()
21
 
* make_jumpbox()
22
 
* bump_topic_allowed()
23
 
* get_context()
24
 
* decode_message()
25
 
* strip_bbcode()
26
 
* generate_text_for_display()
27
 
* generate_text_for_storage()
28
 
* generate_text_for_edit()
29
 
* make_clickable_callback()
30
 
* make_clickable()
31
 
* censor_text()
32
 
* bbcode_nl2br()
33
 
* smiley_text()
34
 
* parse_attachments()
35
 
* extension_allowed()
36
 
* truncate_string()
37
 
* get_username_string()
38
 
* class bitfield
39
 
*/
40
 
 
41
 
/**
42
 
* Generate sort selection fields
43
 
*/
44
 
function gen_sort_selects(&$limit_days, &$sort_by_text, &$sort_days, &$sort_key, &$sort_dir, &$s_limit_days, &$s_sort_key, &$s_sort_dir, &$u_sort_param)
45
 
{
46
 
        global $user;
47
 
 
48
 
        $sort_dir_text = array('a' => $user->lang['ASCENDING'], 'd' => $user->lang['DESCENDING']);
49
 
 
50
 
        // Check if the key is selectable. If not, we reset to the first key found.
51
 
        // This ensures the values are always valid.
52
 
        if (!isset($limit_days[$sort_days]))
53
 
        {
54
 
                @reset($limit_days);
55
 
                $sort_days = key($limit_days);
56
 
        }
57
 
 
58
 
        if (!isset($sort_by_text[$sort_key]))
59
 
        {
60
 
                @reset($sort_by_text);
61
 
                $sort_key = key($sort_by_text);
62
 
        }
63
 
 
64
 
        if (!isset($sort_dir_text[$sort_dir]))
65
 
        {
66
 
                @reset($sort_dir_text);
67
 
                $sort_dir = key($sort_dir_text);
68
 
        }
69
 
 
70
 
        $s_limit_days = '<select name="st">';
71
 
        foreach ($limit_days as $day => $text)
72
 
        {
73
 
                $selected = ($sort_days == $day) ? ' selected="selected"' : '';
74
 
                $s_limit_days .= '<option value="' . $day . '"' . $selected . '>' . $text . '</option>';
75
 
        }
76
 
        $s_limit_days .= '</select>';
77
 
 
78
 
        $s_sort_key = '<select name="sk">';
79
 
        foreach ($sort_by_text as $key => $text)
80
 
        {
81
 
                $selected = ($sort_key == $key) ? ' selected="selected"' : '';
82
 
                $s_sort_key .= '<option value="' . $key . '"' . $selected . '>' . $text . '</option>';
83
 
        }
84
 
        $s_sort_key .= '</select>';
85
 
 
86
 
        $s_sort_dir = '<select name="sd">';
87
 
        foreach ($sort_dir_text as $key => $value)
88
 
        {
89
 
                $selected = ($sort_dir == $key) ? ' selected="selected"' : '';
90
 
                $s_sort_dir .= '<option value="' . $key . '"' . $selected . '>' . $value . '</option>';
91
 
        }
92
 
        $s_sort_dir .= '</select>';
93
 
 
94
 
        $u_sort_param = "st=$sort_days&amp;sk=$sort_key&amp;sd=$sort_dir";
95
 
 
96
 
        return;
97
 
}
98
 
 
99
 
/**
100
 
* Generate Jumpbox
101
 
*/
102
 
function make_jumpbox($action, $forum_id = false, $select_all = false, $acl_list = false, $force_display = false)
103
 
{
104
 
        global $config, $auth, $template, $user, $db;
105
 
 
106
 
        // We only return if the jumpbox is not forced to be displayed (in case it is needed for functionality)
107
 
        if (!$config['load_jumpbox'] && $force_display === false)
108
 
        {
109
 
                return;
110
 
        }
111
 
 
112
 
        $sql = 'SELECT forum_id, forum_name, parent_id, forum_type, left_id, right_id
113
 
                FROM ' . FORUMS_TABLE . '
114
 
                ORDER BY left_id ASC';
115
 
        $result = $db->sql_query($sql, 600);
116
 
 
117
 
        $right = $padding = 0;
118
 
        $padding_store = array('0' => 0);
119
 
        $display_jumpbox = false;
120
 
        $iteration = 0;
121
 
 
122
 
        // Sometimes it could happen that forums will be displayed here not be displayed within the index page
123
 
        // This is the result of forums not displayed at index, having list permissions and a parent of a forum with no permissions.
124
 
        // If this happens, the padding could be "broken"
125
 
 
126
 
        while ($row = $db->sql_fetchrow($result))
127
 
        {
128
 
                if ($row['left_id'] < $right)
129
 
                {
130
 
                        $padding++;
131
 
                        $padding_store[$row['parent_id']] = $padding;
132
 
                }
133
 
                else if ($row['left_id'] > $right + 1)
134
 
                {
135
 
                        // Ok, if the $padding_store for this parent is empty there is something wrong. For now we will skip over it.
136
 
                        // @todo digging deep to find out "how" this can happen.
137
 
                        $padding = (isset($padding_store[$row['parent_id']])) ? $padding_store[$row['parent_id']] : $padding;
138
 
                }
139
 
 
140
 
                $right = $row['right_id'];
141
 
 
142
 
                if ($row['forum_type'] == FORUM_CAT && ($row['left_id'] + 1 == $row['right_id']))
143
 
                {
144
 
                        // Non-postable forum with no subforums, don't display
145
 
                        continue;
146
 
                }
147
 
 
148
 
                if (!$auth->acl_get('f_list', $row['forum_id']))
149
 
                {
150
 
                        // if the user does not have permissions to list this forum skip
151
 
                        continue;
152
 
                }
153
 
 
154
 
                if ($acl_list && !$auth->acl_gets($acl_list, $row['forum_id']))
155
 
                {
156
 
                        continue;
157
 
                }
158
 
 
159
 
                if (!$display_jumpbox)
160
 
                {
161
 
                        $template->assign_block_vars('jumpbox_forums', array(
162
 
                                'FORUM_ID'              => ($select_all) ? 0 : -1,
163
 
                                'FORUM_NAME'    => ($select_all) ? $user->lang['ALL_FORUMS'] : $user->lang['SELECT_FORUM'],
164
 
                                'S_FORUM_COUNT' => $iteration)
165
 
                        );
166
 
 
167
 
                        $iteration++;
168
 
                        $display_jumpbox = true;
169
 
                }
170
 
 
171
 
                $template->assign_block_vars('jumpbox_forums', array(
172
 
                        'FORUM_ID'              => $row['forum_id'],
173
 
                        'FORUM_NAME'    => $row['forum_name'],
174
 
                        'SELECTED'              => ($row['forum_id'] == $forum_id) ? ' selected="selected"' : '',
175
 
                        'S_FORUM_COUNT' => $iteration,
176
 
                        'S_IS_CAT'              => ($row['forum_type'] == FORUM_CAT) ? true : false,
177
 
                        'S_IS_LINK'             => ($row['forum_type'] == FORUM_LINK) ? true : false,
178
 
                        'S_IS_POST'             => ($row['forum_type'] == FORUM_POST) ? true : false)
179
 
                );
180
 
 
181
 
                for ($i = 0; $i < $padding; $i++)
182
 
                {
183
 
                        $template->assign_block_vars('jumpbox_forums.level', array());
184
 
                }
185
 
                $iteration++;
186
 
        }
187
 
        $db->sql_freeresult($result);
188
 
        unset($padding_store);
189
 
 
190
 
        $template->assign_vars(array(
191
 
                'S_DISPLAY_JUMPBOX'     => $display_jumpbox,
192
 
                'S_JUMPBOX_ACTION'      => $action)
193
 
        );
194
 
 
195
 
        return;
196
 
}
197
 
 
198
 
/**
199
 
* Bump Topic Check - used by posting and viewtopic
200
 
*/
201
 
function bump_topic_allowed($forum_id, $topic_bumped, $last_post_time, $topic_poster, $last_topic_poster)
202
 
{
203
 
        global $config, $auth, $user;
204
 
 
205
 
        // Check permission and make sure the last post was not already bumped
206
 
        if (!$auth->acl_get('f_bump', $forum_id) || $topic_bumped)
207
 
        {
208
 
                return false;
209
 
        }
210
 
 
211
 
        // Check bump time range, is the user really allowed to bump the topic at this time?
212
 
        $bump_time = ($config['bump_type'] == 'm') ? $config['bump_interval'] * 60 : (($config['bump_type'] == 'h') ? $config['bump_interval'] * 3600 : $config['bump_interval'] * 86400);
213
 
 
214
 
        // Check bump time
215
 
        if ($last_post_time + $bump_time > time())
216
 
        {
217
 
                return false;
218
 
        }
219
 
 
220
 
        // Check bumper, only topic poster and last poster are allowed to bump
221
 
        if ($topic_poster != $user->data['user_id'] && $last_topic_poster != $user->data['user_id'])
222
 
        {
223
 
                return false;
224
 
        }
225
 
 
226
 
        // A bump time of 0 will completely disable the bump feature... not intended but might be useful.
227
 
        return $bump_time;
228
 
}
229
 
 
230
 
/**
231
 
* Generates a text with approx. the specified length which contains the specified words and their context
232
 
*
233
 
* @param        string  $text   The full text from which context shall be extracted
234
 
* @param        string  $words  An array of words which should be contained in the result, has to be a valid part of a PCRE pattern (escape with preg_quote!)
235
 
* @param        int             $length The desired length of the resulting text, however the result might be shorter or longer than this value
236
 
*
237
 
* @return       string                  Context of the specified words separated by "..."
238
 
*/
239
 
function get_context($text, $words, $length = 400)
240
 
{
241
 
        // first replace all whitespaces with single spaces
242
 
        $text = preg_replace('/ +/', ' ', strtr($text, "\t\n\r\x0C ", '     '), $text);
243
 
 
244
 
        $word_indizes = array();
245
 
        if (sizeof($words))
246
 
        {
247
 
                $match = '';
248
 
                // find the starting indizes of all words
249
 
                foreach ($words as $word)
250
 
                {
251
 
                        if ($word)
252
 
                        {
253
 
                                if (preg_match('#(?:[^\w]|^)(' . $word . ')(?:[^\w]|$)#i', $text, $match))
254
 
                                {
255
 
                                        $pos = utf8_strpos($text, $match[1]);
256
 
                                        if ($pos !== false)
257
 
                                        {
258
 
                                                $word_indizes[] = $pos;
259
 
                                        }
260
 
                                }
261
 
                        }
262
 
                }
263
 
                unset($match);
264
 
 
265
 
                if (sizeof($word_indizes))
266
 
                {
267
 
                        $word_indizes = array_unique($word_indizes);
268
 
                        sort($word_indizes);
269
 
 
270
 
                        $wordnum = sizeof($word_indizes);
271
 
                        // number of characters on the right and left side of each word
272
 
                        $sequence_length = (int) ($length / (2 * $wordnum)) - 2;
273
 
                        $final_text = '';
274
 
                        $word = $j = 0;
275
 
                        $final_text_index = -1;
276
 
 
277
 
                        // cycle through every character in the original text
278
 
                        for ($i = $word_indizes[$word], $n = utf8_strlen($text); $i < $n; $i++)
279
 
                        {
280
 
                                // if the current position is the start of one of the words then append $sequence_length characters to the final text
281
 
                                if (isset($word_indizes[$word]) && ($i == $word_indizes[$word]))
282
 
                                {
283
 
                                        if ($final_text_index < $i - $sequence_length - 1)
284
 
                                        {
285
 
                                                $final_text .= '... ' . preg_replace('#^([^ ]*)#', '', utf8_substr($text, $i - $sequence_length, $sequence_length));
286
 
                                        }
287
 
                                        else
288
 
                                        {
289
 
                                                // if the final text is already nearer to the current word than $sequence_length we only append the text
290
 
                                                // from its current index on and distribute the unused length to all other sequenes
291
 
                                                $sequence_length += (int) (($final_text_index - $i + $sequence_length + 1) / (2 * $wordnum));
292
 
                                                $final_text .= utf8_substr($text, $final_text_index + 1, $i - $final_text_index - 1);
293
 
                                        }
294
 
                                        $final_text_index = $i - 1;
295
 
 
296
 
                                        // add the following characters to the final text (see below)
297
 
                                        $word++;
298
 
                                        $j = 1;
299
 
                                }
300
 
 
301
 
                                if ($j > 0)
302
 
                                {
303
 
                                        // add the character to the final text and increment the sequence counter
304
 
                                        $final_text .= utf8_substr($text, $i, 1);
305
 
                                        $final_text_index++;
306
 
                                        $j++;
307
 
 
308
 
                                        // if this is a whitespace then check whether we are done with this sequence
309
 
                                        if (utf8_substr($text, $i, 1) == ' ')
310
 
                                        {
311
 
                                                // only check whether we have to exit the context generation completely if we haven't already reached the end anyway
312
 
                                                if ($i + 4 < $n)
313
 
                                                {
314
 
                                                        if (($j > $sequence_length && $word >= $wordnum) || utf8_strlen($final_text) > $length)
315
 
                                                        {
316
 
                                                                $final_text .= ' ...';
317
 
                                                                break;
318
 
                                                        }
319
 
                                                }
320
 
                                                else
321
 
                                                {
322
 
                                                        // make sure the text really reaches the end
323
 
                                                        $j -= 4;
324
 
                                                }
325
 
 
326
 
                                                // stop context generation and wait for the next word
327
 
                                                if ($j > $sequence_length)
328
 
                                                {
329
 
                                                        $j = 0;
330
 
                                                }
331
 
                                        }
332
 
                                }
333
 
                        }
334
 
                        return $final_text;
335
 
                }
336
 
        }
337
 
 
338
 
        if (!sizeof($words) || !sizeof($word_indizes))
339
 
        {
340
 
                return (utf8_strlen($text) >= $length + 3) ? utf8_substr($text, 0, $length) . '...' : $text;
341
 
        }
342
 
}
343
 
 
344
 
/**
345
 
* Decode text whereby text is coming from the db and expected to be pre-parsed content
346
 
* We are placing this outside of the message parser because we are often in need of it...
347
 
*/
348
 
function decode_message(&$message, $bbcode_uid = '')
349
 
{
350
 
        global $config;
351
 
 
352
 
        if ($bbcode_uid)
353
 
        {
354
 
                $match = array('<br />', "[/*:m:$bbcode_uid]", ":u:$bbcode_uid", ":o:$bbcode_uid", ":$bbcode_uid");
355
 
                $replace = array("\n", '', '', '', '');
356
 
        }
357
 
        else
358
 
        {
359
 
                $match = array('<br />');
360
 
                $replace = array("\n");
361
 
        }
362
 
 
363
 
        $message = str_replace($match, $replace, $message);
364
 
 
365
 
        $match = get_preg_expression('bbcode_htm');
366
 
        $replace = array('\1', '\1', '\2', '\1', '', '');
367
 
 
368
 
        $message = preg_replace($match, $replace, $message);
369
 
}
370
 
 
371
 
/**
372
 
* Strips all bbcode from a text and returns the plain content
373
 
*/
374
 
function strip_bbcode(&$text, $uid = '')
375
 
{
376
 
        if (!$uid)
377
 
        {
378
 
                $uid = '[0-9a-z]{5,}';
379
 
        }
380
 
 
381
 
        $text = preg_replace("#\[\/?[a-z0-9\*\+\-]+(?:=(?:&quot;.*&quot;|[^\]]*))?(?::[a-z])?(\:$uid)\]#", ' ', $text);
382
 
 
383
 
        $match = get_preg_expression('bbcode_htm');
384
 
        $replace = array('\1', '\1', '\2', '\1', '', '');
385
 
        
386
 
        $text = preg_replace($match, $replace, $text);
387
 
}
388
 
 
389
 
/**
390
 
* For display of custom parsed text on user-facing pages
391
 
* Expects $text to be the value directly from the database (stored value)
392
 
*/
393
 
function generate_text_for_display($text, $uid, $bitfield, $flags)
394
 
{
395
 
        static $bbcode;
396
 
 
397
 
        if (!$text)
398
 
        {
399
 
                return '';
400
 
        }
401
 
 
402
 
        $text = censor_text($text);
403
 
 
404
 
        // Parse bbcode if bbcode uid stored and bbcode enabled
405
 
        if ($uid && ($flags & OPTION_FLAG_BBCODE))
406
 
        {
407
 
                if (!class_exists('bbcode'))
408
 
                {
409
 
                        global $phpbb_root_path, $phpEx;
410
 
                        include($phpbb_root_path . 'includes/bbcode.' . $phpEx);
411
 
                }
412
 
 
413
 
                if (empty($bbcode))
414
 
                {
415
 
                        $bbcode = new bbcode($bitfield);
416
 
                }
417
 
                else
418
 
                {
419
 
                        $bbcode->bbcode($bitfield);
420
 
                }
421
 
                
422
 
                $bbcode->bbcode_second_pass($text, $uid);
423
 
        }
424
 
 
425
 
        $text = bbcode_nl2br($text);
426
 
        $text = smiley_text($text, !($flags & OPTION_FLAG_SMILIES));
427
 
 
428
 
        return $text;
429
 
}
430
 
 
431
 
/**
432
 
* For parsing custom parsed text to be stored within the database.
433
 
* This function additionally returns the uid and bitfield that needs to be stored.
434
 
* Expects $text to be the value directly from request_var() and in it's non-parsed form
435
 
*/
436
 
function generate_text_for_storage(&$text, &$uid, &$bitfield, &$flags, $allow_bbcode = false, $allow_urls = false, $allow_smilies = false)
437
 
{
438
 
        global $phpbb_root_path, $phpEx;
439
 
 
440
 
        $uid = $bitfield = '';
441
 
 
442
 
        if (!$text)
443
 
        {
444
 
                return;
445
 
        }
446
 
 
447
 
        if (!class_exists('parse_message'))
448
 
        {
449
 
                include($phpbb_root_path . 'includes/message_parser.' . $phpEx);
450
 
        }
451
 
 
452
 
        $message_parser = new parse_message($text);
453
 
        $message_parser->parse($allow_bbcode, $allow_urls, $allow_smilies);
454
 
 
455
 
        $text = $message_parser->message;
456
 
        $uid = $message_parser->bbcode_uid;
457
 
 
458
 
        // If the bbcode_bitfield is empty, there is no need for the uid to be stored.
459
 
        if (!$message_parser->bbcode_bitfield)
460
 
        {
461
 
                $uid = '';
462
 
        }
463
 
 
464
 
        $flags = (($allow_bbcode) ? OPTION_FLAG_BBCODE : 0) + (($allow_smilies) ? OPTION_FLAG_SMILIES : 0) + (($allow_urls) ? OPTION_FLAG_LINKS : 0);
465
 
        $bitfield = $message_parser->bbcode_bitfield;
466
 
 
467
 
        return;
468
 
}
469
 
 
470
 
/**
471
 
* For decoding custom parsed text for edits as well as extracting the flags
472
 
* Expects $text to be the value directly from the database (pre-parsed content)
473
 
*/
474
 
function generate_text_for_edit($text, $uid, $flags)
475
 
{
476
 
        global $phpbb_root_path, $phpEx;
477
 
 
478
 
        decode_message($text, $uid);
479
 
 
480
 
        return array(
481
 
                'allow_bbcode'  => ($flags & OPTION_FLAG_BBCODE) ? 1 : 0,
482
 
                'allow_smilies' => ($flags & OPTION_FLAG_SMILIES) ? 1 : 0,
483
 
                'allow_urls'    => ($flags & OPTION_FLAG_LINKS) ? 1 : 0,
484
 
                'text'                  => $text
485
 
        );
486
 
}
487
 
 
488
 
/**
489
 
* A subroutine of make_clickable used with preg_replace
490
 
* It places correct HTML around an url, shortens the displayed text
491
 
* and makes sure no entities are inside URLs
492
 
*/
493
 
function make_clickable_callback($type, $whitespace, $url, $relative_url, $class)
494
 
{
495
 
        $append                 = '';
496
 
        $url                    = htmlspecialchars_decode($url);
497
 
        $relative_url   = htmlspecialchars_decode($relative_url);
498
 
 
499
 
        // make sure no HTML entities were matched
500
 
        $chars = array('<', '>', '"');
501
 
        $split = false;
502
 
 
503
 
        foreach ($chars as $char)
504
 
        {
505
 
                $next_split = strpos($url, $char);
506
 
                if ($next_split !== false)
507
 
                {
508
 
                        $split = ($split !== false) ? min($split, $next_split) : $next_split;
509
 
                }
510
 
        }
511
 
 
512
 
        if ($split !== false)
513
 
        {
514
 
                // an HTML entity was found, so the URL has to end before it
515
 
                $append                 = substr($url, $split) . $relative_url;
516
 
                $url                    = substr($url, 0, $split);
517
 
                $relative_url   = '';
518
 
        }
519
 
        else if ($relative_url)
520
 
        {
521
 
                // same for $relative_url
522
 
                $split = false;
523
 
                foreach ($chars as $char)
524
 
                {
525
 
                        $next_split = strpos($relative_url, $char);
526
 
                        if ($next_split !== false)
527
 
                        {
528
 
                                $split = ($split !== false) ? min($split, $next_split) : $next_split;
529
 
                        }
530
 
                }
531
 
 
532
 
                if ($split !== false)
533
 
                {
534
 
                        $append                 = substr($relative_url, $split);
535
 
                        $relative_url   = substr($relative_url, 0, $split);
536
 
                }
537
 
        }
538
 
 
539
 
        // if the last character of the url is a punctuation mark, exclude it from the url
540
 
        $last_char = ($relative_url) ? $relative_url[strlen($relative_url) - 1] : $url[strlen($url) - 1];
541
 
 
542
 
        switch ($last_char)
543
 
        {
544
 
                case '.':
545
 
                case '?':
546
 
                case '!':
547
 
                case ':':
548
 
                case ',':
549
 
                        $append = $last_char;
550
 
                        if ($relative_url)
551
 
                        {
552
 
                                $relative_url = substr($relative_url, 0, -1);
553
 
                        }
554
 
                        else
555
 
                        {
556
 
                                $url = substr($url, 0, -1);
557
 
                        }
558
 
                break;
559
 
        }
560
 
 
561
 
        switch ($type)
562
 
        {
563
 
                case MAGIC_URL_LOCAL:
564
 
                        $tag                    = 'l';
565
 
                        $relative_url   = preg_replace('/[&?]sid=[0-9a-f]{32}$/', '', preg_replace('/([&?])sid=[0-9a-f]{32}&/', '$1', $relative_url));
566
 
                        $url                    = $url . '/' . $relative_url;
567
 
                        $text                   = ($relative_url) ? $relative_url : $url;
568
 
                break;
569
 
 
570
 
                case MAGIC_URL_FULL:
571
 
                        $tag    = 'm';
572
 
                        $text   = (strlen($url) > 55) ? substr($url, 0, 39) . ' ... ' . substr($url, -10) : $url;
573
 
                break;
574
 
 
575
 
                case MAGIC_URL_WWW:
576
 
                        $tag    = 'w';
577
 
                        $url    = 'http://' . $url;
578
 
                        $text   = (strlen($url) > 55) ? substr($url, 0, 39) . ' ... ' . substr($url, -10) : $url;
579
 
                break;
580
 
 
581
 
                case MAGIC_URL_EMAIL:
582
 
                        $tag    = 'e';
583
 
                        $text   = (strlen($url) > 55) ? substr($url, 0, 39) . ' ... ' . substr($url, -10) : $url;
584
 
                        $url    = 'mailto:' . $url;
585
 
                break;
586
 
        }
587
 
 
588
 
        $url    = htmlspecialchars($url);
589
 
        $text   = htmlspecialchars($text);
590
 
        $append = htmlspecialchars($append);
591
 
 
592
 
        $html   = "$whitespace<!-- $tag --><a$class href=\"$url\">$text</a><!-- $tag -->$append";
593
 
 
594
 
        return $html;
595
 
}
596
 
 
597
 
/**
598
 
* make_clickable function
599
 
*
600
 
* Replace magic urls of form http://xxx.xxx., www.xxx. and xxx@xxx.xxx.
601
 
* Cuts down displayed size of link if over 50 chars, turns absolute links
602
 
* into relative versions when the server/script path matches the link
603
 
*/
604
 
function make_clickable($text, $server_url = false, $class = 'postlink')
605
 
{
606
 
        if ($server_url === false)
607
 
        {
608
 
                $server_url = generate_board_url();
609
 
        }
610
 
 
611
 
        static $magic_url_match;
612
 
        static $magic_url_replace;
613
 
        static $static_class;
614
 
 
615
 
        if (!is_array($magic_url_match) || $static_class != $class)
616
 
        {
617
 
                $static_class = $class;
618
 
                $class = ($static_class) ? ' class="' . $static_class . '"' : '';
619
 
                $local_class = ($static_class) ? ' class="' . $static_class . '-local"' : '';
620
 
 
621
 
                $magic_url_match = $magic_url_replace = array();
622
 
                // Be sure to not let the matches cross over. ;)
623
 
 
624
 
                // relative urls for this board
625
 
                $magic_url_match[] = '#(^|[\n\t (>.])(' . preg_quote($server_url, '#') . ')/(' . get_preg_expression('relative_url_inline') . ')#ie';
626
 
                $magic_url_replace[] = "make_clickable_callback(MAGIC_URL_LOCAL, '\$1', '\$2', '\$3', '$local_class')";
627
 
 
628
 
                // matches a xxxx://aaaaa.bbb.cccc. ...
629
 
                $magic_url_match[] = '#(^|[\n\t (>.])(' . get_preg_expression('url_inline') . ')#ie';
630
 
                $magic_url_replace[] = "make_clickable_callback(MAGIC_URL_FULL, '\$1', '\$2', '', '$class')";
631
 
 
632
 
                // matches a "www.xxxx.yyyy[/zzzz]" kinda lazy URL thing
633
 
                $magic_url_match[] = '#(^|[\n\t (>])(' . get_preg_expression('www_url_inline') . ')#ie';
634
 
                $magic_url_replace[] = "make_clickable_callback(MAGIC_URL_WWW, '\$1', '\$2', '', '$class')";
635
 
 
636
 
                // matches an email@domain type address at the start of a line, or after a space or after what might be a BBCode.
637
 
                $magic_url_match[] = '/(^|[\n\t (>])(' . get_preg_expression('email') . ')/ie';
638
 
                $magic_url_replace[] = "make_clickable_callback(MAGIC_URL_EMAIL, '\$1', '\$2', '', '')";
639
 
        }
640
 
 
641
 
        return preg_replace($magic_url_match, $magic_url_replace, $text);
642
 
}
643
 
 
644
 
/**
645
 
* Censoring
646
 
*/
647
 
function censor_text($text)
648
 
{
649
 
        static $censors;
650
 
        global $cache;
651
 
 
652
 
        if (!isset($censors) || !is_array($censors))
653
 
        {
654
 
                // obtain_word_list is taking care of the users censor option and the board-wide option
655
 
                $censors = $cache->obtain_word_list();
656
 
        }
657
 
 
658
 
        if (sizeof($censors))
659
 
        {
660
 
                return preg_replace($censors['match'], $censors['replace'], $text);
661
 
        }
662
 
 
663
 
        return $text;
664
 
}
665
 
 
666
 
/**
667
 
* custom version of nl2br which takes custom BBCodes into account
668
 
*/
669
 
function bbcode_nl2br($text)
670
 
{
671
 
        // custom BBCodes might contain carriage returns so they
672
 
        // are not converted into <br /> so now revert that
673
 
        $text = str_replace(array("\n", "\r"), array('<br />', "\n"), $text);
674
 
        return $text;
675
 
}
676
 
 
677
 
/**
678
 
* Smiley processing
679
 
*/
680
 
function smiley_text($text, $force_option = false)
681
 
{
682
 
        global $config, $user, $phpbb_root_path;
683
 
 
684
 
        if ($force_option || !$config['allow_smilies'] || !$user->optionget('viewsmilies'))
685
 
        {
686
 
                return preg_replace('#<!\-\- s(.*?) \-\-><img src="\{SMILIES_PATH\}\/.*? \/><!\-\- s\1 \-\->#', '\1', $text);
687
 
        }
688
 
        else
689
 
        {
690
 
                return preg_replace('#<!\-\- s(.*?) \-\-><img src="\{SMILIES_PATH\}\/(.*?) \/><!\-\- s\1 \-\->#', '<img src="' . $phpbb_root_path . $config['smilies_path'] . '/\2 />', $text);
691
 
        }
692
 
}
693
 
 
694
 
/**
695
 
* General attachment parsing
696
 
*
697
 
* @param mixed $forum_id The forum id the attachments are displayed in (false if in private message)
698
 
* @param string &$message The post/private message
699
 
* @param array &$attachments The attachments to parse for (inline) display. The attachments array will hold templated data after parsing.
700
 
* @param array &$update_count The attachment counts to be updated - will be filled
701
 
* @param bool $preview If set to true the attachments are parsed for preview. Within preview mode the comments are fetched from the given $attachments array and not fetched from the database.
702
 
*/
703
 
function parse_attachments($forum_id, &$message, &$attachments, &$update_count, $preview = false)
704
 
{
705
 
        if (!sizeof($attachments))
706
 
        {
707
 
                return;
708
 
        }
709
 
 
710
 
        global $template, $cache, $user;
711
 
        global $extensions, $config, $phpbb_root_path, $phpEx;
712
 
 
713
 
        //
714
 
        $compiled_attachments = array();
715
 
 
716
 
        if (!isset($template->filename['attachment_tpl']))
717
 
        {
718
 
                $template->set_filenames(array(
719
 
                        'attachment_tpl'        => 'attachment.html')
720
 
                );
721
 
        }
722
 
 
723
 
        if (empty($extensions) || !is_array($extensions))
724
 
        {
725
 
                $extensions = $cache->obtain_attach_extensions($forum_id);
726
 
        }
727
 
 
728
 
        // Look for missing attachment information...
729
 
        $attach_ids = array();
730
 
        foreach ($attachments as $pos => $attachment)
731
 
        {
732
 
                // If is_orphan is set, we need to retrieve the attachments again...
733
 
                if (!isset($attachment['extension']) && !isset($attachment['physical_filename']))
734
 
                {
735
 
                        $attach_ids[(int) $attachment['attach_id']] = $pos;
736
 
                }
737
 
        }
738
 
 
739
 
        // Grab attachments (security precaution)
740
 
        if (sizeof($attach_ids))
741
 
        {
742
 
                global $db;
743
 
 
744
 
                $new_attachment_data = array();
745
 
 
746
 
                $sql = 'SELECT *
747
 
                        FROM ' . ATTACHMENTS_TABLE . '
748
 
                        WHERE ' . $db->sql_in_set('attach_id', array_keys($attach_ids));
749
 
                $result = $db->sql_query($sql);
750
 
 
751
 
                while ($row = $db->sql_fetchrow($result))
752
 
                {
753
 
                        if (!isset($attach_ids[$row['attach_id']]))
754
 
                        {
755
 
                                continue;
756
 
                        }
757
 
 
758
 
                        // If we preview attachments we will set some retrieved values here
759
 
                        if ($preview)
760
 
                        {
761
 
                                $row['attach_comment'] = $attachments[$attach_ids[$row['attach_id']]]['attach_comment'];
762
 
                        }
763
 
 
764
 
                        $new_attachment_data[$attach_ids[$row['attach_id']]] = $row;
765
 
                }
766
 
                $db->sql_freeresult($result);
767
 
 
768
 
                $attachments = $new_attachment_data;
769
 
                unset($new_attachment_data);
770
 
        }
771
 
 
772
 
        // Sort correctly
773
 
        if ($config['display_order'])
774
 
        {
775
 
                // Ascending sort
776
 
                krsort($attachments);
777
 
        }
778
 
        else
779
 
        {
780
 
                // Descending sort
781
 
                ksort($attachments);
782
 
        }
783
 
 
784
 
        foreach ($attachments as $attachment)
785
 
        {
786
 
                if (!sizeof($attachment))
787
 
                {
788
 
                        continue;
789
 
                }
790
 
 
791
 
                // We need to reset/empty the _file block var, because this function might be called more than once
792
 
                $template->destroy_block_vars('_file');
793
 
 
794
 
                $block_array = array();
795
 
                
796
 
                // Some basics...
797
 
                $attachment['extension'] = strtolower(trim($attachment['extension']));
798
 
                $filename = $phpbb_root_path . $config['upload_path'] . '/' . basename($attachment['physical_filename']);
799
 
                $thumbnail_filename = $phpbb_root_path . $config['upload_path'] . '/thumb_' . basename($attachment['physical_filename']);
800
 
 
801
 
                $upload_icon = '';
802
 
 
803
 
                if (isset($extensions[$attachment['extension']]))
804
 
                {
805
 
                        if ($user->img('icon_topic_attach', '') && !$extensions[$attachment['extension']]['upload_icon'])
806
 
                        {
807
 
                                $upload_icon = $user->img('icon_topic_attach', '');
808
 
                        }
809
 
                        else if ($extensions[$attachment['extension']]['upload_icon'])
810
 
                        {
811
 
                                $upload_icon = '<img src="' . $phpbb_root_path . $config['upload_icons_path'] . '/' . trim($extensions[$attachment['extension']]['upload_icon']) . '" alt="" />';
812
 
                        }
813
 
                }
814
 
 
815
 
                $filesize = $attachment['filesize'];
816
 
                $size_lang = ($filesize >= 1048576) ? $user->lang['MB'] : ( ($filesize >= 1024) ? $user->lang['KB'] : $user->lang['BYTES'] );
817
 
                $filesize = ($filesize >= 1048576) ? round((round($filesize / 1048576 * 100) / 100), 2) : (($filesize >= 1024) ? round((round($filesize / 1024 * 100) / 100), 2) : $filesize);
818
 
 
819
 
                $comment = bbcode_nl2br(censor_text($attachment['attach_comment']));
820
 
 
821
 
                $block_array += array(
822
 
                        'UPLOAD_ICON'           => $upload_icon,
823
 
                        'FILESIZE'                      => $filesize,
824
 
                        'SIZE_LANG'                     => $size_lang,
825
 
                        'DOWNLOAD_NAME'         => basename($attachment['real_filename']),
826
 
                        'COMMENT'                       => $comment,
827
 
                );
828
 
 
829
 
                $denied = false;
830
 
 
831
 
                if (!extension_allowed($forum_id, $attachment['extension'], $extensions))
832
 
                {
833
 
                        $denied = true;
834
 
 
835
 
                        $block_array += array(
836
 
                                'S_DENIED'                      => true,
837
 
                                'DENIED_MESSAGE'        => sprintf($user->lang['EXTENSION_DISABLED_AFTER_POSTING'], $attachment['extension'])
838
 
                        );
839
 
                }
840
 
 
841
 
                if (!$denied)
842
 
                {
843
 
                        $l_downloaded_viewed = $download_link = '';
844
 
                        $display_cat = $extensions[$attachment['extension']]['display_cat'];
845
 
 
846
 
                        if ($display_cat == ATTACHMENT_CATEGORY_IMAGE)
847
 
                        {
848
 
                                if ($attachment['thumbnail'])
849
 
                                {
850
 
                                        $display_cat = ATTACHMENT_CATEGORY_THUMB;
851
 
                                }
852
 
                                else
853
 
                                {
854
 
                                        if ($config['img_display_inlined'])
855
 
                                        {
856
 
                                                if ($config['img_link_width'] || $config['img_link_height'])
857
 
                                                {
858
 
                                                        $dimension = @getimagesize($filename);
859
 
 
860
 
                                                        // If the dimensions could not be determined or the image being 0x0 we display it as a link for safety purposes
861
 
                                                        if ($dimension === false || empty($dimension[0]) || empty($dimension[1]))
862
 
                                                        {
863
 
                                                                $display_cat = ATTACHMENT_CATEGORY_NONE;
864
 
                                                        }
865
 
                                                        else
866
 
                                                        {
867
 
                                                                $display_cat = ($dimension[0] <= $config['img_link_width'] && $dimension[1] <= $config['img_link_height']) ? ATTACHMENT_CATEGORY_IMAGE : ATTACHMENT_CATEGORY_NONE;
868
 
                                                        }
869
 
                                                }
870
 
                                        }
871
 
                                        else
872
 
                                        {
873
 
                                                $display_cat = ATTACHMENT_CATEGORY_NONE;
874
 
                                        }
875
 
                                }
876
 
                        }
877
 
 
878
 
                        // Make some descisions based on user options being set.
879
 
                        if (($display_cat == ATTACHMENT_CATEGORY_IMAGE || $display_cat == ATTACHMENT_CATEGORY_THUMB) && !$user->optionget('viewimg'))
880
 
                        {
881
 
                                $display_cat = ATTACHMENT_CATEGORY_NONE;
882
 
                        }
883
 
 
884
 
                        if ($display_cat == ATTACHMENT_CATEGORY_FLASH && !$user->optionget('viewflash'))
885
 
                        {
886
 
                                $display_cat = ATTACHMENT_CATEGORY_NONE;
887
 
                        }
888
 
 
889
 
                        $download_link = append_sid("{$phpbb_root_path}download/file.$phpEx", 'id=' . $attachment['attach_id']);
890
 
 
891
 
                        switch ($display_cat)
892
 
                        {
893
 
                                // Images
894
 
                                case ATTACHMENT_CATEGORY_IMAGE:
895
 
                                        $l_downloaded_viewed = 'VIEWED_COUNT';
896
 
                                        $inline_link = append_sid("{$phpbb_root_path}download/file.$phpEx", 'id=' . $attachment['attach_id']);
897
 
                                        $download_link .= '&amp;mode=view';
898
 
 
899
 
                                        $block_array += array(
900
 
                                                'S_IMAGE'               => true,
901
 
                                                'U_INLINE_LINK'         => $inline_link,
902
 
                                        );
903
 
 
904
 
                                        $update_count[] = $attachment['attach_id'];
905
 
                                break;
906
 
 
907
 
                                // Images, but display Thumbnail
908
 
                                case ATTACHMENT_CATEGORY_THUMB:
909
 
                                        $l_downloaded_viewed = 'VIEWED_COUNT';
910
 
                                        $thumbnail_link = append_sid("{$phpbb_root_path}download/file.$phpEx", 'id=' . $attachment['attach_id'] . '&amp;t=1');
911
 
                                        $download_link .= '&amp;mode=view';
912
 
 
913
 
                                        $block_array += array(
914
 
                                                'S_THUMBNAIL'           => true,
915
 
                                                'THUMB_IMAGE'           => $thumbnail_link,
916
 
                                        );
917
 
                                break;
918
 
 
919
 
                                // Windows Media Streams
920
 
                                case ATTACHMENT_CATEGORY_WM:
921
 
                                        $l_downloaded_viewed = 'VIEWED_COUNT';
922
 
 
923
 
                                        // Giving the filename directly because within the wm object all variables are in local context making it impossible
924
 
                                        // to validate against a valid session (all params can differ)
925
 
                                        // $download_link = $filename;
926
 
 
927
 
                                        $block_array += array(
928
 
                                                'U_FORUM'               => generate_board_url(),
929
 
                                                'ATTACH_ID'             => $attachment['attach_id'],
930
 
                                                'S_WM_FILE'             => true,
931
 
                                        );
932
 
 
933
 
                                        // Viewed/Heared File ... update the download count
934
 
                                        $update_count[] = $attachment['attach_id'];
935
 
                                break;
936
 
 
937
 
                                // Real Media Streams
938
 
                                case ATTACHMENT_CATEGORY_RM:
939
 
                                case ATTACHMENT_CATEGORY_QUICKTIME:
940
 
                                        $l_downloaded_viewed = 'VIEWED_COUNT';
941
 
 
942
 
                                        $block_array += array(
943
 
                                                'S_RM_FILE'                     => ($display_cat == ATTACHMENT_CATEGORY_RM) ? true : false,
944
 
                                                'S_QUICKTIME_FILE'      => ($display_cat == ATTACHMENT_CATEGORY_QUICKTIME) ? true : false,
945
 
                                                'U_FORUM'                       => generate_board_url(),
946
 
                                                'ATTACH_ID'                     => $attachment['attach_id'],
947
 
                                        );
948
 
 
949
 
                                        // Viewed/Heared File ... update the download count
950
 
                                        $update_count[] = $attachment['attach_id'];
951
 
                                break;
952
 
 
953
 
                                // Macromedia Flash Files
954
 
                                case ATTACHMENT_CATEGORY_FLASH:
955
 
                                        list($width, $height) = @getimagesize($filename);
956
 
 
957
 
                                        $l_downloaded_viewed = 'VIEWED_COUNT';
958
 
 
959
 
                                        $block_array += array(
960
 
                                                'S_FLASH_FILE'  => true,
961
 
                                                'WIDTH'                 => $width,
962
 
                                                'HEIGHT'                => $height,
963
 
                                        );
964
 
 
965
 
                                        // Viewed/Heared File ... update the download count
966
 
                                        $update_count[] = $attachment['attach_id'];
967
 
                                break;
968
 
 
969
 
                                default:
970
 
                                        $l_downloaded_viewed = 'DOWNLOAD_COUNT';
971
 
 
972
 
                                        $block_array += array(
973
 
                                                'S_FILE'                => true,
974
 
                                        );
975
 
                                break;
976
 
                        }
977
 
 
978
 
                        $l_download_count = (!isset($attachment['download_count']) || $attachment['download_count'] == 0) ? $user->lang[$l_downloaded_viewed . '_NONE'] : (($attachment['download_count'] == 1) ? sprintf($user->lang[$l_downloaded_viewed], $attachment['download_count']) : sprintf($user->lang[$l_downloaded_viewed . 'S'], $attachment['download_count']));
979
 
 
980
 
                        $block_array += array(
981
 
                                'U_DOWNLOAD_LINK'               => $download_link,
982
 
                                'L_DOWNLOAD_COUNT'              => $l_download_count
983
 
                        );
984
 
                }
985
 
 
986
 
                $template->assign_block_vars('_file', $block_array);
987
 
 
988
 
                $compiled_attachments[] = $template->assign_display('attachment_tpl');
989
 
        }
990
 
 
991
 
        $attachments = $compiled_attachments;
992
 
        unset($compiled_attachments);
993
 
 
994
 
        $tpl_size = sizeof($attachments);
995
 
 
996
 
        $unset_tpl = array();
997
 
 
998
 
        preg_match_all('#<!\-\- ia([0-9]+) \-\->(.*?)<!\-\- ia\1 \-\->#', $message, $matches, PREG_PATTERN_ORDER);
999
 
 
1000
 
        $replace = array();
1001
 
        foreach ($matches[0] as $num => $capture)
1002
 
        {
1003
 
                // Flip index if we are displaying the reverse way
1004
 
                $index = ($config['display_order']) ? ($tpl_size-($matches[1][$num] + 1)) : $matches[1][$num];
1005
 
 
1006
 
                $replace['from'][] = $matches[0][$num];
1007
 
                $replace['to'][] = (isset($attachments[$index])) ? $attachments[$index] : sprintf($user->lang['MISSING_INLINE_ATTACHMENT'], $matches[2][array_search($index, $matches[1])]);
1008
 
 
1009
 
                $unset_tpl[] = $index;
1010
 
        }
1011
 
 
1012
 
        if (isset($replace['from']))
1013
 
        {
1014
 
                $message = str_replace($replace['from'], $replace['to'], $message);
1015
 
        }
1016
 
 
1017
 
        $unset_tpl = array_unique($unset_tpl);
1018
 
 
1019
 
        // Needed to let not display the inlined attachments at the end of the post again
1020
 
        foreach ($unset_tpl as $index)
1021
 
        {
1022
 
                unset($attachments[$index]);
1023
 
        }
1024
 
}
1025
 
 
1026
 
/**
1027
 
* Check if extension is allowed to be posted.
1028
 
*
1029
 
* @param mixed $forum_id The forum id to check or false if private message
1030
 
* @param string $extension The extension to check, for example zip.
1031
 
* @param array &$extensions The extension array holding the information from the cache (will be obtained if empty)
1032
 
*
1033
 
* @return bool False if the extension is not allowed to be posted, else true.
1034
 
*/
1035
 
function extension_allowed($forum_id, $extension, &$extensions)
1036
 
{
1037
 
        if (empty($extensions))
1038
 
        {
1039
 
                global $cache;
1040
 
                $extensions = $cache->obtain_attach_extensions($forum_id);
1041
 
        }
1042
 
 
1043
 
        return (!isset($extensions['_allowed_'][$extension])) ? false : true;
1044
 
}
1045
 
 
1046
 
/**
1047
 
* Truncates string while retaining special characters if going over the max length
1048
 
* The default max length is 60 at the moment
1049
 
*/
1050
 
function truncate_string($string, $max_length = 60, $allow_reply = true, $append = '')
1051
 
{
1052
 
        $chars = array();
1053
 
 
1054
 
        $strip_reply = false;
1055
 
        $stripped = false;
1056
 
        if ($allow_reply && strpos($string, 'Re: ') === 0)
1057
 
        {
1058
 
                $strip_reply = true;
1059
 
                $string = substr($string, 4);
1060
 
        }
1061
 
 
1062
 
        $_chars = utf8_str_split(htmlspecialchars_decode($string));
1063
 
        $chars = array_map('utf8_htmlspecialchars', $_chars);
1064
 
 
1065
 
        // Now check the length ;)
1066
 
        if (sizeof($chars) > $max_length)
1067
 
        {
1068
 
                // Cut off the last elements from the array
1069
 
                $string = implode('', array_slice($chars, 0, $max_length - utf8_strlen($append)));
1070
 
                $stripped = true;
1071
 
        }
1072
 
 
1073
 
        if ($strip_reply)
1074
 
        {
1075
 
                $string = 'Re: ' . $string;
1076
 
        }
1077
 
        
1078
 
        if ($append != '' && $stripped)
1079
 
        {
1080
 
                $string = $string . $append;
1081
 
        }
1082
 
 
1083
 
        return $string;
1084
 
}
1085
 
 
1086
 
/**
1087
 
* Get username details for placing into templates.
1088
 
*
1089
 
* @param string $mode Can be profile (for getting an url to the profile), username (for obtaining the username), colour (for obtaining the user colour), full (for obtaining a html string representing a coloured link to the users profile) or no_profile (the same as full but forcing no profile link)
1090
 
* @param int $user_id The users id
1091
 
* @param string $username The users name
1092
 
* @param string $username_colour The users colour
1093
 
* @param string $guest_username optional parameter to specify the guest username. It will be used in favor of the GUEST language variable then.
1094
 
* @param string $custom_profile_url optional parameter to specify a profile url. The user id get appended to this url as &amp;u={user_id}
1095
 
*
1096
 
* @return string A string consisting of what is wanted based on $mode.
1097
 
*/
1098
 
function get_username_string($mode, $user_id, $username, $username_colour = '', $guest_username = false, $custom_profile_url = false)
1099
 
{
1100
 
        global $phpbb_root_path, $phpEx, $user, $auth;
1101
 
 
1102
 
        $profile_url = '';
1103
 
        $username_colour = ($username_colour) ? '#' . $username_colour : '';
1104
 
 
1105
 
        if ($guest_username === false)
1106
 
        {
1107
 
                $username = ($username) ? $username : $user->lang['GUEST'];
1108
 
        }
1109
 
        else
1110
 
        {
1111
 
                $username = ($user_id && $user_id != ANONYMOUS) ? $username : ((!empty($guest_username)) ? $guest_username : $user->lang['GUEST']);
1112
 
        }
1113
 
 
1114
 
        // Only show the link if not anonymous
1115
 
        if ($mode != 'no_profile' && $user_id && $user_id != ANONYMOUS)
1116
 
        {
1117
 
                // Do not show the link if the user is already logged in but do not have u_viewprofile permissions (relevant for bots mostly).
1118
 
                // For all others the link leads to a login page or the profile.
1119
 
                if ($user->data['user_id'] != ANONYMOUS && !$auth->acl_get('u_viewprofile'))
1120
 
                {
1121
 
                        $profile_url = '';
1122
 
                }
1123
 
                else
1124
 
                {
1125
 
                        $profile_url = ($custom_profile_url !== false) ? $custom_profile_url . '&amp;u=' . (int) $user_id : append_sid("{$phpbb_root_path}memberlist.$phpEx", 'mode=viewprofile&amp;u=' . (int) $user_id);
1126
 
                }
1127
 
        }
1128
 
        else
1129
 
        {
1130
 
                $profile_url = '';
1131
 
        }
1132
 
 
1133
 
        switch ($mode)
1134
 
        {
1135
 
                case 'profile':
1136
 
                        return $profile_url;
1137
 
                break;
1138
 
 
1139
 
                case 'username':
1140
 
                        return $username;
1141
 
                break;
1142
 
 
1143
 
                case 'colour':
1144
 
                        return $username_colour;
1145
 
                break;
1146
 
 
1147
 
                case 'no_profile':
1148
 
                case 'full':
1149
 
                default:
1150
 
 
1151
 
                        $tpl = '';
1152
 
                        if (!$profile_url && !$username_colour)
1153
 
                        {
1154
 
                                $tpl = '{USERNAME}';
1155
 
                        }
1156
 
                        else if (!$profile_url && $username_colour)
1157
 
                        {
1158
 
                                $tpl = '<span style="color: {USERNAME_COLOUR};" class="username-coloured">{USERNAME}</span>';
1159
 
                        }
1160
 
                        else if ($profile_url && !$username_colour)
1161
 
                        {
1162
 
                                $tpl = '<a href="{PROFILE_URL}">{USERNAME}</a>';
1163
 
                        }
1164
 
                        else if ($profile_url && $username_colour)
1165
 
                        {
1166
 
                                $tpl = '<a href="{PROFILE_URL}" style="color: {USERNAME_COLOUR};" class="username-coloured">{USERNAME}</a>';
1167
 
                        }
1168
 
 
1169
 
                        return str_replace(array('{PROFILE_URL}', '{USERNAME_COLOUR}', '{USERNAME}'), array($profile_url, $username_colour, $username), $tpl);
1170
 
                break;
1171
 
        }
1172
 
}
1173
 
 
1174
 
/**
1175
 
* @package phpBB3
1176
 
*/
1177
 
class bitfield
1178
 
{
1179
 
        var $data;
1180
 
 
1181
 
        function bitfield($bitfield = '')
1182
 
        {
1183
 
                $this->data = base64_decode($bitfield);
1184
 
        }
1185
 
 
1186
 
        /**
1187
 
        */
1188
 
        function get($n)
1189
 
        {
1190
 
                // Get the ($n / 8)th char
1191
 
                $byte = $n >> 3;
1192
 
 
1193
 
                if (strlen($this->data) >= $byte + 1)
1194
 
                {
1195
 
                        $c = $this->data[$byte];
1196
 
        
1197
 
                        // Lookup the ($n % 8)th bit of the byte
1198
 
                        $bit = 7 - ($n & 7);
1199
 
                        return (bool) (ord($c) & (1 << $bit));
1200
 
                }
1201
 
                else
1202
 
                {
1203
 
                        return false;
1204
 
                }
1205
 
        }
1206
 
 
1207
 
        function set($n)
1208
 
        {
1209
 
                $byte = $n >> 3;
1210
 
                $bit = 7 - ($n & 7);
1211
 
 
1212
 
                if (strlen($this->data) >= $byte + 1)
1213
 
                {
1214
 
                        $this->data[$byte] = $this->data[$byte] | chr(1 << $bit);
1215
 
                }
1216
 
                else
1217
 
                {
1218
 
                        $this->data .= str_repeat("\0", $byte - strlen($this->data));
1219
 
                        $this->data .= chr(1 << $bit);
1220
 
                }
1221
 
        }
1222
 
 
1223
 
        function clear($n)
1224
 
        {
1225
 
                $byte = $n >> 3;
1226
 
 
1227
 
                if (strlen($this->data) >= $byte + 1)
1228
 
                {
1229
 
                        $bit = 7 - ($n & 7);
1230
 
                        $this->data[$byte] = $this->data[$byte] &~ chr(1 << $bit);
1231
 
                }
1232
 
        }
1233
 
 
1234
 
        function get_blob()
1235
 
        {
1236
 
                return $this->data;
1237
 
        }
1238
 
 
1239
 
        function get_base64()
1240
 
        {
1241
 
                return base64_encode($this->data);
1242
 
        }
1243
 
 
1244
 
        function get_bin()
1245
 
        {
1246
 
                $bin = '';
1247
 
                $len = strlen($this->data);
1248
 
 
1249
 
                for ($i = 0; $i < $len; ++$i)
1250
 
                {
1251
 
                        $bin .= str_pad(decbin(ord($this->data[$i])), 8, '0', STR_PAD_LEFT);
1252
 
                }
1253
 
 
1254
 
                return $bin;
1255
 
        }
1256
 
 
1257
 
        function get_all_set()
1258
 
        {
1259
 
                return array_keys(array_filter(str_split($this->get_bin())));
1260
 
        }
1261
 
 
1262
 
        function merge($bitfield)
1263
 
        {
1264
 
                $this->data = $this->data | $bitfield->get_blob();
1265
 
        }
1266
 
}
1267
 
 
1268
 
?>
 
 
b'\\ No newline at end of file'