Merge lp:~xabilon/ubuntu-fr-forum/mise-a-jour-FluxBB1.4.8 into lp:ubuntu-fr-forum

Proposed by xabilon
Status: Merged
Merged at revision: 145
Proposed branch: lp:~xabilon/ubuntu-fr-forum/mise-a-jour-FluxBB1.4.8
Merge into: lp:ubuntu-fr-forum
Diff against target: 7882 lines (+3130/-1060)
119 files modified
BDD_update.sql (+0/-32)
BDD_update_145_148.sql (+21/-0)
README-ufr (+1/-5)
admin_bans.php (+8/-8)
admin_categories.php (+2/-2)
admin_censoring.php (+1/-1)
admin_forums.php (+13/-12)
admin_groups.php (+33/-23)
admin_index.php (+9/-8)
admin_loader.php (+2/-2)
admin_maintenance.php (+2/-2)
admin_options.php (+2/-2)
admin_permissions.php (+1/-1)
admin_ranks.php (+3/-3)
admin_reports.php (+1/-1)
admin_users.php (+91/-52)
common.js (+7/-1)
config.php.exemple (+5/-1)
db_update.php (+97/-20)
delete.php (+1/-1)
edit.php (+4/-1)
extern.php (+1/-1)
footer.php (+2/-1)
header.php (+14/-21)
help.php (+11/-2)
include/cache.php (+4/-2)
include/cache_fluxtoolbar.php (+12/-6)
include/common.php (+19/-12)
include/common_admin.php (+4/-4)
include/dblayer/common_db.php (+7/-7)
include/dblayer/mysql.php (+3/-3)
include/dblayer/mysql_innodb.php (+3/-3)
include/dblayer/mysqli.php (+3/-3)
include/dblayer/mysqli_innodb.php (+3/-3)
include/dblayer/pgsql.php (+10/-10)
include/dblayer/sqlite.php (+19/-19)
include/email.php (+171/-19)
include/functions.php (+142/-30)
include/jscolor/jscolor.js (+915/-0)
include/parser.php (+130/-92)
include/search_idx.php (+22/-19)
include/template/main.tpl (+2/-2)
include/toolbar_func.js (+209/-82)
include/utf8/utf8.php (+1/-1)
include/utf8/utils/bad.php (+47/-52)
install.php (+151/-146)
lang/English/admin_groups.php (+3/-1)
lang/English/admin_index.php (+3/-3)
lang/English/admin_options.php (+11/-11)
lang/English/admin_users.php (+3/-0)
lang/English/common.php (+10/-20)
lang/English/fluxtoolbar.php (+2/-4)
lang/English/fluxtoolbar_admin.php (+3/-3)
lang/English/install.php (+1/-1)
lang/English/mail_templates/activate_email.tpl (+1/-1)
lang/English/mail_templates/activate_password.tpl (+1/-1)
lang/English/mail_templates/banned_email_change.tpl (+9/-0)
lang/English/mail_templates/banned_email_post.tpl (+9/-0)
lang/English/mail_templates/banned_email_register.tpl (+9/-0)
lang/English/mail_templates/dupe_email_change.tpl (+9/-0)
lang/English/mail_templates/dupe_email_register.tpl (+9/-0)
lang/English/mail_templates/form_email.tpl (+1/-1)
lang/English/mail_templates/new_reply.tpl (+1/-1)
lang/English/mail_templates/new_reply_full.tpl (+3/-3)
lang/English/mail_templates/new_report.tpl (+9/-0)
lang/English/mail_templates/new_topic.tpl (+1/-1)
lang/English/mail_templates/new_topic_full.tpl (+3/-3)
lang/English/mail_templates/new_user.tpl (+9/-0)
lang/English/mail_templates/rename.tpl (+1/-1)
lang/English/mail_templates/welcome.tpl (+1/-1)
lang/English/post.php (+1/-1)
lang/English/prof_reg.php (+11/-11)
lang/English/profile.php (+1/-0)
lang/English/search.php (+10/-10)
lang/English/update.php (+3/-4)
lang/Francais/admin_groups.php (+2/-0)
lang/Francais/admin_index.php (+2/-2)
lang/Francais/admin_options.php (+11/-11)
lang/Francais/admin_users.php (+3/-0)
lang/Francais/common.php (+11/-20)
lang/Francais/delete.php (+1/-1)
lang/Francais/fluxtoolbar.php (+2/-4)
lang/Francais/fluxtoolbar_admin.php (+6/-6)
lang/Francais/help.php (+6/-0)
lang/Francais/install.php (+1/-1)
lang/Francais/mail_templates/activate_email.tpl (+1/-1)
lang/Francais/mail_templates/banned_email_change.tpl (+9/-0)
lang/Francais/mail_templates/banned_email_post.tpl (+9/-0)
lang/Francais/mail_templates/banned_email_register.tpl (+9/-0)
lang/Francais/mail_templates/dupe_email_change.tpl (+9/-0)
lang/Francais/mail_templates/dupe_email_register.tpl (+9/-0)
lang/Francais/mail_templates/new_pm.tpl (+9/-0)
lang/Francais/mail_templates/new_reply_full.tpl (+2/-2)
lang/Francais/mail_templates/new_report.tpl (+9/-0)
lang/Francais/mail_templates/new_topic.tpl (+1/-1)
lang/Francais/mail_templates/new_topic_full.tpl (+2/-2)
lang/Francais/mail_templates/new_user.tpl (+9/-0)
lang/Francais/mail_templates/rename.tpl (+1/-1)
lang/Francais/misc.php (+1/-1)
lang/Francais/pms.php (+125/-0)
lang/Francais/pms_plugin.php (+30/-0)
lang/Francais/prof_reg.php (+14/-15)
lang/Francais/profile.php (+1/-0)
lang/Francais/search.php (+7/-5)
lang/Francais/update.php (+3/-0)
login.php (+5/-5)
misc.php (+20/-10)
moderate.php (+10/-12)
plugins/AP_FluxToolBar.php (+17/-11)
post.php (+41/-25)
profile.php (+55/-14)
register.php (+39/-20)
search.php.orig (+73/-40)
smiley_picker.php (+182/-0)
style/imports/base_admin.css (+9/-0)
style/imports/minmax.js (+11/-1)
userlist.php (+3/-2)
viewforum.php (+3/-22)
viewtopic.php (+10/-25)
To merge this branch: bzr merge lp:~xabilon/ubuntu-fr-forum/mise-a-jour-FluxBB1.4.8
Reviewer Review Type Date Requested Status
Ubuntu-fr-webteam Pending
Review via email: mp+94710@code.launchpad.net

Description of the change

Mise à jour vers FluxBB1.4.8 (résolution de bugs) - Changelog : http://fluxbb.org/forums/viewtopic.php?id=6031
Il y a eu des changements dans search.php. Le script présent dans ce merge est l'ancien (revu par YoBoY), les performances du nouveau search.php de FluxBB seront testées ultérieurement.

Mise à jour de la FluxToolBar (correction de la balise color).

Variable IS_DEV pour exclure le forum.dev des moteurs de recherche

Petite mise à jour de la BDD (voir BDD_Update_145_148.sql)

To post a comment you must log in.
146. By xabilon

Petite mise à jour de BDD_update_145_148

Revision history for this message
YoBoY (yoboy-leguesh) wrote :

concrètement faut tester quoi ?

Revision history for this message
xabilon (xabilon) wrote :

