phpBB
Statistics
| Revision:

root / branches / phpBB-3_0_0 / phpBB / includes / functions_content.php

History | View | Annotate | Download (37.7 kB)

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