Juste si la mise à jour se passe bien (maj PHP + modifs BDD + variable IS_DEV dans config.php pour empêhcer l'indexation du .dev). Après, pour les fonctionnalités, on verra sur forum.dev

Je m'en occuperai plutôt à partir de ce week-end (vacances)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== removed file 'BDD_update.sql'
2--- BDD_update.sql 2011-04-20 14:55:05 +0000
3+++ BDD_update.sql 1970-01-01 00:00:00 +0000
4@@ -1,32 +0,0 @@
5--- Requêtes pour transformer une BDD de fluxbb 1.4.2 en 1.4.5
6-
7-CREATE TABLE `forum_topic_subscriptions` SELECT * FROM `forum_subscriptions`;
8-
9-CREATE TABLE IF NOT EXISTS `forum_forum_subscriptions` (
10- `user_id` int(10) unsigned NOT NULL DEFAULT '0',
11- `forum_id` int(10) unsigned NOT NULL DEFAULT '0',
12- PRIMARY KEY (`user_id`,`forum_id`)
13-) ENGINE=MyISAM DEFAULT CHARSET=utf8;
14-
15--- MaJ des numéros de version :
16-
17-UPDATE forum_config SET conf_value = '1.4.5' WHERE conf_name = 'o_cur_version';
18-UPDATE forum_config SET conf_value = '11' WHERE conf_name = 'o_database_revision';
19-UPDATE forum_config SET conf_value = '2' WHERE conf_name = 'o_searchindex_revision';
20-UPDATE forum_config SET conf_value = '2' WHERE conf_name = 'o_parser_revision';
21-
22-INSERT INTO forum_config VALUES ('o_forum_subscriptions', '0');
23-INSERT INTO forum_config VALUES ('o_topic_subscriptions', '1');
24-
25--- C'est tout :-)
26-COMMIT;
27-
28--- N'oubliez pas de vider le cache de fluxbb !
29-
30-
31-
32--- Si la migration s'est bien passée, vous pouvez nettoyer via les requêtes suivantes :
33-
34--- DROP TABLE `forum_subscriptions`;
35--- DELETE FROM `forum_config` WHERE `conf_name` = 'o_subscriptions';
36--- COMMIT;
37
38=== added file 'BDD_update_145_148.sql'
39--- BDD_update_145_148.sql 1970-01-01 00:00:00 +0000
40+++ BDD_update_145_148.sql 2012-02-27 14:24:17 +0000
41@@ -0,0 +1,21 @@
42+-- Requêtes pour transformer une BDD de fluxbb 1.4.5 en 1.4.8
43+
44+-- MaJ des numéros de version :
45+
46+UPDATE forum_config SET conf_value = '1.4.8' WHERE conf_name = 'o_cur_version';
47+UPDATE forum_config SET conf_value = '15' WHERE conf_name = 'o_database_revision';
48+UPDATE forum_config SET conf_value = '2' WHERE conf_name = 'o_searchindex_revision';
49+UPDATE forum_config SET conf_value = '2' WHERE conf_name = 'o_parser_revision';
50+UPDATE forum_config SET conf_value = '1' WHERE conf_name = 'o_feed_type';
51+
52+INSERT INTO forum_config VALUES ('o_feed_ttl', '5');
53+INSERT INTO forum_config VALUES ('o_topic_subscriptions', '1');
54+
55+ALTER TABLE forum_groups ADD g_report_flood smallint(6) NOT NULL DEFAULT '60';
56+
57+ALTER TABLE forum_users ADD last_report_sent int(10) UNSIGNED NULL AFTER last_email_sent;
58+
59+-- C'est tout :-)
60+COMMIT;
61+
62+-- N'oubliez pas de vider le cache de fluxbb !
63
64=== modified file 'README-ufr'
65--- README-ufr 2012-02-22 18:37:55 +0000
66+++ README-ufr 2012-02-27 14:24:17 +0000
67@@ -10,11 +10,7 @@
68 FIXME : il y a peut être une façon plus élégante de le faire
69 Redirection:
70 functions.php l1288
71-Mise à jour des membres en ligne:
72- commenté dans include/common.php
73- l'appel se fait dans update_online.php, cette url devrait être appelée par un cron type :
74- http_proxy= curl -H Host:forum.ubuntu-fr.org http://127.0.0.1:80/update_online.php
75- et la page bien évidemment limitée en accès
76+
77
78 FLUXBB 1.4.0 :
79
80
81=== modified file 'admin_bans.php'
82--- admin_bans.php 2011-04-19 22:53:21 +0000
83+++ admin_bans.php 2012-02-27 14:24:17 +0000
84@@ -1,7 +1,7 @@
85 <?php
86
87 /**
88- * Copyright (C) 2008-2011 FluxBB
89+ * Copyright (C) 2008-2012 FluxBB
90 * based on code by Rickard Andersson copyright (C) 2002-2008 PunBB
91 * License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher
92 */
93@@ -192,7 +192,7 @@
94 message($lang_admin_bans['Must enter message']);
95 else if (strtolower($ban_user) == 'guest')
96 message($lang_admin_bans['Cannot ban guest message']);
97-
98+
99 // Make sure we're not banning an admin or moderator
100 if (!empty($ban_user))
101 {
102@@ -200,13 +200,13 @@
103 if ($db->num_rows($result))
104 {
105 $group_id = $db->result($result);
106-
107+
108 if ($group_id == PUN_ADMIN)
109 message(sprintf($lang_admin_bans['User is admin message'], pun_htmlspecialchars($ban_user)));
110-
111+
112 $result = $db->query('SELECT g_moderator FROM '.$db->prefix.'groups WHERE g_id='.$group_id) or error('Unable to fetch group info', __FILE__, __LINE__, $db->error());
113 $is_moderator_group = $db->result($result);
114-
115+
116 if ($is_moderator_group)
117 message(sprintf($lang_admin_bans['User is mod message'], pun_htmlspecialchars($ban_user)));
118 }
119@@ -215,7 +215,7 @@
120 // Validate IP/IP range (it's overkill, I know)
121 if ($ban_ip != '')
122 {
123- $ban_ip = preg_replace('/\s{2,}/S', ' ', $ban_ip);
124+ $ban_ip = preg_replace('%\s{2,}%S', ' ', $ban_ip);
125 $addresses = explode(' ', $ban_ip);
126 $addresses = array_map('pun_trim', $addresses);
127
128@@ -244,7 +244,7 @@
129 {
130 $octets[$c] = (strlen($octets[$c]) > 1) ? ltrim($octets[$c], "0") : $octets[$c];
131
132- if ($c > 3 || preg_match('/[^0-9]/', $octets[$c]) || intval($octets[$c]) > 255)
133+ if ($c > 3 || preg_match('%[^0-9]%', $octets[$c]) || intval($octets[$c]) > 255)
134 message($lang_admin_bans['Invalid IP message']);
135 }
136
137@@ -259,7 +259,7 @@
138 require PUN_ROOT.'include/email.php';
139 if ($ban_email != '' && !is_valid_email($ban_email))
140 {
141- if (!preg_match('/^[a-z0-9-]+(\.[a-z0-9-]+)*(\.[a-z]{2,4})$/', $ban_email))
142+ if (!preg_match('%^[a-z0-9-]+(\.[a-z0-9-]+)*(\.[a-z]{2,4})$%', $ban_email))
143 message($lang_admin_bans['Invalid e-mail message']);
144 }
145
146
147=== modified file 'admin_categories.php'
148--- admin_categories.php 2011-04-19 22:53:21 +0000
149+++ admin_categories.php 2012-02-27 14:24:17 +0000
150@@ -1,7 +1,7 @@
151 <?php
152
153 /**
154- * Copyright (C) 2008-2011 FluxBB
155+ * Copyright (C) 2008-2012 FluxBB
156 * based on code by Rickard Andersson copyright (C) 2002-2008 PunBB
157 * License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher
158 */
159@@ -138,7 +138,7 @@
160 if ($cur_cat['name'] == '')
161 message($lang_admin_categories['Must enter name message']);
162
163- if ($cur_cat['order'] == '' || preg_match('/[^0-9]/', $cur_cat['order']))
164+ if ($cur_cat['order'] == '' || preg_match('%[^0-9]%', $cur_cat['order']))
165 message($lang_admin_categories['Must enter integer message']);
166
167 $db->query('UPDATE '.$db->prefix.'categories SET cat_name=\''.$db->escape($cur_cat['name']).'\', disp_position='.$cur_cat['order'].' WHERE id='.intval($cat_id)) or error('Unable to update category', __FILE__, __LINE__, $db->error());
168
169=== modified file 'admin_censoring.php'
170--- admin_censoring.php 2011-04-19 22:53:21 +0000
171+++ admin_censoring.php 2012-02-27 14:24:17 +0000
172@@ -1,7 +1,7 @@
173 <?php
174
175 /**
176- * Copyright (C) 2008-2011 FluxBB
177+ * Copyright (C) 2008-2012 FluxBB
178 * based on code by Rickard Andersson copyright (C) 2002-2008 PunBB
179 * License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher
180 */
181
182=== modified file 'admin_forums.php'
183--- admin_forums.php 2011-04-19 22:53:21 +0000
184+++ admin_forums.php 2012-02-27 14:24:17 +0000
185@@ -1,7 +1,7 @@
186 <?php
187
188 /**
189- * Copyright (C) 2008-2011 FluxBB
190+ * Copyright (C) 2008-2012 FluxBB
191 * based on code by Rickard Andersson copyright (C) 2002-2008 PunBB
192 * License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher
193 */
194@@ -128,7 +128,7 @@
195 foreach ($_POST['position'] as $forum_id => $disp_position)
196 {
197 $disp_position = trim($disp_position);
198- if ($disp_position == '' || preg_match('/[^0-9]/', $disp_position))
199+ if ($disp_position == '' || preg_match('%[^0-9]%', $disp_position))
200 message($lang_admin_forums['Must be integer message']);
201
202 $db->query('UPDATE '.$db->prefix.'forums SET disp_position='.$disp_position.' WHERE id='.intval($forum_id)) or error('Unable to update forum', __FILE__, __LINE__, $db->error());
203@@ -308,6 +308,8 @@
204
205 $result = $db->query('SELECT g.g_id, g.g_title, g.g_read_board, g.g_post_replies, g.g_post_topics, fp.read_forum, fp.post_replies, fp.post_topics FROM '.$db->prefix.'groups AS g LEFT JOIN '.$db->prefix.'forum_perms AS fp ON (g.g_id=fp.group_id AND fp.forum_id='.$forum_id.') WHERE g.g_id!='.PUN_ADMIN.' ORDER BY g.g_id') or error('Unable to fetch group forum permission list', __FILE__, __LINE__, $db->error());
206
207+ $cur_index = 7;
208+
209 while ($cur_perm = $db->fetch_assoc($result))
210 {
211 $read_forum = ($cur_perm['read_forum'] != '0') ? true : false;
212@@ -324,15 +326,15 @@
213 <th class="atcl"><?php echo pun_htmlspecialchars($cur_perm['g_title']) ?></th>
214 <td<?php if (!$read_forum_def) echo ' class="nodefault"'; ?>>
215 <input type="hidden" name="read_forum_old[<?php echo $cur_perm['g_id'] ?>]" value="<?php echo ($read_forum) ? '1' : '0'; ?>" />
216- <input type="checkbox" name="read_forum_new[<?php echo $cur_perm['g_id'] ?>]" value="1"<?php echo ($read_forum) ? ' checked="checked"' : ''; ?><?php echo ($cur_perm['g_read_board'] == '0') ? ' disabled="disabled"' : ''; ?> />
217+ <input type="checkbox" name="read_forum_new[<?php echo $cur_perm['g_id'] ?>]" value="1"<?php echo ($read_forum) ? ' checked="checked"' : ''; ?><?php echo ($cur_perm['g_read_board'] == '0') ? ' disabled="disabled"' : ''; ?> tabindex="<?php echo $cur_index++ ?>" />
218 </td>
219 <td<?php if (!$post_replies_def && $cur_forum['redirect_url'] == '') echo ' class="nodefault"'; ?>>
220 <input type="hidden" name="post_replies_old[<?php echo $cur_perm['g_id'] ?>]" value="<?php echo ($post_replies) ? '1' : '0'; ?>" />
221- <input type="checkbox" name="post_replies_new[<?php echo $cur_perm['g_id'] ?>]" value="1"<?php echo ($post_replies) ? ' checked="checked"' : ''; ?><?php echo ($cur_forum['redirect_url'] != '') ? ' disabled="disabled"' : ''; ?> />
222+ <input type="checkbox" name="post_replies_new[<?php echo $cur_perm['g_id'] ?>]" value="1"<?php echo ($post_replies) ? ' checked="checked"' : ''; ?><?php echo ($cur_forum['redirect_url'] != '') ? ' disabled="disabled"' : ''; ?> tabindex="<?php echo $cur_index++ ?>" />
223 </td>
224 <td<?php if (!$post_topics_def && $cur_forum['redirect_url'] == '') echo ' class="nodefault"'; ?>>
225 <input type="hidden" name="post_topics_old[<?php echo $cur_perm['g_id'] ?>]" value="<?php echo ($post_topics) ? '1' : '0'; ?>" />
226- <input type="checkbox" name="post_topics_new[<?php echo $cur_perm['g_id'] ?>]" value="1"<?php echo ($post_topics) ? ' checked="checked"' : ''; ?><?php echo ($cur_forum['redirect_url'] != '') ? ' disabled="disabled"' : ''; ?> />
227+ <input type="checkbox" name="post_topics_new[<?php echo $cur_perm['g_id'] ?>]" value="1"<?php echo ($post_topics) ? ' checked="checked"' : ''; ?><?php echo ($cur_forum['redirect_url'] != '') ? ' disabled="disabled"' : ''; ?> tabindex="<?php echo $cur_index++ ?>" />
228 </td>
229 </tr>
230 <?php
231@@ -342,11 +344,11 @@
232 ?>
233 </tbody>
234 </table>
235- <div class="fsetsubmit"><input type="submit" name="revert_perms" value="<?php echo $lang_admin_forums['Revert to default'] ?>" /></div>
236+ <div class="fsetsubmit"><input type="submit" name="revert_perms" value="<?php echo $lang_admin_forums['Revert to default'] ?>" tabindex="<?php echo $cur_index++ ?>" /></div>
237 </div>
238 </fieldset>
239 </div>
240- <p class="submitend"><input type="submit" name="save" value="<?php echo $lang_admin_common['Save changes'] ?>" /></p>
241+ <p class="submitend"><input type="submit" name="save" value="<?php echo $lang_admin_common['Save changes'] ?>" tabindex="<?php echo $cur_index++ ?>" /></p>
242 </form>
243 </div>
244 </div>
245@@ -415,7 +417,7 @@
246 <p class="submittop"><input type="submit" name="update_positions" value="<?php echo $lang_admin_forums['Update positions'] ?>" tabindex="3" /></p>
247 <?php
248
249-$tabindex_count = 4;
250+$cur_index = 4;
251
252 $cur_category = 0;
253 while ($cur_forum = $db->fetch_assoc($result))
254@@ -446,13 +448,12 @@
255
256 ?>
257 <tr>
258- <td class="tcl"><a href="admin_forums.php?edit_forum=<?php echo $cur_forum['fid'] ?>"><?php echo $lang_admin_forums['Edit link'] ?></a> | <a href="admin_forums.php?del_forum=<?php echo $cur_forum['fid'] ?>"><?php echo $lang_admin_forums['Delete link'] ?></a></td>
259- <td class="tc2"><input type="text" name="position[<?php echo $cur_forum['fid'] ?>]" size="3" maxlength="3" value="<?php echo $cur_forum['disp_position'] ?>" tabindex="<?php echo $tabindex_count ?>" /></td>
260+ <td class="tcl"><a href="admin_forums.php?edit_forum=<?php echo $cur_forum['fid'] ?>" tabindex="<?php echo $cur_index++ ?>"><?php echo $lang_admin_forums['Edit link'] ?></a> | <a href="admin_forums.php?del_forum=<?php echo $cur_forum['fid'] ?>" tabindex="<?php echo $cur_index++ ?>"><?php echo $lang_admin_forums['Delete link'] ?></a></td>
261+ <td class="tc2"><input type="text" name="position[<?php echo $cur_forum['fid'] ?>]" size="3" maxlength="3" value="<?php echo $cur_forum['disp_position'] ?>" tabindex="<?php echo $cur_index++ ?>" /></td>
262 <td class="tcr"><strong><?php echo pun_htmlspecialchars($cur_forum['forum_name']) ?></strong></td>
263 </tr>
264 <?php
265
266- $tabindex_count += 2;
267 }
268
269 ?>
270@@ -461,7 +462,7 @@
271 </div>
272 </fieldset>
273 </div>
274- <p class="submitend"><input type="submit" name="update_positions" value="<?php echo $lang_admin_forums['Update positions'] ?>" tabindex="<?php echo $tabindex_count ?>" /></p>
275+ <p class="submitend"><input type="submit" name="update_positions" value="<?php echo $lang_admin_forums['Update positions'] ?>" tabindex="<?php echo $cur_index++ ?>" /></p>
276 </form>
277 </div>
278 <?php
279
280=== modified file 'admin_groups.php'
281--- admin_groups.php 2011-04-19 22:53:21 +0000
282+++ admin_groups.php 2012-02-27 14:24:17 +0000
283@@ -1,7 +1,7 @@
284 <?php
285
286 /**
287- * Copyright (C) 2008-2011 FluxBB
288+ * Copyright (C) 2008-2012 FluxBB
289 * based on code by Rickard Andersson copyright (C) 2002-2008 PunBB
290 * License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher
291 */
292@@ -101,128 +101,135 @@
293 <tr>
294 <th scope="row"><?php echo $lang_admin_groups['Rename users label'] ?></th>
295 <td>
296- <input type="radio" name="mod_rename_users" value="1"<?php if ($group['g_mod_rename_users'] == '1') echo ' checked="checked"' ?> tabindex="5" />&#160;<strong><?php echo $lang_admin_common['Yes'] ?></strong>&#160;&#160;&#160;<input type="radio" name="mod_rename_users" value="0"<?php if ($group['g_mod_rename_users'] == '0') echo ' checked="checked"' ?> tabindex="6" />&#160;<strong><?php echo $lang_admin_common['No'] ?></strong>
297+ <input type="radio" name="mod_rename_users" value="1"<?php if ($group['g_mod_rename_users'] == '1') echo ' checked="checked"' ?> tabindex="7" />&#160;<strong><?php echo $lang_admin_common['Yes'] ?></strong>&#160;&#160;&#160;<input type="radio" name="mod_rename_users" value="0"<?php if ($group['g_mod_rename_users'] == '0') echo ' checked="checked"' ?> tabindex="8" />&#160;<strong><?php echo $lang_admin_common['No'] ?></strong>
298 <span><?php echo $lang_admin_groups['Rename users help'] ?></span>
299 </td>
300 </tr>
301 <tr>
302 <th scope="row"><?php echo $lang_admin_groups['Change passwords label'] ?></th>
303 <td>
304- <input type="radio" name="mod_change_passwords" value="1"<?php if ($group['g_mod_change_passwords'] == '1') echo ' checked="checked"' ?> tabindex="5" />&#160;<strong><?php echo $lang_admin_common['Yes'] ?></strong>&#160;&#160;&#160;<input type="radio" name="mod_change_passwords" value="0"<?php if ($group['g_mod_change_passwords'] == '0') echo ' checked="checked"' ?> tabindex="6" />&#160;<strong><?php echo $lang_admin_common['No'] ?></strong>
305+ <input type="radio" name="mod_change_passwords" value="1"<?php if ($group['g_mod_change_passwords'] == '1') echo ' checked="checked"' ?> tabindex="9" />&#160;<strong><?php echo $lang_admin_common['Yes'] ?></strong>&#160;&#160;&#160;<input type="radio" name="mod_change_passwords" value="0"<?php if ($group['g_mod_change_passwords'] == '0') echo ' checked="checked"' ?> tabindex="10" />&#160;<strong><?php echo $lang_admin_common['No'] ?></strong>
306 <span><?php echo $lang_admin_groups['Change passwords help'] ?></span>
307 </td>
308 </tr>
309 <tr>
310 <th scope="row"><?php echo $lang_admin_groups['Ban users label'] ?></th>
311 <td>
312- <input type="radio" name="mod_ban_users" value="1"<?php if ($group['g_mod_ban_users'] == '1') echo ' checked="checked"' ?> tabindex="5" />&#160;<strong><?php echo $lang_admin_common['Yes'] ?></strong>&#160;&#160;&#160;<input type="radio" name="mod_ban_users" value="0"<?php if ($group['g_mod_ban_users'] == '0') echo ' checked="checked"' ?> tabindex="6" />&#160;<strong><?php echo $lang_admin_common['No'] ?></strong>
313+ <input type="radio" name="mod_ban_users" value="1"<?php if ($group['g_mod_ban_users'] == '1') echo ' checked="checked"' ?> tabindex="11" />&#160;<strong><?php echo $lang_admin_common['Yes'] ?></strong>&#160;&#160;&#160;<input type="radio" name="mod_ban_users" value="0"<?php if ($group['g_mod_ban_users'] == '0') echo ' checked="checked"' ?> tabindex="12" />&#160;<strong><?php echo $lang_admin_common['No'] ?></strong>
314 <span><?php echo $lang_admin_groups['Ban users help'] ?></span>
315 </td>
316 </tr>
317 <?php endif; endif; ?> <tr>
318 <th scope="row"><?php echo $lang_admin_groups['Read board label'] ?></th>
319 <td>
320- <input type="radio" name="read_board" value="1"<?php if ($group['g_read_board'] == '1') echo ' checked="checked"' ?> tabindex="3" />&#160;<strong><?php echo $lang_admin_common['Yes'] ?></strong>&#160;&#160;&#160;<input type="radio" name="read_board" value="0"<?php if ($group['g_read_board'] == '0') echo ' checked="checked"' ?> tabindex="4" />&#160;<strong><?php echo $lang_admin_common['No'] ?></strong>
321+ <input type="radio" name="read_board" value="1"<?php if ($group['g_read_board'] == '1') echo ' checked="checked"' ?> tabindex="13" />&#160;<strong><?php echo $lang_admin_common['Yes'] ?></strong>&#160;&#160;&#160;<input type="radio" name="read_board" value="0"<?php if ($group['g_read_board'] == '0') echo ' checked="checked"' ?> tabindex="14" />&#160;<strong><?php echo $lang_admin_common['No'] ?></strong>
322 <span><?php echo $lang_admin_groups['Read board help'] ?></span>
323 </td>
324 </tr>
325 <tr>
326 <th scope="row"><?php echo $lang_admin_groups['View user info label'] ?></th>
327 <td>
328- <input type="radio" name="view_users" value="1"<?php if ($group['g_view_users'] == '1') echo ' checked="checked"' ?> tabindex="3" />&#160;<strong><?php echo $lang_admin_common['Yes'] ?></strong>&#160;&#160;&#160;<input type="radio" name="view_users" value="0"<?php if ($group['g_view_users'] == '0') echo ' checked="checked"' ?> tabindex="4" />&#160;<strong><?php echo $lang_admin_common['No'] ?></strong>
329+ <input type="radio" name="view_users" value="1"<?php if ($group['g_view_users'] == '1') echo ' checked="checked"' ?> tabindex="15" />&#160;<strong><?php echo $lang_admin_common['Yes'] ?></strong>&#160;&#160;&#160;<input type="radio" name="view_users" value="0"<?php if ($group['g_view_users'] == '0') echo ' checked="checked"' ?> tabindex="16" />&#160;<strong><?php echo $lang_admin_common['No'] ?></strong>
330 <span><?php echo $lang_admin_groups['View user info help'] ?></span>
331 </td>
332 </tr>
333 <tr>
334 <th scope="row"><?php echo $lang_admin_groups['Post replies label'] ?></th>
335 <td>
336- <input type="radio" name="post_replies" value="1"<?php if ($group['g_post_replies'] == '1') echo ' checked="checked"' ?> tabindex="5" />&#160;<strong><?php echo $lang_admin_common['Yes'] ?></strong>&#160;&#160;&#160;<input type="radio" name="post_replies" value="0"<?php if ($group['g_post_replies'] == '0') echo ' checked="checked"' ?> tabindex="6" />&#160;<strong><?php echo $lang_admin_common['No'] ?></strong>
337+ <input type="radio" name="post_replies" value="1"<?php if ($group['g_post_replies'] == '1') echo ' checked="checked"' ?> tabindex="17" />&#160;<strong><?php echo $lang_admin_common['Yes'] ?></strong>&#160;&#160;&#160;<input type="radio" name="post_replies" value="0"<?php if ($group['g_post_replies'] == '0') echo ' checked="checked"' ?> tabindex="18" />&#160;<strong><?php echo $lang_admin_common['No'] ?></strong>
338 <span><?php echo $lang_admin_groups['Post replies help'] ?></span>
339 </td>
340 </tr>
341 <tr>
342 <th scope="row"><?php echo $lang_admin_groups['Post topics label'] ?></th>
343 <td>
344- <input type="radio" name="post_topics" value="1"<?php if ($group['g_post_topics'] == '1') echo ' checked="checked"' ?> tabindex="7" />&#160;<strong><?php echo $lang_admin_common['Yes'] ?></strong>&#160;&#160;&#160;<input type="radio" name="post_topics" value="0"<?php if ($group['g_post_topics'] == '0') echo ' checked="checked"' ?> tabindex="8" />&#160;<strong><?php echo $lang_admin_common['No'] ?></strong>
345+ <input type="radio" name="post_topics" value="1"<?php if ($group['g_post_topics'] == '1') echo ' checked="checked"' ?> tabindex="19" />&#160;<strong><?php echo $lang_admin_common['Yes'] ?></strong>&#160;&#160;&#160;<input type="radio" name="post_topics" value="0"<?php if ($group['g_post_topics'] == '0') echo ' checked="checked"' ?> tabindex="20" />&#160;<strong><?php echo $lang_admin_common['No'] ?></strong>
346 <span><?php echo $lang_admin_groups['Post topics help'] ?></span>
347 </td>
348 </tr>
349 <?php if ($group['g_id'] != PUN_GUEST): ?> <tr>
350 <th scope="row"><?php echo $lang_admin_groups['Edit posts label'] ?></th>
351 <td>
352- <input type="radio" name="edit_posts" value="1"<?php if ($group['g_edit_posts'] == '1') echo ' checked="checked"' ?> tabindex="11" />&#160;<strong><?php echo $lang_admin_common['Yes'] ?></strong>&#160;&#160;&#160;<input type="radio" name="edit_posts" value="0"<?php if ($group['g_edit_posts'] == '0') echo ' checked="checked"' ?> tabindex="12" />&#160;<strong><?php echo $lang_admin_common['No'] ?></strong>
353+ <input type="radio" name="edit_posts" value="1"<?php if ($group['g_edit_posts'] == '1') echo ' checked="checked"' ?> tabindex="21" />&#160;<strong><?php echo $lang_admin_common['Yes'] ?></strong>&#160;&#160;&#160;<input type="radio" name="edit_posts" value="0"<?php if ($group['g_edit_posts'] == '0') echo ' checked="checked"' ?> tabindex="22" />&#160;<strong><?php echo $lang_admin_common['No'] ?></strong>
354 <span><?php echo $lang_admin_groups['Edit posts help'] ?></span>
355 </td>
356 </tr>
357 <tr>
358 <th scope="row"><?php echo $lang_admin_groups['Delete posts label'] ?></th>
359 <td>
360- <input type="radio" name="delete_posts" value="1"<?php if ($group['g_delete_posts'] == '1') echo ' checked="checked"' ?> tabindex="13" />&#160;<strong><?php echo $lang_admin_common['Yes'] ?></strong>&#160;&#160;&#160;<input type="radio" name="delete_posts" value="0"<?php if ($group['g_delete_posts'] == '0') echo ' checked="checked"' ?> tabindex="14" />&#160;<strong><?php echo $lang_admin_common['No'] ?></strong>
361+ <input type="radio" name="delete_posts" value="1"<?php if ($group['g_delete_posts'] == '1') echo ' checked="checked"' ?> tabindex="23" />&#160;<strong><?php echo $lang_admin_common['Yes'] ?></strong>&#160;&#160;&#160;<input type="radio" name="delete_posts" value="0"<?php if ($group['g_delete_posts'] == '0') echo ' checked="checked"' ?> tabindex="24" />&#160;<strong><?php echo $lang_admin_common['No'] ?></strong>
362 <span><?php echo $lang_admin_groups['Delete posts help'] ?></span>
363 </td>
364 </tr>
365 <tr>
366 <th scope="row"><?php echo $lang_admin_groups['Delete topics label'] ?></th>
367 <td>
368- <input type="radio" name="delete_topics" value="1"<?php if ($group['g_delete_topics'] == '1') echo ' checked="checked"' ?> tabindex="15" />&#160;<strong><?php echo $lang_admin_common['Yes'] ?></strong>&#160;&#160;&#160;<input type="radio" name="delete_topics" value="0"<?php if ($group['g_delete_topics'] == '0') echo ' checked="checked"' ?> tabindex="16" />&#160;<strong><?php echo $lang_admin_common['No'] ?></strong>
369+ <input type="radio" name="delete_topics" value="1"<?php if ($group['g_delete_topics'] == '1') echo ' checked="checked"' ?> tabindex="25" />&#160;<strong><?php echo $lang_admin_common['Yes'] ?></strong>&#160;&#160;&#160;<input type="radio" name="delete_topics" value="0"<?php if ($group['g_delete_topics'] == '0') echo ' checked="checked"' ?> tabindex="26" />&#160;<strong><?php echo $lang_admin_common['No'] ?></strong>
370 <span><?php echo $lang_admin_groups['Delete topics help'] ?></span>
371 </td>
372 </tr>
373 <tr>
374 <th scope="row"><?php echo $lang_admin_groups['Set own title label'] ?></th>
375 <td>
376- <input type="radio" name="set_title" value="1"<?php if ($group['g_set_title'] == '1') echo ' checked="checked"' ?> tabindex="17" />&#160;<strong><?php echo $lang_admin_common['Yes'] ?></strong>&#160;&#160;&#160;<input type="radio" name="set_title" value="0"<?php if ($group['g_set_title'] == '0') echo ' checked="checked"' ?> tabindex="18" />&#160;<strong><?php echo $lang_admin_common['No'] ?></strong>
377+ <input type="radio" name="set_title" value="1"<?php if ($group['g_set_title'] == '1') echo ' checked="checked"' ?> tabindex="27" />&#160;<strong><?php echo $lang_admin_common['Yes'] ?></strong>&#160;&#160;&#160;<input type="radio" name="set_title" value="0"<?php if ($group['g_set_title'] == '0') echo ' checked="checked"' ?> tabindex="28" />&#160;<strong><?php echo $lang_admin_common['No'] ?></strong>
378 <span><?php echo $lang_admin_groups['Set own title help'] ?></span>
379 </td>
380 </tr>
381 <?php endif; ?> <tr>
382 <th scope="row"><?php echo $lang_admin_groups['User search label'] ?></th>
383 <td>
384- <input type="radio" name="search" value="1"<?php if ($group['g_search'] == '1') echo ' checked="checked"' ?> tabindex="19" />&#160;<strong><?php echo $lang_admin_common['Yes'] ?></strong>&#160;&#160;&#160;<input type="radio" name="search" value="0"<?php if ($group['g_search'] == '0') echo ' checked="checked"' ?> tabindex="20" />&#160;<strong><?php echo $lang_admin_common['No'] ?></strong>
385+ <input type="radio" name="search" value="1"<?php if ($group['g_search'] == '1') echo ' checked="checked"' ?> tabindex="29" />&#160;<strong><?php echo $lang_admin_common['Yes'] ?></strong>&#160;&#160;&#160;<input type="radio" name="search" value="0"<?php if ($group['g_search'] == '0') echo ' checked="checked"' ?> tabindex="30" />&#160;<strong><?php echo $lang_admin_common['No'] ?></strong>
386 <span><?php echo $lang_admin_groups['User search help'] ?></span>
387 </td>
388 </tr>
389 <tr>
390 <th scope="row"><?php echo $lang_admin_groups['User list search label'] ?></th>
391 <td>
392- <input type="radio" name="search_users" value="1"<?php if ($group['g_search_users'] == '1') echo ' checked="checked"' ?> tabindex="21" />&#160;<strong><?php echo $lang_admin_common['Yes'] ?></strong>&#160;&#160;&#160;<input type="radio" name="search_users" value="0"<?php if ($group['g_search_users'] == '0') echo ' checked="checked"' ?> tabindex="22" />&#160;<strong><?php echo $lang_admin_common['No'] ?></strong>
393+ <input type="radio" name="search_users" value="1"<?php if ($group['g_search_users'] == '1') echo ' checked="checked"' ?> tabindex="31" />&#160;<strong><?php echo $lang_admin_common['Yes'] ?></strong>&#160;&#160;&#160;<input type="radio" name="search_users" value="0"<?php if ($group['g_search_users'] == '0') echo ' checked="checked"' ?> tabindex="32" />&#160;<strong><?php echo $lang_admin_common['No'] ?></strong>
394 <span><?php echo $lang_admin_groups['User list search help'] ?></span>
395 </td>
396 </tr>
397 <?php if ($group['g_id'] != PUN_GUEST): ?> <tr>
398 <th scope="row"><?php echo $lang_admin_groups['Send e-mails label'] ?></th>
399 <td>
400- <input type="radio" name="send_email" value="1"<?php if ($group['g_send_email'] == '1') echo ' checked="checked"' ?> tabindex="21" />&#160;<strong><?php echo $lang_admin_common['Yes'] ?></strong>&#160;&#160;&#160;<input type="radio" name="send_email" value="0"<?php if ($group['g_send_email'] == '0') echo ' checked="checked"' ?> tabindex="22" />&#160;<strong><?php echo $lang_admin_common['No'] ?></strong>
401+ <input type="radio" name="send_email" value="1"<?php if ($group['g_send_email'] == '1') echo ' checked="checked"' ?> tabindex="33" />&#160;<strong><?php echo $lang_admin_common['Yes'] ?></strong>&#160;&#160;&#160;<input type="radio" name="send_email" value="0"<?php if ($group['g_send_email'] == '0') echo ' checked="checked"' ?> tabindex="34" />&#160;<strong><?php echo $lang_admin_common['No'] ?></strong>
402 <span><?php echo $lang_admin_groups['Send e-mails help'] ?></span>
403 </td>
404 </tr>
405 <?php endif; ?> <tr>
406 <th scope="row"><?php echo $lang_admin_groups['Post flood label'] ?></th>
407 <td>
408- <input type="text" name="post_flood" size="5" maxlength="4" value="<?php echo $group['g_post_flood'] ?>" tabindex="24" />
409+ <input type="text" name="post_flood" size="5" maxlength="4" value="<?php echo $group['g_post_flood'] ?>" tabindex="35" />
410 <span><?php echo $lang_admin_groups['Post flood help'] ?></span>
411 </td>
412 </tr>
413 <tr>
414 <th scope="row"><?php echo $lang_admin_groups['Search flood label'] ?></th>
415 <td>
416- <input type="text" name="search_flood" size="5" maxlength="4" value="<?php echo $group['g_search_flood'] ?>" tabindex="25" />
417+ <input type="text" name="search_flood" size="5" maxlength="4" value="<?php echo $group['g_search_flood'] ?>" tabindex="36" />
418 <span><?php echo $lang_admin_groups['Search flood help'] ?></span>
419 </td>
420 </tr>
421 <?php if ($group['g_id'] != PUN_GUEST): ?> <tr>
422 <th scope="row"><?php echo $lang_admin_groups['E-mail flood label'] ?></th>
423 <td>
424- <input type="text" name="email_flood" size="5" maxlength="4" value="<?php echo $group['g_email_flood'] ?>" tabindex="26" />
425+ <input type="text" name="email_flood" size="5" maxlength="4" value="<?php echo $group['g_email_flood'] ?>" tabindex="37" />
426 <span><?php echo $lang_admin_groups['E-mail flood help'] ?></span>
427 </td>
428 </tr>
429+ <tr>
430+ <th scope="row"><?php echo $lang_admin_groups['Report flood label'] ?></th>
431+ <td>
432+ <input type="text" name="report_flood" size="5" maxlength="4" value="<?php echo $group['g_report_flood'] ?>" tabindex="38" />
433+ <span><?php echo $lang_admin_groups['Report flood help'] ?></span>
434+ </td>
435+ </tr>
436 <?php endif; endif; ?> </table>
437 <?php if ($group['g_moderator'] == '1' ): ?> <p class="warntext"><?php echo $lang_admin_groups['Moderator info'] ?></p>
438 <?php endif; ?> </div>
439 </fieldset>
440 </div>
441- <p class="submitend"><input type="submit" name="add_edit_group" value="<?php echo $lang_admin_common['Save'] ?>" tabindex="26" /></p>
442+ <p class="submitend"><input type="submit" name="add_edit_group" value="<?php echo $lang_admin_common['Save'] ?>" tabindex="39" /></p>
443 </form>
444 </div>
445 </div>
446@@ -263,6 +270,7 @@
447 $post_flood = isset($_POST['post_flood']) ? intval($_POST['post_flood']) : '0';
448 $search_flood = isset($_POST['search_flood']) ? intval($_POST['search_flood']) : '0';
449 $email_flood = isset($_POST['email_flood']) ? intval($_POST['email_flood']) : '0';
450+ $report_flood = isset($_POST['report_flood']) ? intval($_POST['report_flood']) : '0';
451
452 if ($title == '')
453 message($lang_admin_groups['Must enter title message']);
454@@ -275,7 +283,7 @@
455 if ($db->num_rows($result))
456 message(sprintf($lang_admin_groups['Title already exists message'], pun_htmlspecialchars($title)));
457
458- $db->query('INSERT INTO '.$db->prefix.'groups (g_title, g_user_title, g_moderator, g_mod_edit_users, g_mod_rename_users, g_mod_change_passwords, g_mod_ban_users, g_read_board, g_view_users, g_post_replies, g_post_topics, g_edit_posts, g_delete_posts, g_delete_topics, g_set_title, g_search, g_search_users, g_send_email, g_post_flood, g_search_flood, g_email_flood) VALUES(\''.$db->escape($title).'\', '.$user_title.', '.$moderator.', '.$mod_edit_users.', '.$mod_rename_users.', '.$mod_change_passwords.', '.$mod_ban_users.', '.$read_board.', '.$view_users.', '.$post_replies.', '.$post_topics.', '.$edit_posts.', '.$delete_posts.', '.$delete_topics.', '.$set_title.', '.$search.', '.$search_users.', '.$send_email.', '.$post_flood.', '.$search_flood.', '.$email_flood.')') or error('Unable to add group', __FILE__, __LINE__, $db->error());
459+ $db->query('INSERT INTO '.$db->prefix.'groups (g_title, g_user_title, g_moderator, g_mod_edit_users, g_mod_rename_users, g_mod_change_passwords, g_mod_ban_users, g_read_board, g_view_users, g_post_replies, g_post_topics, g_edit_posts, g_delete_posts, g_delete_topics, g_set_title, g_search, g_search_users, g_send_email, g_post_flood, g_search_flood, g_email_flood, g_report_flood) VALUES(\''.$db->escape($title).'\', '.$user_title.', '.$moderator.', '.$mod_edit_users.', '.$mod_rename_users.', '.$mod_change_passwords.', '.$mod_ban_users.', '.$read_board.', '.$view_users.', '.$post_replies.', '.$post_topics.', '.$edit_posts.', '.$delete_posts.', '.$delete_topics.', '.$set_title.', '.$search.', '.$search_users.', '.$send_email.', '.$post_flood.', '.$search_flood.', '.$email_flood.', '.$report_flood.')') or error('Unable to add group', __FILE__, __LINE__, $db->error());
460 $new_group_id = $db->insert_id();
461
462 // Now lets copy the forum specific permissions from the group which this group is based on
463@@ -289,7 +297,7 @@
464 if ($db->num_rows($result))
465 message(sprintf($lang_admin_groups['Title already exists message'], pun_htmlspecialchars($title)));
466
467- $db->query('UPDATE '.$db->prefix.'groups SET g_title=\''.$db->escape($title).'\', g_user_title='.$user_title.', g_moderator='.$moderator.', g_mod_edit_users='.$mod_edit_users.', g_mod_rename_users='.$mod_rename_users.', g_mod_change_passwords='.$mod_change_passwords.', g_mod_ban_users='.$mod_ban_users.', g_read_board='.$read_board.', g_view_users='.$view_users.', g_post_replies='.$post_replies.', g_post_topics='.$post_topics.', g_edit_posts='.$edit_posts.', g_delete_posts='.$delete_posts.', g_delete_topics='.$delete_topics.', g_set_title='.$set_title.', g_search='.$search.', g_search_users='.$search_users.', g_send_email='.$send_email.', g_post_flood='.$post_flood.', g_search_flood='.$search_flood.', g_email_flood='.$email_flood.' WHERE g_id='.intval($_POST['group_id'])) or error('Unable to update group', __FILE__, __LINE__, $db->error());
468+ $db->query('UPDATE '.$db->prefix.'groups SET g_title=\''.$db->escape($title).'\', g_user_title='.$user_title.', g_moderator='.$moderator.', g_mod_edit_users='.$mod_edit_users.', g_mod_rename_users='.$mod_rename_users.', g_mod_change_passwords='.$mod_change_passwords.', g_mod_ban_users='.$mod_ban_users.', g_read_board='.$read_board.', g_view_users='.$view_users.', g_post_replies='.$post_replies.', g_post_topics='.$post_topics.', g_edit_posts='.$edit_posts.', g_delete_posts='.$delete_posts.', g_delete_topics='.$delete_topics.', g_set_title='.$set_title.', g_search='.$search.', g_search_users='.$search_users.', g_send_email='.$send_email.', g_post_flood='.$post_flood.', g_search_flood='.$search_flood.', g_email_flood='.$email_flood.', g_report_flood='.$report_flood.' WHERE g_id='.intval($_POST['group_id'])) or error('Unable to update group', __FILE__, __LINE__, $db->error());
469 }
470
471 // Regenerate the quick jump cache
472@@ -393,7 +401,7 @@
473 </div>
474 </fieldset>
475 </div>
476- <p class="buttons"><input type="submit" name="del_group_comply" value="<?php echo $lang_admin_common['Delete'] ?>" /><a href="javascript:history.go(-1)"><?php echo $lang_admin_common['Go back'] ?></a></p>
477+ <p class="buttons"><input type="submit" name="del_group_comply" value="<?php echo $lang_admin_common['Delete'] ?>" tabindex="1" /><a href="javascript:history.go(-1)" tabindex="2"><?php echo $lang_admin_common['Go back'] ?></a></p>
478 </form>
479 </div>
480 </div>
481@@ -540,10 +548,12 @@
482 <table cellspacing="0">
483 <?php
484
485+$cur_index = 5;
486+
487 $result = $db->query('SELECT g_id, g_title FROM '.$db->prefix.'groups ORDER BY g_id') or error('Unable to fetch user group list', __FILE__, __LINE__, $db->error());
488
489 while ($cur_group = $db->fetch_assoc($result))
490- echo "\t\t\t\t\t\t\t\t".'<tr><th scope="row"><a href="admin_groups.php?edit_group='.$cur_group['g_id'].'">'.$lang_admin_groups['Edit link'].'</a>'.(($cur_group['g_id'] > PUN_MEMBER) ? ' | <a href="admin_groups.php?del_group='.$cur_group['g_id'].'">'.$lang_admin_groups['Delete link'].'</a>' : '').'</th><td>'.pun_htmlspecialchars($cur_group['g_title']).'</td></tr>'."\n";
491+ echo "\t\t\t\t\t\t\t\t".'<tr><th scope="row"><a href="admin_groups.php?edit_group='.$cur_group['g_id'].'" tabindex="'.$cur_index++.'">'.$lang_admin_groups['Edit link'].'</a>'.(($cur_group['g_id'] > PUN_MEMBER) ? ' | <a href="admin_groups.php?del_group='.$cur_group['g_id'].'" tabindex="'.$cur_index++.'">'.$lang_admin_groups['Delete link'].'</a>' : '').'</th><td>'.pun_htmlspecialchars($cur_group['g_title']).'</td></tr>'."\n";
492
493 ?>
494 </table>
495
496=== modified file 'admin_index.php'
497--- admin_index.php 2011-04-19 22:53:21 +0000
498+++ admin_index.php 2012-02-27 14:24:17 +0000
499@@ -1,7 +1,7 @@
500 <?php
501
502 /**
503- * Copyright (C) 2008-2011 FluxBB
504+ * Copyright (C) 2008-2012 FluxBB
505 * based on code by Rickard Andersson copyright (C) 2002-2008 PunBB
506 * License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher
507 */
508@@ -70,7 +70,7 @@
509 $load_averages = @explode(' ', $load_averages);
510 $server_load = isset($load_averages[2]) ? $load_averages[0].' '.$load_averages[1].' '.$load_averages[2] : $lang_admin_index['Not available'];
511 }
512-else if (!in_array(PHP_OS, array('WINNT', 'WIN32')) && preg_match('/averages?: ([0-9\.]+),?\s+([0-9\.]+),?\s+([0-9\.]+)/i', @exec('uptime'), $load_averages))
513+else if (!in_array(PHP_OS, array('WINNT', 'WIN32')) && preg_match('%averages?: ([0-9\.]+),?\s+([0-9\.]+),?\s+([0-9\.]+)%i', @exec('uptime'), $load_averages))
514 $server_load = $load_averages[1].' '.$load_averages[2].' '.$load_averages[3];
515 else
516 $server_load = $lang_admin_index['Not available'];
517@@ -147,24 +147,25 @@
518 <dl>
519 <dt><?php echo $lang_admin_index['FluxBB version label'] ?></dt>
520 <dd>
521- <?php printf($lang_admin_index['FluxBB version data'], $pun_config['o_cur_version'], '<a href="admin_index.php?action=check_upgrade">'.$lang_admin_index['Check for upgrade'].'</a>') ?>
522+ <?php printf($lang_admin_index['FluxBB version data']."\n", $pun_config['o_cur_version'], '<a href="admin_index.php?action=check_upgrade">'.$lang_admin_index['Check for upgrade'].'</a>') ?>
523 </dd>
524 <dt><?php echo $lang_admin_index['Server load label'] ?></dt>
525 <dd>
526- <?php printf($lang_admin_index['Server load data'], $server_load, $num_online) ?>
527+ <?php printf($lang_admin_index['Server load data']."\n", $server_load, $num_online) ?>
528 </dd>
529 <?php if ($pun_user['g_id'] == PUN_ADMIN): ?> <dt><?php echo $lang_admin_index['Environment label'] ?></dt>
530 <dd>
531 <?php printf($lang_admin_index['Environment data OS'], PHP_OS) ?><br />
532 <?php printf($lang_admin_index['Environment data version'], phpversion(), '<a href="admin_index.php?action=phpinfo">'.$lang_admin_index['Show info'].'</a>') ?><br />
533- <?php printf($lang_admin_index['Environment data acc'], $php_accelerator) ?>
534+ <?php printf($lang_admin_index['Environment data acc']."\n", $php_accelerator) ?>
535 </dd>
536 <dt><?php echo $lang_admin_index['Database label'] ?></dt>
537 <dd>
538 <?php echo implode(' ', $db->get_version())."\n" ?>
539-<?php if (isset($total_records) && isset($total_size)): ?> <br /><?php printf($lang_admin_index['Database data rows'], forum_number_format($total_records)) ?>
540- <br /><?php printf($lang_admin_index['Database data size'], $total_size) ?>
541-<?php endif; ?> </dd><?php endif; ?>
542+<?php if (isset($total_records) && isset($total_size)): ?> <br /><?php printf($lang_admin_index['Database data rows']."\n", forum_number_format($total_records)) ?>
543+ <br /><?php printf($lang_admin_index['Database data size']."\n", $total_size) ?>
544+<?php endif; ?> </dd>
545+<?php endif; ?>
546 </dl>
547 </div>
548 </div>
549
550=== modified file 'admin_loader.php'
551--- admin_loader.php 2011-04-19 22:53:21 +0000
552+++ admin_loader.php 2012-02-27 14:24:17 +0000
553@@ -1,7 +1,7 @@
554 <?php
555
556 /**
557- * Copyright (C) 2008-2011 FluxBB
558+ * Copyright (C) 2008-2012 FluxBB
559 * based on code by Rickard Andersson copyright (C) 2002-2008 PunBB
560 * License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher
561 */
562@@ -19,7 +19,7 @@
563
564 // The plugin to load should be supplied via GET
565 $plugin = isset($_GET['plugin']) ? $_GET['plugin'] : '';
566-if (!preg_match('/^AM?P_(\w*?)\.php$/i', $plugin))
567+if (!preg_match('%^AM?P_(\w*?)\.php$%i', $plugin))
568 message($lang_common['Bad request']);
569
570 // AP_ == Admins only, AMP_ == admins and moderators
571
572=== modified file 'admin_maintenance.php'
573--- admin_maintenance.php 2011-04-19 22:53:21 +0000
574+++ admin_maintenance.php 2012-02-27 14:24:17 +0000
575@@ -1,7 +1,7 @@
576 <?php
577
578 /**
579- * Copyright (C) 2008-2011 FluxBB
580+ * Copyright (C) 2008-2012 FluxBB
581 * based on code by Rickard Andersson copyright (C) 2002-2008 PunBB
582 * License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher
583 */
584@@ -173,7 +173,7 @@
585 }
586
587 $prune_days = trim($_POST['req_prune_days']);
588- if ($prune_days == '' || preg_match('/[^0-9]/', $prune_days))
589+ if ($prune_days == '' || preg_match('%[^0-9]%', $prune_days))
590 message($lang_admin_maintenance['Days must be integer message']);
591
592 $prune_date = time() - ($prune_days * 86400);
593
594=== modified file 'admin_options.php'
595--- admin_options.php 2011-04-19 22:53:21 +0000
596+++ admin_options.php 2012-02-27 14:24:17 +0000
597@@ -1,7 +1,7 @@
598 <?php
599
600 /**
601- * Copyright (C) 2008-2011 FluxBB
602+ * Copyright (C) 2008-2012 FluxBB
603 * based on code by Rickard Andersson copyright (C) 2002-2008 PunBB
604 * License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher
605 */
606@@ -118,7 +118,7 @@
607 message($lang_admin_options['Invalid webmaster e-mail message']);
608
609 if ($form['mailing_list'] != '')
610- $form['mailing_list'] = strtolower(preg_replace('/\s/S', '', $form['mailing_list']));
611+ $form['mailing_list'] = strtolower(preg_replace('%\s%S', '', $form['mailing_list']));
612
613 // Make sure avatars_dir doesn't end with a slash
614 if (substr($form['avatars_dir'], -1) == '/')
615
616=== modified file 'admin_permissions.php'
617--- admin_permissions.php 2011-04-19 22:53:21 +0000
618+++ admin_permissions.php 2012-02-27 14:24:17 +0000
619@@ -1,7 +1,7 @@
620 <?php
621
622 /**
623- * Copyright (C) 2008-2011 FluxBB
624+ * Copyright (C) 2008-2012 FluxBB
625 * based on code by Rickard Andersson copyright (C) 2002-2008 PunBB
626 * License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher
627 */
628
629=== modified file 'admin_ranks.php'
630--- admin_ranks.php 2011-04-19 22:53:21 +0000
631+++ admin_ranks.php 2012-02-27 14:24:17 +0000
632@@ -1,7 +1,7 @@
633 <?php
634
635 /**
636- * Copyright (C) 2008-2011 FluxBB
637+ * Copyright (C) 2008-2012 FluxBB
638 * based on code by Rickard Andersson copyright (C) 2002-2008 PunBB
639 * License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher
640 */
641@@ -31,7 +31,7 @@
642 if ($rank == '')
643 message($lang_admin_ranks['Must enter title message']);
644
645- if ($min_posts == '' || preg_match('/[^0-9]/', $min_posts))
646+ if ($min_posts == '' || preg_match('%[^0-9]%', $min_posts))
647 message($lang_admin_ranks['Must be integer message']);
648
649 // Make sure there isn't already a rank with the same min_posts value
650@@ -64,7 +64,7 @@
651 if ($rank == '')
652 message($lang_admin_ranks['Must enter title message']);
653
654- if ($min_posts == '' || preg_match('/[^0-9]/', $min_posts))
655+ if ($min_posts == '' || preg_match('%[^0-9]%', $min_posts))
656 message($lang_admin_ranks['Must be integer message']);
657
658 // Make sure there isn't already a rank with the same min_posts value
659
660=== modified file 'admin_reports.php'
661--- admin_reports.php 2011-04-19 22:53:21 +0000
662+++ admin_reports.php 2012-02-27 14:24:17 +0000
663@@ -1,7 +1,7 @@
664 <?php
665
666 /**
667- * Copyright (C) 2008-2011 FluxBB
668+ * Copyright (C) 2008-2012 FluxBB
669 * based on code by Rickard Andersson copyright (C) 2002-2008 PunBB
670 * License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher
671 */
672
673=== modified file 'admin_users.php'
674--- admin_users.php 2011-04-19 22:53:21 +0000
675+++ admin_users.php 2012-02-27 14:24:17 +0000
676@@ -1,7 +1,7 @@
677 <?php
678
679 /**
680- * Copyright (C) 2008-2011 FluxBB
681+ * Copyright (C) 2008-2012 FluxBB
682 * based on code by Rickard Andersson copyright (C) 2002-2008 PunBB
683 * License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher
684 */
685@@ -125,7 +125,7 @@
686 {
687 $ip = trim($_GET['show_users']);
688
689- if (!@preg_match('/^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$/', $ip) && !@preg_match('/^((([0-9A-Fa-f]{1,4}:){7}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){6}:[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){5}:([0-9A-Fa-f]{1,4}:)?[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){4}:([0-9A-Fa-f]{1,4}:){0,2}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){3}:([0-9A-Fa-f]{1,4}:){0,3}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){2}:([0-9A-Fa-f]{1,4}:){0,4}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){6}((\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b)\.){3}(\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b))|(([0-9A-Fa-f]{1,4}:){0,5}:((\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b)\.){3}(\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b))|(::([0-9A-Fa-f]{1,4}:){0,5}((\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b)\.){3}(\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b))|([0-9A-Fa-f]{1,4}::([0-9A-Fa-f]{1,4}:){0,5}[0-9A-Fa-f]{1,4})|(::([0-9A-Fa-f]{1,4}:){0,6}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){1,7}:))$/', $ip))
690+ if (!@preg_match('%^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$%', $ip) && !@preg_match('%^((([0-9A-Fa-f]{1,4}:){7}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){6}:[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){5}:([0-9A-Fa-f]{1,4}:)?[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){4}:([0-9A-Fa-f]{1,4}:){0,2}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){3}:([0-9A-Fa-f]{1,4}:){0,3}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){2}:([0-9A-Fa-f]{1,4}:){0,4}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){6}((\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b)\.){3}(\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b))|(([0-9A-Fa-f]{1,4}:){0,5}:((\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b)\.){3}(\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b))|(::([0-9A-Fa-f]{1,4}:){0,5}((\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b)\.){3}(\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b))|([0-9A-Fa-f]{1,4}::([0-9A-Fa-f]{1,4}:){0,5}[0-9A-Fa-f]{1,4})|(::([0-9A-Fa-f]{1,4}:){0,6}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){1,7}:))$%', $ip))
691 message($lang_admin_users['Bad IP message']);
692
693 // Fetch user count
694@@ -260,26 +260,26 @@
695 message($lang_common['No permission']);
696
697 confirm_referrer('admin_users.php');
698-
699+
700 if (isset($_POST['users']))
701 {
702 $user_ids = is_array($_POST['users']) ? array_keys($_POST['users']) : explode(',', $_POST['users']);
703 $user_ids = array_map('intval', $user_ids);
704-
705+
706 // Delete invalid IDs
707 $user_ids = array_diff($user_ids, array(0, 1));
708 }
709 else
710 $user_ids = array();
711-
712+
713 if (empty($user_ids))
714 message($lang_admin_users['No users selected']);
715-
716+
717 // Are we trying to batch move any admins?
718 $result = $db->query('SELECT COUNT(*) FROM '.$db->prefix.'users WHERE id IN ('.implode(',', $user_ids).') AND group_id='.PUN_ADMIN) or error('Unable to fetch user info', __FILE__, __LINE__, $db->error());
719 if ($db->result($result) > 0)
720 message($lang_admin_users['No move admins message']);
721-
722+
723 // Fetch all user groups
724 $all_groups = array();
725 $result = $db->query('SELECT g_id, g_title FROM '.$db->prefix.'groups WHERE g_id NOT IN ('.PUN_GUEST.','.PUN_ADMIN.') ORDER BY g_title ASC') or error('Unable to fetch groups', __FILE__, __LINE__, $db->error());
726@@ -289,11 +289,11 @@
727 if (isset($_POST['move_users_comply']))
728 {
729 $new_group = isset($_POST['new_group']) && isset($all_groups[$_POST['new_group']]) ? $_POST['new_group'] : message($lang_admin_users['Invalid group message']);
730-
731+
732 // Is the new group a moderator group?
733 $result = $db->query('SELECT g_moderator FROM '.$db->prefix.'groups WHERE g_id='.$new_group) or error('Unable to fetch group info', __FILE__, __LINE__, $db->error());
734 $new_group_mod = $db->result($result);
735-
736+
737 // Fetch user groups
738 $user_groups = array();
739 $result = $db->query('SELECT id, group_id FROM '.$db->prefix.'users WHERE id IN ('.implode(',', $user_ids).')') or error('Unable to fetch user groups', __FILE__, __LINE__, $db->error());
740@@ -301,10 +301,10 @@
741 {
742 if (!isset($user_groups[$cur_user['group_id']]))
743 $user_groups[$cur_user['group_id']] = array();
744-
745+
746 $user_groups[$cur_user['group_id']][] = $cur_user['id'];
747 }
748-
749+
750 // Are any users moderators?
751 $group_ids = array_keys($user_groups);
752 $result = $db->query('SELECT g_id, g_moderator FROM '.$db->prefix.'groups WHERE g_id IN ('.implode(',', $group_ids).')') or error('Unable to fetch group moderators', __FILE__, __LINE__, $db->error());
753@@ -313,7 +313,7 @@
754 if ($cur_group['g_moderator'] == '0')
755 unset($user_groups[$cur_group['g_id']]);
756 }
757-
758+
759 if (!empty($user_groups) && $new_group != PUN_ADMIN && $new_group_mod != '1')
760 {
761 // Fetch forum list and clean up their moderator list
762@@ -321,25 +321,25 @@
763 while ($cur_forum = $db->fetch_assoc($result))
764 {
765 $cur_moderators = ($cur_forum['moderators'] != '') ? unserialize($cur_forum['moderators']) : array();
766-
767+
768 foreach ($user_groups as $group_users)
769 $cur_moderators = array_diff($cur_moderators, $group_users);
770-
771+
772 $cur_moderators = (!empty($cur_moderators)) ? '\''.$db->escape(serialize($cur_moderators)).'\'' : 'NULL';
773 $db->query('UPDATE '.$db->prefix.'forums SET moderators='.$cur_moderators.' WHERE id='.$cur_forum['id']) or error('Unable to update forum', __FILE__, __LINE__, $db->error());
774 }
775 }
776-
777+
778 // Change user group
779 $db->query('UPDATE '.$db->prefix.'users SET group_id='.$new_group.' WHERE id IN ('.implode(',', $user_ids).')') or error('Unable to change user group', __FILE__, __LINE__, $db->error());
780-
781+
782 redirect('admin_users.php', $lang_admin_users['Users move redirect']);
783 }
784
785 $page_title = array(pun_htmlspecialchars($pun_config['o_board_title']), $lang_admin_common['Admin'], $lang_admin_common['Users'], $lang_admin_users['Move users']);
786 define('PUN_ACTIVE_PAGE', 'admin');
787 require PUN_ROOT.'header.php';
788-
789+
790 generate_admin_menu('users');
791
792 ?>
793@@ -386,21 +386,21 @@
794 message($lang_common['No permission']);
795
796 confirm_referrer('admin_users.php');
797-
798+
799 if (isset($_POST['users']))
800 {
801 $user_ids = is_array($_POST['users']) ? array_keys($_POST['users']) : explode(',', $_POST['users']);
802 $user_ids = array_map('intval', $user_ids);
803-
804+
805 // Delete invalid IDs
806 $user_ids = array_diff($user_ids, array(0, 1));
807 }
808 else
809 $user_ids = array();
810-
811+
812 if (empty($user_ids))
813 message($lang_admin_users['No users selected']);
814-
815+
816 // Are we trying to delete any admins?
817 $result = $db->query('SELECT COUNT(*) FROM '.$db->prefix.'users WHERE id IN ('.implode(',', $user_ids).') AND group_id='.PUN_ADMIN) or error('Unable to fetch user info', __FILE__, __LINE__, $db->error());
818 if ($db->result($result) > 0)
819@@ -415,10 +415,10 @@
820 {
821 if (!isset($user_groups[$cur_user['group_id']]))
822 $user_groups[$cur_user['group_id']] = array();
823-
824+
825 $user_groups[$cur_user['group_id']][] = $cur_user['id'];
826 }
827-
828+
829 // Are any users moderators?
830 $group_ids = array_keys($user_groups);
831 $result = $db->query('SELECT g_id, g_moderator FROM '.$db->prefix.'groups WHERE g_id IN ('.implode(',', $group_ids).')') or error('Unable to fetch group moderators', __FILE__, __LINE__, $db->error());
832@@ -427,7 +427,7 @@
833 if ($cur_group['g_moderator'] == '0')
834 unset($user_groups[$cur_group['g_id']]);
835 }
836-
837+
838 // Fetch forum list and clean up their moderator list
839 $result = $db->query('SELECT id, moderators FROM '.$db->prefix.'forums') or error('Unable to fetch forum list', __FILE__, __LINE__, $db->error());
840 while ($cur_forum = $db->fetch_assoc($result))
841@@ -436,18 +436,18 @@
842
843 foreach ($user_groups as $group_users)
844 $cur_moderators = array_diff($cur_moderators, $group_users);
845-
846+
847 $cur_moderators = (!empty($cur_moderators)) ? '\''.$db->escape(serialize($cur_moderators)).'\'' : 'NULL';
848 $db->query('UPDATE '.$db->prefix.'forums SET moderators='.$cur_moderators.' WHERE id='.$cur_forum['id']) or error('Unable to update forum', __FILE__, __LINE__, $db->error());
849 }
850-
851+
852 // Delete any subscriptions
853 $db->query('DELETE FROM '.$db->prefix.'topic_subscriptions WHERE user_id IN ('.implode(',', $user_ids).')') or error('Unable to delete topic subscriptions', __FILE__, __LINE__, $db->error());
854 $db->query('DELETE FROM '.$db->prefix.'forum_subscriptions WHERE user_id IN ('.implode(',', $user_ids).')') or error('Unable to delete forum subscriptions', __FILE__, __LINE__, $db->error());
855-
856+
857 // Remove them from the online list (if they happen to be logged in)
858 $db->query('DELETE FROM '.$db->prefix.'online WHERE user_id IN ('.implode(',', $user_ids).')') or error('Unable to remove users from online list', __FILE__, __LINE__, $db->error());
859-
860+
861 // Should we delete all posts made by these users?
862 if (isset($_POST['delete_posts']))
863 {
864@@ -482,14 +482,20 @@
865 // Delete user avatars
866 foreach ($user_ids as $user_id)
867 delete_avatar($user_id);
868-
869+
870+ // Regenerate the users info cache
871+ if (!defined('FORUM_CACHE_FUNCTIONS_LOADED'))
872+ require PUN_ROOT.'include/cache.php';
873+
874+ generate_users_info_cache();
875+
876 redirect('admin_users.php', $lang_admin_users['Users delete redirect']);
877 }
878
879 $page_title = array(pun_htmlspecialchars($pun_config['o_board_title']), $lang_admin_common['Admin'], $lang_admin_common['Users'], $lang_admin_users['Delete users']);
880 define('PUN_ACTIVE_PAGE', 'admin');
881 require PUN_ROOT.'header.php';
882-
883+
884 generate_admin_menu('users');
885
886 ?>
887@@ -529,61 +535,61 @@
888 message($lang_common['No permission']);
889
890 confirm_referrer('admin_users.php');
891-
892+
893 if (isset($_POST['users']))
894 {
895 $user_ids = is_array($_POST['users']) ? array_keys($_POST['users']) : explode(',', $_POST['users']);
896 $user_ids = array_map('intval', $user_ids);
897-
898+
899 // Delete invalid IDs
900 $user_ids = array_diff($user_ids, array(0, 1));
901 }
902 else
903 $user_ids = array();
904-
905+
906 if (empty($user_ids))
907 message($lang_admin_users['No users selected']);
908-
909+
910 // Are we trying to ban any admins?
911 $result = $db->query('SELECT COUNT(*) FROM '.$db->prefix.'users WHERE id IN ('.implode(',', $user_ids).') AND group_id='.PUN_ADMIN) or error('Unable to fetch group info', __FILE__, __LINE__, $db->error());
912 if ($db->result($result) > 0)
913 message($lang_admin_users['No ban admins message']);
914-
915+
916 // Also, we cannot ban moderators
917 $result = $db->query('SELECT COUNT(*) FROM '.$db->prefix.'users AS u INNER JOIN '.$db->prefix.'groups AS g ON u.group_id=g.g_id WHERE g.g_moderator=1 AND u.id IN ('.implode(',', $user_ids).')') or error('Unable to fetch moderator group info', __FILE__, __LINE__, $db->error());
918 if ($db->result($result) > 0)
919 message($lang_admin_users['No ban mods message']);
920-
921+
922 if (isset($_POST['ban_users_comply']))
923 {
924 $ban_message = pun_trim($_POST['ban_message']);
925 $ban_expire = pun_trim($_POST['ban_expire']);
926 $ban_the_ip = isset($_POST['ban_the_ip']) ? intval($_POST['ban_the_ip']) : 0;
927-
928+
929 if ($ban_expire != '' && $ban_expire != 'Never')
930 {
931 $ban_expire = strtotime($ban_expire.' GMT');
932-
933+
934 if ($ban_expire == -1 || !$ban_expire)
935 message($lang_admin_users['Invalid date message'].' '.$lang_admin_users['Invalid date reasons']);
936-
937+
938 $diff = ($pun_user['timezone'] + $pun_user['dst']) * 3600;
939 $ban_expire -= $diff;
940-
941+
942 if ($ban_expire <= time())
943 message($lang_admin_users['Invalid date message'].' '.$lang_admin_users['Invalid date reasons']);
944 }
945 else
946 $ban_expire = 'NULL';
947-
948+
949 $ban_message = ($ban_message != '') ? '\''.$db->escape($ban_message).'\'' : 'NULL';
950-
951+
952 // Fetch user information
953 $user_info = array();
954 $result = $db->query('SELECT id, username, email, registration_ip FROM '.$db->prefix.'users WHERE id IN ('.implode(',', $user_ids).')') or error('Unable to fetch user info', __FILE__, __LINE__, $db->error());
955 while ($cur_user = $db->fetch_assoc($result))
956 $user_info[$cur_user['id']] = array('username' => $cur_user['username'], 'email' => $cur_user['email'], 'ip' => $cur_user['registration_ip']);
957-
958+
959 // Overwrite the registration IP with one from the last post (if it exists)
960 if ($ban_the_ip != 0)
961 {
962@@ -591,23 +597,23 @@
963 while ($cur_address = $db->fetch_assoc($result))
964 $user_info[$cur_address['poster_id']]['ip'] = $cur_address['poster_ip'];
965 }
966-
967+
968 // And insert the bans!
969 foreach ($user_ids as $user_id)
970 {
971 $ban_username = '\''.$db->escape($user_info[$user_id]['username']).'\'';
972 $ban_email = '\''.$db->escape($user_info[$user_id]['email']).'\'';
973 $ban_ip = ($ban_the_ip != 0) ? '\''.$db->escape($user_info[$user_id]['ip']).'\'' : 'NULL';
974-
975+
976 $db->query('INSERT INTO '.$db->prefix.'bans (username, ip, email, message, expire, ban_creator) VALUES('.$ban_username.', '.$ban_ip.', '.$ban_email.', '.$ban_message.', '.$ban_expire.', '.$pun_user['id'].')') or error('Unable to add ban', __FILE__, __LINE__, $db->error());
977 }
978-
979+
980 // Regenerate the bans cache
981 if (!defined('FORUM_CACHE_FUNCTIONS_LOADED'))
982 require PUN_ROOT.'include/cache.php';
983-
984+
985 generate_bans_cache();
986-
987+
988 redirect('admin_users.php', $lang_admin_users['Users banned redirect']);
989 }
990
991@@ -678,9 +684,11 @@
992 $posts_less = isset($_GET['posts_less']) ? trim($_GET['posts_less']) : '';
993 $last_post_after = isset($_GET['last_post_after']) ? trim($_GET['last_post_after']) : '';
994 $last_post_before = isset($_GET['last_post_before']) ? trim($_GET['last_post_before']) : '';
995+ $last_visit_after = isset($_GET['last_visit_after']) ? trim($_GET['last_visit_after']) : '';
996+ $last_visit_before = isset($_GET['last_visit_before']) ? trim($_GET['last_visit_before']) : '';
997 $registered_after = isset($_GET['registered_after']) ? trim($_GET['registered_after']) : '';
998 $registered_before = isset($_GET['registered_before']) ? trim($_GET['registered_before']) : '';
999- $order_by = isset($_GET['order_by']) && in_array($_GET['order_by'], array('username', 'email', 'num_posts', 'last_post', 'registered')) ? $_GET['order_by'] : 'username';
1000+ $order_by = isset($_GET['order_by']) && in_array($_GET['order_by'], array('username', 'email', 'num_posts', 'last_post', 'last_visit', 'registered')) ? $_GET['order_by'] : 'username';
1001 $direction = isset($_GET['direction']) && $_GET['direction'] == 'DESC' ? 'DESC' : 'ASC';
1002 $user_group = isset($_GET['user_group']) ? intval($_GET['user_group']) : -1;
1003
1004@@ -688,7 +696,7 @@
1005 $query_str[] = 'direction='.$direction;
1006 $query_str[] = 'user_group='.$user_group;
1007
1008- if (preg_match('/[^0-9]/', $posts_greater.$posts_less))
1009+ if (preg_match('%[^0-9]%', $posts_greater.$posts_less))
1010 message($lang_admin_users['Non numeric message']);
1011
1012 // Try to convert date/time to timestamps
1013@@ -712,6 +720,26 @@
1014
1015 $conditions[] = 'u.last_post<'.$last_post_before;
1016 }
1017+ if ($last_visit_after != '')
1018+ {
1019+ $query_str[] = 'last_visit_after='.$last_visit_after;
1020+
1021+ $last_visit_after = strtotime($last_visit_after);
1022+ if ($last_visit_after === false || $last_visit_after == -1)
1023+ message($lang_admin_users['Invalid date time message']);
1024+
1025+ $conditions[] = 'u.last_visit>'.$last_visit_after;
1026+ }
1027+ if ($last_visit_before != '')
1028+ {
1029+ $query_str[] = 'last_visit_before='.$last_visit_before;
1030+
1031+ $last_visit_before = strtotime($last_visit_before);
1032+ if ($last_visit_before === false || $last_visit_before == -1)
1033+ message($lang_admin_users['Invalid date time message']);
1034+
1035+ $conditions[] = 'u.last_visit<'.$last_visit_before;
1036+ }
1037 if ($registered_after != '')
1038 {
1039 $query_str[] = 'registered_after='.$registered_after;
1040@@ -769,7 +797,7 @@
1041
1042 // Generate paging links
1043 $paging_links = '<span class="pages-label">'.$lang_common['Pages'].' </span>'.paginate($num_pages, $p, 'admin_users.php?find_user=&amp;'.implode('&amp;', $query_str));
1044-
1045+
1046 // Some helper variables for permissions
1047 $can_delete = $can_move = $pun_user['g_id'] == PUN_ADMIN;
1048 $can_ban = $pun_user['g_id'] == PUN_ADMIN || ($pun_user['g_moderator'] == '1' && $pun_user['g_mod_ban_users'] == '1');
1049@@ -839,7 +867,7 @@
1050 <td class="tc5"><?php echo ($user_data['admin_note'] != '') ? pun_htmlspecialchars($user_data['admin_note']) : '&#160;' ?></td>
1051 <td class="tcr"><?php echo $actions ?></td>
1052 <?php if ($can_action): ?> <td class="tcmod"><input type="checkbox" name="users[<?php echo $user_data['id'] ?>]" value="1" /></td>
1053-<?php endif; ?>
1054+<?php endif; ?>
1055 </tr>
1056 <?php
1057
1058@@ -969,6 +997,16 @@
1059 <span><?php echo $lang_admin_users['Date help'] ?></span></td>
1060 </tr>
1061 <tr>
1062+ <th scope="row"><?php echo $lang_admin_users['Last visit after label'] ?></th>
1063+ <td><input type="text" name="last_visit_after" size="24" maxlength="19" tabindex="17" />
1064+ <span><?php echo $lang_admin_users['Date help'] ?></span></td>
1065+ </tr>
1066+ <tr>
1067+ <th scope="row"><?php echo $lang_admin_users['Last visit before label'] ?></th>
1068+ <td><input type="text" name="last_visit_before" size="24" maxlength="19" tabindex="18" />
1069+ <span><?php echo $lang_admin_users['Date help'] ?></span></td>
1070+ </tr>
1071+ <tr>
1072 <th scope="row"><?php echo $lang_admin_users['Registered after label'] ?></th>
1073 <td><input type="text" name="registered_after" size="24" maxlength="19" tabindex="19" />
1074 <span><?php echo $lang_admin_users['Date help'] ?></span></td>
1075@@ -986,6 +1024,7 @@
1076 <option value="email"><?php echo $lang_admin_users['Order by e-mail'] ?></option>
1077 <option value="num_posts"><?php echo $lang_admin_users['Order by posts'] ?></option>
1078 <option value="last_post"><?php echo $lang_admin_users['Order by last post'] ?></option>
1079+ <option value="last_visit"><?php echo $lang_admin_users['Order by last visit'] ?></option>
1080 <option value="registered"><?php echo $lang_admin_users['Order by registered'] ?></option>
1081 </select>&#160;&#160;&#160;<select name="direction" tabindex="22">
1082 <option value="ASC" selected="selected"><?php echo $lang_admin_users['Ascending'] ?></option>
1083
1084=== modified file 'common.js'
1085--- common.js 2011-04-19 22:53:21 +0000
1086+++ common.js 2012-02-27 14:24:17 +0000
1087@@ -1,4 +1,10 @@
1088
1089+/**
1090+ * Copyright (C) 2008-2012 FluxBB
1091+ * based on code by Rickard Andersson copyright (C) 2002-2008 PunBB
1092+ * License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher
1093+ */
1094+
1095 function select_checkboxes(curFormId, link, new_string)
1096 {
1097 var curForm = document.getElementById(curFormId);
1098@@ -29,4 +35,4 @@
1099 link.innerHTML = new_string;
1100
1101 return false;
1102-}
1103\ No newline at end of file
1104+}
1105
1106=== modified file 'config.php.exemple'
1107--- config.php.exemple 2011-04-21 10:38:20 +0000
1108+++ config.php.exemple 2012-02-27 14:24:17 +0000
1109@@ -18,4 +18,8 @@
1110 // définition de la constante du static. URL complète, avec un / à la fin
1111 define('UFR_STATIC', 'chemin/vers/le/dossier/static/');
1112 // si le serveur est derrière un behind proxy
1113-define('FORUM_BEHIND_REVERSE_PROXY', true);
1114\ No newline at end of file
1115+define('FORUM_BEHIND_REVERSE_PROXY', true);
1116+// pour éviter l'indexation par Google
1117+define('IS_DEV', 1);
1118+// pour activer le traçage des stats
1119+define ('PIWIK', 1);
1120\ No newline at end of file
1121
1122=== modified file 'db_update.php'
1123--- db_update.php 2011-04-19 22:53:21 +0000
1124+++ db_update.php 2012-02-27 14:24:17 +0000
1125@@ -1,15 +1,15 @@
1126 <?php
1127
1128 /**
1129- * Copyright (C) 2008-2011 FluxBB
1130+ * Copyright (C) 2008-2012 FluxBB
1131 * based on code by Rickard Andersson copyright (C) 2002-2008 PunBB
1132 * License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher
1133 */
1134
1135 // The FluxBB version this script updates to
1136-define('UPDATE_TO', '1.4.5');
1137+define('UPDATE_TO', '1.4.8');
1138
1139-define('UPDATE_TO_DB_REVISION', 11);
1140+define('UPDATE_TO_DB_REVISION', 15);
1141 define('UPDATE_TO_SI_REVISION', 2);
1142 define('UPDATE_TO_PARSER_REVISION', 2);
1143
1144@@ -129,6 +129,7 @@
1145 if (!file_exists(PUN_ROOT.'lang/'.$default_lang.'/update.php'))
1146 $default_lang = 'English';
1147
1148+require PUN_ROOT.'lang/'.$default_lang.'/common.php';
1149 require PUN_ROOT.'lang/'.$default_lang.'/update.php';
1150
1151 // Check current version
1152@@ -277,8 +278,8 @@
1153 $str = html_entity_decode($str, ENT_QUOTES, 'UTF-8');
1154
1155 // Replace numeric entities
1156- $str = preg_replace_callback('/&#([0-9]+);/', 'utf8_callback_1', $str);
1157- $str = preg_replace_callback('/&#x([a-f0-9]+);/i', 'utf8_callback_2', $str);
1158+ $str = preg_replace_callback('%&#([0-9]+);%', 'utf8_callback_1', $str);
1159+ $str = preg_replace_callback('%&#x([a-f0-9]+);%i', 'utf8_callback_2', $str);
1160
1161 // Remove "bad" characters
1162 $str = remove_bad_characters($str);
1163@@ -339,7 +340,7 @@
1164 $allow_null = ($cur_column['Null'] == 'YES');
1165 $collate = (substr($cur_column['Collation'], -3) == 'bin') ? 'utf8_bin' : 'utf8_general_ci';
1166
1167- $db->alter_field($table, $cur_column['Field'], preg_replace('/'.$type.'/i', $types[$type], $cur_column['Type']), $allow_null, $cur_column['Default'], null, true) or error('Unable to alter field to binary', __FILE__, __LINE__, $db->error());
1168+ $db->alter_field($table, $cur_column['Field'], preg_replace('%'.$type.'%i', $types[$type], $cur_column['Type']), $allow_null, $cur_column['Default'], null, true) or error('Unable to alter field to binary', __FILE__, __LINE__, $db->error());
1169 $db->alter_field($table, $cur_column['Field'], $cur_column['Type'].' CHARACTER SET utf8 COLLATE '.$collate, $allow_null, $cur_column['Default'], null, true) or error('Unable to alter field to utf8', __FILE__, __LINE__, $db->error());
1170 }
1171 }
1172@@ -459,17 +460,59 @@
1173 // Show form
1174 if (empty($stage))
1175 {
1176+ if (file_exists(FORUM_CACHE_DIR.'db_update.lock'))
1177+ {
1178+ // Deal with newlines, tabs and multiple spaces
1179+ $pattern = array("\t", ' ', ' ');
1180+ $replace = array('&#160; &#160; ', '&#160; ', ' &#160;');
1181+ $message = str_replace($pattern, $replace, $pun_config['o_maintenance_message']);
1182+
1183+?>
1184+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="<?php echo $lang_common['lang_identifier'] ?>" lang="<?php echo $lang_common['lang_identifier'] ?>" dir="<?php echo $lang_common['lang_direction'] ?>">
1185+<head>
1186+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
1187+<title><?php echo $lang_update['Maintenance'] ?></title>
1188+<link rel="stylesheet" type="text/css" href="style/<?php echo $default_style ?>.css" />
1189+</head>
1190+<body>
1191+
1192+<div id="punmaint" class="pun">
1193+<div class="top-box"><div><!-- Top Corners --></div></div>
1194+<div class="punwrap">
1195+
1196+<div id="brdmain">
1197+<div class="block">
1198+ <h2><?php echo $lang_update['Maintenance'] ?></h2>
1199+ <div class="box">
1200+ <div class="inbox">
1201+ <p><?php echo $message ?></p>
1202+ </div>
1203+ </div>
1204+</div>
1205+</div>
1206+
1207+</div>
1208+<div class="end-box"><div><!-- Bottom Corners --></div></div>
1209+</div>
1210+
1211+</body>
1212+</html>
1213+<?php
1214+
1215+ }
1216+ else
1217+ {
1218
1219 ?>
1220 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
1221
1222-<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en" dir="ltr">
1223+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="<?php echo $lang_common['lang_identifier'] ?>" lang="<?php echo $lang_common['lang_identifier'] ?>" dir="<?php echo $lang_common['lang_direction'] ?>">
1224 <head>
1225 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
1226 <title><?php echo $lang_update['Update'] ?></title>
1227 <link rel="stylesheet" type="text/css" href="style/<?php echo $default_style ?>.css" />
1228 </head>
1229-<body onload="document.getElementById('install').req_db_type.focus();document.getElementById('install').start.disabled=false;">
1230+<body onload="document.getElementById('install').req_db_pass.focus();document.getElementById('install').start.disabled=false;">
1231
1232 <div id="pundb_update" class="pun">
1233 <div class="top-box"><div><!-- Top Corners --></div></div>
1234@@ -488,7 +531,7 @@
1235 <div class="blockform">
1236 <h2><span><?php echo $lang_update['Update'] ?></span></h2>
1237 <div class="box">
1238- <form method="post" action="db_update.php">
1239+ <form id="install" method="post" action="db_update.php">
1240 <input type="hidden" name="stage" value="start" />
1241 <div class="inform">
1242 <fieldset>
1243@@ -497,6 +540,11 @@
1244 <p><?php echo $lang_update['Database password info'] ?></p>
1245 <p><strong><?php echo $lang_update['Note']; ?></strong> <?php echo $lang_update['Database password note'] ?></p>
1246 <label class="required"><strong><?php echo $lang_update['Database password'] ?> <span><?php echo $lang_update['Required'] ?></span></strong><br /><input type="password" id="req_db_pass" name="req_db_pass" /><br /></label>
1247+ <p><?php echo $lang_update['Maintenance message info'] ?></p>
1248+ <div class="txtarea">
1249+ <label class="required"><strong><?php echo $lang_update['Maintenance message'] ?> <span><?php echo $lang_update['Required'] ?></span></strong><br />
1250+ <textarea name="req_maintenance_message" rows="4" cols="65"><?php echo pun_htmlspecialchars($pun_config['o_maintenance_message']) ?></textarea><br /></label>
1251+ </div>
1252 </div>
1253 </fieldset>
1254 </div>
1255@@ -559,6 +607,7 @@
1256 </html>
1257 <?php
1258
1259+ }
1260 $db->end_transaction();
1261 $db->close();
1262 exit;
1263@@ -602,6 +651,25 @@
1264
1265 fwrite($fh, $uid);
1266 fclose($fh);
1267+
1268+ // Update maintenance message
1269+ if ($_POST['req_maintenance_message'] != '')
1270+ $maintenance_message = pun_trim(pun_linebreaks($_POST['req_maintenance_message']));
1271+ else
1272+ {
1273+ // Load the admin_options.php language file
1274+ require PUN_ROOT.'lang/'.$default_lang.'/admin_options.php';
1275+
1276+ $maintenance_message = $lang_admin_options['Default maintenance message'];
1277+ }
1278+
1279+ $db->query('UPDATE '.$db->prefix.'config SET conf_value=\''.$db->escape($maintenance_message).'\' WHERE conf_name=\'o_maintenance_message\'') or error('Unable to update board config', __FILE__, __LINE__, $db->error());
1280+
1281+ // Regenerate the config cache
1282+ if (!defined('FORUM_CACHE_FUNCTIONS_LOADED'))
1283+ require PUN_ROOT.'include/cache.php';
1284+
1285+ generate_config_cache();
1286 }
1287 }
1288 else if (isset($_GET['uid']))
1289@@ -719,7 +787,7 @@
1290 {
1291 // Make an educated guess regarding base_url
1292 $base_url = (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on') ? 'https://' : 'http://'; // protocol
1293- $base_url .= preg_replace('/:(80|443)$/', '', $_SERVER['HTTP_HOST']); // host[:port]
1294+ $base_url .= preg_replace('%:(80|443)$%', '', $_SERVER['HTTP_HOST']); // host[:port]
1295 $base_url .= str_replace('\\', '/', dirname($_SERVER['SCRIPT_NAME'])); // path
1296 }
1297
1298@@ -753,7 +821,7 @@
1299 $mod_gid = $db->result($result);
1300 else
1301 {
1302- $db->query('INSERT INTO '.$db->prefix.'groups (g_title, g_user_title, g_moderator, g_mod_edit_users, g_mod_rename_users, g_mod_change_passwords, g_mod_ban_users, g_read_board, g_view_users, g_post_replies, g_post_topics, g_edit_posts, g_delete_posts, g_delete_topics, g_set_title, g_search, g_search_users, g_send_email, g_post_flood, g_search_flood, g_email_flood) VALUES('."'Moderators', 'Moderator', 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0)") or error('Unable to add group', __FILE__, __LINE__, $db->error());
1303+ $db->query('INSERT INTO '.$db->prefix.'groups (g_title, g_user_title, g_moderator, g_mod_edit_users, g_mod_rename_users, g_mod_change_passwords, g_mod_ban_users, g_read_board, g_view_users, g_post_replies, g_post_topics, g_edit_posts, g_delete_posts, g_delete_topics, g_set_title, g_search, g_search_users, g_send_email, g_post_flood, g_search_flood, g_email_flood, g_report_flood) VALUES('."'Moderators', 'Moderator', 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0)") or error('Unable to add group', __FILE__, __LINE__, $db->error());
1304 $mod_gid = $db->insert_id();
1305 }
1306
1307@@ -916,9 +984,14 @@
1308 $db->add_field('groups', 'g_send_email', 'TINYINT(1)', false, 1, 'g_search_users') or error('Unable to add g_send_email field', __FILE__, __LINE__, $db->error());
1309 $db->add_field('groups', 'g_email_flood', 'SMALLINT(6)', false, 60, 'g_search_flood') or error('Unable to add g_email_flood field', __FILE__, __LINE__, $db->error());
1310
1311- // Set non-default g_send_email and g_flood_email values properly
1312+ // Add the last_report_sent column to the users table and the g_report_flood
1313+ // column to the groups table
1314+ $db->add_field('users', 'last_report_sent', 'INT(10) UNSIGNED', true, null, 'last_email_sent') or error('Unable to add last_report_sent field', __FILE__, __LINE__, $db->error());
1315+ $db->add_field('groups', 'g_report_flood', 'SMALLINT(6)', false, 60, 'g_email_flood') or error('Unable to add g_report_flood field', __FILE__, __LINE__, $db->error());
1316+
1317+ // Set non-default g_send_email, g_flood_email and g_flood_report values properly
1318 $db->query('UPDATE '.$db->prefix.'groups SET g_send_email = 0 WHERE g_id = 3') or error('Unable to update group email permissions', __FILE__, __LINE__, $db->error());
1319- $db->query('UPDATE '.$db->prefix.'groups SET g_email_flood = 0 WHERE g_id IN (1,2,3)') or error('Unable to update group email permissions', __FILE__, __LINE__, $db->error());
1320+ $db->query('UPDATE '.$db->prefix.'groups SET g_email_flood = 0, g_report_flood = 0 WHERE g_id IN (1,2,3)') or error('Unable to update group email permissions', __FILE__, __LINE__, $db->error());
1321
1322 // Add the auto notify/subscription option to the users table
1323 $db->add_field('users', 'auto_notify', 'TINYINT(1)', false, 0, 'notify_with_post') or error('Unable to add auto_notify field', __FILE__, __LINE__, $db->error());
1324@@ -1086,6 +1159,10 @@
1325 if ($pun_config['o_default_style'] != $default_style)
1326 $db->query('UPDATE '.$db->prefix.'config SET conf_value = \''.$db->escape($default_style).'\' WHERE conf_name = \'o_default_style\'') or error('Unable to update default style config', __FILE__, __LINE__, $db->error());
1327
1328+ // For MySQL(i) without InnoDB, change the engine of the online table (for performance reasons)
1329+ if ($db_type == 'mysql' || $db_type == 'mysqli')
1330+ $db->query('ALTER TABLE '.$db->prefix.'online ENGINE = MyISAM') or error('Unable to change engine type of online table to MyISAM', __FILE__, __LINE__, $db->error());
1331+
1332 // Should we do charset conversion or not?
1333 if (strpos($cur_version, '1.2') === 0 && isset($_POST['convert_charset']))
1334 $query_str = '?stage=conv_bans&req_old_charset='.$old_charset;
1335@@ -1458,14 +1535,14 @@
1336 $errors[$id][] = $lang_update['Username too long error'];
1337 else if (!strcasecmp($username, 'Guest'))
1338 $errors[$id][] = $lang_update['Username Guest reserved error'];
1339- else if (preg_match('/[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}/', $username) || preg_match('/((([0-9A-Fa-f]{1,4}:){7}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){6}:[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){5}:([0-9A-Fa-f]{1,4}:)?[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){4}:([0-9A-Fa-f]{1,4}:){0,2}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){3}:([0-9A-Fa-f]{1,4}:){0,3}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){2}:([0-9A-Fa-f]{1,4}:){0,4}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){6}((\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b)\.){3}(\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b))|(([0-9A-Fa-f]{1,4}:){0,5}:((\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b)\.){3}(\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b))|(::([0-9A-Fa-f]{1,4}:){0,5}((\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b)\.){3}(\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b))|([0-9A-Fa-f]{1,4}::([0-9A-Fa-f]{1,4}:){0,5}[0-9A-Fa-f]{1,4})|(::([0-9A-Fa-f]{1,4}:){0,6}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){1,7}:))/', $username))
1340+ else if (preg_match('%[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}%', $username) || preg_match('%((([0-9A-Fa-f]{1,4}:){7}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){6}:[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){5}:([0-9A-Fa-f]{1,4}:)?[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){4}:([0-9A-Fa-f]{1,4}:){0,2}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){3}:([0-9A-Fa-f]{1,4}:){0,3}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){2}:([0-9A-Fa-f]{1,4}:){0,4}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){6}((\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b)\.){3}(\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b))|(([0-9A-Fa-f]{1,4}:){0,5}:((\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b)\.){3}(\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b))|(::([0-9A-Fa-f]{1,4}:){0,5}((\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b)\.){3}(\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b))|([0-9A-Fa-f]{1,4}::([0-9A-Fa-f]{1,4}:){0,5}[0-9A-Fa-f]{1,4})|(::([0-9A-Fa-f]{1,4}:){0,6}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){1,7}:))%', $username))
1341 $errors[$id][] = $lang_update['Username IP format error'];
1342 else if ((strpos($username, '[') !== false || strpos($username, ']') !== false) && strpos($username, '\'') !== false && strpos($username, '"') !== false)
1343 $errors[$id][] = $lang_update['Username bad characters error'];
1344- else if (preg_match('/(?:\[\/?(?:b|u|s|ins|del|em|i|h|colou?r|quote|code|img|url|email|list|\*)\]|\[(?:img|url|quote|list)=)/i', $username))
1345+ else if (preg_match('%(?:\[/?(?:b|u|s|ins|del|em|i|h|colou?r|quote|code|img|url|email|list|\*)\]|\[(?:img|url|quote|list)=)%i', $username))
1346 $errors[$id][] = $lang_update['Username BBCode error'];
1347
1348- $result = $db->query('SELECT username FROM '.$db->prefix.'users WHERE (UPPER(username)=UPPER(\''.$db->escape($username).'\') OR UPPER(username)=UPPER(\''.$db->escape(ucp_preg_replace('/[^\p{L}\p{N}]/u', '', $username)).'\')) AND id>1') or error('Unable to fetch user info', __FILE__, __LINE__, $db->error());
1349+ $result = $db->query('SELECT username FROM '.$db->prefix.'users WHERE (UPPER(username)=UPPER(\''.$db->escape($username).'\') OR UPPER(username)=UPPER(\''.$db->escape(ucp_preg_replace('%[^\p{L}\p{N}]%u', '', $username)).'\')) AND id>1') or error('Unable to fetch user info', __FILE__, __LINE__, $db->error());
1350
1351 if ($db->num_rows($result))
1352 {
1353@@ -1535,7 +1612,7 @@
1354 $mail_message = str_replace('<base_url>', get_base_url().'/', $mail_message);
1355 $mail_message = str_replace('<old_username>', $old_username, $mail_message);
1356 $mail_message = str_replace('<new_username>', $username, $mail_message);
1357- $mail_message = str_replace('<board_mailer>', $pun_config['o_board_title'].' Mailer', $mail_message);
1358+ $mail_message = str_replace('<board_mailer>', $pun_config['o_board_title'], $mail_message);
1359
1360 pun_mail($cur_user['email'], $mail_subject, $mail_message);
1361
1362@@ -1551,7 +1628,7 @@
1363 ?>
1364 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
1365
1366-<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en" dir="ltr">
1367+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="<?php echo $lang_common['lang_identifier'] ?>" lang="<?php echo $lang_common['lang_identifier'] ?>" dir="<?php echo $lang_common['lang_direction'] ?>">
1368 <head>
1369 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
1370 <title><?php echo $lang_update['Update'] ?></title>
1371@@ -1788,7 +1865,7 @@
1372 ?>
1373 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
1374
1375-<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en" dir="ltr">
1376+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="<?php echo $lang_common['lang_identifier'] ?>" lang="<?php echo $lang_common['lang_identifier'] ?>" dir="<?php echo $lang_common['lang_direction'] ?>">
1377 <head>
1378 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
1379 <title><?php echo $lang_update['Update'] ?></title>
1380@@ -1828,4 +1905,4 @@
1381 $db->close();
1382
1383 if ($query_str != '')
1384- exit('<script type="text/javascript">window.location="db_update.php'.$query_str.'&uid='.$uid.'"</script><noscript>'.sprintf($lang_update['JavaScript disabled'], sprintf('<a href="db_update.php'.$query_str.'&uid='.$uid.'">%s</a>', $lang_update['Click here to continue'])).'</noscript>');
1385+ exit('<script type="text/javascript">window.location="db_update.php'.$query_str.'&uid='.$uid.'"</script><noscript><meta http-equiv="refresh" content="0;url=db_update.php'.$query_str.'&uid='.$uid.'" /></noscript>');
1386
1387=== modified file 'delete.php'
1388--- delete.php 2011-04-19 22:53:21 +0000
1389+++ delete.php 2012-02-27 14:24:17 +0000
1390@@ -1,7 +1,7 @@
1391 <?php
1392
1393 /**
1394- * Copyright (C) 2008-2011 FluxBB
1395+ * Copyright (C) 2008-2012 FluxBB
1396 * based on code by Rickard Andersson copyright (C) 2002-2008 PunBB
1397 * License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher
1398 */
1399
1400=== modified file 'edit.php'
1401--- edit.php 2011-05-07 20:23:43 +0000
1402+++ edit.php 2012-02-27 14:24:17 +0000
1403@@ -1,7 +1,7 @@
1404 <?php
1405
1406 /**
1407- * Copyright (C) 2008-2011 FluxBB
1408+ * Copyright (C) 2008-2012 FluxBB
1409 * based on code by Rickard Andersson copyright (C) 2002-2008 PunBB
1410 * License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher
1411 */
1412@@ -108,6 +108,9 @@
1413 $stick_topic = isset($_POST['stick_topic']) ? '1' : '0';
1414 if (!$is_admmod)
1415 $stick_topic = $cur_post['sticky'];
1416+
1417+ // Replace four-byte characters (MySQL cannot handle them)
1418+ $message = strip_bad_multibyte_chars($message);
1419
1420 // Did everything go according to plan?
1421 if (empty($errors) && !isset($_POST['preview']))
1422
1423=== modified file 'extern.php'
1424--- extern.php 2011-04-19 22:53:21 +0000
1425+++ extern.php 2012-02-27 14:24:17 +0000
1426@@ -1,7 +1,7 @@
1427 <?php
1428
1429 /**
1430- * Copyright (C) 2008-2011 FluxBB
1431+ * Copyright (C) 2008-2012 FluxBB
1432 * based on code by Rickard Andersson copyright (C) 2002-2008 PunBB
1433 * License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher
1434 */
1435
1436=== modified file 'footer.php'
1437--- footer.php 2011-04-19 22:53:21 +0000
1438+++ footer.php 2012-02-27 14:24:17 +0000
1439@@ -1,7 +1,7 @@
1440 <?php
1441
1442 /**
1443- * Copyright (C) 2008-2011 FluxBB
1444+ * Copyright (C) 2008-2012 FluxBB
1445 * based on code by Rickard Andersson copyright (C) 2002-2008 PunBB
1446 * License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher
1447 */
1448@@ -122,6 +122,7 @@
1449 </div>
1450 <?php
1451
1452+
1453 // Display debug info (if enabled/defined)
1454 if (defined('PUN_DEBUG'))
1455 {
1456
1457=== modified file 'header.php'
1458--- header.php 2011-06-06 13:48:17 +0000
1459+++ header.php 2012-02-27 14:24:17 +0000
1460@@ -1,7 +1,7 @@
1461 <?php
1462
1463 /**
1464- * Copyright (C) 2008-2011 FluxBB
1465+ * Copyright (C) 2008-2012 FluxBB
1466 * based on code by Rickard Andersson copyright (C) 2002-2008 PunBB
1467 * License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher
1468 */
1469@@ -54,7 +54,7 @@
1470 $tpl_main = file_get_contents($tpl_file);
1471
1472 // START SUBST - <pun_include "*">
1473-preg_match_all('#<pun_include "([^/\\\\]*?)\.(php[45]?|inc|html?|txt)">#', $tpl_main, $pun_includes, PREG_SET_ORDER);
1474+preg_match_all('%<pun_include "([^/\\\\]*?)\.(php[45]?|inc|html?|txt)">%i', $tpl_main, $pun_includes, PREG_SET_ORDER);
1475
1476 foreach ($pun_includes as $cur_include)
1477 {
1478@@ -144,7 +144,7 @@
1479 endif;
1480
1481 // BEGIN ADD AlternativeSites
1482-if (!$is_ubuntu)
1483+if (!$is_ubuntu || defined('IS_DEV'))
1484 echo '<meta name="GOOGLEBOT" content="NOINDEX, NOFOLLOW" />'."\n";
1485 // END ADD AlternativeSites
1486
1487@@ -197,7 +197,7 @@
1488 /* <![CDATA[ */
1489 function process_form(the_form)
1490 {
1491- var element_names = {
1492+ var required_fields = {
1493 <?php
1494 // Output a JavaScript object with localised field names
1495 $tpl_temp = count($required_fields);
1496@@ -213,14 +213,11 @@
1497 for (var i = 0; i < the_form.length; ++i)
1498 {
1499 var elem = the_form.elements[i];
1500- if (elem.name && (/^req_/.test(elem.name)))
1501+ if (elem.name && required_fields[elem.name] && !elem.value && elem.type && (/^(?:text(?:area)?|password|file)$/i.test(elem.type)))
1502 {
1503- if (!elem.value && elem.type && (/^(?:text(?:area)?|password|file)$/i.test(elem.type)))
1504- {
1505- alert('"' + element_names[elem.name] + '" <?php echo $lang_common['required field'] ?>');
1506- elem.focus();
1507- return false;
1508- }
1509+ alert('"' + required_fields[elem.name] + '" <?php echo $lang_common['required field'] ?>');
1510+ elem.focus();
1511+ return false;
1512 }
1513 }
1514 }
1515@@ -235,12 +232,8 @@
1516 // JavaScript tricks for IE6 and older
1517 echo '<!--[if lte IE 6]><script type="text/javascript" src="style/imports/minmax.js"></script><![endif]-->'."\n";
1518
1519-if (!isset($page_head))
1520- $page_head = array();
1521-
1522-$page_head['top'] = '<link rel="top" href="index.php" title="'.$lang_common['Forum index'].'" />';
1523-
1524-echo implode("\n", $page_head)."\n";
1525+if (isset($page_head))
1526+ echo implode("\n", $page_head)."\n";
1527
1528 $tpl_temp = trim(ob_get_contents());
1529 $tpl_main = str_replace('<pun_head>', $tpl_temp, $tpl_main);
1530@@ -311,7 +304,7 @@
1531 // Are there any additional navlinks we should insert into the array before imploding it?
1532 if ($pun_user['g_read_board'] == '1' && $pun_config['o_additional_navlinks'] != '')
1533 {
1534- if (preg_match_all('#([0-9]+)\s*=\s*(.*?)\n#s', $pun_config['o_additional_navlinks']."\n", $extra_links))
1535+ if (preg_match_all('%([0-9]+)\s*=\s*(.*?)\n%s', $pun_config['o_additional_navlinks']."\n", $extra_links))
1536 {
1537 // Insert any additional links into the $links array (at the correct index)
1538 $num_links = count($extra_links[1]);
1539@@ -365,7 +358,7 @@
1540
1541
1542 // Generate all that jazz
1543-$tpl_temp = '<div id="brdwelcome" class="inbox">'."\n\t\t\t";
1544+$tpl_temp = '<div id="brdwelcome" class="inbox">';
1545
1546 // The status information
1547 if (is_array($page_statusinfo))
1548@@ -382,10 +375,10 @@
1549 //{
1550 // $tpl_temp .= "\n\t\t\t".'<ul class="conr">';
1551 // $tpl_temp .= "\n\t\t\t\t".'<li><span>'.$lang_common['Topic searches'].' '.implode(' | ', $page_topicsearches).'</span></li>';
1552-// $tpl_temp .= "\n\t\t\t".'</ul>'."\n\t\t\t".'<div class="clearer"></div>';
1553+// $tpl_temp .= "\n\t\t\t".'</ul>';
1554 //}
1555
1556-$tpl_temp .= "\n\t\t".'</div>';
1557+$tpl_temp .= "\n\t\t\t".'<div class="clearer"></div>'."\n\t\t".'</div>';
1558
1559 $tpl_main = str_replace('<pun_status>', $tpl_temp, $tpl_main);
1560 // END SUBST - <pun_status>
1561
1562=== modified file 'help.php'
1563--- help.php 2011-04-19 22:53:21 +0000
1564+++ help.php 2012-02-27 14:24:17 +0000
1565@@ -1,7 +1,7 @@
1566 <?php
1567
1568 /**
1569- * Copyright (C) 2008-2011 FluxBB
1570+ * Copyright (C) 2008-2012 FluxBB
1571 * based on code by Rickard Andersson copyright (C) 2002-2008 PunBB
1572 * License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher
1573 */
1574@@ -55,12 +55,21 @@
1575 <p><?php echo $lang_help['Links info'] ?></p>
1576 <p><code>[url=<?php echo pun_htmlspecialchars(get_base_url(true).'/') ?>]<?php echo pun_htmlspecialchars($pun_config['o_board_title']) ?>[/url]</code> <?php echo $lang_help['produces'] ?> <samp><a href="<?php echo pun_htmlspecialchars(get_base_url(true).'/') ?>"><?php echo pun_htmlspecialchars($pun_config['o_board_title']) ?></a></samp></p>
1577 <p><code>[url]<?php echo pun_htmlspecialchars(get_base_url(true).'/') ?>[/url]</code> <?php echo $lang_help['produces'] ?> <samp><a href="<?php echo pun_htmlspecialchars(get_base_url(true).'/') ?>"><?php echo pun_htmlspecialchars(get_base_url(true).'/') ?></a></samp></p>
1578+ <p><code>[url=/help.php]<?php echo $lang_help['This help page'] ?>[/url]</code> <?php echo $lang_help['produces'] ?> <samp><a href="<?php echo pun_htmlspecialchars(get_base_url(true).'/help.php') ?>"><?php echo $lang_help['This help page'] ?></a></samp></p>
1579 <p><code>[email]myname@mydomain.com[/email]</code> <?php echo $lang_help['produces'] ?> <samp><a href="mailto:myname@mydomain.com">myname@mydomain.com</a></samp></p>
1580 <p><code>[email=myname@mydomain.com]<?php echo $lang_help['My email address'] ?>[/email]</code> <?php echo $lang_help['produces'] ?> <samp><a href="mailto:myname@mydomain.com"><?php echo $lang_help['My email address'] ?></a></samp></p>
1581+ <p><code>[topic=1]<?php echo $lang_help['Test topic'] ?>[/topic]</code> <?php echo $lang_help['produces'] ?> <samp><a href="<?php echo pun_htmlspecialchars(get_base_url(true).'/viewtopic.php?id=1') ?>"><?php echo $lang_help['Test topic'] ?></a></samp></p>
1582+ <p><code>[topic]1[/topic]</code> <?php echo $lang_help['produces'] ?> <samp><a href="<?php echo pun_htmlspecialchars(get_base_url(true).'/viewtopic.php?id=1') ?>"><?php echo pun_htmlspecialchars(get_base_url(true).'/viewtopic.php?id=1') ?></a></samp></p>
1583+ <p><code>[post=1]<?php echo $lang_help['Test post'] ?>[/post]</code> <?php echo $lang_help['produces'] ?> <samp><a href="<?php echo pun_htmlspecialchars(get_base_url(true).'/viewtopic.php?pid=1#p1') ?>"><?php echo $lang_help['Test post'] ?></a></samp></p>
1584+ <p><code>[post]1[/post]</code> <?php echo $lang_help['produces'] ?> <samp><a href="<?php echo pun_htmlspecialchars(get_base_url(true).'/viewtopic.php?pid=1#p1') ?>"><?php echo pun_htmlspecialchars(get_base_url(true).'/viewtopic.php?pid=1#p1') ?></a></samp></p>
1585+ <p><code>[forum=1]<?php echo $lang_help['Test forum'] ?>[/forum]</code> <?php echo $lang_help['produces'] ?> <samp><a href="<?php echo pun_htmlspecialchars(get_base_url(true).'/viewforum.php?id=1') ?>"><?php echo $lang_help['Test forum'] ?></a></samp></p>
1586+ <p><code>[forum]1[/forum]</code> <?php echo $lang_help['produces'] ?> <samp><a href="<?php echo pun_htmlspecialchars(get_base_url(true).'/viewforum.php?id=1') ?>"><?php echo pun_htmlspecialchars(get_base_url(true).'/viewforum.php?id=1') ?></a></samp></p>
1587+ <p><code>[user=2]<?php echo $lang_help['Test user'] ?>[/user]</code> <?php echo $lang_help['produces'] ?> <samp><a href="<?php echo pun_htmlspecialchars(get_base_url(true).'/profile.php?id=2') ?>"><?php echo $lang_help['Test user'] ?></a></samp></p>
1588+ <p><code>[user]2[/user]</code> <?php echo $lang_help['produces'] ?> <samp><a href="<?php echo pun_htmlspecialchars(get_base_url(true).'/profile.php?id=2') ?>"><?php echo pun_htmlspecialchars(get_base_url(true).'/profile.php?id=2') ?></a></samp></p>
1589 </div>
1590 <div class="inbox">
1591 <p><a name="img"></a><?php echo $lang_help['Images info'] ?></p>
1592- <p><code>[img=<?php echo $lang_help['FluxBB bbcode test'] ?>]<?php echo pun_htmlspecialchars(get_base_url(true)) ?>/img/test.png[/img]</code> <?php echo $lang_help['produces'] ?> <samp><img src="<?php echo pun_htmlspecialchars(get_base_url(true)) ?>/img/test.png" alt="<?php echo $lang_help['FluxBB bbcode test'] ?>" /></samp></p>
1593+ <p><code>[img=<?php echo $lang_help['FluxBB bbcode test'] ?>]<?php echo pun_htmlspecialchars(get_base_url(true)) ?>/img/test.png[/img]</code> <?php echo $lang_help['produces'] ?> <samp><img style="height: 21px" src="<?php echo pun_htmlspecialchars(get_base_url(true)) ?>/img/test.png" alt="<?php echo $lang_help['FluxBB bbcode test'] ?>" /></samp></p>
1594 </div>
1595 </div>
1596 <h2><span><?php echo $lang_help['Quotes'] ?></span></h2>
1597
1598=== modified file 'img/smilies/big_smile.png'
1599Binary files img/smilies/big_smile.png 2008-07-12 15:11:09 +0000 and img/smilies/big_smile.png 2012-02-27 14:24:17 +0000 differ
1600=== modified file 'img/smilies/cool.png'
1601Binary files img/smilies/cool.png 2008-07-12 15:11:09 +0000 and img/smilies/cool.png 2012-02-27 14:24:17 +0000 differ
1602=== modified file 'img/smilies/hmm.png'
1603Binary files img/smilies/hmm.png 2008-07-12 15:11:09 +0000 and img/smilies/hmm.png 2012-02-27 14:24:17 +0000 differ
1604=== modified file 'img/smilies/lol.png'
1605Binary files img/smilies/lol.png 2008-07-12 15:11:09 +0000 and img/smilies/lol.png 2012-02-27 14:24:17 +0000 differ
1606=== modified file 'img/smilies/mad.png'
1607Binary files img/smilies/mad.png 2008-07-12 15:11:09 +0000 and img/smilies/mad.png 2012-02-27 14:24:17 +0000 differ
1608=== modified file 'img/smilies/neutral.png'
1609Binary files img/smilies/neutral.png 2008-07-12 15:11:09 +0000 and img/smilies/neutral.png 2012-02-27 14:24:17 +0000 differ
1610=== modified file 'img/smilies/roll.png'
1611Binary files img/smilies/roll.png 2008-07-12 15:11:09 +0000 and img/smilies/roll.png 2012-02-27 14:24:17 +0000 differ
1612=== modified file 'img/smilies/sad.png'
1613Binary files img/smilies/sad.png 2008-07-12 15:11:09 +0000 and img/smilies/sad.png 2012-02-27 14:24:17 +0000 differ
1614=== modified file 'img/smilies/smile.png'
1615Binary files img/smilies/smile.png 2008-07-12 15:11:09 +0000 and img/smilies/smile.png 2012-02-27 14:24:17 +0000 differ
1616=== modified file 'img/smilies/tongue.png'
1617Binary files img/smilies/tongue.png 2008-07-12 15:11:09 +0000 and img/smilies/tongue.png 2012-02-27 14:24:17 +0000 differ
1618=== modified file 'img/smilies/wink.png'
1619Binary files img/smilies/wink.png 2008-07-12 15:11:09 +0000 and img/smilies/wink.png 2012-02-27 14:24:17 +0000 differ
1620=== modified file 'img/smilies/yikes.png'
1621Binary files img/smilies/yikes.png 2008-07-12 15:11:09 +0000 and img/smilies/yikes.png 2012-02-27 14:24:17 +0000 differ
1622=== modified file 'include/cache.php'
1623--- include/cache.php 2011-04-19 22:53:21 +0000
1624+++ include/cache.php 2012-02-27 14:24:17 +0000
1625@@ -1,7 +1,7 @@
1626 <?php
1627
1628 /**
1629- * Copyright (C) 2008-2011 FluxBB
1630+ * Copyright (C) 2008-2012 FluxBB
1631 * based on code by Rickard Andersson copyright (C) 2002-2008 PunBB
1632 * License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher
1633 */
1634@@ -20,6 +20,8 @@
1635
1636 // Get the forum config from the DB
1637 $result = $db->query('SELECT * FROM '.$db->prefix.'config', true) or error('Unable to fetch forum config', __FILE__, __LINE__, $db->error());
1638+
1639+ $output = array();
1640 while ($cur_config_item = $db->fetch_row($result))
1641 $output[$cur_config_item[0]] = $cur_config_item[1];
1642
1643@@ -183,7 +185,7 @@
1644 for ($i = 0; $i < $num_words; $i++)
1645 {
1646 list($search_for[$i], $replace_with[$i]) = $db->fetch_row($result);
1647- $search_for[$i] = '/(?<=[^\p{L}\p{N}])('.str_replace('\*', '[\p{L}\p{N}]*?', preg_quote($search_for[$i], '/')).')(?=[^\p{L}\p{N}])/iu';
1648+ $search_for[$i] = '%(?<=[^\p{L}\p{N}])('.str_replace('\*', '[\p{L}\p{N}]*?', preg_quote($search_for[$i], '%')).')(?=[^\p{L}\p{N}])%iu';
1649 }
1650
1651 // Output censored words as PHP code
1652
1653=== modified file 'include/cache_fluxtoolbar.php'
1654--- include/cache_fluxtoolbar.php 2010-10-08 13:18:35 +0000
1655+++ include/cache_fluxtoolbar.php 2012-02-27 14:24:17 +0000
1656@@ -1,7 +1,7 @@
1657 <?php
1658 /***********************************************************************
1659
1660- Copyright (C) 2010 Mpok
1661+ Copyright (C) 2010-2011 Mpok
1662 based on code Copyright (C) 2006 Vincent Garnier
1663 License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher
1664
1665@@ -15,7 +15,7 @@
1666 {
1667 $fh = @fopen(FORUM_CACHE_DIR.$cache, 'wb');
1668 if (!$fh)
1669- error('Unable to write configuration cache file to cache directory. Please make sure PHP has write access to the directory \'cache\'', __FILE__, __LINE__);
1670+ error('Unable to write configuration cache file to cache directory. Please make sure PHP has write access to the directory \''.pun_htmlspecialchars(FORUM_CACHE_DIR).'\'', __FILE__, __LINE__);
1671 fwrite($fh, $text);
1672 fclose($fh);
1673 }
1674@@ -45,14 +45,14 @@
1675 }
1676
1677 // Output for checking
1678- $output_check .= 'if (preg_match(\'/(?:\[\/?(?:'.implode($tags, '|').')\]';
1679+ $output_check .= 'if (preg_match(\'%(?:\[/?(?:'.implode($tags, '|').')\]';
1680 if (!empty($tags_prompt))
1681 $output_check .= '|\[(?:'.implode($tags_prompt, '|').')=';
1682- $output_check .= ')/i\', $username))'."\n";
1683+ $output_check .= ')%i\', $username))'."\n";
1684 $output_check .= "\t".'$errors[] = $lang_prof_reg[\'Username BBCode\'];'."\n";
1685
1686 // Output for search
1687- $output_search .= '$text = preg_replace(\'/\[\/?('.implode($tags, '|').')(?:\=[^\]]*)?\]/\', \' \', $text);'."\n";
1688+ $output_search .= '$text = preg_replace(\'%\[/?('.implode($tags, '|').')(?:\=[^\]]*)?\]%\', \' \', $text);'."\n";
1689 }
1690
1691 write_cache('cache_fluxtoolbar_tag_check.php', $output_check);
1692@@ -87,11 +87,17 @@
1693 }
1694
1695 // Include the fluxtoolbar language files
1696- $output .= '<?php require_once PUN_ROOT.\'lang/\'.$pun_user[\'language\'].\'/fluxtoolbar.php\'; ?>'."\n";
1697+ $output .= '<?php'."\n".
1698+ 'if (file_exists(PUN_ROOT.\'lang/\'.$pun_user[\'language\'].\'/fluxtoolbar.php\'))'."\n".
1699+ "\t".'require_once PUN_ROOT.\'lang/\'.$pun_user[\'language\'].\'/fluxtoolbar.php\';'."\n".
1700+ 'else'."\n".
1701+ "\t".'require_once PUN_ROOT.\'lang/English/fluxtoolbar.php\';'."\n".
1702+ '?>'."\n";
1703
1704 // Start output JS
1705 $output .=
1706 '<script type="text/javascript" src="include/toolbar_func.js"></script>'."\n".
1707+ '<script type="text/javascript" src="include/jscolor/jscolor.js"></script>'."\n".
1708 '<noscript><p><strong><?php echo $lang_ftb[\'enable_js\'] ?></strong></p></noscript>'."\n".
1709 '<script type="text/javascript">'."\n".
1710 '/* <![CDATA[ */'."\n";
1711
1712=== modified file 'include/common.php'
1713--- include/common.php 2012-02-22 14:33:28 +0000
1714+++ include/common.php 2012-02-27 14:24:17 +0000
1715@@ -1,7 +1,7 @@
1716 <?php
1717
1718 /**
1719- * Copyright (C) 2008-2011 FluxBB
1720+ * Copyright (C) 2008-2012 FluxBB
1721 * based on code by Rickard Andersson copyright (C) 2002-2008 PunBB
1722 * License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher
1723 */
1724@@ -10,9 +10,9 @@
1725 exit('The constant PUN_ROOT must be defined and point to a valid FluxBB installation root directory.');
1726
1727 // Define the version and database revision that this code was written for
1728-define('FORUM_VERSION', '1.4.5');
1729+define('FORUM_VERSION', '1.4.8');
1730
1731-define('FORUM_DB_REVISION', 11);
1732+define('FORUM_DB_REVISION', 15);
1733 define('FORUM_SI_REVISION', 2);
1734 define('FORUM_PARSER_REVISION', 2);
1735
1736@@ -70,8 +70,8 @@
1737 if (get_magic_quotes_runtime())
1738 set_magic_quotes_runtime(0);
1739
1740-// Strip slashes from GET/POST/COOKIE (if magic_quotes_gpc is enabled)
1741-if (get_magic_quotes_gpc())
1742+// Strip slashes from GET/POST/COOKIE/REQUEST/FILES (if magic_quotes_gpc is enabled)
1743+if (!defined('FORUM_DISABLE_STRIPSLASHES') && get_magic_quotes_gpc())
1744 {
1745 function stripslashes_array($array)
1746 {
1747@@ -82,6 +82,13 @@
1748 $_POST = stripslashes_array($_POST);
1749 $_COOKIE = stripslashes_array($_COOKIE);
1750 $_REQUEST = stripslashes_array($_REQUEST);
1751+ if (is_array($_FILES))
1752+ {
1753+ // Don't strip valid slashes from tmp_name path on Windows
1754+ foreach ($_FILES AS $key => $value)
1755+ $_FILES[$key]['tmp_name'] = str_replace('\\', '\\\\', $value['tmp_name']);
1756+ $_FILES = stripslashes_array($_FILES);
1757+ }
1758 }
1759
1760 // If a cookie name is not specified in config.php, we use the default (pun_cookie)
1761@@ -130,13 +137,13 @@
1762
1763 // Verify that we are running the proper database schema revision
1764 if (!isset($pun_config['o_database_revision']) || $pun_config['o_database_revision'] < FORUM_DB_REVISION ||
1765- !isset($pun_config['o_searchindex_revision']) || $pun_config['o_searchindex_revision'] < FORUM_SI_REVISION ||
1766- !isset($pun_config['o_parser_revision']) || $pun_config['o_parser_revision'] < FORUM_PARSER_REVISION ||
1767- version_compare($pun_config['o_cur_version'], FORUM_VERSION, '<'))
1768- {
1769- header('Location: db_update.php');
1770- exit;
1771- }
1772+ !isset($pun_config['o_searchindex_revision']) || $pun_config['o_searchindex_revision'] < FORUM_SI_REVISION ||
1773+ !isset($pun_config['o_parser_revision']) || $pun_config['o_parser_revision'] < FORUM_PARSER_REVISION ||
1774+ version_compare($pun_config['o_cur_version'], FORUM_VERSION, '<'))
1775+{
1776+ header('Location: db_update.php');
1777+ exit;
1778+}
1779
1780 // Enable output buffering
1781 if (!defined('PUN_DISABLE_BUFFERING'))
1782
1783=== modified file 'include/common_admin.php'
1784--- include/common_admin.php 2011-04-19 22:53:21 +0000
1785+++ include/common_admin.php 2012-02-27 14:24:17 +0000
1786@@ -1,7 +1,7 @@
1787 <?php
1788
1789 /**
1790- * Copyright (C) 2008-2011 FluxBB
1791+ * Copyright (C) 2008-2012 FluxBB
1792 * based on code by Rickard Andersson copyright (C) 2002-2008 PunBB
1793 * License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher
1794 */
1795@@ -14,7 +14,7 @@
1796 if (file_exists(PUN_ROOT.'lang/'.$pun_user['language'].'/admin_common.php'))
1797 $admin_language = $pun_user['language'];
1798 else if (file_exists(PUN_ROOT.'lang/'.$pun_config['o_default_lang'].'/admin_common.php'))
1799- $admin_language = $pun_config['language'];
1800+ $admin_language = $pun_config['o_default_lang'];
1801 else
1802 $admin_language = 'English';
1803
1804@@ -83,8 +83,8 @@
1805 <ul>
1806 <?php
1807
1808- foreach ($plugins as $cur_plugin)
1809- echo "\t\t\t\t\t".'<li'.(($page == $cur_plugin[1]) ? ' class="isactive"' : '').'><a href="admin_loader.php?plugin='.$cur_plugin[1].'">'.str_replace('_', ' ', $cur_plugin[0]).'</a></li>'."\n";
1810+ foreach ($plugins as $plugin_name => $plugin)
1811+ echo "\t\t\t\t\t".'<li'.(($page == $plugin_name) ? ' class="isactive"' : '').'><a href="admin_loader.php?plugin='.$plugin_name.'">'.str_replace('_', ' ', $plugin).'</a></li>'."\n";
1812
1813 ?>
1814 </ul>
1815
1816=== modified file 'include/dblayer/common_db.php'
1817--- include/dblayer/common_db.php 2011-04-19 22:53:21 +0000
1818+++ include/dblayer/common_db.php 2012-02-27 14:24:17 +0000
1819@@ -1,7 +1,7 @@
1820 <?php
1821
1822 /**
1823- * Copyright (C) 2008-2011 FluxBB
1824+ * Copyright (C) 2008-2012 FluxBB
1825 * based on code by Rickard Andersson copyright (C) 2002-2008 PunBB
1826 * License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher
1827 */
1828@@ -15,27 +15,27 @@
1829 switch ($db_type)
1830 {
1831 case 'mysql':
1832- require PUN_ROOT.'include/dblayer/mysql.php';
1833+ require_once PUN_ROOT.'include/dblayer/mysql.php';
1834 break;
1835
1836 case 'mysql_innodb':
1837- require PUN_ROOT.'include/dblayer/mysql_innodb.php';
1838+ require_once PUN_ROOT.'include/dblayer/mysql_innodb.php';
1839 break;
1840
1841 case 'mysqli':
1842- require PUN_ROOT.'include/dblayer/mysqli.php';
1843+ require_once PUN_ROOT.'include/dblayer/mysqli.php';
1844 break;
1845
1846 case 'mysqli_innodb':
1847- require PUN_ROOT.'include/dblayer/mysqli_innodb.php';
1848+ require_once PUN_ROOT.'include/dblayer/mysqli_innodb.php';
1849 break;
1850
1851 case 'pgsql':
1852- require PUN_ROOT.'include/dblayer/pgsql.php';
1853+ require_once PUN_ROOT.'include/dblayer/pgsql.php';
1854 break;
1855
1856 case 'sqlite':
1857- require PUN_ROOT.'include/dblayer/sqlite.php';
1858+ require_once PUN_ROOT.'include/dblayer/sqlite.php';
1859 break;
1860
1861 default:
1862
1863=== modified file 'include/dblayer/mysql.php'
1864--- include/dblayer/mysql.php 2011-04-19 22:53:21 +0000
1865+++ include/dblayer/mysql.php 2012-02-27 14:24:17 +0000
1866@@ -1,7 +1,7 @@
1867 <?php
1868
1869 /**
1870- * Copyright (C) 2008-2011 FluxBB
1871+ * Copyright (C) 2008-2012 FluxBB
1872 * based on code by Rickard Andersson copyright (C) 2002-2008 PunBB
1873 * License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher
1874 */
1875@@ -24,7 +24,7 @@
1876 var $error_msg = 'Unknown';
1877
1878 var $datatype_transformations = array(
1879- '/^SERIAL$/' => 'INT(10) UNSIGNED AUTO_INCREMENT'
1880+ '%^SERIAL$%' => 'INT(10) UNSIGNED AUTO_INCREMENT'
1881 );
1882
1883
1884@@ -204,7 +204,7 @@
1885
1886 return array(
1887 'name' => 'MySQL Standard',
1888- 'version' => preg_replace('/^([^-]+).*$/', '\\1', $this->result($result))
1889+ 'version' => preg_replace('%^([^-]+).*$%', '\\1', $this->result($result))
1890 );
1891 }
1892
1893
1894=== modified file 'include/dblayer/mysql_innodb.php'
1895--- include/dblayer/mysql_innodb.php 2011-04-19 22:53:21 +0000
1896+++ include/dblayer/mysql_innodb.php 2012-02-27 14:24:17 +0000
1897@@ -1,7 +1,7 @@
1898 <?php
1899
1900 /**
1901- * Copyright (C) 2008-2011 FluxBB
1902+ * Copyright (C) 2008-2012 FluxBB
1903 * based on code by Rickard Andersson copyright (C) 2002-2008 PunBB
1904 * License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher
1905 */
1906@@ -25,7 +25,7 @@
1907 var $error_msg = 'Unknown';
1908
1909 var $datatype_transformations = array(
1910- '/^SERIAL$/' => 'INT(10) UNSIGNED AUTO_INCREMENT'
1911+ '%^SERIAL$%' => 'INT(10) UNSIGNED AUTO_INCREMENT'
1912 );
1913
1914
1915@@ -218,7 +218,7 @@
1916
1917 return array(
1918 'name' => 'MySQL Standard (InnoDB)',
1919- 'version' => preg_replace('/^([^-]+).*$/', '\\1', $this->result($result))
1920+ 'version' => preg_replace('%^([^-]+).*$%', '\\1', $this->result($result))
1921 );
1922 }
1923
1924
1925=== modified file 'include/dblayer/mysqli.php'
1926--- include/dblayer/mysqli.php 2011-04-19 22:53:21 +0000
1927+++ include/dblayer/mysqli.php 2012-02-27 14:24:17 +0000
1928@@ -1,7 +1,7 @@
1929 <?php
1930
1931 /**
1932- * Copyright (C) 2008-2011 FluxBB
1933+ * Copyright (C) 2008-2012 FluxBB
1934 * based on code by Rickard Andersson copyright (C) 2002-2008 PunBB
1935 * License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher
1936 */
1937@@ -24,7 +24,7 @@
1938 var $error_msg = 'Unknown';
1939
1940 var $datatype_transformations = array(
1941- '/^SERIAL$/' => 'INT(10) UNSIGNED AUTO_INCREMENT'
1942+ '%^SERIAL$%' => 'INT(10) UNSIGNED AUTO_INCREMENT'
1943 );
1944
1945
1946@@ -211,7 +211,7 @@
1947
1948 return array(
1949 'name' => 'MySQL Improved',
1950- 'version' => preg_replace('/^([^-]+).*$/', '\\1', $this->result($result))
1951+ 'version' => preg_replace('%^([^-]+).*$%', '\\1', $this->result($result))
1952 );
1953 }
1954
1955
1956=== modified file 'include/dblayer/mysqli_innodb.php'
1957--- include/dblayer/mysqli_innodb.php 2011-04-19 22:53:21 +0000
1958+++ include/dblayer/mysqli_innodb.php 2012-02-27 14:24:17 +0000
1959@@ -1,7 +1,7 @@
1960 <?php
1961
1962 /**
1963- * Copyright (C) 2008-2011 FluxBB
1964+ * Copyright (C) 2008-2012 FluxBB
1965 * based on code by Rickard Andersson copyright (C) 2002-2008 PunBB
1966 * License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher
1967 */
1968@@ -25,7 +25,7 @@
1969 var $error_msg = 'Unknown';
1970
1971 var $datatype_transformations = array(
1972- '/^SERIAL$/' => 'INT(10) UNSIGNED AUTO_INCREMENT'
1973+ '%^SERIAL$%' => 'INT(10) UNSIGNED AUTO_INCREMENT'
1974 );
1975
1976
1977@@ -224,7 +224,7 @@
1978
1979 return array(
1980 'name' => 'MySQL Improved (InnoDB)',
1981- 'version' => preg_replace('/^([^-]+).*$/', '\\1', $this->result($result))
1982+ 'version' => preg_replace('%^([^-]+).*$%', '\\1', $this->result($result))
1983 );
1984 }
1985
1986
1987=== modified file 'include/dblayer/pgsql.php'
1988--- include/dblayer/pgsql.php 2011-04-19 22:53:21 +0000
1989+++ include/dblayer/pgsql.php 2012-02-27 14:24:17 +0000
1990@@ -1,7 +1,7 @@
1991 <?php
1992
1993 /**
1994- * Copyright (C) 2008-2011 FluxBB
1995+ * Copyright (C) 2008-2012 FluxBB
1996 * based on code by Rickard Andersson copyright (C) 2002-2008 PunBB
1997 * License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher
1998 */
1999@@ -26,12 +26,12 @@
2000 var $error_msg = 'Unknown';
2001
2002 var $datatype_transformations = array(
2003- '/^(TINY|SMALL)INT( )?(\\([0-9]+\\))?( )?(UNSIGNED)?$/i' => 'SMALLINT',
2004- '/^(MEDIUM)?INT( )?(\\([0-9]+\\))?( )?(UNSIGNED)?$/i' => 'INTEGER',
2005- '/^BIGINT( )?(\\([0-9]+\\))?( )?(UNSIGNED)?$/i' => 'BIGINT',
2006- '/^(TINY|MEDIUM|LONG)?TEXT$/i' => 'TEXT',
2007- '/^DOUBLE( )?(\\([0-9,]+\\))?( )?(UNSIGNED)?$/i' => 'DOUBLE PRECISION',
2008- '/^FLOAT( )?(\\([0-9]+\\))?( )?(UNSIGNED)?$/i' => 'REAL'
2009+ '%^(TINY|SMALL)INT( )?(\\([0-9]+\\))?( )?(UNSIGNED)?$%i' => 'SMALLINT',
2010+ '%^(MEDIUM)?INT( )?(\\([0-9]+\\))?( )?(UNSIGNED)?$%i' => 'INTEGER',
2011+ '%^BIGINT( )?(\\([0-9]+\\))?( )?(UNSIGNED)?$%i' => 'BIGINT',
2012+ '%^(TINY|MEDIUM|LONG)?TEXT$%i' => 'TEXT',
2013+ '%^DOUBLE( )?(\\([0-9,]+\\))?( )?(UNSIGNED)?$%i' => 'DOUBLE PRECISION',
2014+ '%^FLOAT( )?(\\([0-9]+\\))?( )?(UNSIGNED)?$%i' => 'REAL'
2015 );
2016
2017
2018@@ -100,7 +100,7 @@
2019 function query($sql, $unbuffered = false) // $unbuffered is ignored since there is no pgsql_unbuffered_query()
2020 {
2021 if (strrpos($sql, 'LIMIT') !== false)
2022- $sql = preg_replace('#LIMIT ([0-9]+),([ 0-9]+)#', 'LIMIT \\2 OFFSET \\1', $sql);
2023+ $sql = preg_replace('%LIMIT ([0-9]+),([ 0-9]+)%', 'LIMIT \\2 OFFSET \\1', $sql);
2024
2025 if (defined('PUN_SHOW_QUERIES'))
2026 $q_start = get_microtime();
2027@@ -173,7 +173,7 @@
2028
2029 if ($query_id && $this->last_query_text[$query_id] != '')
2030 {
2031- if (preg_match('/^INSERT INTO ([a-z0-9\_\-]+)/is', $this->last_query_text[$query_id], $table_name))
2032+ if (preg_match('%^INSERT INTO ([a-z0-9\_\-]+)%is', $this->last_query_text[$query_id], $table_name))
2033 {
2034 // Hack (don't ask)
2035 if (substr($table_name[1], -6) == 'groups')
2036@@ -266,7 +266,7 @@
2037
2038 return array(
2039 'name' => 'PostgreSQL',
2040- 'version' => preg_replace('/^[^0-9]+([^\s,-]+).*$/', '\\1', $this->result($result))
2041+ 'version' => preg_replace('%^[^0-9]+([^\s,-]+).*$%', '\\1', $this->result($result))
2042 );
2043 }
2044
2045
2046=== modified file 'include/dblayer/sqlite.php'
2047--- include/dblayer/sqlite.php 2011-04-19 22:53:21 +0000
2048+++ include/dblayer/sqlite.php 2012-02-27 14:24:17 +0000
2049@@ -1,7 +1,7 @@
2050 <?php
2051
2052 /**
2053- * Copyright (C) 2008-2011 FluxBB
2054+ * Copyright (C) 2008-2012 FluxBB
2055 * based on code by Rickard Andersson copyright (C) 2002-2008 PunBB
2056 * License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher
2057 */
2058@@ -25,9 +25,9 @@
2059 var $error_msg = 'Unknown';
2060
2061 var $datatype_transformations = array(
2062- '/^SERIAL$/' => 'INTEGER',
2063- '/^(TINY|SMALL|MEDIUM|BIG)?INT( )?(\\([0-9]+\\))?( )?(UNSIGNED)?$/i' => 'INTEGER',
2064- '/^(TINY|MEDIUM|LONG)?TEXT$/i' => 'TEXT'
2065+ '%^SERIAL$%' => 'INTEGER',
2066+ '%^(TINY|SMALL|MEDIUM|BIG)?INT( )?(\\([0-9]+\\))?( )?(UNSIGNED)?$%i' => 'INTEGER',
2067+ '%^(TINY|MEDIUM|LONG)?TEXT$%i' => 'TEXT'
2068 );
2069
2070
2071@@ -49,7 +49,7 @@
2072 if (!is_readable($db_name))
2073 error('Unable to open database \''.$db_name.'\' for reading. Permission denied', __FILE__, __LINE__);
2074
2075- if (!is_writable($db_name))
2076+ if (!forum_is_writable($db_name))
2077 error('Unable to open database \''.$db_name.'\' for writing. Permission denied', __FILE__, __LINE__);
2078
2079 if ($p_connect)
2080@@ -279,7 +279,7 @@
2081 if (!$this->num_rows($result))
2082 return false;
2083
2084- return preg_match('/[\r\n]'.preg_quote($field_name).' /', $this->result($result));
2085+ return preg_match('%[\r\n]'.preg_quote($field_name, '%').' %', $this->result($result));
2086 }
2087
2088
2089@@ -345,7 +345,7 @@
2090 if (!$this->table_exists($table_name, $no_prefix))
2091 return true;
2092
2093- return $this->query('DROP TABLE '.($no_prefix ? '' : $this->prefix).$table_name) ? true : false;
2094+ return $this->query('DROP TABLE '.($no_prefix ? '' : $this->prefix).$this->escape($table_name)) ? true : false;
2095 }
2096
2097
2098@@ -372,7 +372,7 @@
2099 $result &= $this->query('INSERT INTO '.($no_prefix ? '' : $this->prefix).$this->escape($new_name).' SELECT * FROM '.($no_prefix ? '' : $this->prefix).$this->escape($old_name)) ? true : false;
2100
2101 // Drop old table
2102- $result &= $this->drop_table(($no_prefix ? '' : $this->prefix).$this->escape($table_name));
2103+ $result &= $this->drop_table($table_name, $no_prefix);
2104
2105 return $result;
2106 }
2107@@ -405,7 +405,7 @@
2108 $table['columns'] = array();
2109 foreach ($table_lines as $table_line)
2110 {
2111- $table_line = pun_trim($table_line);
2112+ $table_line = trim($table_line, " \t\n\r,"); // trim spaces, tabs, newlines, and commas
2113 if (substr($table_line, 0, 12) == 'CREATE TABLE')
2114 continue;
2115 else if (substr($table_line, 0, 11) == 'PRIMARY KEY')
2116@@ -413,7 +413,7 @@
2117 else if (substr($table_line, 0, 6) == 'UNIQUE')
2118 $table['unique'] = $table_line;
2119 else if (substr($table_line, 0, strpos($table_line, ' ')) != '')
2120- $table['columns'][substr($table_line, 0, strpos($table_line, ' '))] = pun_trim(substr($table_line, strpos($table_line, ' ')));
2121+ $table['columns'][substr($table_line, 0, strpos($table_line, ' '))] = trim(substr($table_line, strpos($table_line, ' ')));
2122 }
2123
2124 return $table;
2125@@ -444,23 +444,23 @@
2126 $query .= ' DEFAULT '.$default_value;
2127
2128 $old_columns = array_keys($table['columns']);
2129- array_insert($table['columns'], $after_field, $query.',', $field_name);
2130+ array_insert($table['columns'], $after_field, $query, $field_name);
2131
2132 $new_table = 'CREATE TABLE '.($no_prefix ? '' : $this->prefix).$this->escape($table_name).' (';
2133
2134 foreach ($table['columns'] as $cur_column => $column_details)
2135- $new_table .= "\n".$cur_column.' '.$column_details;
2136+ $new_table .= "\n".$cur_column.' '.$column_details.',';
2137
2138 if (isset($table['unique']))
2139 $new_table .= "\n".$table['unique'].',';
2140
2141 if (isset($table['primary_key']))
2142- $new_table .= "\n".$table['primary_key'];
2143+ $new_table .= "\n".$table['primary_key'].',';
2144
2145 $new_table = trim($new_table, ',')."\n".');';
2146
2147 // Drop old table
2148- $result &= $this->drop_table(($no_prefix ? '' : $this->prefix).$this->escape($table_name));
2149+ $result &= $this->drop_table($table_name, $no_prefix);
2150
2151 // Create new table
2152 $result &= $this->query($new_table) ? true : false;
2153@@ -476,7 +476,7 @@
2154 $result &= $this->query('INSERT INTO '.($no_prefix ? '' : $this->prefix).$this->escape($table_name).' ('.implode(', ', $old_columns).') SELECT * FROM '.($no_prefix ? '' : $this->prefix).$this->escape($table_name).'_t'.$now) ? true : false;
2155
2156 // Drop temp table
2157- $result &= $this->drop_table(($no_prefix ? '' : $this->prefix).$this->escape($table_name).'_t'.$now);
2158+ $result &= $this->drop_table($table_name.'_t'.$now, $no_prefix);
2159
2160 return $result;
2161 }
2162@@ -509,18 +509,18 @@
2163 $new_table = 'CREATE TABLE '.($no_prefix ? '' : $this->prefix).$this->escape($table_name).' (';
2164
2165 foreach ($table['columns'] as $cur_column => $column_details)
2166- $new_table .= "\n".$cur_column.' '.$column_details;
2167+ $new_table .= "\n".$cur_column.' '.$column_details.',';
2168
2169 if (isset($table['unique']))
2170 $new_table .= "\n".$table['unique'].',';
2171
2172 if (isset($table['primary_key']))
2173- $new_table .= "\n".$table['primary_key'];
2174+ $new_table .= "\n".$table['primary_key'].',';
2175
2176 $new_table = trim($new_table, ',')."\n".');';
2177
2178 // Drop old table
2179- $result &= $this->drop_table(($no_prefix ? '' : $this->prefix).$this->escape($table_name));
2180+ $result &= $this->drop_table($table_name, $no_prefix);
2181
2182 // Create new table
2183 $result &= $this->query($new_table) ? true : false;
2184@@ -537,7 +537,7 @@
2185 $result &= $this->query('INSERT INTO '.($no_prefix ? '' : $this->prefix).$this->escape($table_name).' SELECT '.implode(', ', $new_columns).' FROM '.($no_prefix ? '' : $this->prefix).$this->escape($table_name).'_t'.$now) ? true : false;
2186
2187 // Drop temp table
2188- $result &= $this->drop_table(($no_prefix ? '' : $this->prefix).$this->escape($table_name).'_t'.$now);
2189+ $result &= $this->drop_table($table_name.'_t'.$now, $no_prefix);
2190
2191 return $result;
2192 }
2193
2194=== modified file 'include/email.php'
2195--- include/email.php 2011-04-19 22:53:21 +0000
2196+++ include/email.php 2012-02-27 14:24:17 +0000
2197@@ -1,7 +1,7 @@
2198 <?php
2199
2200 /**
2201- * Copyright (C) 2008-2011 FluxBB
2202+ * Copyright (C) 2008-2012 FluxBB
2203 * based on code by Rickard Andersson copyright (C) 2002-2008 PunBB
2204 * License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher
2205 */
2206@@ -20,7 +20,7 @@
2207 if (strlen($email) > 80)
2208 return false;
2209
2210- return preg_match('/^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|("[^"]+"))@((\[\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\])|(([a-zA-Z\d\-]+\.)+[a-zA-Z]{2,}))$/', $email);
2211+ return preg_match('%^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|("[^"]+"))@((\[\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\])|(([a-zA-Z\d\-]+\.)+[a-zA-Z]{2,}))$%', $email);
2212 }
2213
2214
2215@@ -56,6 +56,157 @@
2216
2217
2218 //
2219+// Make a post email safe
2220+//
2221+function bbcode2email($text, $wrap_length = 72)
2222+{
2223+ static $base_url;
2224+
2225+ if (!isset($base_url))
2226+ $base_url = get_base_url();
2227+
2228+ $text = pun_trim($text, "\t\n ");
2229+
2230+ $shortcut_urls = array(
2231+ 'topic' => '/viewtopic.php?id=$1',
2232+ 'post' => '/viewtopic.php?pid=$1#p$1',
2233+ 'forum' => '/viewforum.php?id=$1',
2234+ 'user' => '/profile.php?id=$1',
2235+ );
2236+
2237+ // Split code blocks and text so BBcode in codeblocks won't be touched
2238+ list($code, $text) = extract_blocks($text, '[code]', '[/code]');
2239+
2240+ // Strip all bbcodes, except the quote, url, img, email, code and list items bbcodes
2241+ $text = preg_replace(array(
2242+ '%\[/?(?!(?:quote|url|topic|post|user|forum|img|email|code|list|\*))[a-z]+(?:=[^\]]+)?\]%i',
2243+ '%\n\[/?list(?:=[^\]]+)?\]%i' // A separate regex for the list tags to get rid of some whitespace
2244+ ), '', $text);
2245+
2246+ // Match the deepest nested bbcode
2247+ // An adapted example from Mastering Regular Expressions
2248+ $match_quote_regex = '%
2249+ \[(quote|\*|url|img|email|topic|post|user|forum)(?:=([^\]]+))?\]
2250+ (
2251+ (?>[^\[]*)
2252+ (?>
2253+ (?!\[/?\1(?:=[^\]]+)?\])
2254+ \[
2255+ [^\[]*
2256+ )*
2257+ )
2258+ \[/\1\]
2259+ %ix';
2260+
2261+ $url_index = 1;
2262+ $url_stack = array();
2263+ while (preg_match($match_quote_regex, $text, $matches))
2264+ {
2265+ // Quotes
2266+ if ($matches[1] == 'quote')
2267+ {
2268+ // Put '>' or '> ' at the start of a line
2269+ $replacement = preg_replace(
2270+ array('%^(?=\>)%m', '%^(?!\>)%m'),
2271+ array('>', '> '),
2272+ $matches[2]." said:\n".$matches[3]);
2273+ }
2274+
2275+ // List items
2276+ elseif ($matches[1] == '*')
2277+ {
2278+ $replacement = ' * '.$matches[3];
2279+ }
2280+
2281+ // URLs and emails
2282+ elseif (in_array($matches[1], array('url', 'email')))
2283+ {
2284+ if (!empty($matches[2]))
2285+ {
2286+ $replacement = '['.$matches[3].']['.$url_index.']';
2287+ $url_stack[$url_index] = $matches[2];
2288+ $url_index++;
2289+ }
2290+ else
2291+ $replacement = '['.$matches[3].']';
2292+ }
2293+
2294+ // Images
2295+ elseif ($matches[1] == 'img')
2296+ {
2297+ if (!empty($matches[2]))
2298+ $replacement = '['.$matches[2].']['.$url_index.']';
2299+ else
2300+ $replacement = '['.basename($matches[3]).']['.$url_index.']';
2301+
2302+ $url_stack[$url_index] = $matches[3];
2303+ $url_index++;
2304+ }
2305+
2306+ // Topic, post, forum and user URLs
2307+ elseif (in_array($matches[1], array('topic', 'post', 'forum', 'user')))
2308+ {
2309+ $url = isset($shortcut_urls[$matches[1]]) ? $base_url.$shortcut_urls[$matches[1]] : '';
2310+
2311+ if (!empty($matches[2]))
2312+ {
2313+ $replacement = '['.$matches[3].']['.$url_index.']';
2314+ $url_stack[$url_index] = str_replace('$1', $matches[2], $url);
2315+ $url_index++;
2316+ }
2317+ else
2318+ $replacement = '['.str_replace('$1', $matches[3], $url).']';
2319+ }
2320+
2321+ // Update the main text if there is a replacment
2322+ if (!is_null($replacement))
2323+ {
2324+ $text = str_replace($matches[0], $replacement, $text);
2325+ $replacement = null;
2326+ }
2327+ }
2328+
2329+ // Put code blocks and text together
2330+ if (isset($code))
2331+ {
2332+ $parts = explode("\1", $text);
2333+ $text = '';
2334+ foreach ($parts as $i => $part)
2335+ {
2336+ $text .= $part;
2337+ if (isset($code[$i]))
2338+ $text .= trim($code[$i], "\n\r");
2339+ }
2340+ }
2341+
2342+ // Put URLs at the bottom
2343+ if ($url_stack)
2344+ {
2345+ $text .= "\n\n";
2346+ foreach ($url_stack as $i => $url)
2347+ $text .= "\n".' ['.$i.']: '.$url;
2348+ }
2349+
2350+ // Wrap lines if $wrap_length is higher than -1
2351+ if ($wrap_length > -1)
2352+ {
2353+ // Split all lines and wrap them individually
2354+ $parts = explode("\n", $text);
2355+ foreach ($parts as $k => $part)
2356+ {
2357+ preg_match('%^(>+ )?(.*)%', $part, $matches);
2358+ $parts[$k] = wordwrap($matches[1].$matches[2], $wrap_length -
2359+ strlen($matches[1]), "\n".$matches[1]);
2360+ }
2361+
2362+ return implode("\n", $parts);
2363+ }
2364+ else
2365+ return $text;
2366+}
2367+
2368+
2369+//
2370 // Wrapper for PHP's mail()
2371 //
2372 function pun_mail($to, $subject, $message, $reply_to_email = '', $reply_to_name = '')
2373@@ -63,19 +214,19 @@
2374 global $pun_config, $lang_common;
2375
2376 // Default sender/return address
2377- $from_name = str_replace('"', '', $pun_config['o_board_title'].' '.$lang_common['Mailer']);
2378+ $from_name = sprintf($lang_common['Mailer'], $pun_config['o_board_title']);
2379 $from_email = $pun_config['o_webmaster_email'];
2380
2381 // Do a little spring cleaning
2382- $to = pun_trim(preg_replace('#[\n\r]+#s', '', $to));
2383- $subject = pun_trim(preg_replace('#[\n\r]+#s', '', $subject));
2384- $from_email = pun_trim(preg_replace('#[\n\r:]+#s', '', $from_email));
2385- $from_name = pun_trim(preg_replace('#[\n\r:]+#s', '', str_replace('"', '', $from_name)));
2386- $reply_to_email = pun_trim(preg_replace('#[\n\r:]+#s', '', $reply_to_email));
2387- $reply_to_name = pun_trim(preg_replace('#[\n\r:]+#s', '', str_replace('"', '', $reply_to_name)));
2388+ $to = pun_trim(preg_replace('%[\n\r]+%s', '', $to));
2389+ $subject = pun_trim(preg_replace('%[\n\r]+%s', '', $subject));
2390+ $from_email = pun_trim(preg_replace('%[\n\r:]+%s', '', $from_email));
2391+ $from_name = pun_trim(preg_replace('%[\n\r:]+%s', '', str_replace('"', '', $from_name)));
2392+ $reply_to_email = pun_trim(preg_replace('%[\n\r:]+%s', '', $reply_to_email));
2393+ $reply_to_name = pun_trim(preg_replace('%[\n\r:]+%s', '', str_replace('"', '', $reply_to_name)));
2394
2395 // Set up some headers to take advantage of UTF-8
2396- $from = encode_mail_text($from_name).' <'.$from_email.'>';
2397+ $from = '"'.encode_mail_text($from_name).'" <'.$from_email.'>';
2398 $subject = encode_mail_text($subject);
2399
2400 $headers = 'From: '.$from."\r\n".'Date: '.gmdate('r')."\r\n".'MIME-Version: 1.0'."\r\n".'Content-transfer-encoding: 8bit'."\r\n".'Content-type: text/plain; charset=utf-8'."\r\n".'X-Mailer: FluxBB Mailer';
2401@@ -83,24 +234,25 @@
2402 // If we specified a reply-to email, we deal with it here
2403 if (!empty($reply_to_email))
2404 {
2405- $reply_to = encode_mail_text($reply_to_name).' <'.$reply_to_email.'>';
2406+ $reply_to = '"'.encode_mail_text($reply_to_name).'" <'.$reply_to_email.'>';
2407
2408 $headers .= "\r\n".'Reply-To: '.$reply_to;
2409 }
2410
2411- // Make sure all linebreaks are CRLF in message (and strip out any NULL bytes)
2412- $message = str_replace(array("\n", "\0"), array("\r\n", ''), pun_linebreaks($message));
2413+ // Make sure all linebreaks are LF in message (and strip out any NULL bytes)
2414+ $message = str_replace("\0", '', pun_linebreaks($message));
2415
2416 if ($pun_config['o_smtp_host'] != '')
2417+ {
2418+ // Headers should be \r\n
2419+ // Message should be ??
2420+ $message = str_replace("\n", "\r\n", $message);
2421 smtp_mail($to, $subject, $message, $headers);
2422+ }
2423 else
2424 {
2425- // Change the linebreaks used in the headers according to OS
2426- if (strtoupper(substr(PHP_OS, 0, 3)) == 'MAC')
2427- $headers = str_replace("\r\n", "\r", $headers);
2428- else if (strtoupper(substr(PHP_OS, 0, 3)) != 'WIN')
2429- $headers = str_replace("\r\n", "\n", $headers);
2430-
2431+ // Headers should be \r\n
2432+ // Message should be \n
2433 mail($to, $subject, $message, $headers);
2434 }
2435 }
2436
2437=== modified file 'include/functions.php'
2438--- include/functions.php 2011-09-24 10:32:58 +0000
2439+++ include/functions.php 2012-02-27 14:24:17 +0000
2440@@ -1,7 +1,7 @@
2441 <?php
2442
2443 /**
2444- * Copyright (C) 2008-2011 FluxBB
2445+ * Copyright (C) 2008-2012 FluxBB
2446 * based on code by Rickard Andersson copyright (C) 2002-2008 PunBB
2447 * License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher
2448 */
2449@@ -26,7 +26,7 @@
2450 $now = time();
2451
2452 // If the cookie is set and it matches the correct pattern, then read the values from it
2453- if (isset($_COOKIE[$cookie_name]) && preg_match('/^(\d+)\|([0-9a-fA-F]+)\|(\d+)\|([0-9a-fA-F]+)$/', $_COOKIE[$cookie_name], $matches))
2454+ if (isset($_COOKIE[$cookie_name]) && preg_match('%^(\d+)\|([0-9a-fA-F]+)\|(\d+)\|([0-9a-fA-F]+)$%', $_COOKIE[$cookie_name], $matches))
2455 {
2456 $cookie = array(
2457 'user_id' => intval($matches[1]),
2458@@ -246,7 +246,7 @@
2459 // Fetch guest user
2460 $result = $db->query('SELECT u.*, g.*, o.logged, o.last_post, o.last_search FROM '.$db->prefix.'users AS u INNER JOIN '.$db->prefix.'groups AS g ON u.group_id=g.g_id LEFT JOIN '.$db->prefix.'online AS o ON o.ident=\''.$remote_addr.'\' WHERE u.id=1') or error('Unable to fetch guest information', __FILE__, __LINE__, $db->error());
2461 if (!$db->num_rows($result))
2462- exit('Unable to fetch guest information. The table \''.$db->prefix.'users\' must contain an entry with id = 1 that represents anonymous users.');
2463+ exit('Unable to fetch guest information. Your database must contain both a guest user and a guest user group.');
2464
2465 $pun_user = $db->fetch_assoc($result);
2466
2467@@ -428,7 +428,7 @@
2468 global $db, $pun_config, $errors, $lang_prof_reg, $lang_register, $lang_common, $pun_bans;
2469
2470 // Convert multiple whitespace characters into one (to prevent people from registering with indistinguishable usernames)
2471- $username = preg_replace('#\s+#s', ' ', $username);
2472+ $username = preg_replace('%\s+%s', ' ', $username);
2473
2474 // Validate username
2475 if (pun_strlen($username) < 2)
2476@@ -437,11 +437,11 @@
2477 $errors[] = $lang_prof_reg['Username too long'];
2478 else if (!strcasecmp($username, 'Guest') || !strcasecmp($username, $lang_common['Guest']))
2479 $errors[] = $lang_prof_reg['Username guest'];
2480- else if (preg_match('/[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}/', $username) || preg_match('/((([0-9A-Fa-f]{1,4}:){7}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){6}:[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){5}:([0-9A-Fa-f]{1,4}:)?[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){4}:([0-9A-Fa-f]{1,4}:){0,2}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){3}:([0-9A-Fa-f]{1,4}:){0,3}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){2}:([0-9A-Fa-f]{1,4}:){0,4}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){6}((\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b)\.){3}(\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b))|(([0-9A-Fa-f]{1,4}:){0,5}:((\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b)\.){3}(\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b))|(::([0-9A-Fa-f]{1,4}:){0,5}((\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b)\.){3}(\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b))|([0-9A-Fa-f]{1,4}::([0-9A-Fa-f]{1,4}:){0,5}[0-9A-Fa-f]{1,4})|(::([0-9A-Fa-f]{1,4}:){0,6}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){1,7}:))/', $username))
2481+ else if (preg_match('%[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}%', $username) || preg_match('%((([0-9A-Fa-f]{1,4}:){7}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){6}:[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){5}:([0-9A-Fa-f]{1,4}:)?[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){4}:([0-9A-Fa-f]{1,4}:){0,2}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){3}:([0-9A-Fa-f]{1,4}:){0,3}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){2}:([0-9A-Fa-f]{1,4}:){0,4}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){6}((\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b)\.){3}(\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b))|(([0-9A-Fa-f]{1,4}:){0,5}:((\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b)\.){3}(\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b))|(::([0-9A-Fa-f]{1,4}:){0,5}((\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b)\.){3}(\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b))|([0-9A-Fa-f]{1,4}::([0-9A-Fa-f]{1,4}:){0,5}[0-9A-Fa-f]{1,4})|(::([0-9A-Fa-f]{1,4}:){0,6}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){1,7}:))%', $username))
2482 $errors[] = $lang_prof_reg['Username IP'];
2483 else if ((strpos($username, '[') !== false || strpos($username, ']') !== false) && strpos($username, '\'') !== false && strpos($username, '"') !== false)
2484 $errors[] = $lang_prof_reg['Username reserved chars'];
2485- else if (preg_match('/(?:\[\/?(?:b|u|s|ins|del|em|i|h|colou?r|quote|code|img|url|email|list|\*)\]|\[(?:img|url|quote|list)=)/i', $username))
2486+ else if (preg_match('%(?:\[/?(?:b|u|s|ins|del|em|i|h|colou?r|quote|code|img|url|email|list|\*|topic|post|forum|user)\]|\[(?:img|url|quote|list)=)%i', $username))
2487 $errors[] = $lang_prof_reg['Username BBCode'];
2488
2489 /* FluxToolBar */
2490@@ -460,7 +460,7 @@
2491 // Check that the username (or a too similar username) is not already registered
2492 $query = ($exclude_id) ? ' AND id!='.$exclude_id : '';
2493
2494- $result = $db->query('SELECT username FROM '.$db->prefix.'users WHERE (UPPER(username)=UPPER(\''.$db->escape($username).'\') OR UPPER(username)=UPPER(\''.$db->escape(ucp_preg_replace('/[^\p{L}\p{N}]/u', '', $username)).'\')) AND id>1'.$query) or error('Unable to fetch user info', __FILE__, __LINE__, $db->error());
2495+ $result = $db->query('SELECT username FROM '.$db->prefix.'users WHERE (UPPER(username)=UPPER(\''.$db->escape($username).'\') OR UPPER(username)=UPPER(\''.$db->escape(ucp_preg_replace('%[^\p{L}\p{N}]%u', '', $username)).'\')) AND id>1'.$query) or error('Unable to fetch user info', __FILE__, __LINE__, $db->error());
2496
2497 if ($db->num_rows($result))
2498 {
2499@@ -1237,7 +1237,7 @@
2500 $tpl_maint = file_get_contents($tpl_file);
2501
2502 // START SUBST - <pun_include "*">
2503- preg_match_all('#<pun_include "([^/\\\\]*?)\.(php[45]?|inc|html?|txt)">#', $tpl_maint, $pun_includes, PREG_SET_ORDER);
2504+ preg_match_all('%<pun_include "([^/\\\\]*?)\.(php[45]?|inc|html?|txt)">%i', $tpl_maint, $pun_includes, PREG_SET_ORDER);
2505
2506 foreach ($pun_includes as $cur_include)
2507 {
2508@@ -1327,7 +1327,7 @@
2509 $destination_url = get_base_url(true).'/'.$destination_url;
2510
2511 // Do a little spring cleaning
2512- $destination_url = preg_replace('/([\r\n])|(%0[ad])|(;\s*data\s*:)/i', '', $destination_url);
2513+ $destination_url = preg_replace('%([\r\n])|(\%0[ad])|(;\s*data\s*:)%i', '', $destination_url);
2514
2515 // If the delay is 0 seconds, we might as well skip the redirect all together
2516 if ($pun_config['o_redirect_delay'] == '0')
2517@@ -1363,7 +1363,7 @@
2518 $tpl_redir = file_get_contents($tpl_file);
2519
2520 // START SUBST - <pun_include "*">
2521- preg_match_all('#<pun_include "([^/\\\\]*?)\.(php[45]?|inc|html?|txt)">#', $tpl_redir, $pun_includes, PREG_SET_ORDER);
2522+ preg_match_all('%<pun_include "([^/\\\\]*?)\.(php[45]?|inc|html?|txt)">%i', $tpl_redir, $pun_includes, PREG_SET_ORDER);
2523
2524 foreach ($pun_includes as $cur_include)
2525 {
2526@@ -1647,7 +1647,7 @@
2527 $array = utf8_bad_strip($array);
2528
2529 // Remove control characters
2530- $array = preg_replace('/[\x{00}-\x{08}\x{0b}-\x{0c}\x{0e}-\x{1f}]/', '', $array);
2531+ $array = preg_replace('%[\x00-\x08\x0b-\x0c\x0e-\x1f]%', '', $array);
2532
2533 // Replace some "bad" characters
2534 $array = str_replace(array_keys($bad_utf8_chars), array_values($bad_utf8_chars), $array);
2535@@ -1661,12 +1661,14 @@
2536 //
2537 function file_size($size)
2538 {
2539+ global $lang_common;
2540+
2541 $units = array('B', 'KiB', 'MiB', 'GiB', 'TiB', 'PiB', 'EiB');
2542
2543 for ($i = 0; $size > 1024; $i++)
2544 $size /= 1024;
2545
2546- return round($size, 2).' '.$units[$i];
2547+ return sprintf($lang_common['Size unit '.$units[$i]], round($size, 2));;
2548 }
2549
2550
2551@@ -1756,10 +1758,12 @@
2552 $suffix = substr($entry, strlen($entry) - 4);
2553
2554 if ($suffix == '.php' && ((!$is_admin && $prefix == 'AMP') || ($is_admin && ($prefix == 'AP' || $prefix == 'AMP'))))
2555- $plugins[] = array(substr($entry, strpos($entry, '_') + 1, -4), $entry);
2556+ $plugins[$entry] = substr($entry, strpos($entry, '_') + 1, -4);
2557 }
2558 $d->close();
2559
2560+ natcasesort($plugins);
2561+
2562 return $plugins;
2563 }
2564
2565@@ -1767,35 +1771,84 @@
2566 //
2567 // Split text into chunks ($inside contains all text inside $start and $end, and $outside contains all text outside)
2568 //
2569-function split_text($text, $start, $end, &$errors, $retab = true)
2570+function split_text($text, $start, $end, $retab = true)
2571 {
2572 global $pun_config, $lang_common;
2573
2574- $tokens = explode($start, $text);
2575-
2576- $outside[] = $tokens[0];
2577-
2578- $num_tokens = count($tokens);
2579- for ($i = 1; $i < $num_tokens; ++$i)
2580- {
2581- $temp = explode($end, $tokens[$i]);
2582-
2583- if (count($temp) != 2)
2584+ $result = array(0 => array(), 1 => array()); // 0 = inside, 1 = outside
2585+
2586+ // split the text into parts
2587+ $parts = preg_split('%'.preg_quote($start, '%').'(.*)'.preg_quote($end, '%').'%Us', $text, -1, PREG_SPLIT_DELIM_CAPTURE);
2588+ $num_parts = count($parts);
2589+
2590+ // preg_split results in outside parts having even indices, inside parts having odd
2591+ for ($i = 0;$i < $num_parts;$i++)
2592+ $result[1 - ($i % 2)][] = $parts[$i];
2593+
2594+ if ($pun_config['o_indent_num_spaces'] != 8 && $retab)
2595+ {
2596+ $spaces = str_repeat(' ', $pun_config['o_indent_num_spaces']);
2597+ $result[1] = str_replace("\t", $spaces, $result[1]);
2598+ }
2599+
2600+ return $result;
2601+}
2602+
2603+
2604+//
2605+// Extract blocks from a text with a starting and ending string
2606+// This function always matches the most outer block so nesting is possible
2607+//
2608+function extract_blocks($text, $start, $end, $retab = true)
2609+{
2610+ global $pun_config;
2611+
2612+ $code = array();
2613+ $start_len = strlen($start);
2614+ $end_len = strlen($end);
2615+ $regex = '%(?:'.preg_quote($start, '%').'|'.preg_quote($end, '%').')%';
2616+ $matches = array();
2617+
2618+ if (preg_match_all($regex, $text, $matches))
2619+ {
2620+ $counter = $offset = 0;
2621+ $start_pos = $end_pos = false;
2622+
2623+ foreach ($matches[0] as $match)
2624 {
2625- $errors[] = $lang_common['BBCode code problem'];
2626- return array(null, array($text));
2627+ if ($match == $start)
2628+ {
2629+ if ($counter == 0)
2630+ $start_pos = strpos($text, $start);
2631+ $counter++;
2632+ }
2633+ elseif ($match == $end)
2634+ {
2635+ $counter--;
2636+ if ($counter == 0)
2637+ $end_pos = strpos($text, $end, $offset + 1);
2638+ $offset = strpos($text, $end, $offset + 1);
2639+ }
2640+
2641+ if ($start_pos !== false && $end_pos !== false)
2642+ {
2643+ $code[] = substr($text, $start_pos + $start_len,
2644+ $end_pos - $start_pos - $start_len);
2645+ $text = substr_replace($text, "\1", $start_pos,
2646+ $end_pos - $start_pos + $end_len);
2647+ $start_pos = $end_pos = false;
2648+ $offset = 0;
2649+ }
2650 }
2651- $inside[] = $temp[0];
2652- $outside[] = $temp[1];
2653 }
2654
2655 if ($pun_config['o_indent_num_spaces'] != 8 && $retab)
2656 {
2657 $spaces = str_repeat(' ', $pun_config['o_indent_num_spaces']);
2658- $inside = str_replace("\t", $spaces, $inside);
2659+ $text = str_replace("\t", $spaces, $text);
2660 }
2661
2662- return array($inside, $outside);
2663+ return array($code, $text);
2664 }
2665
2666 //
2667@@ -1935,6 +1988,65 @@
2668 return $replaced;
2669 }
2670
2671+//
2672+// Replace four-byte characters with a question mark
2673+//
2674+// As MySQL cannot properly handle four-byte characters with the default utf-8
2675+// charset up until version 5.5.3 (where a special charset has to be used), they
2676+// need to be replaced, by question marks in this case.
2677+//
2678+function strip_bad_multibyte_chars($str)
2679+{
2680+ $result = '';
2681+ $length = strlen($str);
2682+
2683+ for ($i = 0; $i < $length; $i++)
2684+ {
2685+ // Replace four-byte characters (11110www 10zzzzzz 10yyyyyy 10xxxxxx)
2686+ $ord = ord($str[$i]);
2687+ if ($ord >= 240 && $ord <= 244)
2688+ {
2689+ $result .= '?';
2690+ $i += 3;
2691+ }
2692+ else
2693+ {
2694+ $result .= $str[$i];
2695+ }
2696+ }
2697+
2698+ return $result;
2699+}
2700+
2701+//
2702+// Check whether a file/folder is writable.
2703+//
2704+// This function also works on Windows Server where ACLs seem to be ignored.
2705+//
2706+function forum_is_writable($path)
2707+{
2708+ if (is_dir($path))
2709+ {
2710+ $path = rtrim($path, '/').'/';
2711+ return forum_is_writable($path.uniqid(mt_rand()).'.tmp');
2712+ }
2713+
2714+ // Check temporary file for read/write capabilities
2715+ $rm = file_exists($path);
2716+ $f = @fopen($path, 'a');
2717+
2718+ if ($f === false)
2719+ return false;
2720+
2721+ fclose($f);
2722+
2723+ if (!$rm)
2724+ @unlink($path);
2725+
2726+ return true;
2727+}
2728+
2729+
2730 // DEBUG FUNCTIONS BELOW
2731
2732 //
2733
2734=== added directory 'include/jscolor'
2735=== added file 'include/jscolor/arrow.gif'
2736Binary files include/jscolor/arrow.gif 1970-01-01 00:00:00 +0000 and include/jscolor/arrow.gif 2012-02-27 14:24:17 +0000 differ
2737=== added file 'include/jscolor/cross.gif'
2738Binary files include/jscolor/cross.gif 1970-01-01 00:00:00 +0000 and include/jscolor/cross.gif 2012-02-27 14:24:17 +0000 differ
2739=== added file 'include/jscolor/hs.png'
2740Binary files include/jscolor/hs.png 1970-01-01 00:00:00 +0000 and include/jscolor/hs.png 2012-02-27 14:24:17 +0000 differ
2741=== added file 'include/jscolor/hv.png'
2742Binary files include/jscolor/hv.png 1970-01-01 00:00:00 +0000 and include/jscolor/hv.png 2012-02-27 14:24:17 +0000 differ
2743=== added file 'include/jscolor/jscolor.js'
2744--- include/jscolor/jscolor.js 1970-01-01 00:00:00 +0000
2745+++ include/jscolor/jscolor.js 2012-02-27 14:24:17 +0000
2746@@ -0,0 +1,915 @@
2747+/**
2748+ * jscolor, JavaScript Color Picker
2749+ *
2750+ * @version 1.3.10
2751+ * @license GNU Lesser General Public License, http://www.gnu.org/copyleft/lesser.html
2752+ * @author Jan Odvarko, http://odvarko.cz
2753+ * @created 2008-06-15
2754+ * @updated 2011-11-03
2755+ * @link http://jscolor.com
2756+ */
2757+
2758+
2759+var jscolor = {
2760+
2761+
2762+ dir : '', // location of jscolor directory (leave empty to autodetect)
2763+ bindClass : 'color', // class name
2764+ binding : true, // automatic binding via <input class="...">
2765+ preloading : true, // use image preloading?
2766+
2767+
2768+ install : function() {
2769+ jscolor.addEvent(window, 'load', jscolor.init);
2770+ },
2771+
2772+
2773+ init : function() {
2774+ if(jscolor.binding) {
2775+ jscolor.bind();
2776+ }
2777+ if(jscolor.preloading) {
2778+ jscolor.preload();
2779+ }
2780+ },
2781+
2782+
2783+ getDir : function() {
2784+ if(!jscolor.dir) {
2785+ var detected = jscolor.detectDir();
2786+ jscolor.dir = detected!==false ? detected : 'jscolor/';
2787+ }
2788+ return jscolor.dir;
2789+ },
2790+
2791+
2792+ detectDir : function() {
2793+ var base = location.href;
2794+
2795+ var e = document.getElementsByTagName('base');
2796+ for(var i=0; i<e.length; i+=1) {
2797+ if(e[i].href) { base = e[i].href; }
2798+ }
2799+
2800+ var e = document.getElementsByTagName('script');
2801+ for(var i=0; i<e.length; i+=1) {
2802+ if(e[i].src && /(^|\/)jscolor\.js([?#].*)?$/i.test(e[i].src)) {
2803+ var src = new jscolor.URI(e[i].src);
2804+ var srcAbs = src.toAbsolute(base);
2805+ srcAbs.path = srcAbs.path.replace(/[^\/]+$/, ''); // remove filename
2806+ srcAbs.query = null;
2807+ srcAbs.fragment = null;
2808+ return srcAbs.toString();
2809+ }
2810+ }
2811+ return false;
2812+ },
2813+
2814+
2815+ bind : function() {
2816+ var matchClass = new RegExp('(^|\\s)('+jscolor.bindClass+')\\s*(\\{[^}]*\\})?', 'i');
2817+ var e = document.getElementsByTagName('input');
2818+ for(var i=0; i<e.length; i+=1) {
2819+ var m;
2820+ if(!e[i].color && e[i].className && (m = e[i].className.match(matchClass))) {
2821+ var prop = {};
2822+ if(m[3]) {
2823+ try {
2824+ eval('prop='+m[3]);
2825+ } catch(eInvalidProp) {}
2826+ }
2827+ e[i].color = new jscolor.color(e[i], prop);
2828+ }
2829+ }
2830+ },
2831+
2832+
2833+ preload : function() {
2834+ for(var fn in jscolor.imgRequire) {
2835+ if(jscolor.imgRequire.hasOwnProperty(fn)) {
2836+ jscolor.loadImage(fn);
2837+ }
2838+ }
2839+ },
2840+
2841+
2842+ images : {
2843+ pad : [ 181, 101 ],
2844+ sld : [ 16, 101 ],
2845+ cross : [ 15, 15 ],
2846+ arrow : [ 7, 11 ]
2847+ },
2848+
2849+
2850+ imgRequire : {},
2851+ imgLoaded : {},
2852+
2853+
2854+ requireImage : function(filename) {
2855+ jscolor.imgRequire[filename] = true;
2856+ },
2857+
2858+
2859+ loadImage : function(filename) {
2860+ if(!jscolor.imgLoaded[filename]) {
2861+ jscolor.imgLoaded[filename] = new Image();
2862+ jscolor.imgLoaded[filename].src = jscolor.getDir()+filename;
2863+ }
2864+ },
2865+
2866+
2867+ fetchElement : function(mixed) {
2868+ return typeof mixed === 'string' ? document.getElementById(mixed) : mixed;
2869+ },
2870+
2871+
2872+ addEvent : function(el, evnt, func) {
2873+ if(el.addEventListener) {
2874+ el.addEventListener(evnt, func, false);
2875+ } else if(el.attachEvent) {
2876+ el.attachEvent('on'+evnt, func);
2877+ }
2878+ },
2879+
2880+
2881+ fireEvent : function(el, evnt) {
2882+ if(!el) {
2883+ return;
2884+ }
2885+ if(document.createEvent) {
2886+ var ev = document.createEvent('HTMLEvents');
2887+ ev.initEvent(evnt, true, true);
2888+ el.dispatchEvent(ev);
2889+ } else if(document.createEventObject) {
2890+ var ev = document.createEventObject();
2891+ el.fireEvent('on'+evnt, ev);
2892+ } else if(el['on'+evnt]) { // alternatively use the traditional event model (IE5)
2893+ el['on'+evnt]();
2894+ }
2895+ },
2896+
2897+
2898+ getElementPos : function(e) {
2899+ var e1=e, e2=e;
2900+ var x=0, y=0;
2901+ if(e1.offsetParent) {
2902+ do {
2903+ x += e1.offsetLeft;
2904+ y += e1.offsetTop;
2905+ } while(e1 = e1.offsetParent);
2906+ }
2907+ while((e2 = e2.parentNode) && e2.nodeName.toUpperCase() !== 'BODY') {
2908+ x -= e2.scrollLeft;
2909+ y -= e2.scrollTop;
2910+ }
2911+ return [x, y];
2912+ },
2913+
2914+
2915+ getElementSize : function(e) {
2916+ return [e.offsetWidth, e.offsetHeight];
2917+ },
2918+
2919+
2920+ getRelMousePos : function(e) {
2921+ var x = 0, y = 0;
2922+ if (!e) { e = window.event; }
2923+ if (typeof e.offsetX === 'number') {
2924+ x = e.offsetX;
2925+ y = e.offsetY;
2926+ } else if (typeof e.layerX === 'number') {
2927+ x = e.layerX;
2928+ y = e.layerY;
2929+ }
2930+ return { x: x, y: y };
2931+ },
2932+
2933+
2934+ getViewPos : function() {
2935+ if(typeof window.pageYOffset === 'number') {
2936+ return [window.pageXOffset, window.pageYOffset];
2937+ } else if(document.body && (document.body.scrollLeft || document.body.scrollTop)) {
2938+ return [document.body.scrollLeft, document.body.scrollTop];
2939+ } else if(document.documentElement && (document.documentElement.scrollLeft || document.documentElement.scrollTop)) {
2940+ return [document.documentElement.scrollLeft, document.documentElement.scrollTop];
2941+ } else {
2942+ return [0, 0];
2943+ }
2944+ },
2945+
2946+
2947+ getViewSize : function() {
2948+ if(typeof window.innerWidth === 'number') {
2949+ return [window.innerWidth, window.innerHeight];
2950+ } else if(document.body && (document.body.clientWidth || document.body.clientHeight)) {
2951+ return [document.body.clientWidth, document.body.clientHeight];
2952+ } else if(document.documentElement && (document.documentElement.clientWidth || document.documentElement.clientHeight)) {
2953+ return [document.documentElement.clientWidth, document.documentElement.clientHeight];
2954+ } else {
2955+ return [0, 0];
2956+ }
2957+ },
2958+
2959+
2960+ URI : function(uri) { // See RFC3986
2961+
2962+ this.scheme = null;
2963+ this.authority = null;
2964+ this.path = '';
2965+ this.query = null;
2966+ this.fragment = null;
2967+
2968+ this.parse = function(uri) {
2969+ var m = uri.match(/^(([A-Za-z][0-9A-Za-z+.-]*)(:))?((\/\/)([^\/?#]*))?([^?#]*)((\?)([^#]*))?((#)(.*))?/);
2970+ this.scheme = m[3] ? m[2] : null;
2971+ this.authority = m[5] ? m[6] : null;
2972+ this.path = m[7];
2973+ this.query = m[9] ? m[10] : null;
2974+ this.fragment = m[12] ? m[13] : null;
2975+ return this;
2976+ };
2977+
2978+ this.toString = function() {
2979+ var result = '';
2980+ if(this.scheme !== null) { result = result + this.scheme + ':'; }
2981+ if(this.authority !== null) { result = result + '//' + this.authority; }
2982+ if(this.path !== null) { result = result + this.path; }
2983+ if(this.query !== null) { result = result + '?' + this.query; }
2984+ if(this.fragment !== null) { result = result + '#' + this.fragment; }
2985+ return result;
2986+ };
2987+
2988+ this.toAbsolute = function(base) {
2989+ var base = new jscolor.URI(base);
2990+ var r = this;
2991+ var t = new jscolor.URI;
2992+
2993+ if(base.scheme === null) { return false; }
2994+
2995+ if(r.scheme !== null && r.scheme.toLowerCase() === base.scheme.toLowerCase()) {
2996+ r.scheme = null;
2997+ }
2998+
2999+ if(r.scheme !== null) {
3000+ t.scheme = r.scheme;
3001+ t.authority = r.authority;
3002+ t.path = removeDotSegments(r.path);
3003+ t.query = r.query;
3004+ } else {
3005+ if(r.authority !== null) {
3006+ t.authority = r.authority;
3007+ t.path = removeDotSegments(r.path);
3008+ t.query = r.query;
3009+ } else {
3010+ if(r.path === '') { // TODO: == or === ?
3011+ t.path = base.path;
3012+ if(r.query !== null) {
3013+ t.query = r.query;
3014+ } else {
3015+ t.query = base.query;
3016+ }
3017+ } else {
3018+ if(r.path.substr(0,1) === '/') {
3019+ t.path = removeDotSegments(r.path);
3020+ } else {
3021+ if(base.authority !== null && base.path === '') { // TODO: == or === ?
3022+ t.path = '/'+r.path;
3023+ } else {
3024+ t.path = base.path.replace(/[^\/]+$/,'')+r.path;
3025+ }
3026+ t.path = removeDotSegments(t.path);
3027+ }
3028+ t.query = r.query;
3029+ }
3030+ t.authority = base.authority;
3031+ }
3032+ t.scheme = base.scheme;
3033+ }
3034+ t.fragment = r.fragment;
3035+
3036+ return t;
3037+ };
3038+
3039+ function removeDotSegments(path) {
3040+ var out = '';
3041+ while(path) {
3042+ if(path.substr(0,3)==='../' || path.substr(0,2)==='./') {
3043+ path = path.replace(/^\.+/,'').substr(1);
3044+ } else if(path.substr(0,3)==='/./' || path==='/.') {
3045+ path = '/'+path.substr(3);
3046+ } else if(path.substr(0,4)==='/../' || path==='/..') {
3047+ path = '/'+path.substr(4);
3048+ out = out.replace(/\/?[^\/]*$/, '');
3049+ } else if(path==='.' || path==='..') {
3050+ path = '';
3051+ } else {
3052+ var rm = path.match(/^\/?[^\/]*/)[0];
3053+ path = path.substr(rm.length);
3054+ out = out + rm;
3055+ }
3056+ }
3057+ return out;
3058+ }
3059+
3060+ if(uri) {
3061+ this.parse(uri);
3062+ }
3063+
3064+ },
3065+
3066+
3067+ /*
3068+ * Usage example:
3069+ * var myColor = new jscolor.color(myInputElement)
3070+ */
3071+
3072+ color : function(target, prop) {
3073+
3074+
3075+ this.required = true; // refuse empty values?
3076+ this.adjust = true; // adjust value to uniform notation?
3077+ this.hash = false; // prefix color with # symbol?
3078+ this.caps = true; // uppercase?
3079+ this.slider = true; // show the value/saturation slider?
3080+ this.valueElement = target; // value holder
3081+ this.styleElement = target; // where to reflect current color
3082+ this.onImmediateChange = null; // onchange callback (can be either string or function)
3083+ this.hsv = [0, 0, 1]; // read-only 0-6, 0-1, 0-1
3084+ this.rgb = [1, 1, 1]; // read-only 0-1, 0-1, 0-1
3085+
3086+ this.pickerOnfocus = true; // display picker on focus?
3087+ this.pickerMode = 'HSV'; // HSV | HVS
3088+ this.pickerPosition = 'bottom'; // left | right | top | bottom
3089+ this.pickerButtonHeight = 20; // px
3090+ this.pickerClosable = false;
3091+ this.pickerCloseText = 'Close';
3092+ this.pickerButtonColor = 'ButtonText'; // px
3093+ this.pickerFace = 10; // px
3094+ this.pickerFaceColor = 'ThreeDFace'; // CSS color
3095+ this.pickerBorder = 1; // px
3096+ this.pickerBorderColor = 'ThreeDHighlight ThreeDShadow ThreeDShadow ThreeDHighlight'; // CSS color
3097+ this.pickerInset = 1; // px
3098+ this.pickerInsetColor = 'ThreeDShadow ThreeDHighlight ThreeDHighlight ThreeDShadow'; // CSS color
3099+ this.pickerZIndex = 10000;
3100+
3101+
3102+ for(var p in prop) {
3103+ if(prop.hasOwnProperty(p)) {
3104+ this[p] = prop[p];
3105+ }
3106+ }
3107+
3108+
3109+ this.hidePicker = function() {
3110+ if(isPickerOwner()) {
3111+ removePicker();
3112+ }
3113+ };
3114+
3115+
3116+ this.showPicker = function() {
3117+ if(!isPickerOwner()) {
3118+ var tp = jscolor.getElementPos(target); // target pos
3119+ var ts = jscolor.getElementSize(target); // target size
3120+ var vp = jscolor.getViewPos(); // view pos
3121+ var vs = jscolor.getViewSize(); // view size
3122+ var ps = getPickerDims(this); // picker size
3123+ var a, b, c;
3124+ switch(this.pickerPosition.toLowerCase()) {
3125+ case 'left': a=1; b=0; c=-1; break;
3126+ case 'right':a=1; b=0; c=1; break;
3127+ case 'top': a=0; b=1; c=-1; break;
3128+ default: a=0; b=1; c=1; break;
3129+ }
3130+ var l = (ts[b]+ps[b])/2;
3131+ var pp = [ // picker pos
3132+ -vp[a]+tp[a]+ps[a] > vs[a] ?
3133+ (-vp[a]+tp[a]+ts[a]/2 > vs[a]/2 && tp[a]+ts[a]-ps[a] >= 0 ? tp[a]+ts[a]-ps[a] : tp[a]) :
3134+ tp[a],
3135+ -vp[b]+tp[b]+ts[b]+ps[b]-l+l*c > vs[b] ?
3136+ (-vp[b]+tp[b]+ts[b]/2 > vs[b]/2 && tp[b]+ts[b]-l-l*c >= 0 ? tp[b]+ts[b]-l-l*c : tp[b]+ts[b]-l+l*c) :
3137+ (tp[b]+ts[b]-l+l*c >= 0 ? tp[b]+ts[b]-l+l*c : tp[b]+ts[b]-l-l*c)
3138+ ];
3139+ drawPicker(pp[a], pp[b]);
3140+ }
3141+ };
3142+
3143+
3144+ this.importColor = function() {
3145+ if(!valueElement) {
3146+ this.exportColor();
3147+ } else {
3148+ if(!this.adjust) {
3149+ if(!this.fromString(valueElement.value, leaveValue)) {
3150+ styleElement.style.backgroundColor = styleElement.jscStyle.backgroundColor;
3151+ styleElement.style.color = styleElement.jscStyle.color;
3152+ this.exportColor(leaveValue | leaveStyle);
3153+ }
3154+ } else if(!this.required && /^\s*$/.test(valueElement.value)) {
3155+ valueElement.value = '';
3156+ styleElement.style.backgroundColor = styleElement.jscStyle.backgroundColor;
3157+ styleElement.style.color = styleElement.jscStyle.color;
3158+ this.exportColor(leaveValue | leaveStyle);
3159+
3160+ } else if(this.fromString(valueElement.value)) {
3161+ // OK
3162+ } else {
3163+ this.exportColor();
3164+ }
3165+ }
3166+ };
3167+
3168+
3169+ this.exportColor = function(flags) {
3170+ if(!(flags & leaveValue) && valueElement) {
3171+ var value = this.toString();
3172+ if(this.caps) { value = value.toUpperCase(); }
3173+ if(this.hash) { value = '#'+value; }
3174+ valueElement.value = value;
3175+ }
3176+ if(!(flags & leaveStyle) && styleElement) {
3177+ styleElement.style.backgroundColor =
3178+ '#'+this.toString();
3179+ styleElement.style.color =
3180+ 0.213 * this.rgb[0] +
3181+ 0.715 * this.rgb[1] +
3182+ 0.072 * this.rgb[2]
3183+ < 0.5 ? '#FFF' : '#000';
3184+ }
3185+ if(!(flags & leavePad) && isPickerOwner()) {
3186+ redrawPad();
3187+ }
3188+ if(!(flags & leaveSld) && isPickerOwner()) {
3189+ redrawSld();
3190+ }
3191+ };
3192+
3193+
3194+ this.fromHSV = function(h, s, v, flags) { // null = don't change
3195+ h<0 && (h=0) || h>6 && (h=6);
3196+ s<0 && (s=0) || s>1 && (s=1);
3197+ v<0 && (v=0) || v>1 && (v=1);
3198+ this.rgb = HSV_RGB(
3199+ h===null ? this.hsv[0] : (this.hsv[0]=h),
3200+ s===null ? this.hsv[1] : (this.hsv[1]=s),
3201+ v===null ? this.hsv[2] : (this.hsv[2]=v)
3202+ );
3203+ this.exportColor(flags);
3204+ };
3205+
3206+
3207+ this.fromRGB = function(r, g, b, flags) { // null = don't change
3208+ r<0 && (r=0) || r>1 && (r=1);
3209+ g<0 && (g=0) || g>1 && (g=1);
3210+ b<0 && (b=0) || b>1 && (b=1);
3211+ var hsv = RGB_HSV(
3212+ r===null ? this.rgb[0] : (this.rgb[0]=r),
3213+ g===null ? this.rgb[1] : (this.rgb[1]=g),
3214+ b===null ? this.rgb[2] : (this.rgb[2]=b)
3215+ );
3216+ if(hsv[0] !== null) {
3217+ this.hsv[0] = hsv[0];
3218+ }
3219+ if(hsv[2] !== 0) {
3220+ this.hsv[1] = hsv[1];
3221+ }
3222+ this.hsv[2] = hsv[2];
3223+ this.exportColor(flags);
3224+ };
3225+
3226+
3227+ this.fromString = function(hex, flags) {
3228+ var m = hex.match(/^\W*([0-9A-F]{3}([0-9A-F]{3})?)\W*$/i);
3229+ if(!m) {
3230+ return false;
3231+ } else {
3232+ if(m[1].length === 6) { // 6-char notation
3233+ this.fromRGB(
3234+ parseInt(m[1].substr(0,2),16) / 255,
3235+ parseInt(m[1].substr(2,2),16) / 255,
3236+ parseInt(m[1].substr(4,2),16) / 255,
3237+ flags
3238+ );
3239+ } else { // 3-char notation
3240+ this.fromRGB(
3241+ parseInt(m[1].charAt(0)+m[1].charAt(0),16) / 255,
3242+ parseInt(m[1].charAt(1)+m[1].charAt(1),16) / 255,
3243+ parseInt(m[1].charAt(2)+m[1].charAt(2),16) / 255,
3244+ flags
3245+ );
3246+ }
3247+ return true;
3248+ }
3249+ };
3250+
3251+
3252+ this.toString = function() {
3253+ return (
3254+ (0x100 | Math.round(255*this.rgb[0])).toString(16).substr(1) +
3255+ (0x100 | Math.round(255*this.rgb[1])).toString(16).substr(1) +
3256+ (0x100 | Math.round(255*this.rgb[2])).toString(16).substr(1)
3257+ );
3258+ };
3259+
3260+
3261+ function RGB_HSV(r, g, b) {
3262+ var n = Math.min(Math.min(r,g),b);
3263+ var v = Math.max(Math.max(r,g),b);
3264+ var m = v - n;
3265+ if(m === 0) { return [ null, 0, v ]; }
3266+ var h = r===n ? 3+(b-g)/m : (g===n ? 5+(r-b)/m : 1+(g-r)/m);
3267+ return [ h===6?0:h, m/v, v ];
3268+ }
3269+
3270+
3271+ function HSV_RGB(h, s, v) {
3272+ if(h === null) { return [ v, v, v ]; }
3273+ var i = Math.floor(h);
3274+ var f = i%2 ? h-i : 1-(h-i);
3275+ var m = v * (1 - s);
3276+ var n = v * (1 - s*f);
3277+ switch(i) {
3278+ case 6:
3279+ case 0: return [v,n,m];
3280+ case 1: return [n,v,m];
3281+ case 2: return [m,v,n];
3282+ case 3: return [m,n,v];
3283+ case 4: return [n,m,v];
3284+ case 5: return [v,m,n];
3285+ }
3286+ }
3287+
3288+
3289+ function removePicker() {
3290+ delete jscolor.picker.owner;
3291+ document.getElementsByTagName('body')[0].removeChild(jscolor.picker.boxB);
3292+ }
3293+
3294+
3295+ function drawPicker(x, y) {
3296+ if(!jscolor.picker) {
3297+ jscolor.picker = {
3298+ box : document.createElement('div'),
3299+ boxB : document.createElement('div'),
3300+ pad : document.createElement('div'),
3301+ padB : document.createElement('div'),
3302+ padM : document.createElement('div'),
3303+ sld : document.createElement('div'),
3304+ sldB : document.createElement('div'),
3305+ sldM : document.createElement('div'),
3306+ btn : document.createElement('div'),
3307+ btnS : document.createElement('span'),
3308+ btnT : document.createTextNode(THIS.pickerCloseText)
3309+ };
3310+ for(var i=0,segSize=4; i<jscolor.images.sld[1]; i+=segSize) {
3311+ var seg = document.createElement('div');
3312+ seg.style.height = segSize+'px';
3313+ seg.style.fontSize = '1px';
3314+ seg.style.lineHeight = '0';
3315+ jscolor.picker.sld.appendChild(seg);
3316+ }
3317+ jscolor.picker.sldB.appendChild(jscolor.picker.sld);
3318+ jscolor.picker.box.appendChild(jscolor.picker.sldB);
3319+ jscolor.picker.box.appendChild(jscolor.picker.sldM);
3320+ jscolor.picker.padB.appendChild(jscolor.picker.pad);
3321+ jscolor.picker.box.appendChild(jscolor.picker.padB);
3322+ jscolor.picker.box.appendChild(jscolor.picker.padM);
3323+ jscolor.picker.btnS.appendChild(jscolor.picker.btnT);
3324+ jscolor.picker.btn.appendChild(jscolor.picker.btnS);
3325+ jscolor.picker.box.appendChild(jscolor.picker.btn);
3326+ jscolor.picker.boxB.appendChild(jscolor.picker.box);
3327+ }
3328+
3329+ var p = jscolor.picker;
3330+
3331+ // controls interaction
3332+ p.box.onmouseup =
3333+ p.box.onmouseout = function() { target.focus(); };
3334+ p.box.onmousedown = function() { abortBlur=true; };
3335+ p.box.onmousemove = function(e) {
3336+ if (holdPad || holdSld) {
3337+ holdPad && setPad(e);
3338+ holdSld && setSld(e);
3339+ if (document.selection) {
3340+ document.selection.empty();
3341+ } else if (window.getSelection) {
3342+ window.getSelection().removeAllRanges();
3343+ }
3344+ dispatchImmediateChange();
3345+ }
3346+ };
3347+ p.padM.onmouseup =
3348+ p.padM.onmouseout = function() { if(holdPad) { holdPad=false; jscolor.fireEvent(valueElement,'change'); } };
3349+ p.padM.onmousedown = function(e) {
3350+ holdPad=true;
3351+ setPad(e);
3352+ dispatchImmediateChange();
3353+ };
3354+ p.sldM.onmouseup =
3355+ p.sldM.onmouseout = function() { if(holdSld) { holdSld=false; jscolor.fireEvent(valueElement,'change'); } };
3356+ p.sldM.onmousedown = function(e) {
3357+ holdSld=true;
3358+ setSld(e);
3359+ dispatchImmediateChange();
3360+ };
3361+
3362+ // picker
3363+ var dims = getPickerDims(THIS);
3364+ p.box.style.width = dims[0] + 'px';
3365+ p.box.style.height = dims[1] + 'px';
3366+
3367+ // picker border
3368+ p.boxB.style.position = 'absolute';
3369+ p.boxB.style.clear = 'both';
3370+ p.boxB.style.left = x+'px';
3371+ p.boxB.style.top = y+'px';
3372+ p.boxB.style.zIndex = THIS.pickerZIndex;
3373+ p.boxB.style.border = THIS.pickerBorder+'px solid';
3374+ p.boxB.style.borderColor = THIS.pickerBorderColor;
3375+ p.boxB.style.background = THIS.pickerFaceColor;
3376+
3377+ // pad image
3378+ p.pad.style.width = jscolor.images.pad[0]+'px';
3379+ p.pad.style.height = jscolor.images.pad[1]+'px';
3380+
3381+ // pad border
3382+ p.padB.style.position = 'absolute';
3383+ p.padB.style.left = THIS.pickerFace+'px';
3384+ p.padB.style.top = THIS.pickerFace+'px';
3385+ p.padB.style.border = THIS.pickerInset+'px solid';
3386+ p.padB.style.borderColor = THIS.pickerInsetColor;
3387+
3388+ // pad mouse area
3389+ p.padM.style.position = 'absolute';
3390+ p.padM.style.left = '0';
3391+ p.padM.style.top = '0';
3392+ p.padM.style.width = THIS.pickerFace + 2*THIS.pickerInset + jscolor.images.pad[0] + jscolor.images.arrow[0] + 'px';
3393+ p.padM.style.height = p.box.style.height;
3394+ p.padM.style.cursor = 'crosshair';
3395+
3396+ // slider image
3397+ p.sld.style.overflow = 'hidden';
3398+ p.sld.style.width = jscolor.images.sld[0]+'px';
3399+ p.sld.style.height = jscolor.images.sld[1]+'px';
3400+
3401+ // slider border
3402+ p.sldB.style.display = THIS.slider ? 'block' : 'none';
3403+ p.sldB.style.position = 'absolute';
3404+ p.sldB.style.right = THIS.pickerFace+'px';
3405+ p.sldB.style.top = THIS.pickerFace+'px';
3406+ p.sldB.style.border = THIS.pickerInset+'px solid';
3407+ p.sldB.style.borderColor = THIS.pickerInsetColor;
3408+
3409+ // slider mouse area
3410+ p.sldM.style.display = THIS.slider ? 'block' : 'none';
3411+ p.sldM.style.position = 'absolute';
3412+ p.sldM.style.right = '0';
3413+ p.sldM.style.top = '0';
3414+ p.sldM.style.width = jscolor.images.sld[0] + jscolor.images.arrow[0] + THIS.pickerFace + 2*THIS.pickerInset + 'px';
3415+ p.sldM.style.height = p.box.style.height;
3416+ try {
3417+ p.sldM.style.cursor = 'pointer';
3418+ } catch(eOldIE) {
3419+ p.sldM.style.cursor = 'hand';
3420+ }
3421+
3422+ // "close" button
3423+ function setBtnBorder() {
3424+ var insetColors = THIS.pickerInsetColor.split(/\s+/);
3425+ var pickerOutsetColor = insetColors.length < 2 ? insetColors[0] : insetColors[1] + ' ' + insetColors[0] + ' ' + insetColors[0] + ' ' + insetColors[1];
3426+ p.btn.style.borderColor = pickerOutsetColor;
3427+ }
3428+ p.btn.style.display = THIS.pickerClosable ? 'block' : 'none';
3429+ p.btn.style.position = 'absolute';
3430+ p.btn.style.left = THIS.pickerFace + 'px';
3431+ p.btn.style.bottom = THIS.pickerFace + 'px';
3432+ p.btn.style.padding = '0 15px';
3433+ p.btn.style.height = '18px';
3434+ p.btn.style.border = THIS.pickerInset + 'px solid';
3435+ setBtnBorder();
3436+ p.btn.style.color = THIS.pickerButtonColor;
3437+ p.btn.style.font = '12px sans-serif';
3438+ p.btn.style.textAlign = 'center';
3439+ try {
3440+ p.btn.style.cursor = 'pointer';
3441+ } catch(eOldIE) {
3442+ p.btn.style.cursor = 'hand';
3443+ }
3444+ p.btn.onmousedown = function () {
3445+ THIS.hidePicker();
3446+ };
3447+ p.btnS.style.lineHeight = p.btn.style.height;
3448+
3449+ // load images in optimal order
3450+ switch(modeID) {
3451+ case 0: var padImg = 'hs.png'; break;
3452+ case 1: var padImg = 'hv.png'; break;
3453+ }
3454+ p.padM.style.backgroundImage = "url('"+jscolor.getDir()+"cross.gif')";
3455+ p.padM.style.backgroundRepeat = "no-repeat";
3456+ p.sldM.style.backgroundImage = "url('"+jscolor.getDir()+"arrow.gif')";
3457+ p.sldM.style.backgroundRepeat = "no-repeat";
3458+ p.pad.style.backgroundImage = "url('"+jscolor.getDir()+padImg+"')";
3459+ p.pad.style.backgroundRepeat = "no-repeat";
3460+ p.pad.style.backgroundPosition = "0 0";
3461+
3462+ // place pointers
3463+ redrawPad();
3464+ redrawSld();
3465+
3466+ jscolor.picker.owner = THIS;
3467+ document.getElementsByTagName('body')[0].appendChild(p.boxB);
3468+ }
3469+
3470+
3471+ function getPickerDims(o) {
3472+ var dims = [
3473+ 2*o.pickerInset + 2*o.pickerFace + jscolor.images.pad[0] +
3474+ (o.slider ? 2*o.pickerInset + 2*jscolor.images.arrow[0] + jscolor.images.sld[0] : 0),
3475+ o.pickerClosable ?
3476+ 4*o.pickerInset + 3*o.pickerFace + jscolor.images.pad[1] + o.pickerButtonHeight :
3477+ 2*o.pickerInset + 2*o.pickerFace + jscolor.images.pad[1]
3478+ ];
3479+ return dims;
3480+ }
3481+
3482+
3483+ function redrawPad() {
3484+ // redraw the pad pointer
3485+ switch(modeID) {
3486+ case 0: var yComponent = 1; break;
3487+ case 1: var yComponent = 2; break;
3488+ }
3489+ var x = Math.round((THIS.hsv[0]/6) * (jscolor.images.pad[0]-1));
3490+ var y = Math.round((1-THIS.hsv[yComponent]) * (jscolor.images.pad[1]-1));
3491+ jscolor.picker.padM.style.backgroundPosition =
3492+ (THIS.pickerFace+THIS.pickerInset+x - Math.floor(jscolor.images.cross[0]/2)) + 'px ' +
3493+ (THIS.pickerFace+THIS.pickerInset+y - Math.floor(jscolor.images.cross[1]/2)) + 'px';
3494+
3495+ // redraw the slider image
3496+ var seg = jscolor.picker.sld.childNodes;
3497+
3498+ switch(modeID) {
3499+ case 0:
3500+ var rgb = HSV_RGB(THIS.hsv[0], THIS.hsv[1], 1);
3501+ for(var i=0; i<seg.length; i+=1) {
3502+ seg[i].style.backgroundColor = 'rgb('+
3503+ (rgb[0]*(1-i/seg.length)*100)+'%,'+
3504+ (rgb[1]*(1-i/seg.length)*100)+'%,'+
3505+ (rgb[2]*(1-i/seg.length)*100)+'%)';
3506+ }
3507+ break;
3508+ case 1:
3509+ var rgb, s, c = [ THIS.hsv[2], 0, 0 ];
3510+ var i = Math.floor(THIS.hsv[0]);
3511+ var f = i%2 ? THIS.hsv[0]-i : 1-(THIS.hsv[0]-i);
3512+ switch(i) {
3513+ case 6:
3514+ case 0: rgb=[0,1,2]; break;
3515+ case 1: rgb=[1,0,2]; break;
3516+ case 2: rgb=[2,0,1]; break;
3517+ case 3: rgb=[2,1,0]; break;
3518+ case 4: rgb=[1,2,0]; break;
3519+ case 5: rgb=[0,2,1]; break;
3520+ }
3521+ for(var i=0; i<seg.length; i+=1) {
3522+ s = 1 - 1/(seg.length-1)*i;
3523+ c[1] = c[0] * (1 - s*f);
3524+ c[2] = c[0] * (1 - s);
3525+ seg[i].style.backgroundColor = 'rgb('+
3526+ (c[rgb[0]]*100)+'%,'+
3527+ (c[rgb[1]]*100)+'%,'+
3528+ (c[rgb[2]]*100)+'%)';
3529+ }
3530+ break;
3531+ }
3532+ }
3533+
3534+
3535+ function redrawSld() {
3536+ // redraw the slider pointer
3537+ switch(modeID) {
3538+ case 0: var yComponent = 2; break;
3539+ case 1: var yComponent = 1; break;
3540+ }
3541+ var y = Math.round((1-THIS.hsv[yComponent]) * (jscolor.images.sld[1]-1));
3542+ jscolor.picker.sldM.style.backgroundPosition =
3543+ '0 ' + (THIS.pickerFace+THIS.pickerInset+y - Math.floor(jscolor.images.arrow[1]/2)) + 'px';
3544+ }
3545+
3546+
3547+ function isPickerOwner() {
3548+ return jscolor.picker && jscolor.picker.owner === THIS;
3549+ }
3550+
3551+
3552+ function blurTarget() {
3553+ if(valueElement === target) {
3554+ THIS.importColor();
3555+ }
3556+ if(THIS.pickerOnfocus) {
3557+ THIS.hidePicker();
3558+ }
3559+ }
3560+
3561+
3562+ function blurValue() {
3563+ if(valueElement !== target) {
3564+ THIS.importColor();
3565+ }
3566+ }
3567+
3568+
3569+ function setPad(e) {
3570+ var mpos = jscolor.getRelMousePos(e);
3571+ var x = mpos.x - THIS.pickerFace - THIS.pickerInset;
3572+ var y = mpos.y - THIS.pickerFace - THIS.pickerInset;
3573+ switch(modeID) {
3574+ case 0: THIS.fromHSV(x*(6/(jscolor.images.pad[0]-1)), 1 - y/(jscolor.images.pad[1]-1), null, leaveSld); break;
3575+ case 1: THIS.fromHSV(x*(6/(jscolor.images.pad[0]-1)), null, 1 - y/(jscolor.images.pad[1]-1), leaveSld); break;
3576+ }
3577+ }
3578+
3579+
3580+ function setSld(e) {
3581+ var mpos = jscolor.getRelMousePos(e);
3582+ var y = mpos.y - THIS.pickerFace - THIS.pickerInset;
3583+ switch(modeID) {
3584+ case 0: THIS.fromHSV(null, null, 1 - y/(jscolor.images.sld[1]-1), leavePad); break;
3585+ case 1: THIS.fromHSV(null, 1 - y/(jscolor.images.sld[1]-1), null, leavePad); break;
3586+ }
3587+ }
3588+
3589+
3590+ function dispatchImmediateChange() {
3591+ if (THIS.onImmediateChange) {
3592+ if (typeof THIS.onImmediateChange === 'string') {
3593+ eval(THIS.onImmediateChange);
3594+ } else {
3595+ THIS.onImmediateChange(THIS);
3596+ }
3597+ }
3598+ }
3599+
3600+
3601+ var THIS = this;
3602+ var modeID = this.pickerMode.toLowerCase()==='hvs' ? 1 : 0;
3603+ var abortBlur = false;
3604+ var
3605+ valueElement = jscolor.fetchElement(this.valueElement),
3606+ styleElement = jscolor.fetchElement(this.styleElement);
3607+ var
3608+ holdPad = false,
3609+ holdSld = false;
3610+ var
3611+ leaveValue = 1<<0,
3612+ leaveStyle = 1<<1,
3613+ leavePad = 1<<2,
3614+ leaveSld = 1<<3;
3615+
3616+ // target
3617+ jscolor.addEvent(target, 'focus', function() {
3618+ if(THIS.pickerOnfocus) { THIS.showPicker(); }
3619+ });
3620+ jscolor.addEvent(target, 'blur', function() {
3621+ if(!abortBlur) {
3622+ window.setTimeout(function(){ abortBlur || blurTarget(); abortBlur=false; }, 0);
3623+ } else {
3624+ abortBlur = false;
3625+ }
3626+ });
3627+
3628+ // valueElement
3629+ if(valueElement) {
3630+ var updateField = function() {
3631+ THIS.fromString(valueElement.value, leaveValue);
3632+ };
3633+ jscolor.addEvent(valueElement, 'keyup', updateField);
3634+ jscolor.addEvent(valueElement, 'input', updateField);
3635+ jscolor.addEvent(valueElement, 'blur', blurValue);
3636+ valueElement.setAttribute('autocomplete', 'off');
3637+ }
3638+
3639+ // styleElement
3640+ if(styleElement) {
3641+ styleElement.jscStyle = {
3642+ backgroundColor : styleElement.style.backgroundColor,
3643+ color : styleElement.style.color
3644+ };
3645+ }
3646+
3647+ // require images
3648+ switch(modeID) {
3649+ case 0: jscolor.requireImage('hs.png'); break;
3650+ case 1: jscolor.requireImage('hv.png'); break;
3651+ }
3652+ jscolor.requireImage('cross.gif');
3653+ jscolor.requireImage('arrow.gif');
3654+
3655+ this.importColor();
3656+ }
3657+
3658+};
3659+
3660+
3661+jscolor.install();
3662
3663=== modified file 'include/parser.php'
3664--- include/parser.php 2011-04-22 23:42:35 +0000
3665+++ include/parser.php 2012-02-27 14:24:17 +0000
3666@@ -1,7 +1,7 @@
3667 <?php
3668
3669 /**
3670- * Copyright (C) 2008-2011 FluxBB
3671+ * Copyright (C) 2008-2012 FluxBB
3672 * based on code by Rickard Andersson copyright (C) 2002-2008 PunBB
3673 * License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher
3674 */
3675@@ -83,13 +83,10 @@
3676
3677 // If the message contains a code tag we have to split it up (text within [code][/code] shouldn't be touched)
3678 if (strpos($text, '[code]') !== false && strpos($text, '[/code]') !== false)
3679- {
3680- list($inside, $outside) = split_text($text, '[code]', '[/code]', $errors);
3681- $text = implode("\1", $outside);
3682- }
3683+ list($inside, $text) = extract_blocks($text, '[code]', '[/code]');
3684
3685 // Tidy up lists
3686- $temp = preg_replace($re_list, 'preparse_list_tag(\'$2\', \'$1\', $errors)', $text);
3687+ $temp = preg_replace($re_list, 'preparse_list_tag(\'$2\', \'$1\')', $text);
3688
3689 // If the regex failed
3690 if ($temp === null)
3691@@ -125,7 +122,7 @@
3692 $text = $temp_text;
3693
3694 // Remove empty tags
3695- while (($new_text = strip_empty_bbcode($text, $errors)) !== false)
3696+ while (($new_text = strip_empty_bbcode($text)) !== false)
3697 {
3698 if ($new_text != $text)
3699 {
3700@@ -147,17 +144,14 @@
3701 //
3702 // Strip empty bbcode tags from some text
3703 //
3704-function strip_empty_bbcode($text, &$errors)
3705+function strip_empty_bbcode($text)
3706 {
3707 // If the message contains a code tag we have to split it up (empty tags within [code][/code] are fine)
3708 if (strpos($text, '[code]') !== false && strpos($text, '[/code]') !== false)
3709- {
3710- list($inside, $outside) = split_text($text, '[code]', '[/code]', $errors);
3711- $text = implode("\1", $outside);
3712- }
3713+ list($inside, $text) = extract_blocks($text, '[code]', '[/code]');
3714
3715 // Remove empty tags
3716- while (($new_text = preg_replace('/\[(b|u|s|ins|del|em|i|h|colou?r|doc|apt|quote|img|url|email|list|acronym|q|sup|sub|left|right|center|justify|video)(?:\=[^\]]*)?\]\s*\[\/\1\]/', '', $text)) !== NULL)
3717+ while (($new_text = preg_replace('%\[(b|u|s|ins|del|em|i|h|colou?r|doc|apt|quote|img|url|email|list|topic|post|forum|user|acronym|q|sup|sub|left|right|center|justify|video)(?:\=[^\]]*)?\]\s*\[/\1\]%', '', $text)) !== NULL)
3718 {
3719 if ($new_text != $text)
3720 $text = $new_text;
3721@@ -168,20 +162,18 @@
3722 // If we split up the message before we have to concatenate it together again (code tags)
3723 if (isset($inside))
3724 {
3725- $outside = explode("\1", $text);
3726+ $parts = explode("\1", $text);
3727 $text = '';
3728-
3729- $num_tokens = count($outside);
3730- for ($i = 0; $i < $num_tokens; ++$i)
3731+ foreach ($parts as $i => $part)
3732 {
3733- $text .= $outside[$i];
3734+ $text .= $part;
3735 if (isset($inside[$i]))
3736 $text .= '[code]'.$inside[$i].'[/code]';
3737 }
3738 }
3739
3740 // Remove empty code tags
3741- while (($new_text = preg_replace('/\[(code)\]\s*\[\/\1\]/', '', $text)) !== NULL)
3742+ while (($new_text = preg_replace('%\[(code)\]\s*\[/\1\]%', '', $text)) !== NULL)
3743 {
3744 if ($new_text != $text)
3745 $text = $new_text;
3746@@ -203,7 +195,7 @@
3747 // Start off by making some arrays of bbcode tags and what we need to do with each one
3748
3749 // List of all the tags
3750- $tags = array('quote', 'code', 'b', 'i', 'u', 's', 'ins', 'del', 'em', 'color', 'colour', 'doc', 'apt', 'url', 'email', 'img', 'list', '*', 'h', 'acronym', 'q', 'sup', 'sub', 'left', 'right', 'center', 'justify', 'video');
3751+ $tags = array('quote', 'code', 'b', 'i', 'u', 's', 'ins', 'del', 'em', 'color', 'colour', 'doc', 'apt', 'url', 'email', 'img', 'list', '*', 'h', 'topic', 'post', 'forum', 'user', 'acronym', 'q', 'sup', 'sub', 'left', 'right', 'center', 'justify', 'video');
3752 // List of tags that we need to check are open (You could not put b,i,u in here then illegal nesting like [b][i][/b][/i] would be allowed)
3753 $tags_opened = $tags;
3754 // and tags we need to check are closed (the same as above, added it just in case)
3755@@ -215,28 +207,32 @@
3756 // Block tags, block tags can only go within another block tag, they cannot be in a normal tag
3757 $tags_block = array('quote', 'code', 'list', 'h', '*', 'left', 'right', 'center', 'justify');
3758 // Inline tags, we do not allow new lines in these
3759- $tags_inline = array('b', 'i', 'u', 's', 'ins', 'del', 'em', 'color', 'colour', 'h', 'acronym', 'q', 'sup', 'sub');
3760+ $tags_inline = array('b', 'i', 'u', 's', 'ins', 'del', 'em', 'color', 'colour', 'h', 'topic', 'post', 'forum', 'user', 'acronym', 'q', 'sup', 'sub');
3761 // Tags we trim interior space
3762 $tags_trim = array('img', 'video');
3763 // Tags we remove quotes from the argument
3764- $tags_quotes = array('url', 'email', 'img', 'video');
3765+ $tags_quotes = array('url', 'email', 'img', 'video', 'topic', 'post', 'forum', 'user');
3766 // Tags we limit bbcode in
3767 $tags_limit_bbcode = array(
3768- '*' => array('b', 'i', 'u', 's', 'ins', 'del', 'em', 'color', 'colour', 'url', 'email', 'list', 'img', 'code', 'acronym', 'q', 'sup', 'sub', 'video'),
3769+ '*' => array('b', 'i', 'u', 's', 'ins', 'del', 'em', 'color', 'colour', 'url', 'email', 'list', 'img', 'code', 'topic', 'post', 'forum', 'user', 'acronym', 'q', 'sup', 'sub', 'video'),
3770 'list' => array('*'),
3771- 'url' => array('b', 'i', 'u', 's', 'ins', 'del', 'em', 'color', 'colour', 'img', 'acronym', 'q', 'sup', 'sub'),
3772- 'email' => array('b', 'i', 'u', 's', 'ins', 'del', 'em', 'color', 'colour', 'img', 'acronym', 'q', 'sup', 'sub'),
3773+ 'url' => array('img', 'acronym', 'q', 'sup', 'sub'),
3774+ 'email' => array('img', 'acronym', 'q', 'sup', 'sub'),
3775+ 'topic' => array('img', 'acronym', 'q', 'sup', 'sub'),
3776+ 'post' => array('img', 'acronym', 'q', 'sup', 'sub'),
3777+ 'forum' => array('img', 'acronym', 'q', 'sup', 'sub'),
3778+ 'user' => array('img', 'acronym', 'q', 'sup', 'sub'),
3779 'img' => array(),
3780- 'h' => array('b', 'i', 'u', 's', 'ins', 'del', 'em', 'color', 'colour', 'url', 'email'),
3781+ 'h' => array('b', 'i', 'u', 's', 'ins', 'del', 'em', 'color', 'colour', 'url', 'email', 'topic', 'post', 'forum', 'user'),
3782 'video' => array()
3783 );
3784 // Tags we can automatically fix bad nesting
3785
3786- $tags_fix = array('quote', 'b', 'i', 'u', 's', 'ins', 'del', 'em', 'color', 'colour', 'url', 'email', 'h');
3787-
3788- $split_text = preg_split("/(\[[\*a-zA-Z0-9-\/]*?(?:=.*?)?\])/", $text, -1, PREG_SPLIT_DELIM_CAPTURE|PREG_SPLIT_NO_EMPTY);
3789-
3790- $open_tags = array('post');
3791+ $tags_fix = array('quote', 'b', 'i', 'u', 's', 'ins', 'del', 'em', 'color', 'colour', 'url', 'email', 'h', 'topic', 'post', 'forum', 'user');
3792+
3793+ $split_text = preg_split('%(\[[\*a-zA-Z0-9-/]*?(?:=.*?)?\])%', $text, -1, PREG_SPLIT_DELIM_CAPTURE|PREG_SPLIT_NO_EMPTY);
3794+
3795+ $open_tags = array('fluxbb-bbcode');
3796 $open_args = array('');
3797 $opened_tag = 0;
3798 $new_text = '';
3799@@ -244,6 +240,7 @@
3800 $current_nest = '';
3801 $current_depth = array();
3802 $limit_bbcode = $tags;
3803+ $count_ignored = array();
3804
3805 foreach ($split_text as $current)
3806 {
3807@@ -254,7 +251,6 @@
3808 if (substr($current, 0, 1) != '[' || substr($current, -1, 1) != ']')
3809 {
3810 // It's not a bbcode tag so we put it on the end and continue
3811-
3812 // If we are nested too deeply don't add to the end
3813 if ($current_nest)
3814 continue;
3815@@ -264,7 +260,7 @@
3816 if (in_array($open_tags[$opened_tag], $tags_inline) && strpos($current, "\n") !== false)
3817 {
3818 // Deal with new lines
3819- $split_current = preg_split("/(\n\n+)/", $current, -1, PREG_SPLIT_DELIM_CAPTURE|PREG_SPLIT_NO_EMPTY);
3820+ $split_current = preg_split('%(\n\n+)%', $current, -1, PREG_SPLIT_DELIM_CAPTURE|PREG_SPLIT_NO_EMPTY);
3821 $current = '';
3822
3823 if (!pun_trim($split_current[0], "\n")) // The first part is a linebreak so we need to handle any open tags first
3824@@ -366,13 +362,24 @@
3825 $current = strtolower($current);
3826
3827 // This is if we are currently in a tag which escapes other bbcode such as code
3828+ // We keep a cound of ignored bbcodes (code tags) so we can nest them, but
3829+ // only balanced sets of tags can be nested
3830 if ($current_ignore)
3831 {
3832+ // Increase the current ignored tags counter
3833+ if ('['.$current_ignore.']' == $current)
3834+ $count_ignored[$current_tag]++;
3835+
3836+ // Decrease the current ignored tags counter
3837 if ('[/'.$current_ignore.']' == $current)
3838+ $count_ignored[$current_tag]--;
3839+
3840+ if ('[/'.$current_ignore.']' == $current && $count_ignored[$current_tag] == 0)
3841 {
3842 // We've finished the ignored section
3843 $current = '[/'.$current_tag.']';
3844 $current_ignore = '';
3845+ $count_ignored = array();
3846 }
3847
3848 $new_text .= $current;
3849@@ -407,7 +414,6 @@
3850 if (substr($current, 1, 1) == '/')
3851 {
3852 // This is if we are closing a tag
3853-
3854 if ($opened_tag == 0 || !in_array($current_tag, $open_tags))
3855 {
3856 // We tried to close a tag which is not open
3857@@ -530,6 +536,7 @@
3858 {
3859 // It's an ignore tag so we don't need to worry about what's inside it
3860 $current_ignore = $current_tag;
3861+ $count_ignored[$current_tag] = 1;
3862 $new_text .= $current;
3863 continue;
3864 }
3865@@ -561,7 +568,7 @@
3866 // Remove quotes from arguments for certain tags
3867 if (strpos($current, '=') !== false && in_array($current_tag, $tags_quotes))
3868 {
3869- $current = preg_replace('#\['.$current_tag.'=("|\'|)(.*?)\\1\]\s*#i', '['.$current_tag.'=$2]', $current);
3870+ $current = preg_replace('%\['.$current_tag.'=("|\'|)(.*?)\\1\]\s*%i', '['.$current_tag.'=$2]', $current);
3871 }
3872
3873 if (in_array($current_tag, array_keys($tags_limit_bbcode)))
3874@@ -600,7 +607,7 @@
3875 //
3876 // Preparse the contents of [list] bbcode
3877 //
3878-function preparse_list_tag($content, $type = '*', &$errors)
3879+function preparse_list_tag($content, $type = '*')
3880 {
3881 global $lang_common, $re_list;
3882
3883@@ -609,7 +616,7 @@
3884
3885 if (strpos($content,'[list') !== false)
3886 {
3887- $content = preg_replace($re_list, 'preparse_list_tag(\'$2\', \'$1\', $errors)', $content);
3888+ $content = preg_replace($re_list, 'preparse_list_tag(\'$2\', \'$1\')', $content);
3889 }
3890
3891 $items = explode('[*]', str_replace('\"', '"', $content));
3892@@ -631,11 +638,18 @@
3893 function handle_url_tag($url, $link = '', $bbcode = false)
3894 {
3895 $url = pun_trim($url);
3896+
3897+ // Deal with [url][img]http://example.com/test.png[/img][/url]
3898+ if (preg_match('%<img src=\\\\"(.*?)\\\\"%', $url, $matches))
3899+ return handle_url_tag($matches[1], $url, $bbcode);
3900+
3901 $full_url = str_replace(array(' ', '\'', '`', '"'), array('%20', '', '', ''), $url);
3902 if (strpos($url, 'www.') === 0) // If it starts with www, we add http://
3903 $full_url = 'http://'.$full_url;
3904 else if (strpos($url, 'ftp.') === 0) // Else if it starts with ftp, we add ftp://
3905 $full_url = 'ftp://'.$full_url;
3906+ else if (strpos($url, '/') === 0) // Allow for relative URLs that start with a slash
3907+ $full_url = get_base_url(true).$full_url;
3908 else if (strpos($url,'./') === 0) // Else if link is relative, we keep it "as it"
3909 $full_url = $full_url;
3910 else if (!preg_match('#^([a-z0-9]{3,6})://#', $url)) // Else if it doesn't start with abcdef://, we add http://
3911@@ -743,9 +757,9 @@
3912
3913 if (strpos($text, '[quote') !== false)
3914 {
3915- $text = preg_replace('#\[quote\]\s*#', '</p><div class="quotebox"><blockquote><div><p>', $text);
3916- $text = preg_replace('#\[quote=(&quot;|&\#039;|"|\'|)(.*?)\\1\]#se', '"</p><div class=\"quotebox\"><cite>".str_replace(array(\'[\', \'\\"\'), array(\'&#91;\', \'"\'), \'$2\')." ".$lang_common[\'wrote\']."</cite><blockquote><div><p>"', $text);
3917- $text = preg_replace('#\s*\[\/quote\]#S', '</p></div></blockquote></div><p>', $text);
3918+ $text = preg_replace('%\[quote\]\s*%', '</p><div class="quotebox"><blockquote><div><p>', $text);
3919+ $text = preg_replace('%\[quote=(&quot;|&\#039;|"|\'|)(.*?)\\1\]%se', '"</p><div class=\"quotebox\"><cite>".str_replace(array(\'[\', \'\\"\'), array(\'&#91;\', \'"\'), \'$2\')." ".$lang_common[\'wrote\']."</cite><blockquote><div><p>"', $text);
3920+ $text = preg_replace('%\s*\[\/quote\]%S', '</p></div></blockquote></div><p>', $text);
3921 }
3922
3923 if (!$is_signature)
3924@@ -754,26 +768,26 @@
3925 $replace[] = 'handle_list_tag(\'$2\', \'$1\')';
3926 }
3927
3928- $pattern[] = '#\[b\](.*?)\[/b\]#ms';
3929- $pattern[] = '#\[i\](.*?)\[/i\]#ms';
3930- $pattern[] = '#\[u\](.*?)\[/u\]#ms';
3931- $pattern[] = '#\[s\](.*?)\[/s\]#ms';
3932- $pattern[] = '#\[del\](.*?)\[/del\]#ms';
3933- $pattern[] = '#\[ins\](.*?)\[/ins\]#ms';
3934- $pattern[] = '#\[em\](.*?)\[/em\]#ms';
3935- $pattern[] = '#\[colou?r=([a-zA-Z]{3,20}|\#[0-9a-fA-F]{6}|\#[0-9a-fA-F]{3})](.*?)\[/colou?r\]#ms';
3936- $pattern[] = '#\[h\](.*?)\[/h\]#ms';
3937- $pattern[] = '#\[acronym\](.*?)\[/acronym\]#ms';
3938- $pattern[] = '#\[acronym=(.*?)\](.*?)\[/acronym\]#ms';
3939- $pattern[] = '#\[q\](.*?)\[/q\]#ms';
3940- $pattern[] = '#\[sup\](.*?)\[/sup\]#ms';
3941- $pattern[] = '#\[sub\](.*?)\[/sub\]#ms';
3942- $pattern[] = '#\[left\](.*?)\[/left\]#ms';
3943- $pattern[] = '#\[right\](.*?)\[/right\]#ms';
3944- $pattern[] = '#\[center\](.*?)\[/center\]#ms';
3945- $pattern[] = '#\[justify\](.*?)\[/justify\]#ms';
3946- $pattern[] = '#\[doc\]([-_\/a-zA-Z0-9]+)\[/doc\]#ms';
3947- $pattern[] = '#\[apt\]([a-zA-Z0-9][-\.a-zA-Z0-9]+)\[/apt\]#ms';
3948+ $pattern[] = '%\[b\](.*?)\[/b\]%ms';
3949+ $pattern[] = '%\[i\](.*?)\[/i\]%ms';
3950+ $pattern[] = '%\[u\](.*?)\[/u\]%ms';
3951+ $pattern[] = '%\[s\](.*?)\[/s\]%ms';
3952+ $pattern[] = '%\[del\](.*?)\[/del\]%ms';
3953+ $pattern[] = '%\[ins\](.*?)\[/ins\]%ms';
3954+ $pattern[] = '%\[em\](.*?)\[/em\]%ms';
3955+ $pattern[] = '%\[colou?r=([a-zA-Z]{3,20}|\#[0-9a-fA-F]{6}|\#[0-9a-fA-F]{3})](.*?)\[/colou?r\]%ms';
3956+ $pattern[] = '%\[h\](.*?)\[/h\]%ms';
3957+ $pattern[] = '%\[acronym\](.*?)\[/acronym\]%ms';
3958+ $pattern[] = '%\[acronym=(.*?)\](.*?)\[/acronym\]%ms';
3959+ $pattern[] = '%\[q\](.*?)\[/q\]%ms';
3960+ $pattern[] = '%\[sup\](.*?)\[/sup\]%ms';
3961+ $pattern[] = '%\[sub\](.*?)\[/sub\]%ms';
3962+ $pattern[] = '%\[left\](.*?)\[/left\]%ms';
3963+ $pattern[] = '%\[right\](.*?)\[/right\]%ms';
3964+ $pattern[] = '%\[center\](.*?)\[/center\]%ms';
3965+ $pattern[] = '%\[justify\](.*?)\[/justify\]%ms';
3966+ $pattern[] = '%\[doc\]([-_\/a-zA-Z0-9]+)\[/doc\]%ms';
3967+ $pattern[] = '%\[apt\]([a-zA-Z0-9][-\.a-zA-Z0-9]+)\[/apt\]%ms';
3968
3969 $replace[] = '<strong>$1</strong>';
3970 $replace[] = '<em>$1</em>';
3971@@ -798,8 +812,8 @@
3972
3973 if (($is_signature && $pun_config['p_sig_img_tag'] == '1') || (!$is_signature && $pun_config['p_message_img_tag'] == '1'))
3974 {
3975- $pattern[] = '#\[img\]((ht|f)tps?://)([^\s<"]*?)\[/img\]#e';
3976- $pattern[] = '#\[img=([^\[]*?)\]((ht|f)tps?://)([^\s<"]*?)\[/img\]#e';
3977+ $pattern[] = '%\[img\]((ht|f)tps?://)([^\s<"]*?)\[/img\]%e';
3978+ $pattern[] = '%\[img=([^\[]*?)\]((ht|f)tps?://)([^\s<"]*?)\[/img\]%e';
3979 if ($is_signature)
3980 {
3981 $replace[] = 'handle_img_tag(\'$1$3\', true)';
3982@@ -815,8 +829,8 @@
3983 // XABILON : parser video
3984 if (($is_signature && $pun_config['p_sig_img_tag'] == '1') || (!$is_signature && $pun_config['p_message_img_tag'] == '1'))
3985 {
3986- $pattern[] = '#\[video\]((ht|f)tps?://)([^\s<"]*?)\[/video\]#e';
3987- $pattern[] = '#\[video=([^\[]*?)\]((ht|f)tps?://)([^\s<"]*?)\[/video\]#e';
3988+ $pattern[] = '%\[video\]((ht|f)tps?://)([^\s<"]*?)\[/video\]%e';
3989+ $pattern[] = '%\[video=([^\[]*?)\]((ht|f)tps?://)([^\s<"]*?)\[/video\]%e';
3990 if ($is_signature)
3991 {
3992 $replace[] = 'handle_vid_tag(\'$1$3\', true)';
3993@@ -829,17 +843,33 @@
3994 }
3995 }
3996
3997- $pattern[] = '#\[url\]([^\[]*?)\[/url\]#e';
3998- $pattern[] = '#\[url=([^\[]+?)\](.*?)\[/url\]#e';
3999- $pattern[] = '#\[youtube\]([^\[]*?)\[/youtube\]#e';
4000- $pattern[] = '#\[email\]([^\[]*?)\[/email\]#';
4001- $pattern[] = '#\[email=([^\[]+?)\](.*?)\[/email\]#';
4002+ $pattern[] = '%\[url\]([^\[]*?)\[/url\]%e';
4003+ $pattern[] = '%\[url=([^\[]+?)\](.*?)\[/url\]%e';
4004+ $pattern[] = '%\[youtube\]([^\[]*?)\[/youtube\]%e';
4005+ $pattern[] = '%\[email\]([^\[]*?)\[/email\]%';
4006+ $pattern[] = '%\[email=([^\[]+?)\](.*?)\[/email\]%';
4007+ $pattern[] = '%\[topic\]([1-9]\d*)\[/topic\]%e';
4008+ $pattern[] = '%\[topic=([1-9]\d*)\](.*?)\[/topic\]%e';
4009+ $pattern[] = '%\[post\]([1-9]\d*)\[/post\]%e';
4010+ $pattern[] = '%\[post=([1-9]\d*)\](.*?)\[/post\]%e';
4011+ $pattern[] = '%\[forum\]([1-9]\d*)\[/forum\]%e';
4012+ $pattern[] = '%\[forum=([1-9]\d*)\](.*?)\[/forum\]%e';
4013+ $pattern[] = '%\[user\]([1-9]\d*)\[/user\]%e';
4014+ $pattern[] = '%\[user=([1-9]\d*)\](.*?)\[/user\]%e';
4015
4016 $replace[] = 'handle_url_tag(\'$1\')';
4017 $replace[] = 'handle_url_tag(\'$1\', \'$2\')';
4018 $replace[] = 'handle_url_tag(\'$1\')';
4019 $replace[] = '<a href="mailto:$1">$1</a>';
4020 $replace[] = '<a href="mailto:$1">$2</a>';
4021+ $replace[] = 'handle_url_tag(\''.get_base_url(true).'/viewtopic.php?id=$1\')';
4022+ $replace[] = 'handle_url_tag(\''.get_base_url(true).'/viewtopic.php?id=$1\', \'$2\')';
4023+ $replace[] = 'handle_url_tag(\''.get_base_url(true).'/viewtopic.php?pid=$1#p$1\')';
4024+ $replace[] = 'handle_url_tag(\''.get_base_url(true).'/viewtopic.php?pid=$1#p$1\', \'$2\')';
4025+ $replace[] = 'handle_url_tag(\''.get_base_url(true).'/viewforum.php?id=$1\')';
4026+ $replace[] = 'handle_url_tag(\''.get_base_url(true).'/viewforum.php?id=$1\', \'$2\')';
4027+ $replace[] = 'handle_url_tag(\''.get_base_url(true).'/profile.php?id=$1\')';
4028+ $replace[] = 'handle_url_tag(\''.get_base_url(true).'/profile.php?id=$1\', \'$2\')';
4029
4030 // This thing takes a while! :)
4031 $text = preg_replace($pattern, $replace, $text);
4032@@ -855,8 +885,8 @@
4033 {
4034 $text = ' '.$text;
4035
4036- $text = ucp_preg_replace('#(?<=[\s\]\)])(<)?(\[)?(\()?([\'"]?)(https?|ftp|news){1}://([\p{L}\p{N}\-]+\.([\p{L}\p{N}\-]+\.)*[\p{L}\p{N}]+(:[0-9]+)?(/[^\s\[]*[^\s.,?!\[;:-])?)\4(?(3)(\)))(?(2)(\]))(?(1)(>))(?![^\s]*\[/(?:url|img|video)\])#uie', 'stripslashes(\'$1$2$3$4\').handle_url_tag(\'$5://$6\', \'$5://$6\', true).stripslashes(\'$4$10$11$12\')', $text);
4037- $text = ucp_preg_replace('#(?<=[\s\]\)])(<)?(\[)?(\()?([\'"]?)(www|ftp)\.(([\p{L}\p{N}\-]+\.)*[\p{L}\p{N}]+(:[0-9]+)?(/[^\s\[]*[^\s.,?!\[;:-])?)\4(?(3)(\)))(?(2)(\]))(?(1)(>))(?![^\s]*\[/(?:url|img|video)\])#uie', 'stripslashes(\'$1$2$3$4\').handle_url_tag(\'$5.$6\', \'$5.$6\', true).stripslashes(\'$4$10$11$12\')', $text);
4038+ $text = ucp_preg_replace('%(?<=[\s\]\)])(<)?(\[)?(\()?([\'"]?)(https?|ftp|news){1}://([\p{L}\p{N}\-]+\.([\p{L}\p{N}\-]+\.)*[\p{L}\p{N}]+(:[0-9]+)?(/(?:[^\s\[]*[^\s.,?!\[;:-])?)?)\4(?(3)(\)))(?(2)(\]))(?(1)(>))(?![^\s]*\[/(?:url|img)\])%uie', 'stripslashes(\'$1$2$3$4\').handle_url_tag(\'$5://$6\', \'$5://$6\', true).stripslashes(\'$4$10$11$12\')', $text);
4039+ $text = ucp_preg_replace('%(?<=[\s\]\)])(<)?(\[)?(\()?([\'"]?)(www|ftp)\.(([\p{L}\p{N}\-]+\.)*[\p{L}\p{N}]+(:[0-9]+)?(/(?:[^\s\[]*[^\s.,?!\[;:-])?)?)\4(?(3)(\)))(?(2)(\]))(?(1)(>))(?![^\s]*\[/(?:url|img)\])%uie', 'stripslashes(\'$1$2$3$4\').handle_url_tag(\'$5.$6\', \'$5.$6\', true).stripslashes(\'$4$10$11$12\')', $text);
4040
4041 return substr($text, 1);
4042 }
4043@@ -874,7 +904,7 @@
4044 foreach ($smilies as $smiley_text => $smiley_img)
4045 {
4046 if (strpos($text, $smiley_text) !== false)
4047- $text = ucp_preg_replace('#(?<=[>\s])'.preg_quote($smiley_text, '#').'(?=[^\p{L}\p{N}])#um', '<img src="'.pun_htmlspecialchars(get_base_url(true).'/img/smilies/'.$smiley_img).'" width="15" height="15" alt="'.substr($smiley_img, 0, strrpos($smiley_img, '.')).'" />', $text);
4048+ $text = ucp_preg_replace('%(?<=[>\s])'.preg_quote($smiley_text, '%').'(?=[^\p{L}\p{N}])%um', '<img src="'.pun_htmlspecialchars(get_base_url(true).'/img/smilies/'.$smiley_img).'" width="15" height="15" alt="'.substr($smiley_img, 0, strrpos($smiley_img, '.')).'" />', $text);
4049 }
4050
4051 return substr($text, 1, -1);
4052@@ -896,10 +926,7 @@
4053
4054 // If the message contains a code tag we have to split it up (text within [code][/code] shouldn't be touched)
4055 if (strpos($text, '[code]') !== false && strpos($text, '[/code]') !== false)
4056- {
4057- list($inside, $outside) = split_text($text, '[code]', '[/code]', $errors);
4058- $text = implode("\1", $outside);
4059- }
4060+ list($inside, $text) = extract_blocks($text, '[code]', '[/code]');
4061
4062 if ($pun_config['p_message_bbcode'] == '1' && strpos($text, '[') !== false && strpos($text, ']') !== false)
4063 $text = do_bbcode($text);
4064@@ -915,16 +942,12 @@
4065 // If we split up the message before we have to concatenate it together again (code tags)
4066 if (isset($inside))
4067 {
4068- $outside = explode("\1", $text);
4069+ $parts = explode("\1", $text);
4070 $text = '';
4071-
4072- $num_tokens = count($outside);
4073-
4074- for ($i = 0; $i < $num_tokens; ++$i)
4075+ foreach ($parts as $i => $part)
4076 {
4077- $text .= $outside[$i];
4078+ $text .= $part;
4079 if (isset($inside[$i]))
4080- // $text .= '</p><div class="codebox"><pre><code>'.pun_trim($inside[$i], "\n\r").'</code></pre></div><p>';
4081 {
4082 $num_lines = (substr_count($inside[$i], "\n"));
4083 $text .= '</p><div class="codebox"><pre'.(($num_lines > 28) ? ' class="vscroll"' : '').'><code>'.pun_trim($inside[$i], "\n\r").'</code></pre></div><p>';
4084@@ -932,10 +955,30 @@
4085 }
4086 }
4087
4088+ return clean_paragraphs($text);
4089+}
4090+
4091+
4092+//
4093+// Clean up paragraphs and line breaks
4094+//
4095+function clean_paragraphs($text)
4096+{
4097 // Add paragraph tag around post, but make sure there are no empty paragraphs
4098- $text = preg_replace('#<br />\s*?<br />((\s*<br />)*)#i', "</p>$1<p>", $text);
4099- $text = str_replace('<p><br />', '<p>', $text);
4100- $text = str_replace('<p></p>', '', '<p>'.$text.'</p>');
4101+ $text = '<p>'.$text.'</p>';
4102+
4103+ // Replace any breaks next to paragraphs so our replace below catches them
4104+ $text = preg_replace('%(</?p>)(?:\s*?<br />){1,2}%i', '$1', $text);
4105+ $text = preg_replace('%(?:<br />\s*?){1,2}(</?p>)%i', '$1', $text);
4106+
4107+ // Remove any empty paragraph tags (inserted via quotes/lists/code/etc) which should be stripped
4108+ $text = str_replace('<p></p>', '', $text);
4109+
4110+ $text = preg_replace('%<br />\s*?<br />%i', '</p><p>', $text);
4111+
4112+ $text = str_replace('<p><br />', '<br /><p>', $text);
4113+ $text = str_replace('<br /></p>', '</p><br />', $text);
4114+ $text = str_replace('<p></p>', '<br /><br />', $text);
4115
4116 return $text;
4117 }
4118@@ -966,10 +1009,5 @@
4119 $replace = array('<br />', '&#160; &#160; ', '&#160; ', ' &#160;');
4120 $text = str_replace($pattern, $replace, $text);
4121
4122- // Add paragraph tag around post, but make sure there are no empty paragraphs
4123- $text = preg_replace('#<br />\s*?<br />((\s*<br />)*)#i', "</p>$1<p>", $text);
4124- $text = str_replace('<p><br />', '<p>', $text);
4125- $text = str_replace('<p></p>', '', '<p>'.$text.'</p>');
4126-
4127- return $text;
4128+ return clean_paragraphs($text);
4129 }
4130
4131=== modified file 'include/search_idx.php'
4132--- include/search_idx.php 2011-04-19 22:53:21 +0000
4133+++ include/search_idx.php 2012-02-27 14:24:17 +0000
4134@@ -1,7 +1,7 @@
4135 <?php
4136
4137 /**
4138- * Copyright (C) 2008-2011 FluxBB
4139+ * Copyright (C) 2008-2012 FluxBB
4140 * based on code by Rickard Andersson copyright (C) 2002-2008 PunBB
4141 * License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher
4142 */
4143@@ -47,25 +47,14 @@
4144 //
4145 function split_words($text, $idx)
4146 {
4147- // Remove BBCode
4148- $text = preg_replace('/\[\/?(b|u|s|ins|del|em|i|h|colou?r|quote|code|img|url|email|list)(?:\=[^\]]*)?\]/', ' ', $text);
4149- /* FluxToolBar */
4150- if (file_exists(FORUM_CACHE_DIR.'cache_fluxtoolbar_tag_search.php'))
4151- include FORUM_CACHE_DIR.'cache_fluxtoolbar_tag_search.php';
4152- else
4153- {
4154- require_once PUN_ROOT.'include/cache_fluxtoolbar.php';
4155- generate_ftb_cache('tags');
4156- require FORUM_CACHE_DIR.'cache_fluxtoolbar_tag_search.php';
4157- }
4158 // Remove any apostrophes or dashes which aren't part of words
4159- $text = substr(ucp_preg_replace('/((?<=[^\p{L}\p{N}])[\'\-]|[\'\-](?=[^\p{L}\p{N}]))/u', '', ' '.$text.' '), 1, -1);
4160+ $text = substr(ucp_preg_replace('%((?<=[^\p{L}\p{N}])[\'\-]|[\'\-](?=[^\p{L}\p{N}]))%u', '', ' '.$text.' '), 1, -1);
4161
4162 // Remove punctuation and symbols (actually anything that isn't a letter or number), allow apostrophes and dashes (and % * if we aren't indexing)
4163- $text = ucp_preg_replace('/(?![\'\-'.($idx ? '' : '%\*').'])[^\p{L}\p{N}]+/u', ' ', $text);
4164+ $text = ucp_preg_replace('%(?![\'\-'.($idx ? '' : '\%\*').'])[^\p{L}\p{N}]+%u', ' ', $text);
4165
4166 // Replace multiple whitespace or dashes
4167- $text = preg_replace('/(\s){2,}/u', '\1', $text);
4168+ $text = preg_replace('%(\s){2,}%u', '\1', $text);
4169
4170 // Fill an array with all the words
4171 $words = array_unique(explode(' ', $text));
4172@@ -116,6 +105,9 @@
4173 if (is_cjk($word))
4174 return !$idx;
4175
4176+ // Exclude % and * when checking whether current word is valid
4177+ $word = str_replace(array('%', '*'), '', $word);
4178+
4179 // Check the word is within the min/max length
4180 $num_chars = pun_strlen($word);
4181 return $num_chars >= PUN_SEARCH_MIN_WORD && $num_chars <= PUN_SEARCH_MAX_WORD;
4182@@ -136,7 +128,7 @@
4183 //
4184 function is_cjk($word)
4185 {
4186- return preg_match('/^'.PUN_CJK_HANGUL_REGEX.'+$/u', $word) ? true : false;
4187+ return preg_match('%^'.PUN_CJK_HANGUL_REGEX.'+$%u', $word) ? true : false;
4188 }
4189
4190
4191@@ -150,12 +142,23 @@
4192 if (!isset($patterns))
4193 {
4194 $patterns = array(
4195- '%\[img=([^\]]*+)\][^[]*+\[/img\]%' => '$1', // Keep the alt description
4196- '%\[(url|email)=[^\]]*+\]([^[]*+(?:(?!\[/\1\])\[[^[]*+)*)\[/\1\]%' => '$2', // Keep the text
4197- '%\[(img|url|email)\]([^[]*+(?:(?!\[/\1\])\[[^[]*+)*)\[/\1\]%' => '', // Remove the whole thing
4198+ '%\[img=([^\]]*+)\]([^[]*+)\[/img\]%' => '$2 $1', // Keep the url and description
4199+ '%\[(url|email)=([^\]]*+)\]([^[]*+(?:(?!\[/\1\])\[[^[]*+)*)\[/\1\]%' => '$2 $3', // Keep the url and text
4200+ '%\[(topic|post|forum|user)\][1-9]\d*\[/\1\]%' => ' ', // Do not index topic/post/forum/user ID
4201+ '%\[/?(b|u|s|ins|del|em|i|h|colou?r|quote|code|img|url|email|list|topic|post|forum|user)(?:\=[^\]]*)?\]%' => ' ' // Remove BBCode
4202 );
4203 }
4204
4205+ /* FluxToolBar */
4206+ if (file_exists(FORUM_CACHE_DIR.'cache_fluxtoolbar_tag_search.php'))
4207+ include FORUM_CACHE_DIR.'cache_fluxtoolbar_tag_search.php';
4208+ else
4209+ {
4210+ require_once PUN_ROOT.'include/cache_fluxtoolbar.php';
4211+ generate_ftb_cache('tags');
4212+ require FORUM_CACHE_DIR.'cache_fluxtoolbar_tag_search.php';
4213+ }
4214+
4215 return preg_replace(array_keys($patterns), array_values($patterns), $text);
4216 }
4217
4218
4219=== modified file 'include/template/main.tpl'
4220--- include/template/main.tpl 2012-02-23 11:48:07 +0000
4221+++ include/template/main.tpl 2012-02-27 14:24:17 +0000
4222@@ -81,7 +81,7 @@
4223 </div>
4224 </div>
4225 </div>
4226-<!-- Inclusion du script pour les stats de Sp4rKy -->
4227-<pun_include "piwik.php">
4228+ <!-- Inclusion du script pour les stats de Sp4rKy -->
4229+ <pun_include "piwik.php">
4230 </body>
4231 </html>
4232
4233=== modified file 'include/toolbar_func.js'
4234--- include/toolbar_func.js 2010-10-08 13:18:35 +0000
4235+++ include/toolbar_func.js 2012-02-27 14:24:17 +0000
4236@@ -1,8 +1,7 @@
4237 /***********************************************************************
4238
4239- Copyright (C) 2010 Mpok
4240+ Copyright (C) 2010-2011 Mpok
4241 based on code Copyright (C) 2006 Vincent Garnier
4242- based on code Copyright (c) 2004 Olivier Meunier and contributors
4243 License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher
4244
4245 ************************************************************************/
4246@@ -19,21 +18,49 @@
4247 var toolbar = document.createElement('div');
4248 toolbar.id = 'toolbar';
4249 toolbar.style.padding = '4px 0';
4250+ var toolbar_range;
4251+ var selected = false;
4252+ var start;
4253+ var before, selection, after;
4254+ var nb_lines_bef, nb_lines_sel;
4255+ var numbut = 0;
4256+ var tabbut = new Array();
4257
4258 var smilies = document.createElement('div');
4259 smilies.id = 'smilies';
4260 smilies.style.display = 'none';
4261 smilies.style.padding = '0.3em 0';
4262
4263+ function doEvent(obj, event, fn, mode)
4264+ {
4265+ if (mode)
4266+ {
4267+ if (obj.addEventListener)
4268+ obj.addEventListener(event, fn, false);
4269+ else if (obj.attachEvent)
4270+ obj.attachEvent ('on' + event, fn);
4271+ }
4272+ else
4273+ {
4274+ if (obj.removeEventListener)
4275+ obj.removeEventListener(event, fn, false);
4276+ else if (obj.detachEvent)
4277+ obj.detachEvent ('on' + event, fn);
4278+ }
4279+ }
4280+
4281 function addButton(src, title, fn)
4282 {
4283 var i = document.createElement('img');
4284+ i.id = 'but_' + numbut;
4285 i.src = bt_img_path + src;
4286 i.title = title.replace(/&quot;/g, '"');
4287+ i.tabIndex = 400;
4288 i.style.padding = '0 5px 0 0';
4289- i.onclick = function() { try { fn() } catch (e) { } return false };
4290- i.tabIndex = 400;
4291 toolbar.appendChild(i);
4292+ tabbut[numbut] = fn;
4293+ doEvent(i, 'click', fn, true);
4294+ numbut++;
4295 }
4296
4297 function addSmiley(src, txt)
4298@@ -46,10 +73,10 @@
4299 htxt = htxt.replace(new RegExp(/&gt;/g), '>');
4300 i.src = smilies_img_path + src;
4301 i.title = txt;
4302+ i.tabIndex = 400;
4303 i.style.verticalAlign = 'middle';
4304 i.style.padding = '0 5px 0 0';
4305- i.onclick = function() { try { encloseSelection(htxt, '') } catch (e) { } return false };
4306- i.tabIndex = 400;
4307+ doEvent(i, 'click', function() {encloseSelection(htxt, '', '')}, true);
4308 smilies.appendChild(i);
4309 }
4310
4311@@ -61,49 +88,102 @@
4312 toolbar.appendChild(s);
4313 }
4314
4315- function encloseSelection(prefix, suffix, fn)
4316+ function unTrim(sel_range, type)
4317+ {
4318+ if (!type)
4319+ var range = sel_range.duplicate();
4320+ else
4321+ {
4322+ var range = document.body.createTextRange();
4323+ range.moveToElementText(textarea);
4324+ range.setEndPoint(type, sel_range);
4325+ }
4326+ var finished = false;
4327+ var trim = range.text;
4328+ var untrim = range.text;
4329+ do
4330+ {
4331+ if (!finished)
4332+ {
4333+ if (range.compareEndPoints('StartToEnd', range) == 0)
4334+ finished = true;
4335+ else
4336+ {
4337+ range.moveEnd('character', -1);
4338+ if (range.text == trim)
4339+ untrim += "\r\n";
4340+ else
4341+ finished = true;
4342+ }
4343+ }
4344+ }
4345+ while (!finished);
4346+ return(untrim);
4347+ }
4348+
4349+ function findSelection()
4350 {
4351 textarea.focus();
4352- var start, end, sel, scrollPos, subst;
4353-
4354- if (typeof(document['selection']) != 'undefined')
4355- sel = document.selection.createRange().text;
4356- else if (typeof(textarea['setSelectionRange']) != 'undefined')
4357+ if (typeof(textarea['setSelectionRange']) != 'undefined')
4358 {
4359 start = textarea.selectionStart;
4360- end = textarea.selectionEnd;
4361- scrollPos = textarea.scrollTop;
4362- sel = textarea.value.substring(start, end);
4363+ before = textarea.value.substring(0, start);
4364+ var end = textarea.selectionEnd;
4365+ after = textarea.value.substring(end);
4366+ selection = textarea.value.substring(start, end);
4367 }
4368-
4369- if (sel.match(/ $/))
4370+ else if (typeof(document['selection']) != 'undefined')
4371 {
4372- // exclude ending space char, if any
4373- sel = sel.substring(0, sel.length - 1);
4374- suffix = suffix + " ";
4375+ toolbar_range = document.selection.createRange();
4376+ selection = unTrim(toolbar_range);
4377+ before = unTrim(toolbar_range, 'EndToStart');
4378+ after = unTrim(toolbar_range, 'StartToEnd');
4379+ var ret_arr = before.match(/\n/g);
4380+ if (ret_arr != null)
4381+ nb_lines_bef = ret_arr.length;
4382+ else
4383+ nb_lines_bef = 0;
4384+ ret_arr = selection.match(/\n/g);
4385+ if (ret_arr != null)
4386+ nb_lines_sel = ret_arr.length;
4387+ else
4388+ nb_lines_sel = 0;
4389 }
4390+ selected = true;
4391+ }
4392
4393+ function encloseSelection(prefix, suffix, fn)
4394+ {
4395+ if (selected == false)
4396+ findSelection();
4397+ selected = false;
4398 if (typeof(fn) == 'function')
4399- var res = (sel) ? fn(sel) : fn('');
4400+ var res = (selection) ? fn(selection) : fn('');
4401+ else if (fn.substring(0, 4) == 'rep=')
4402+ var res = fn.substring(4);
4403 else
4404- var res = (sel) ? sel : '';
4405-
4406- subst = prefix + res + suffix;
4407-
4408- if (typeof(document['selection']) != 'undefined')
4409- {
4410- var range = document.selection.createRange().text = subst;
4411- textarea.caretPos -= suffix.length;
4412- }
4413- else if (typeof(textarea['setSelectionRange']) != 'undefined')
4414- {
4415- textarea.value = textarea.value.substring(0, start) + subst + textarea.value.substring(end);
4416- if (sel)
4417+ var res = (selection) ? selection : '';
4418+ var subst = prefix + res + suffix;
4419+
4420+ var scrollPos = textarea.scrollTop;
4421+ textarea.value = before + subst + after;
4422+ if (typeof(textarea['setSelectionRange']) != 'undefined')
4423+ {
4424+ if (selection || (typeof(fn) != 'function' && fn.substring(0, 4) == 'rep='))
4425 textarea.setSelectionRange(start + subst.length, start + subst.length);
4426 else
4427 textarea.setSelectionRange(start + prefix.length, start + prefix.length);
4428- textarea.scrollTop = scrollPos;
4429- }
4430+ }
4431+ else if (typeof(document['selection']) != 'undefined')
4432+ {
4433+ var dup = toolbar_range.duplicate();
4434+ if (selection || (typeof(fn) != 'function' && fn.substring(0, 4) == 'rep='))
4435+ dup.move('character', before.length - nb_lines_bef - nb_lines_sel + subst.length);
4436+ else
4437+ dup.move('character', before.length - nb_lines_bef + prefix.length);
4438+ dup.select();
4439+ }
4440+ textarea.scrollTop = scrollPos;
4441 }
4442
4443 function draw()
4444@@ -114,9 +194,7 @@
4445
4446 function singleTag(tag)
4447 {
4448- var stag = '[' + tag + ']';
4449- var etag = '[/' + tag + ']';
4450- encloseSelection(stag, etag);
4451+ encloseSelection('[' + tag + ']', '[/' + tag + ']', '');
4452 }
4453
4454 function btSingle(img, tag, label)
4455@@ -128,14 +206,38 @@
4456 {
4457 addButton(img, label,
4458 function() {
4459- encloseSelection('', '',
4460- function(str) {
4461- var var_1 = window.prompt(msg_1, '');
4462- if (!var_1)
4463- return '[' + tag + ']' + str + '[/' + tag + ']';
4464+ var var_1 = window.prompt(msg_1, '');
4465+ if (!var_1)
4466+ singleTag(tag);
4467+ else
4468+ encloseSelection('[' + tag + '=' + var_1 + ']', '[/' + tag +']', '');
4469+ });
4470+ }
4471+
4472+ function btPrompt_2(img, tag, label, msg_1, msg_2, reverse)
4473+ {
4474+ addButton(img, label,
4475+ function() {
4476+ var var_1 = window.prompt(msg_1, '');
4477+ if (!var_1)
4478+ {
4479+ textarea.focus();
4480+ return;
4481+ }
4482+ else
4483+ {
4484+ findSelection();
4485+ var var_2 = window.prompt(msg_2, selection);
4486+ if (var_2)
4487+ {
4488+ if (reverse)
4489+ encloseSelection('[' + tag + '=' + var_2 + ']', '[/' + tag +']', 'rep=' + var_1);
4490 else
4491- return '[' + tag + '=' + var_1 + ']' + str + '[/' + tag +']';
4492- });
4493+ encloseSelection('[' + tag + '=' + var_1 + ']', '[/' + tag +']', 'rep=' + var_2);
4494+ }
4495+ else
4496+ encloseSelection('[' + tag + ']', '[/' + tag + ']', 'rep=' + var_1);
4497+ }
4498 });
4499 }
4500
4501@@ -143,49 +245,74 @@
4502 {
4503 addButton(img, label,
4504 function() {
4505- encloseSelection('', '',
4506- function(str) {
4507- var var_1 = window.prompt(msg_1, '');
4508- if (!var_1)
4509- return str;
4510- else
4511- return '[' + tag + ']' + var_1 + '[/' + tag + ']';
4512- });
4513+ var var_1 = window.prompt(msg_1, '');
4514+ if (!var_1)
4515+ {
4516+ textarea.focus();
4517+ return;
4518+ }
4519+ else
4520+ encloseSelection('[' + tag + ']', '[/' + tag + ']', 'rep=' + var_1);
4521 });
4522 }
4523
4524- function btPrompt_2(img, tag, label, msg_1, msg_2, reverse)
4525+ function switchEvent(mode)
4526 {
4527- addButton(img, label,
4528- function() {
4529- encloseSelection('', '',
4530- function(str) {
4531- var var_1 = window.prompt(msg_1, '');
4532- if (!var_1)
4533- return str;
4534- var var_2 = window.prompt(msg_2, str);
4535- if (var_2)
4536- {
4537- if (reverse)
4538- return '[' + tag + '=' + var_2 + ']' + var_1 + '[/' + tag +']';
4539- else
4540- return '[' + tag + '=' + var_1 + ']' + var_2 + '[/' + tag +']';
4541- }
4542- else
4543- return '[' + tag + ']' + var_1 + '[/' + tag + ']';
4544- });
4545- });
4546+ for (var i = 0; i < toolbar.childNodes.length; i++)
4547+ {
4548+ var child = toolbar.childNodes[i];
4549+ if (child.id.substring(0, 4) == 'but_')
4550+ doEvent(child, 'click', tabbut[child.id.substring(4)], mode);
4551+ }
4552 }
4553
4554 function btColor(img, label)
4555 {
4556- addButton(img, label,
4557- function() {
4558- document.getElementById('req_message').focus();
4559- var width = 380;
4560- var height = 240;
4561- window.open('color_picker.php', 'cp', 'alwaysRaised=yes, dependent=yes, resizable=no, location=no, width=' + width + ', height=' + height + ', menubar=no, status=yes, scrollbars=no, menubar=no');
4562- });
4563+ var i = document.createElement('img');
4564+ i.src = bt_img_path + img;
4565+ i.title = label.replace(/&quot;/g, '"');
4566+ i.style.padding = '0 5px 0 0';
4567+ i.tabIndex = 400;
4568+ toolbar.appendChild(i);
4569+ var p = document.createElement('input');
4570+ p.type = 'text';
4571+ p.id = 'col_choose';
4572+ p.size = 6;
4573+ p.maxLength = 7;
4574+ p.value = '#ffffff';
4575+ p.style.height = '11px';
4576+ p.style.marginTop = '0';
4577+ p.style.marginRight = '2px';
4578+ p.style.verticalAlign = '2px';
4579+ p.style.display = 'none';
4580+ p.tabIndex = 400;
4581+ toolbar.insertBefore(p, i);
4582+ var j = document.createElement('img');
4583+ j.src = bt_img_path + img;
4584+ j.title = label.replace(/&quot;/g, '"');
4585+ j.style.padding = '0 5px 0 0';
4586+ j.style.display = 'none';
4587+ j.tabIndex = 400;
4588+ toolbar.appendChild(j);
4589+ var pick = new jscolor.color(i, {hash: true, caps: false, required: false, adjust: false, valueElement: p, styleElement: p, pickerOnfocus: false, pickerBorder: 2, pickerFaceColor: '#d0d0d0'});
4590+ doEvent(i, 'click', function() {
4591+ findSelection();
4592+ p.style.display = 'inline';
4593+ pick.showPicker();
4594+ i.style.display = 'none';
4595+ j.style.display = 'inline';
4596+ switchEvent(false);
4597+ }, true);
4598+ doEvent(j, 'click', function() {
4599+ pick.hidePicker();
4600+ p.style.display = 'none';
4601+ if (p.value)
4602+ encloseSelection('[color=' + p.value + ']', '[/color]', '');
4603+ i.style.display = 'inline';
4604+ j.style.display = 'none';
4605+ switchEvent(true);
4606+ textarea.focus();
4607+ }, true);
4608 }
4609
4610 function btSmilies(img, label)
4611@@ -211,7 +338,7 @@
4612 var l = document.createElement('span');
4613 l.style.padding = '1em';
4614 l.style.cursor = 'pointer';
4615- l.onclick = function() { popup_smilies() };
4616+ doEvent(l, 'click', popup_smilies, true);
4617 l.appendChild(document.createTextNode(txt));
4618 smilies.appendChild(l);
4619 }
4620
4621=== modified file 'include/utf8/utf8.php'
4622--- include/utf8/utf8.php 2010-10-08 13:18:35 +0000
4623+++ include/utf8/utf8.php 2012-02-27 14:24:17 +0000
4624@@ -34,7 +34,7 @@
4625
4626 if (extension_loaded('mbstring') && !defined('UTF8_USE_MBSTRING') && !defined('UTF8_USE_NATIVE'))
4627 define('UTF8_USE_MBSTRING', true);
4628-else
4629+else if (!defined('UTF8_USE_NATIVE'))
4630 define('UTF8_USE_NATIVE', true);
4631
4632 // utf8_strpos() and utf8_strrpos() need utf8_bad_strip() to strip invalid
4633
4634=== modified file 'include/utf8/utils/bad.php'
4635--- include/utf8/utils/bad.php 2010-10-08 13:18:35 +0000
4636+++ include/utf8/utils/bad.php 2012-02-27 14:24:17 +0000
4637@@ -114,33 +114,9 @@
4638 * @package utf8
4639 * @subpackage bad
4640 */
4641-function utf8_bad_strip($str)
4642+function utf8_bad_strip($original)
4643 {
4644- $UTF8_BAD =
4645- '([\x00-\x7F]'. # ASCII (including control chars)
4646- '|[\xC2-\xDF][\x80-\xBF]'. # Non-overlong 2-byte
4647- '|\xE0[\xA0-\xBF][\x80-\xBF]'. # Excluding overlongs
4648- '|[\xE1-\xEC\xEE\xEF][\x80-\xBF]{2}'. # Straight 3-byte
4649- '|\xED[\x80-\x9F][\x80-\xBF]'. # Excluding surrogates
4650- '|\xF0[\x90-\xBF][\x80-\xBF]{2}'. # Planes 1-3
4651- '|[\xF1-\xF3][\x80-\xBF]{3}'. # Planes 4-15
4652- '|\xF4[\x80-\x8F][\x80-\xBF]{2}'. # Plane 16
4653- '|(.{1}))'; # Invalid byte
4654-
4655- ob_start();
4656-
4657- while (preg_match('/'.$UTF8_BAD.'/S', $str, $matches))
4658- {
4659- if (!isset($matches[2]))
4660- echo $matches[0];
4661-
4662- $str = substr($str, strlen($matches[0]));
4663- }
4664-
4665- $result = ob_get_contents();
4666- ob_end_clean();
4667-
4668- return $result;
4669+ return utf8_bad_replace($original, '');
4670 }
4671
4672 /**
4673@@ -156,34 +132,53 @@
4674 * @package utf8
4675 * @subpackage bad
4676 */
4677-function utf8_bad_replace($str, $replace='?')
4678-{
4679- $UTF8_BAD =
4680- '([\x00-\x7F]'. # ASCII (including control chars)
4681- '|[\xC2-\xDF][\x80-\xBF]'. # Non-overlong 2-byte
4682- '|\xE0[\xA0-\xBF][\x80-\xBF]'. # Excluding overlongs
4683- '|[\xE1-\xEC\xEE\xEF][\x80-\xBF]{2}'. # Straight 3-byte
4684- '|\xED[\x80-\x9F][\x80-\xBF]'. # Excluding surrogates
4685- '|\xF0[\x90-\xBF][\x80-\xBF]{2}'. # Planes 1-3
4686- '|[\xF1-\xF3][\x80-\xBF]{3}'. # Planes 4-15
4687- '|\xF4[\x80-\x8F][\x80-\xBF]{2}'. # Plane 16
4688- '|(.{1}))'; # Invalid byte
4689-
4690- ob_start();
4691-
4692- while (preg_match('/'.$UTF8_BAD.'/S', $str, $matches))
4693- {
4694- if (!isset($matches[2]))
4695- echo $matches[0];
4696- else
4697- echo $replace;
4698-
4699- $str = substr($str, strlen($matches[0]));
4700+function utf8_bad_replace($original, $replace = '?') {
4701+ $result = '';
4702+
4703+ $strlen = strlen($original);
4704+ for ($i = 0; $i < $strlen;) {
4705+ $char = $original[$i++];
4706+ $byte = ord($char);
4707+
4708+ if ($byte < 0x80) $bytes = 0; // 1-bytes (00000000 - 01111111)
4709+ else if ($byte < 0xC0) { // 1-bytes (10000000 - 10111111)
4710+ $result .= $replace;
4711+ continue;
4712+ }
4713+ else if ($byte < 0xE0) $bytes = 1; // 2-bytes (11000000 - 11011111)
4714+ else if ($byte < 0xF0) $bytes = 2; // 3-bytes (11100000 - 11101111)
4715+ else if ($byte < 0xF8) $bytes = 3; // 4-bytes (11110000 - 11110111)
4716+ else if ($byte < 0xFC) $bytes = 4; // 5-bytes (11111000 - 11111011)
4717+ else if ($byte < 0xFE) $bytes = 5; // 6-bytes (11111100 - 11111101)
4718+ else { // Otherwise it's something invalid
4719+ $result .= $replace;
4720+ continue;
4721+ }
4722+
4723+ // Check our input actually has enough data
4724+ if ($i + $bytes > $strlen) {
4725+ $result .= $replace;
4726+ continue;
4727+ }
4728+
4729+ // If we've got this far then we have a multiple-byte character
4730+ for ($j = 0; $j < $bytes; $j++) {
4731+ $byte = $original[$i + $j];
4732+
4733+ $char .= $byte;
4734+ $byte = ord($byte);
4735+
4736+ // Every following byte must be 10000000 - 10111111
4737+ if ($byte < 0x80 || $byte > 0xBF) {
4738+ $result .= $replace;
4739+ continue 2;
4740+ }
4741+ }
4742+
4743+ $i += $bytes;
4744+ $result .= $char;
4745 }
4746
4747- $result = ob_get_contents();
4748- ob_end_clean();
4749-
4750 return $result;
4751 }
4752
4753
4754=== modified file 'install.php'
4755--- install.php 2011-04-19 22:53:21 +0000
4756+++ install.php 2012-02-27 14:24:17 +0000
4757@@ -1,15 +1,15 @@
4758 <?php
4759
4760 /**
4761- * Copyright (C) 2008-2011 FluxBB
4762+ * Copyright (C) 2008-2012 FluxBB
4763 * based on code by Rickard Andersson copyright (C) 2002-2008 PunBB
4764 * License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher
4765 */
4766
4767 // The FluxBB version this script installs
4768-define('FORUM_VERSION', '1.4.5');
4769+define('FORUM_VERSION', '1.4.8');
4770
4771-define('FORUM_DB_REVISION', 11);
4772+define('FORUM_DB_REVISION', 15);
4773 define('FORUM_SI_REVISION', 2);
4774 define('FORUM_PARSER_REVISION', 2);
4775
4776@@ -22,40 +22,6 @@
4777
4778 define('PUN_ROOT', dirname(__FILE__).'/');
4779
4780-// If we've been passed a default language, use it
4781-$install_lang = isset($_REQUEST['install_lang']) ? trim($_REQUEST['install_lang']) : 'English';
4782-
4783-// If such a language pack doesn't exist, or isn't up-to-date enough to translate this page, default to English
4784-if (!file_exists(PUN_ROOT.'lang/'.$install_lang.'/install.php'))
4785- $install_lang = 'English';
4786-
4787-require PUN_ROOT.'lang/'.$install_lang.'/install.php';
4788-
4789-if (file_exists(PUN_ROOT.'config.php'))
4790-{
4791- // Check to see whether FluxBB is already installed
4792- include PUN_ROOT.'config.php';
4793-
4794- // If we have the 1.3-legacy constant defined, define the proper 1.4 constant so we don't get an incorrect "need to install" message
4795- if (defined('FORUM'))
4796- define('PUN', FORUM);
4797-
4798- // If PUN is defined, config.php is probably valid and thus the software is installed
4799- if (defined('PUN'))
4800- exit($lang_install['Already installed']);
4801-}
4802-
4803-// Define PUN because email.php requires it
4804-define('PUN', 1);
4805-
4806-// If the cache directory is not specified, we use the default setting
4807-if (!defined('FORUM_CACHE_DIR'))
4808- define('FORUM_CACHE_DIR', PUN_ROOT.'cache/');
4809-
4810-// Make sure we are running at least MIN_PHP_VERSION
4811-if (!function_exists('version_compare') || version_compare(PHP_VERSION, MIN_PHP_VERSION, '<'))
4812- exit(sprintf($lang_install['You are running error'], 'PHP', PHP_VERSION, FORUM_VERSION, MIN_PHP_VERSION));
4813-
4814 // Load the functions script
4815 require PUN_ROOT.'include/functions.php';
4816
4817@@ -95,6 +61,42 @@
4818 // Turn off PHP time limit
4819 @set_time_limit(0);
4820
4821+
4822+// If we've been passed a default language, use it
4823+$install_lang = isset($_REQUEST['install_lang']) ? trim($_REQUEST['install_lang']) : 'English';
4824+
4825+// If such a language pack doesn't exist, or isn't up-to-date enough to translate this page, default to English
4826+if (!file_exists(PUN_ROOT.'lang/'.$install_lang.'/install.php'))
4827+ $install_lang = 'English';
4828+
4829+require PUN_ROOT.'lang/'.$install_lang.'/install.php';
4830+
4831+if (file_exists(PUN_ROOT.'config.php'))
4832+{
4833+ // Check to see whether FluxBB is already installed
4834+ include PUN_ROOT.'config.php';
4835+
4836+ // If we have the 1.3-legacy constant defined, define the proper 1.4 constant so we don't get an incorrect "need to install" message
4837+ if (defined('FORUM'))
4838+ define('PUN', FORUM);
4839+
4840+ // If PUN is defined, config.php is probably valid and thus the software is installed
4841+ if (defined('PUN'))
4842+ exit($lang_install['Already installed']);
4843+}
4844+
4845+// Define PUN because email.php requires it
4846+define('PUN', 1);
4847+
4848+// If the cache directory is not specified, we use the default setting
4849+if (!defined('FORUM_CACHE_DIR'))
4850+ define('FORUM_CACHE_DIR', PUN_ROOT.'cache/');
4851+
4852+// Make sure we are running at least MIN_PHP_VERSION
4853+if (!function_exists('version_compare') || version_compare(PHP_VERSION, MIN_PHP_VERSION, '<'))
4854+ exit(sprintf($lang_install['You are running error'], 'PHP', PHP_VERSION, FORUM_VERSION, MIN_PHP_VERSION));
4855+
4856+
4857 //
4858 // Generate output to be used for config.php
4859 //
4860@@ -129,7 +131,7 @@
4861 {
4862 // Make an educated guess regarding base_url
4863 $base_url = (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on') ? 'https://' : 'http://'; // protocol
4864- $base_url .= preg_replace('/:(80|443)$/', '', $_SERVER['HTTP_HOST']); // host[:port]
4865+ $base_url .= preg_replace('%:(80|443)$%', '', $_SERVER['HTTP_HOST']); // host[:port]
4866 $base_url .= str_replace('\\', '/', dirname($_SERVER['SCRIPT_NAME'])); // path
4867
4868 if (substr($base_url, -1) == '/')
4869@@ -172,11 +174,11 @@
4870 $alerts[] = $lang_install['Username 2'];
4871 else if (!strcasecmp($username, 'Guest'))
4872 $alerts[] = $lang_install['Username 3'];
4873- else if (preg_match('/[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}/', $username) || preg_match('/((([0-9A-Fa-f]{1,4}:){7}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){6}:[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){5}:([0-9A-Fa-f]{1,4}:)?[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){4}:([0-9A-Fa-f]{1,4}:){0,2}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){3}:([0-9A-Fa-f]{1,4}:){0,3}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){2}:([0-9A-Fa-f]{1,4}:){0,4}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){6}((\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b)\.){3}(\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b))|(([0-9A-Fa-f]{1,4}:){0,5}:((\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b)\.){3}(\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b))|(::([0-9A-Fa-f]{1,4}:){0,5}((\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b)\.){3}(\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b))|([0-9A-Fa-f]{1,4}::([0-9A-Fa-f]{1,4}:){0,5}[0-9A-Fa-f]{1,4})|(::([0-9A-Fa-f]{1,4}:){0,6}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){1,7}:))/', $username))
4874+ else if (preg_match('%[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}%', $username) || preg_match('%((([0-9A-Fa-f]{1,4}:){7}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){6}:[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){5}:([0-9A-Fa-f]{1,4}:)?[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){4}:([0-9A-Fa-f]{1,4}:){0,2}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){3}:([0-9A-Fa-f]{1,4}:){0,3}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){2}:([0-9A-Fa-f]{1,4}:){0,4}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){6}((\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b)\.){3}(\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b))|(([0-9A-Fa-f]{1,4}:){0,5}:((\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b)\.){3}(\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b))|(::([0-9A-Fa-f]{1,4}:){0,5}((\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b)\.){3}(\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b))|([0-9A-Fa-f]{1,4}::([0-9A-Fa-f]{1,4}:){0,5}[0-9A-Fa-f]{1,4})|(::([0-9A-Fa-f]{1,4}:){0,6}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){1,7}:))%', $username))
4875 $alerts[] = $lang_install['Username 4'];
4876 else if ((strpos($username, '[') !== false || strpos($username, ']') !== false) && strpos($username, '\'') !== false && strpos($username, '"') !== false)
4877 $alerts[] = $lang_install['Username 5'];
4878- else if (preg_match('/(?:\[\/?(?:b|u|i|h|colou?r|quote|code|img|url|email|list)\]|\[(?:code|quote|list)=)/i', $username))
4879+ else if (preg_match('%(?:\[/?(?:b|u|i|h|colou?r|quote|code|img|url|email|list)\]|\[(?:code|quote|list)=)%i', $username))
4880 $alerts[] = $lang_install['Username 6'];
4881
4882 if (pun_strlen($password1) < 4)
4883@@ -203,11 +205,11 @@
4884 }
4885
4886 // Check if the cache directory is writable
4887-if (!@is_writable(FORUM_CACHE_DIR))
4888+if (!forum_is_writable(FORUM_CACHE_DIR))
4889 $alerts[] = sprintf($lang_install['Alert cache'], FORUM_CACHE_DIR);
4890
4891 // Check if default avatar directory is writable
4892-if (!@is_writable(PUN_ROOT.'img/avatars/'))
4893+if (!forum_is_writable(PUN_ROOT.'img/avatars/'))
4894 $alerts[] = sprintf($lang_install['Alert avatar'], PUN_ROOT.'img/avatars/');
4895
4896 if (!isset($_POST['form_sent']) || !empty($alerts))
4897@@ -253,11 +255,10 @@
4898 /* <![CDATA[ */
4899 function process_form(the_form)
4900 {
4901- var element_names = {
4902+ var required_fields = {
4903 "req_db_type": "<?php echo $lang_install['Database type'] ?>",
4904 "req_db_host": "<?php echo $lang_install['Database server hostname'] ?>",
4905 "req_db_name": "<?php echo $lang_install['Database name'] ?>",
4906- "db_prefix": "<?php echo $lang_install['Table prefix'] ?>",
4907 "req_username": "<?php echo $lang_install['Administrator username'] ?>",
4908 "req_password1": "<?php echo $lang_install['Administrator password 1'] ?>",
4909 "req_password2": "<?php echo $lang_install['Administrator password 2'] ?>",
4910@@ -270,14 +271,11 @@
4911 for (var i = 0; i < the_form.length; ++i)
4912 {
4913 var elem = the_form.elements[i];
4914- if (elem.name && (/^req_/.test(elem.name)))
4915+ if (elem.name && required_fields[elem.name] && !elem.value && elem.type && (/^(?:text(?:area)?|password|file)$/i.test(elem.type)))
4916 {
4917- if (!elem.value && elem.type && (/^(?:text(?:area)?|password|file)$/i.test(elem.type)))
4918- {
4919- alert('"' + element_names[elem.name] + '" <?php echo $lang_install['Required field'] ?>');
4920- elem.focus();
4921- return false;
4922- }
4923+ alert('"' + required_fields[elem.name] + '" <?php echo $lang_install['Required field'] ?>');
4924+ elem.focus();
4925+ return false;
4926 }
4927 }
4928 }
4929@@ -286,7 +284,7 @@
4930 /* ]]> */
4931 </script>
4932 </head>
4933-<body onload="document.getElementById('install').req_db_type.focus();document.getElementById('install').start.disabled=false;">
4934+<body onload="document.getElementById('install').req_db_type.focus();document.getElementById('install').start.disabled=false;" onunload="">
4935
4936 <div id="puninstall" class="pun">
4937 <div class="top-box"><div><!-- Top Corners --></div></div>
4938@@ -579,7 +577,7 @@
4939 $db = new DBLayer($db_host, $db_username, $db_password, $db_name, $db_prefix, false);
4940
4941 // Validate prefix
4942- if (strlen($db_prefix) > 0 && (!preg_match('/^[a-zA-Z_][a-zA-Z0-9_]*$/', $db_prefix) || strlen($db_prefix) > 40))
4943+ if (strlen($db_prefix) > 0 && (!preg_match('%^[a-zA-Z_][a-zA-Z0-9_]*$%', $db_prefix) || strlen($db_prefix) > 40))
4944 error(sprintf($lang_install['Table prefix error'], $db->prefix));
4945
4946 // Do some DB type specific checks
4947@@ -945,6 +943,11 @@
4948 'datatype' => 'SMALLINT(6)',
4949 'allow_null' => false,
4950 'default' => '60'
4951+ ),
4952+ 'g_report_flood' => array(
4953+ 'datatype' => 'SMALLINT(6)',
4954+ 'allow_null' => false,
4955+ 'default' => '60'
4956 )
4957 ),
4958 'PRIMARY KEY' => array('g_id')
4959@@ -990,8 +993,7 @@
4960 'INDEXES' => array(
4961 'ident_idx' => array('ident'),
4962 'logged_idx' => array('logged')
4963- ),
4964- 'ENGINE' => 'HEAP'
4965+ )
4966 );
4967
4968 if ($db_type == 'mysql' || $db_type == 'mysqli' || $db_type == 'mysql_innodb' || $db_type == 'mysqli_innodb')
4969@@ -1485,7 +1487,7 @@
4970 'language' => array(
4971 'datatype' => 'VARCHAR(25)',
4972 'allow_null' => false,
4973- 'default' => '\'English\''
4974+ 'default' => '\''.$db->escape($default_lang).'\''
4975 ),
4976 'style' => array(
4977 'datatype' => 'VARCHAR(25)',
4978@@ -1509,6 +1511,10 @@
4979 'datatype' => 'INT(10) UNSIGNED',
4980 'allow_null' => true
4981 ),
4982+ 'last_report_sent' => array(
4983+ 'datatype' => 'INT(10) UNSIGNED',
4984+ 'allow_null' => true
4985+ ),
4986 'registered' => array(
4987 'datatype' => 'INT(10) UNSIGNED',
4988 'allow_null' => false,
4989@@ -1555,13 +1561,13 @@
4990 $now = time();
4991
4992 // Insert the four preset groups
4993- $db->query('INSERT INTO '.$db->prefix.'groups ('.($db_type != 'pgsql' ? 'g_id, ' : '').'g_title, g_user_title, g_moderator, g_mod_edit_users, g_mod_rename_users, g_mod_change_passwords, g_mod_ban_users, g_read_board, g_view_users, g_post_replies, g_post_topics, g_edit_posts, g_delete_posts, g_delete_topics, g_set_title, g_search, g_search_users, g_send_email, g_post_flood, g_search_flood, g_email_flood) VALUES('.($db_type != 'pgsql' ? '1, ' : '').'\''.$db->escape($lang_install['Administrators']).'\', \''.$db->escape($lang_install['Administrator']).'\', 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0)') or error('Unable to add group', __FILE__, __LINE__, $db->error());
4994-
4995- $db->query('INSERT INTO '.$db->prefix.'groups ('.($db_type != 'pgsql' ? 'g_id, ' : '').'g_title, g_user_title, g_moderator, g_mod_edit_users, g_mod_rename_users, g_mod_change_passwords, g_mod_ban_users, g_read_board, g_view_users, g_post_replies, g_post_topics, g_edit_posts, g_delete_posts, g_delete_topics, g_set_title, g_search, g_search_users, g_send_email, g_post_flood, g_search_flood, g_email_flood) VALUES('.($db_type != 'pgsql' ? '2, ' : '').'\''.$db->escape($lang_install['Moderators']).'\', \''.$db->escape($lang_install['Moderator']).'\', 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0)') or error('Unable to add group', __FILE__, __LINE__, $db->error());
4996-
4997- $db->query('INSERT INTO '.$db->prefix.'groups ('.($db_type != 'pgsql' ? 'g_id, ' : '').'g_title, g_user_title, g_moderator, g_mod_edit_users, g_mod_rename_users, g_mod_change_passwords, g_mod_ban_users, g_read_board, g_view_users, g_post_replies, g_post_topics, g_edit_posts, g_delete_posts, g_delete_topics, g_set_title, g_search, g_search_users, g_send_email, g_post_flood, g_search_flood, g_email_flood) VALUES('.($db_type != 'pgsql' ? '3, ' : '').'\''.$db->escape($lang_install['Guests']).'\', NULL, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 60, 30, 0)') or error('Unable to add group', __FILE__, __LINE__, $db->error());
4998-
4999- $db->query('INSERT INTO '.$db->prefix.'groups ('.($db_type != 'pgsql' ? 'g_id, ' : '').'g_title, g_user_title, g_moderator, g_mod_edit_users, g_mod_rename_users, g_mod_change_passwords, g_mod_ban_users, g_read_board, g_view_users, g_post_replies, g_post_topics, g_edit_posts, g_delete_posts, g_delete_topics, g_set_title, g_search, g_search_users, g_send_email, g_post_flood, g_search_flood, g_email_flood) VALUES('.($db_type != 'pgsql' ? '4, ' : '').'\''.$db->escape($lang_install['Members']).'\', NULL, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 60, 30, 60)') or error('Unable to add group', __FILE__, __LINE__, $db->error());
5000+ $db->query('INSERT INTO '.$db->prefix.'groups ('.($db_type != 'pgsql' ? 'g_id, ' : '').'g_title, g_user_title, g_moderator, g_mod_edit_users, g_mod_rename_users, g_mod_change_passwords, g_mod_ban_users, g_read_board, g_view_users, g_post_replies, g_post_topics, g_edit_posts, g_delete_posts, g_delete_topics, g_set_title, g_search, g_search_users, g_send_email, g_post_flood, g_search_flood, g_email_flood, g_report_flood) VALUES('.($db_type != 'pgsql' ? '1, ' : '').'\''.$db->escape($lang_install['Administrators']).'\', \''.$db->escape($lang_install['Administrator']).'\', 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0)') or error('Unable to add group', __FILE__, __LINE__, $db->error());
The diff has been truncated for viewing.

Subscribers

People subscribed via source and target branches

to all changes: