Verzeichnisstruktur phpBB-3.3.15
- Veröffentlicht
- 28.08.2024
So funktioniert es
|
|
Auf das letzte Element klicken. Dies geht jeweils ein Schritt zurück |
Auf das Icon klicken, dies öffnet das Verzeichnis. Nochmal klicken schließt das Verzeichnis. |
|
|
(Beispiel Datei-Icons)
|
Auf das Icon klicken um den Quellcode anzuzeigen |
acp_forums.php
0001 <?php
0002 /**
0003 *
0004 * This file is part of the phpBB Forum Software package.
0005 *
0006 * @copyright (c) phpBB Limited <https://www.phpbb.com>
0007 * @license GNU General Public License, version 2 (GPL-2.0)
0008 *
0009 * For full copyright and license information, please see
0010 * the docs/CREDITS.txt file.
0011 *
0012 */
0013
0014 /**
0015 * @ignore
0016 */
0017 if (!defined('IN_PHPBB'))
0018 {
0019 exit;
0020 }
0021
0022 class acp_forums
0023 {
0024 var $u_action;
0025 var $parent_id = 0;
0026
0027 function main($id, $mode)
0028 {
0029 global $db, $user, $auth, $template, $cache, $request, $phpbb_dispatcher;
0030 global $phpbb_admin_path, $phpbb_root_path, $phpEx, $phpbb_log;
0031
0032 $user->add_lang('acp/forums');
0033 $this->tpl_name = 'acp_forums';
0034 $this->page_title = 'ACP_MANAGE_FORUMS';
0035
0036 $form_key = 'acp_forums';
0037 add_form_key($form_key);
0038
0039 $action = $request->variable('action', '');
0040 $update = (isset($_POST['update'])) ? true : false;
0041 $forum_id = $request->variable('f', 0);
0042
0043 $this->parent_id = $request->variable('parent_id', 0);
0044 $forum_data = $errors = array();
0045 if ($update && !check_form_key($form_key))
0046 {
0047 $update = false;
0048 $errors[] = $user->lang['FORM_INVALID'];
0049 }
0050
0051 // Check additional permissions
0052 switch ($action)
0053 {
0054 case 'progress_bar':
0055 $start = $request->variable('start', 0);
0056 $total = $request->variable('total', 0);
0057
0058 $this->display_progress_bar($start, $total);
0059 break;
0060
0061 case 'delete':
0062
0063 if (!$auth->acl_get('a_forumdel'))
0064 {
0065 trigger_error($user->lang['NO_PERMISSION_FORUM_DELETE'] . adm_back_link($this->u_action . '&parent_id=' . $this->parent_id), E_USER_WARNING);
0066 }
0067
0068 break;
0069
0070 case 'add':
0071
0072 if (!$auth->acl_get('a_forumadd'))
0073 {
0074 trigger_error($user->lang['NO_PERMISSION_FORUM_ADD'] . adm_back_link($this->u_action . '&parent_id=' . $this->parent_id), E_USER_WARNING);
0075 }
0076
0077 break;
0078 }
0079
0080 // Major routines
0081 if ($update)
0082 {
0083 switch ($action)
0084 {
0085 case 'delete':
0086 $action_subforums = $request->variable('action_subforums', '');
0087 $subforums_to_id = $request->variable('subforums_to_id', 0);
0088 $action_posts = $request->variable('action_posts', '');
0089 $posts_to_id = $request->variable('posts_to_id', 0);
0090
0091 $errors = $this->delete_forum($forum_id, $action_posts, $action_subforums, $posts_to_id, $subforums_to_id);
0092
0093 if (count($errors))
0094 {
0095 break;
0096 }
0097
0098 $auth->acl_clear_prefetch();
0099 $cache->destroy('sql', FORUMS_TABLE);
0100
0101 trigger_error($user->lang['FORUM_DELETED'] . adm_back_link($this->u_action . '&parent_id=' . $this->parent_id));
0102
0103 break;
0104
0105 case 'edit':
0106 $forum_data = array(
0107 'forum_id' => $forum_id
0108 );
0109
0110 // No break here
0111
0112 case 'add':
0113
0114 $forum_data += array(
0115 'parent_id' => $request->variable('forum_parent_id', $this->parent_id),
0116 'forum_type' => $request->variable('forum_type', FORUM_POST),
0117 'type_action' => $request->variable('type_action', ''),
0118 'forum_status' => $request->variable('forum_status', ITEM_UNLOCKED),
0119 'forum_parents' => '',
0120 'forum_name' => $request->variable('forum_name', '', true),
0121 'forum_link' => $request->variable('forum_link', ''),
0122 'forum_link_track' => $request->variable('forum_link_track', false),
0123 'forum_desc' => $request->variable('forum_desc', '', true),
0124 'forum_desc_uid' => '',
0125 'forum_desc_options' => 7,
0126 'forum_desc_bitfield' => '',
0127 'forum_rules' => $request->variable('forum_rules', '', true),
0128 'forum_rules_uid' => '',
0129 'forum_rules_options' => 7,
0130 'forum_rules_bitfield' => '',
0131 'forum_rules_link' => $request->variable('forum_rules_link', ''),
0132 'forum_image' => $request->variable('forum_image', ''),
0133 'forum_style' => $request->variable('forum_style', 0),
0134 'display_subforum_list' => $request->variable('display_subforum_list', true),
0135 'display_subforum_limit'=> $request->variable('display_subforum_limit', false),
0136 'display_on_index' => $request->variable('display_on_index', true),
0137 'forum_topics_per_page' => $request->variable('topics_per_page', 0),
0138 'enable_indexing' => $request->variable('enable_indexing', true),
0139 'enable_icons' => $request->variable('enable_icons', true),
0140 'enable_prune' => $request->variable('enable_prune', false),
0141 'enable_post_review' => $request->variable('enable_post_review', true),
0142 'enable_quick_reply' => $request->variable('enable_quick_reply', false),
0143 'enable_shadow_prune' => $request->variable('enable_shadow_prune', false),
0144 'prune_days' => $request->variable('prune_days', 7),
0145 'prune_viewed' => $request->variable('prune_viewed', 7),
0146 'prune_freq' => $request->variable('prune_freq', 1),
0147 'prune_old_polls' => $request->variable('prune_old_polls', false),
0148 'prune_announce' => $request->variable('prune_announce', false),
0149 'prune_sticky' => $request->variable('prune_sticky', false),
0150 'prune_shadow_days' => $request->variable('prune_shadow_days', 7),
0151 'prune_shadow_freq' => $request->variable('prune_shadow_freq', 1),
0152 'forum_password' => $request->variable('forum_password', '', true),
0153 'forum_password_confirm'=> $request->variable('forum_password_confirm', '', true),
0154 'forum_password_unset' => $request->variable('forum_password_unset', false),
0155 );
0156
0157 /**
0158 * Request forum data and operate on it (parse texts, etc.)
0159 *
0160 * @event core.acp_manage_forums_request_data
0161 * @var string action Type of the action: add|edit
0162 * @var array forum_data Array with new forum data
0163 * @since 3.1.0-a1
0164 */
0165 $vars = array('action', 'forum_data');
0166 extract($phpbb_dispatcher->trigger_event('core.acp_manage_forums_request_data', compact($vars)));
0167
0168 // On add, add empty forum_options... else do not consider it (not updating it)
0169 if ($action == 'add')
0170 {
0171 $forum_data['forum_options'] = 0;
0172 }
0173
0174 // Use link_display_on_index setting if forum type is link
0175 if ($forum_data['forum_type'] == FORUM_LINK)
0176 {
0177 $forum_data['display_on_index'] = $request->variable('link_display_on_index', false);
0178 }
0179
0180 // Linked forums and categories are not able to be locked...
0181 if ($forum_data['forum_type'] == FORUM_LINK || $forum_data['forum_type'] == FORUM_CAT)
0182 {
0183 $forum_data['forum_status'] = ITEM_UNLOCKED;
0184 }
0185
0186 $forum_data['show_active'] = ($forum_data['forum_type'] == FORUM_POST) ? $request->variable('display_recent', true) : $request->variable('display_active', false);
0187
0188 // Get data for forum rules if specified...
0189 if ($forum_data['forum_rules'])
0190 {
0191 generate_text_for_storage($forum_data['forum_rules'], $forum_data['forum_rules_uid'], $forum_data['forum_rules_bitfield'], $forum_data['forum_rules_options'], $request->variable('rules_parse_bbcode', false), $request->variable('rules_parse_urls', false), $request->variable('rules_parse_smilies', false));
0192 }
0193
0194 // Get data for forum description if specified
0195 if ($forum_data['forum_desc'])
0196 {
0197 generate_text_for_storage($forum_data['forum_desc'], $forum_data['forum_desc_uid'], $forum_data['forum_desc_bitfield'], $forum_data['forum_desc_options'], $request->variable('desc_parse_bbcode', false), $request->variable('desc_parse_urls', false), $request->variable('desc_parse_smilies', false));
0198 }
0199
0200 $errors = $this->update_forum_data($forum_data);
0201
0202 if (!count($errors))
0203 {
0204 $forum_perm_from = $request->variable('forum_perm_from', 0);
0205 $cache->destroy('sql', FORUMS_TABLE);
0206
0207 $copied_permissions = false;
0208 // Copy permissions?
0209 if ($forum_perm_from && $forum_perm_from != $forum_data['forum_id'] &&
0210 ($action != 'edit' || empty($forum_id) || ($auth->acl_get('a_fauth') && $auth->acl_get('a_authusers') && $auth->acl_get('a_authgroups') && $auth->acl_get('a_mauth'))))
0211 {
0212 copy_forum_permissions($forum_perm_from, $forum_data['forum_id'], ($action == 'edit') ? true : false);
0213 phpbb_cache_moderators($db, $cache, $auth);
0214 $copied_permissions = true;
0215 }
0216 /* Commented out because of questionable UI workflow - re-visit for 3.0.7
0217 else if (!$this->parent_id && $action != 'edit' && $auth->acl_get('a_fauth') && $auth->acl_get('a_authusers') && $auth->acl_get('a_authgroups') && $auth->acl_get('a_mauth'))
0218 {
0219 $this->copy_permission_page($forum_data);
0220 return;
0221 }
0222 */
0223 $auth->acl_clear_prefetch();
0224
0225 $acl_url = '&mode=setting_forum_local&forum_id[]=' . $forum_data['forum_id'];
0226
0227 $message = ($action == 'add') ? $user->lang['FORUM_CREATED'] : $user->lang['FORUM_UPDATED'];
0228
0229 // redirect directly to permission settings screen if authed
0230 if ($action == 'add' && !$copied_permissions && $auth->acl_get('a_fauth'))
0231 {
0232 $message .= '<br /><br />' . sprintf($user->lang['REDIRECT_ACL'], '<a href="' . append_sid("{$phpbb_admin_path}index.$phpEx", 'i=permissions' . $acl_url) . '">', '</a>');
0233
0234 meta_refresh(4, append_sid("{$phpbb_admin_path}index.$phpEx", 'i=permissions' . $acl_url));
0235 }
0236
0237 trigger_error($message . adm_back_link($this->u_action . '&parent_id=' . $this->parent_id));
0238 }
0239
0240 break;
0241 }
0242 }
0243
0244 switch ($action)
0245 {
0246 case 'move_up':
0247 case 'move_down':
0248
0249 if (!$forum_id)
0250 {
0251 trigger_error($user->lang['NO_FORUM'] . adm_back_link($this->u_action . '&parent_id=' . $this->parent_id), E_USER_WARNING);
0252 }
0253
0254 $sql = 'SELECT *
0255 FROM ' . FORUMS_TABLE . "
0256 WHERE forum_id = $forum_id";
0257 $result = $db->sql_query($sql);
0258 $row = $db->sql_fetchrow($result);
0259 $db->sql_freeresult($result);
0260
0261 if (!$row)
0262 {
0263 trigger_error($user->lang['NO_FORUM'] . adm_back_link($this->u_action . '&parent_id=' . $this->parent_id), E_USER_WARNING);
0264 }
0265
0266 $move_forum_name = $this->move_forum_by($row, $action, 1);
0267
0268 if ($move_forum_name !== false)
0269 {
0270 $phpbb_log->add('admin', $user->data['user_id'], $user->ip, 'LOG_FORUM_' . strtoupper($action), false, array($row['forum_name'], $move_forum_name));
0271 $cache->destroy('sql', FORUMS_TABLE);
0272 }
0273
0274 if ($request->is_ajax())
0275 {
0276 $json_response = new \phpbb\json_response;
0277 $json_response->send(array('success' => ($move_forum_name !== false)));
0278 }
0279
0280 break;
0281
0282 case 'sync':
0283 if (!$forum_id)
0284 {
0285 trigger_error($user->lang['NO_FORUM'] . adm_back_link($this->u_action . '&parent_id=' . $this->parent_id), E_USER_WARNING);
0286 }
0287
0288 @set_time_limit(0);
0289
0290 $sql = 'SELECT forum_name, (forum_topics_approved + forum_topics_unapproved + forum_topics_softdeleted) AS total_topics
0291 FROM ' . FORUMS_TABLE . "
0292 WHERE forum_id = $forum_id";
0293 $result = $db->sql_query($sql);
0294 $row = $db->sql_fetchrow($result);
0295 $db->sql_freeresult($result);
0296
0297 if (!$row)
0298 {
0299 trigger_error($user->lang['NO_FORUM'] . adm_back_link($this->u_action . '&parent_id=' . $this->parent_id), E_USER_WARNING);
0300 }
0301
0302 if ($row['total_topics'])
0303 {
0304 $sql = 'SELECT MIN(topic_id) as min_topic_id, MAX(topic_id) as max_topic_id
0305 FROM ' . TOPICS_TABLE . '
0306 WHERE forum_id = ' . $forum_id;
0307 $result = $db->sql_query($sql);
0308 $row2 = $db->sql_fetchrow($result);
0309 $db->sql_freeresult($result);
0310
0311 // Typecast to int if there is no data available
0312 $row2['min_topic_id'] = (int) $row2['min_topic_id'];
0313 $row2['max_topic_id'] = (int) $row2['max_topic_id'];
0314
0315 $start = $request->variable('start', $row2['min_topic_id']);
0316
0317 $batch_size = 2000;
0318 $end = $start + $batch_size;
0319
0320 // Sync all topics in batch mode...
0321 sync('topic', 'range', 'topic_id BETWEEN ' . $start . ' AND ' . $end, true, true);
0322
0323 if ($end < $row2['max_topic_id'])
0324 {
0325 // We really need to find a way of showing statistics... no progress here
0326 $sql = 'SELECT COUNT(topic_id) as num_topics
0327 FROM ' . TOPICS_TABLE . '
0328 WHERE forum_id = ' . $forum_id . '
0329 AND topic_id BETWEEN ' . $start . ' AND ' . $end;
0330 $result = $db->sql_query($sql);
0331 $topics_done = $request->variable('topics_done', 0) + (int) $db->sql_fetchfield('num_topics');
0332 $db->sql_freeresult($result);
0333
0334 $start += $batch_size;
0335
0336 $url = $this->u_action . "&parent_id={$this->parent_id}&f=$forum_id&action=sync&start=$start&topics_done=$topics_done&total={$row['total_topics']}";
0337
0338 meta_refresh(0, $url);
0339
0340 $template->assign_vars(array(
0341 'U_PROGRESS_BAR' => $this->u_action . "&action=progress_bar&start=$topics_done&total={$row['total_topics']}",
0342 'UA_PROGRESS_BAR' => addslashes($this->u_action . "&action=progress_bar&start=$topics_done&total={$row['total_topics']}"),
0343 'S_CONTINUE_SYNC' => true,
0344 'L_PROGRESS_EXPLAIN' => sprintf($user->lang['SYNC_IN_PROGRESS_EXPLAIN'], $topics_done, $row['total_topics']))
0345 );
0346
0347 return;
0348 }
0349 }
0350
0351 $url = $this->u_action . "&parent_id={$this->parent_id}&f=$forum_id&action=sync_forum";
0352 meta_refresh(0, $url);
0353
0354 $template->assign_vars(array(
0355 'U_PROGRESS_BAR' => $this->u_action . '&action=progress_bar',
0356 'UA_PROGRESS_BAR' => addslashes($this->u_action . '&action=progress_bar'),
0357 'S_CONTINUE_SYNC' => true,
0358 'L_PROGRESS_EXPLAIN' => sprintf($user->lang['SYNC_IN_PROGRESS_EXPLAIN'], 0, $row['total_topics']))
0359 );
0360
0361 return;
0362
0363 break;
0364
0365 case 'sync_forum':
0366
0367 $sql = 'SELECT forum_name, forum_type
0368 FROM ' . FORUMS_TABLE . "
0369 WHERE forum_id = $forum_id";
0370 $result = $db->sql_query($sql);
0371 $row = $db->sql_fetchrow($result);
0372 $db->sql_freeresult($result);
0373
0374 if (!$row)
0375 {
0376 trigger_error($user->lang['NO_FORUM'] . adm_back_link($this->u_action . '&parent_id=' . $this->parent_id), E_USER_WARNING);
0377 }
0378
0379 sync('forum', 'forum_id', $forum_id, false, true);
0380
0381 $phpbb_log->add('admin', $user->data['user_id'], $user->ip, 'LOG_FORUM_SYNC', false, array($row['forum_name']));
0382
0383 $cache->destroy('sql', FORUMS_TABLE);
0384
0385 $template->assign_var('L_FORUM_RESYNCED', sprintf($user->lang['FORUM_RESYNCED'], $row['forum_name']));
0386
0387 break;
0388
0389 case 'add':
0390 case 'edit':
0391
0392 if ($update)
0393 {
0394 $forum_data['forum_flags'] = 0;
0395 $forum_data['forum_flags'] += ($request->variable('forum_link_track', false)) ? FORUM_FLAG_LINK_TRACK : 0;
0396 $forum_data['forum_flags'] += ($request->variable('prune_old_polls', false)) ? FORUM_FLAG_PRUNE_POLL : 0;
0397 $forum_data['forum_flags'] += ($request->variable('prune_announce', false)) ? FORUM_FLAG_PRUNE_ANNOUNCE : 0;
0398 $forum_data['forum_flags'] += ($request->variable('prune_sticky', false)) ? FORUM_FLAG_PRUNE_STICKY : 0;
0399 $forum_data['forum_flags'] += ($forum_data['show_active']) ? FORUM_FLAG_ACTIVE_TOPICS : 0;
0400 $forum_data['forum_flags'] += ($request->variable('enable_post_review', true)) ? FORUM_FLAG_POST_REVIEW : 0;
0401 $forum_data['forum_flags'] += ($request->variable('enable_quick_reply', false)) ? FORUM_FLAG_QUICK_REPLY : 0;
0402 }
0403
0404 // Initialise $row, so we always have it in the event
0405 $row = array();
0406
0407 // Show form to create/modify a forum
0408 if ($action == 'edit')
0409 {
0410 $this->page_title = 'EDIT_FORUM';
0411 $row = $this->get_forum_info($forum_id);
0412 $old_forum_type = $row['forum_type'];
0413
0414 if (!$update)
0415 {
0416 $forum_data = $row;
0417 }
0418 else
0419 {
0420 $forum_data['left_id'] = $row['left_id'];
0421 $forum_data['right_id'] = $row['right_id'];
0422 }
0423
0424 // Make sure no direct child forums are able to be selected as parents.
0425 $exclude_forums = array();
0426 foreach (get_forum_branch($forum_id, 'children') as $row)
0427 {
0428 $exclude_forums[] = $row['forum_id'];
0429 }
0430
0431 $parents_list = make_forum_select($forum_data['parent_id'], $exclude_forums, false, false, false);
0432
0433 $forum_data['forum_password_confirm'] = $forum_data['forum_password'];
0434 }
0435 else
0436 {
0437 $this->page_title = 'CREATE_FORUM';
0438
0439 $forum_id = $this->parent_id;
0440 $parents_list = make_forum_select($this->parent_id, false, false, false, false);
0441
0442 // Fill forum data with default values
0443 if (!$update)
0444 {
0445 $forum_data = array(
0446 'parent_id' => $this->parent_id,
0447 'forum_type' => FORUM_POST,
0448 'forum_status' => ITEM_UNLOCKED,
0449 'forum_name' => $request->variable('forum_name', '', true),
0450 'forum_link' => '',
0451 'forum_link_track' => false,
0452 'forum_desc' => '',
0453 'forum_rules' => '',
0454 'forum_rules_link' => '',
0455 'forum_image' => '',
0456 'forum_style' => 0,
0457 'display_subforum_list' => true,
0458 'display_subforum_limit' => false,
0459 'display_on_index' => true,
0460 'forum_topics_per_page' => 0,
0461 'enable_indexing' => true,
0462 'enable_icons' => true,
0463 'enable_prune' => false,
0464 'prune_days' => 7,
0465 'prune_viewed' => 7,
0466 'prune_freq' => 1,
0467 'enable_shadow_prune' => false,
0468 'prune_shadow_days' => 7,
0469 'prune_shadow_freq' => 1,
0470 'forum_flags' => FORUM_FLAG_POST_REVIEW + FORUM_FLAG_ACTIVE_TOPICS,
0471 'forum_options' => 0,
0472 'forum_password' => '',
0473 'forum_password_confirm'=> '',
0474 );
0475 }
0476 }
0477
0478 /**
0479 * Initialise data before we display the add/edit form
0480 *
0481 * @event core.acp_manage_forums_initialise_data
0482 * @var string action Type of the action: add|edit
0483 * @var bool update Do we display the form only
0484 * or did the user press submit
0485 * @var int forum_id When editing: the forum id,
0486 * when creating: the parent forum id
0487 * @var array row Array with current forum data
0488 * empty when creating new forum
0489 * @var array forum_data Array with new forum data
0490 * @var string parents_list List of parent options
0491 * @since 3.1.0-a1
0492 */
0493 $vars = array('action', 'update', 'forum_id', 'row', 'forum_data', 'parents_list');
0494 extract($phpbb_dispatcher->trigger_event('core.acp_manage_forums_initialise_data', compact($vars)));
0495
0496 $forum_rules_data = array(
0497 'text' => $forum_data['forum_rules'],
0498 'allow_bbcode' => true,
0499 'allow_smilies' => true,
0500 'allow_urls' => true
0501 );
0502
0503 $forum_desc_data = array(
0504 'text' => $forum_data['forum_desc'],
0505 'allow_bbcode' => true,
0506 'allow_smilies' => true,
0507 'allow_urls' => true
0508 );
0509
0510 $forum_rules_preview = '';
0511
0512 // Parse rules if specified
0513 if ($forum_data['forum_rules'])
0514 {
0515 if (!isset($forum_data['forum_rules_uid']))
0516 {
0517 // Before we are able to display the preview and plane text, we need to parse our $request->variable()'d value...
0518 $forum_data['forum_rules_uid'] = '';
0519 $forum_data['forum_rules_bitfield'] = '';
0520 $forum_data['forum_rules_options'] = 0;
0521
0522 generate_text_for_storage($forum_data['forum_rules'], $forum_data['forum_rules_uid'], $forum_data['forum_rules_bitfield'], $forum_data['forum_rules_options'], $request->variable('rules_allow_bbcode', false), $request->variable('rules_allow_urls', false), $request->variable('rules_allow_smilies', false));
0523 }
0524
0525 // Generate preview content
0526 $forum_rules_preview = generate_text_for_display($forum_data['forum_rules'], $forum_data['forum_rules_uid'], $forum_data['forum_rules_bitfield'], $forum_data['forum_rules_options']);
0527
0528 // decode...
0529 $forum_rules_data = generate_text_for_edit($forum_data['forum_rules'], $forum_data['forum_rules_uid'], $forum_data['forum_rules_options']);
0530 }
0531
0532 // Parse desciption if specified
0533 if ($forum_data['forum_desc'])
0534 {
0535 if (!isset($forum_data['forum_desc_uid']))
0536 {
0537 // Before we are able to display the preview and plane text, we need to parse our $request->variable()'d value...
0538 $forum_data['forum_desc_uid'] = '';
0539 $forum_data['forum_desc_bitfield'] = '';
0540 $forum_data['forum_desc_options'] = 0;
0541
0542 generate_text_for_storage($forum_data['forum_desc'], $forum_data['forum_desc_uid'], $forum_data['forum_desc_bitfield'], $forum_data['forum_desc_options'], $request->variable('desc_allow_bbcode', false), $request->variable('desc_allow_urls', false), $request->variable('desc_allow_smilies', false));
0543 }
0544
0545 // decode...
0546 $forum_desc_data = generate_text_for_edit($forum_data['forum_desc'], $forum_data['forum_desc_uid'], $forum_data['forum_desc_options']);
0547 }
0548
0549 $forum_type_options = '';
0550 $forum_type_ary = array(FORUM_CAT => 'CAT', FORUM_POST => 'FORUM', FORUM_LINK => 'LINK');
0551
0552 foreach ($forum_type_ary as $value => $lang)
0553 {
0554 $forum_type_options .= '<option value="' . $value . '"' . (($value == $forum_data['forum_type']) ? ' selected="selected"' : '') . '>' . $user->lang['TYPE_' . $lang] . '</option>';
0555 }
0556
0557 $styles_list = style_select($forum_data['forum_style'], true);
0558
0559 $statuslist = '<option value="' . ITEM_UNLOCKED . '"' . (($forum_data['forum_status'] == ITEM_UNLOCKED) ? ' selected="selected"' : '') . '>' . $user->lang['UNLOCKED'] . '</option><option value="' . ITEM_LOCKED . '"' . (($forum_data['forum_status'] == ITEM_LOCKED) ? ' selected="selected"' : '') . '>' . $user->lang['LOCKED'] . '</option>';
0560
0561 $sql = 'SELECT forum_id
0562 FROM ' . FORUMS_TABLE . '
0563 WHERE forum_type = ' . FORUM_POST . "
0564 AND forum_id <> $forum_id";
0565 $result = $db->sql_query_limit($sql, 1);
0566
0567 $postable_forum_exists = false;
0568 if ($db->sql_fetchrow($result))
0569 {
0570 $postable_forum_exists = true;
0571 }
0572 $db->sql_freeresult($result);
0573
0574 // Subforum move options
0575 if ($action == 'edit' && $forum_data['forum_type'] == FORUM_CAT)
0576 {
0577 $subforums_id = array();
0578 $subforums = get_forum_branch($forum_id, 'children');
0579
0580 foreach ($subforums as $row)
0581 {
0582 $subforums_id[] = $row['forum_id'];
0583 }
0584
0585 $forums_list = make_forum_select($forum_data['parent_id'], $subforums_id);
0586
0587 if ($postable_forum_exists)
0588 {
0589 $template->assign_vars(array(
0590 'S_MOVE_FORUM_OPTIONS' => make_forum_select($forum_data['parent_id'], $subforums_id)) // , false, true, false???
0591 );
0592 }
0593
0594 $template->assign_vars(array(
0595 'S_HAS_SUBFORUMS' => ($forum_data['right_id'] - $forum_data['left_id'] > 1) ? true : false,
0596 'S_FORUMS_LIST' => $forums_list)
0597 );
0598 }
0599 else if ($postable_forum_exists)
0600 {
0601 $template->assign_vars(array(
0602 'S_MOVE_FORUM_OPTIONS' => make_forum_select($forum_data['parent_id'], $forum_id, false, true, false))
0603 );
0604 }
0605
0606 $s_show_display_on_index = false;
0607
0608 if ($forum_data['parent_id'] > 0)
0609 {
0610 // if this forum is a subforum put the "display on index" checkbox
0611 if ($parent_info = $this->get_forum_info($forum_data['parent_id']))
0612 {
0613 if ($parent_info['parent_id'] > 0 || $parent_info['forum_type'] == FORUM_CAT)
0614 {
0615 $s_show_display_on_index = true;
0616 }
0617 }
0618 }
0619
0620 if (strlen($forum_data['forum_password']) == 32)
0621 {
0622 $errors[] = $user->lang['FORUM_PASSWORD_OLD'];
0623 }
0624
0625 $template_data = array(
0626 'S_EDIT_FORUM' => true,
0627 'S_ERROR' => (count($errors)) ? true : false,
0628 'S_PARENT_ID' => $this->parent_id,
0629 'S_FORUM_PARENT_ID' => $forum_data['parent_id'],
0630 'S_ADD_ACTION' => ($action == 'add') ? true : false,
0631
0632 'U_BACK' => $this->u_action . '&parent_id=' . $this->parent_id,
0633 'U_EDIT_ACTION' => $this->u_action . "&parent_id={$this->parent_id}&action=$action&f=$forum_id",
0634
0635 'L_COPY_PERMISSIONS_EXPLAIN' => $user->lang['COPY_PERMISSIONS_' . strtoupper($action) . '_EXPLAIN'],
0636 'L_TITLE' => $user->lang[$this->page_title],
0637 'ERROR_MSG' => (count($errors)) ? implode('<br />', $errors) : '',
0638
0639 'FORUM_NAME' => $forum_data['forum_name'],
0640 'FORUM_DATA_LINK' => $forum_data['forum_link'],
0641 'FORUM_IMAGE' => $forum_data['forum_image'],
0642 'FORUM_IMAGE_SRC' => ($forum_data['forum_image']) ? $phpbb_root_path . $forum_data['forum_image'] : '',
0643 'FORUM_POST' => FORUM_POST,
0644 'FORUM_LINK' => FORUM_LINK,
0645 'FORUM_CAT' => FORUM_CAT,
0646 'PRUNE_FREQ' => $forum_data['prune_freq'],
0647 'PRUNE_DAYS' => $forum_data['prune_days'],
0648 'PRUNE_VIEWED' => $forum_data['prune_viewed'],
0649 'PRUNE_SHADOW_FREQ' => $forum_data['prune_shadow_freq'],
0650 'PRUNE_SHADOW_DAYS' => $forum_data['prune_shadow_days'],
0651 'TOPICS_PER_PAGE' => $forum_data['forum_topics_per_page'],
0652 'FORUM_RULES_LINK' => $forum_data['forum_rules_link'],
0653 'FORUM_RULES' => $forum_data['forum_rules'],
0654 'FORUM_RULES_PREVIEW' => $forum_rules_preview,
0655 'FORUM_RULES_PLAIN' => $forum_rules_data['text'],
0656 'S_BBCODE_CHECKED' => ($forum_rules_data['allow_bbcode']) ? true : false,
0657 'S_SMILIES_CHECKED' => ($forum_rules_data['allow_smilies']) ? true : false,
0658 'S_URLS_CHECKED' => ($forum_rules_data['allow_urls']) ? true : false,
0659 'S_FORUM_PASSWORD_SET' => (empty($forum_data['forum_password'])) ? false : true,
0660
0661 'FORUM_DESC' => $forum_desc_data['text'],
0662 'S_DESC_BBCODE_CHECKED' => ($forum_desc_data['allow_bbcode']) ? true : false,
0663 'S_DESC_SMILIES_CHECKED' => ($forum_desc_data['allow_smilies']) ? true : false,
0664 'S_DESC_URLS_CHECKED' => ($forum_desc_data['allow_urls']) ? true : false,
0665
0666 'S_FORUM_TYPE_OPTIONS' => $forum_type_options,
0667 'S_STATUS_OPTIONS' => $statuslist,
0668 'S_PARENT_OPTIONS' => $parents_list,
0669 'S_STYLES_OPTIONS' => $styles_list,
0670 'S_FORUM_OPTIONS' => make_forum_select(($action == 'add') ? $forum_data['parent_id'] : false, ($action == 'edit') ? $forum_data['forum_id'] : false, false, false, false),
0671 'S_SHOW_DISPLAY_ON_INDEX' => $s_show_display_on_index,
0672 'S_FORUM_POST' => ($forum_data['forum_type'] == FORUM_POST) ? true : false,
0673 'S_FORUM_ORIG_POST' => (isset($old_forum_type) && $old_forum_type == FORUM_POST) ? true : false,
0674 'S_FORUM_ORIG_CAT' => (isset($old_forum_type) && $old_forum_type == FORUM_CAT) ? true : false,
0675 'S_FORUM_ORIG_LINK' => (isset($old_forum_type) && $old_forum_type == FORUM_LINK) ? true : false,
0676 'S_FORUM_LINK' => ($forum_data['forum_type'] == FORUM_LINK) ? true : false,
0677 'S_FORUM_CAT' => ($forum_data['forum_type'] == FORUM_CAT) ? true : false,
0678 'S_ENABLE_INDEXING' => ($forum_data['enable_indexing']) ? true : false,
0679 'S_TOPIC_ICONS' => ($forum_data['enable_icons']) ? true : false,
0680 'S_DISPLAY_SUBFORUM_LIST' => ($forum_data['display_subforum_list']) ? true : false,
0681 'S_DISPLAY_SUBFORUM_LIMIT' => ($forum_data['display_subforum_limit']) ? true : false,
0682 'S_DISPLAY_ON_INDEX' => ($forum_data['display_on_index']) ? true : false,
0683 'S_PRUNE_ENABLE' => ($forum_data['enable_prune']) ? true : false,
0684 'S_PRUNE_SHADOW_ENABLE' => ($forum_data['enable_shadow_prune']) ? true : false,
0685 'S_FORUM_LINK_TRACK' => ($forum_data['forum_flags'] & FORUM_FLAG_LINK_TRACK) ? true : false,
0686 'S_PRUNE_OLD_POLLS' => ($forum_data['forum_flags'] & FORUM_FLAG_PRUNE_POLL) ? true : false,
0687 'S_PRUNE_ANNOUNCE' => ($forum_data['forum_flags'] & FORUM_FLAG_PRUNE_ANNOUNCE) ? true : false,
0688 'S_PRUNE_STICKY' => ($forum_data['forum_flags'] & FORUM_FLAG_PRUNE_STICKY) ? true : false,
0689 'S_DISPLAY_ACTIVE_TOPICS' => ($forum_data['forum_type'] == FORUM_POST) ? ($forum_data['forum_flags'] & FORUM_FLAG_ACTIVE_TOPICS) : true,
0690 'S_ENABLE_ACTIVE_TOPICS' => ($forum_data['forum_type'] == FORUM_CAT) ? ($forum_data['forum_flags'] & FORUM_FLAG_ACTIVE_TOPICS) : false,
0691 'S_ENABLE_POST_REVIEW' => ($forum_data['forum_flags'] & FORUM_FLAG_POST_REVIEW) ? true : false,
0692 'S_ENABLE_QUICK_REPLY' => ($forum_data['forum_flags'] & FORUM_FLAG_QUICK_REPLY) ? true : false,
0693 'S_CAN_COPY_PERMISSIONS' => ($action != 'edit' || empty($forum_id) || ($auth->acl_get('a_fauth') && $auth->acl_get('a_authusers') && $auth->acl_get('a_authgroups') && $auth->acl_get('a_mauth'))) ? true : false,
0694 );
0695
0696 /**
0697 * Modify forum template data before we display the form
0698 *
0699 * @event core.acp_manage_forums_display_form
0700 * @var string action Type of the action: add|edit
0701 * @var bool update Do we display the form only
0702 * or did the user press submit
0703 * @var int forum_id When editing: the forum id,
0704 * when creating: the parent forum id
0705 * @var array row Array with current forum data
0706 * empty when creating new forum
0707 * @var array forum_data Array with new forum data
0708 * @var string parents_list List of parent options
0709 * @var array errors Array of errors, if you add errors
0710 * ensure to update the template variables
0711 * S_ERROR and ERROR_MSG to display it
0712 * @var array template_data Array with new forum data
0713 * @since 3.1.0-a1
0714 */
0715 $vars = array(
0716 'action',
0717 'update',
0718 'forum_id',
0719 'row',
0720 'forum_data',
0721 'parents_list',
0722 'errors',
0723 'template_data',
0724 );
0725 extract($phpbb_dispatcher->trigger_event('core.acp_manage_forums_display_form', compact($vars)));
0726
0727 $template->assign_vars($template_data);
0728
0729 return;
0730
0731 break;
0732
0733 case 'delete':
0734
0735 if (!$forum_id)
0736 {
0737 trigger_error($user->lang['NO_FORUM'] . adm_back_link($this->u_action . '&parent_id=' . $this->parent_id), E_USER_WARNING);
0738 }
0739
0740 $forum_data = $this->get_forum_info($forum_id);
0741
0742 $subforums_id = array();
0743 $subforums = get_forum_branch($forum_id, 'children');
0744
0745 foreach ($subforums as $row)
0746 {
0747 $subforums_id[] = $row['forum_id'];
0748 }
0749
0750 $forums_list = make_forum_select($forum_data['parent_id'], $subforums_id);
0751
0752 $sql = 'SELECT forum_id
0753 FROM ' . FORUMS_TABLE . '
0754 WHERE forum_type = ' . FORUM_POST . "
0755 AND forum_id <> $forum_id";
0756 $result = $db->sql_query_limit($sql, 1);
0757
0758 if ($db->sql_fetchrow($result))
0759 {
0760 $template->assign_vars(array(
0761 'S_MOVE_FORUM_OPTIONS' => make_forum_select($forum_data['parent_id'], $subforums_id, false, true)) // , false, true, false???
0762 );
0763 }
0764 $db->sql_freeresult($result);
0765
0766 $parent_id = ($this->parent_id == $forum_id) ? 0 : $this->parent_id;
0767
0768 $template->assign_vars(array(
0769 'S_DELETE_FORUM' => true,
0770 'U_ACTION' => $this->u_action . "&parent_id={$parent_id}&action=delete&f=$forum_id",
0771 'U_BACK' => $this->u_action . '&parent_id=' . $this->parent_id,
0772
0773 'FORUM_NAME' => $forum_data['forum_name'],
0774 'S_FORUM_POST' => ($forum_data['forum_type'] == FORUM_POST) ? true : false,
0775 'S_FORUM_LINK' => ($forum_data['forum_type'] == FORUM_LINK) ? true : false,
0776 'S_HAS_SUBFORUMS' => ($forum_data['right_id'] - $forum_data['left_id'] > 1) ? true : false,
0777 'S_FORUMS_LIST' => $forums_list,
0778 'S_ERROR' => (count($errors)) ? true : false,
0779 'ERROR_MSG' => (count($errors)) ? implode('<br />', $errors) : '')
0780 );
0781
0782 return;
0783 break;
0784
0785 case 'copy_perm':
0786 $forum_perm_from = $request->variable('forum_perm_from', 0);
0787
0788 // Copy permissions?
0789 if (!empty($forum_perm_from) && $forum_perm_from != $forum_id)
0790 {
0791 copy_forum_permissions($forum_perm_from, $forum_id, true);
0792 phpbb_cache_moderators($db, $cache, $auth);
0793 $auth->acl_clear_prefetch();
0794 $cache->destroy('sql', FORUMS_TABLE);
0795
0796 $acl_url = '&mode=setting_forum_local&forum_id[]=' . $forum_id;
0797
0798 $message = $user->lang['FORUM_UPDATED'];
0799
0800 // Redirect to permissions
0801 if ($auth->acl_get('a_fauth'))
0802 {
0803 $message .= '<br /><br />' . sprintf($user->lang['REDIRECT_ACL'], '<a href="' . append_sid("{$phpbb_admin_path}index.$phpEx", 'i=permissions' . $acl_url) . '">', '</a>');
0804 }
0805
0806 trigger_error($message . adm_back_link($this->u_action . '&parent_id=' . $this->parent_id));
0807 }
0808
0809 break;
0810 }
0811
0812 // Default management page
0813 if (!$this->parent_id)
0814 {
0815 $navigation = $user->lang['FORUM_INDEX'];
0816 }
0817 else
0818 {
0819 $navigation = '<a href="' . $this->u_action . '">' . $user->lang['FORUM_INDEX'] . '</a>';
0820
0821 $forums_nav = get_forum_branch($this->parent_id, 'parents', 'descending');
0822 foreach ($forums_nav as $row)
0823 {
0824 if ($row['forum_id'] == $this->parent_id)
0825 {
0826 $navigation .= ' -> ' . $row['forum_name'];
0827 }
0828 else
0829 {
0830 $navigation .= ' -> <a href="' . $this->u_action . '&parent_id=' . $row['forum_id'] . '">' . $row['forum_name'] . '</a>';
0831 }
0832 }
0833 }
0834
0835 // Jumpbox
0836 $forum_box = make_forum_select($this->parent_id, false, false, false, false); //make_forum_select($this->parent_id);
0837
0838 if ($action == 'sync' || $action == 'sync_forum')
0839 {
0840 $template->assign_var('S_RESYNCED', true);
0841 }
0842
0843 $sql = 'SELECT *
0844 FROM ' . FORUMS_TABLE . "
0845 WHERE parent_id = $this->parent_id
0846 ORDER BY left_id";
0847 $result = $db->sql_query($sql);
0848
0849 $rowset = array();
0850 while ($row = $db->sql_fetchrow($result))
0851 {
0852 $rowset[(int) $row['forum_id']] = $row;
0853 }
0854 $db->sql_freeresult($result);
0855
0856 /**
0857 * Modify the forum list data
0858 *
0859 * @event core.acp_manage_forums_modify_forum_list
0860 * @var array rowset Array with the forums list data
0861 * @since 3.1.10-RC1
0862 */
0863 $vars = array('rowset');
0864 extract($phpbb_dispatcher->trigger_event('core.acp_manage_forums_modify_forum_list', compact($vars)));
0865
0866 if (!empty($rowset))
0867 {
0868 foreach ($rowset as $row)
0869 {
0870 $forum_type = $row['forum_type'];
0871
0872 if ($row['forum_status'] == ITEM_LOCKED)
0873 {
0874 $folder_image = '<img src="images/icon_folder_lock.gif" alt="' . $user->lang['LOCKED'] . '" />';
0875 }
0876 else
0877 {
0878 switch ($forum_type)
0879 {
0880 case FORUM_LINK:
0881 $folder_image = '<img src="images/icon_folder_link.gif" alt="' . $user->lang['LINK'] . '" />';
0882 break;
0883
0884 default:
0885 $folder_image = ($row['left_id'] + 1 != $row['right_id']) ? '<img src="images/icon_subfolder.gif" alt="' . $user->lang['SUBFORUM'] . '" />' : '<img src="images/icon_folder.gif" alt="' . $user->lang['FOLDER'] . '" />';
0886 break;
0887 }
0888 }
0889
0890 $url = $this->u_action . "&parent_id=$this->parent_id&f={$row['forum_id']}";
0891
0892 $template->assign_block_vars('forums', array(
0893 'FOLDER_IMAGE' => $folder_image,
0894 'FORUM_IMAGE' => ($row['forum_image']) ? '<img src="' . $phpbb_root_path . $row['forum_image'] . '" alt="" />' : '',
0895 'FORUM_IMAGE_SRC' => ($row['forum_image']) ? $phpbb_root_path . $row['forum_image'] : '',
0896 'FORUM_NAME' => $row['forum_name'],
0897 'FORUM_DESCRIPTION' => generate_text_for_display($row['forum_desc'], $row['forum_desc_uid'], $row['forum_desc_bitfield'], $row['forum_desc_options']),
0898 'FORUM_TOPICS' => $row['forum_topics_approved'],
0899 'FORUM_POSTS' => $row['forum_posts_approved'],
0900
0901 'S_FORUM_LINK' => ($forum_type == FORUM_LINK) ? true : false,
0902 'S_FORUM_POST' => ($forum_type == FORUM_POST) ? true : false,
0903
0904 'U_FORUM' => $this->u_action . '&parent_id=' . $row['forum_id'],
0905 'U_MOVE_UP' => $url . '&action=move_up',
0906 'U_MOVE_DOWN' => $url . '&action=move_down',
0907 'U_EDIT' => $url . '&action=edit',
0908 'U_DELETE' => $url . '&action=delete',
0909 'U_SYNC' => $url . '&action=sync')
0910 );
0911 }
0912 }
0913 else if ($this->parent_id)
0914 {
0915 $row = $this->get_forum_info($this->parent_id);
0916
0917 $url = $this->u_action . '&parent_id=' . $this->parent_id . '&f=' . $row['forum_id'];
0918
0919 $template->assign_vars(array(
0920 'S_NO_FORUMS' => true,
0921
0922 'U_EDIT' => $url . '&action=edit',
0923 'U_DELETE' => $url . '&action=delete',
0924 'U_SYNC' => $url . '&action=sync')
0925 );
0926 }
0927 unset($rowset);
0928
0929 $template->assign_vars(array(
0930 'ERROR_MSG' => (count($errors)) ? implode('<br />', $errors) : '',
0931 'NAVIGATION' => $navigation,
0932 'FORUM_BOX' => $forum_box,
0933 'U_SEL_ACTION' => $this->u_action,
0934 'U_ACTION' => $this->u_action . '&parent_id=' . $this->parent_id,
0935
0936 'U_PROGRESS_BAR' => $this->u_action . '&action=progress_bar',
0937 'UA_PROGRESS_BAR' => addslashes($this->u_action . '&action=progress_bar'),
0938 ));
0939 }
0940
0941 /**
0942 * Get forum details
0943 */
0944 function get_forum_info($forum_id)
0945 {
0946 global $db;
0947
0948 $sql = 'SELECT *
0949 FROM ' . FORUMS_TABLE . "
0950 WHERE forum_id = $forum_id";
0951 $result = $db->sql_query($sql);
0952 $row = $db->sql_fetchrow($result);
0953 $db->sql_freeresult($result);
0954
0955 if (!$row)
0956 {
0957 trigger_error("Forum #$forum_id does not exist", E_USER_ERROR);
0958 }
0959
0960 return $row;
0961 }
0962
0963 /**
0964 * Update forum data
0965 */
0966 function update_forum_data(&$forum_data_ary)
0967 {
0968 global $db, $user, $cache, $phpbb_root_path, $phpbb_container, $phpbb_dispatcher, $phpbb_log, $request;
0969
0970 $errors = array();
0971
0972 $forum_data = $forum_data_ary;
0973 /**
0974 * Validate the forum data before we create/update the forum
0975 *
0976 * @event core.acp_manage_forums_validate_data
0977 * @var array forum_data Array with new forum data
0978 * @var array errors Array of errors, should be strings and not
0979 * language key.
0980 * @since 3.1.0-a1
0981 */
0982 $vars = array('forum_data', 'errors');
0983 extract($phpbb_dispatcher->trigger_event('core.acp_manage_forums_validate_data', compact($vars)));
0984 $forum_data_ary = $forum_data;
0985 unset($forum_data);
0986
0987 if ($forum_data_ary['forum_name'] == '')
0988 {
0989 $errors[] = $user->lang['FORUM_NAME_EMPTY'];
0990 }
0991
0992 /**
0993 * Replace Emojis and other 4bit UTF-8 chars not allowed by MySql to UCR / NCR.
0994 * Using their Numeric Character Reference's Hexadecimal notation.
0995 */
0996 $forum_data_ary['forum_name'] = utf8_encode_ucr($forum_data_ary['forum_name']);
0997
0998 /**
0999 * This should never happen again.
1000 * Leaving the fallback here just in case there will be the need of it.
1001 */
1002 if (preg_match_all('/[\x{10000}-\x{10FFFF}]/u', $forum_data_ary['forum_name'], $matches))
1003 {
1004 $character_list = implode('<br>', $matches[0]);
1005
1006 $errors[] = $user->lang('FORUM_NAME_EMOJI', $character_list);
1007 }
1008
1009 if (utf8_strlen($forum_data_ary['forum_desc']) > 4000)
1010 {
1011 $errors[] = $user->lang['FORUM_DESC_TOO_LONG'];
1012 }
1013
1014 if (utf8_strlen($forum_data_ary['forum_rules']) > 4000)
1015 {
1016 $errors[] = $user->lang['FORUM_RULES_TOO_LONG'];
1017 }
1018
1019 if ($forum_data_ary['forum_password'] || $forum_data_ary['forum_password_confirm'])
1020 {
1021 if ($forum_data_ary['forum_password'] != $forum_data_ary['forum_password_confirm'])
1022 {
1023 $forum_data_ary['forum_password'] = $forum_data_ary['forum_password_confirm'] = '';
1024 $errors[] = $user->lang['FORUM_PASSWORD_MISMATCH'];
1025 }
1026 }
1027
1028 if ($forum_data_ary['prune_days'] < 0 || $forum_data_ary['prune_viewed'] < 0 || $forum_data_ary['prune_freq'] < 0)
1029 {
1030 $forum_data_ary['prune_days'] = $forum_data_ary['prune_viewed'] = $forum_data_ary['prune_freq'] = 0;
1031 $errors[] = $user->lang['FORUM_DATA_NEGATIVE'];
1032 }
1033
1034 $range_test_ary = array(
1035 array('lang' => 'FORUM_TOPICS_PAGE', 'value' => $forum_data_ary['forum_topics_per_page'], 'column_type' => 'USINT:0'),
1036 );
1037
1038 if (!empty($forum_data_ary['forum_image']) && !file_exists($phpbb_root_path . $forum_data_ary['forum_image']))
1039 {
1040 $errors[] = $user->lang['FORUM_IMAGE_NO_EXIST'];
1041 }
1042
1043 validate_range($range_test_ary, $errors);
1044
1045 // Set forum flags
1046 // 1 = link tracking
1047 // 2 = prune old polls
1048 // 4 = prune announcements
1049 // 8 = prune stickies
1050 // 16 = show active topics
1051 // 32 = enable post review
1052 $forum_data_ary['forum_flags'] = 0;
1053 $forum_data_ary['forum_flags'] += ($forum_data_ary['forum_link_track']) ? FORUM_FLAG_LINK_TRACK : 0;
1054 $forum_data_ary['forum_flags'] += ($forum_data_ary['prune_old_polls']) ? FORUM_FLAG_PRUNE_POLL : 0;
1055 $forum_data_ary['forum_flags'] += ($forum_data_ary['prune_announce']) ? FORUM_FLAG_PRUNE_ANNOUNCE : 0;
1056 $forum_data_ary['forum_flags'] += ($forum_data_ary['prune_sticky']) ? FORUM_FLAG_PRUNE_STICKY : 0;
1057 $forum_data_ary['forum_flags'] += ($forum_data_ary['show_active']) ? FORUM_FLAG_ACTIVE_TOPICS : 0;
1058 $forum_data_ary['forum_flags'] += ($forum_data_ary['enable_post_review']) ? FORUM_FLAG_POST_REVIEW : 0;
1059 $forum_data_ary['forum_flags'] += ($forum_data_ary['enable_quick_reply']) ? FORUM_FLAG_QUICK_REPLY : 0;
1060
1061 // Unset data that are not database fields
1062 $forum_data_sql = $forum_data_ary;
1063
1064 unset($forum_data_sql['forum_link_track']);
1065 unset($forum_data_sql['prune_old_polls']);
1066 unset($forum_data_sql['prune_announce']);
1067 unset($forum_data_sql['prune_sticky']);
1068 unset($forum_data_sql['show_active']);
1069 unset($forum_data_sql['enable_post_review']);
1070 unset($forum_data_sql['enable_quick_reply']);
1071 unset($forum_data_sql['forum_password_confirm']);
1072
1073 // What are we going to do tonight Brain? The same thing we do everynight,
1074 // try to take over the world ... or decide whether to continue update
1075 // and if so, whether it's a new forum/cat/link or an existing one
1076 if (count($errors))
1077 {
1078 return $errors;
1079 }
1080
1081 // As we don't know the old password, it's kinda tricky to detect changes
1082 if ($forum_data_sql['forum_password_unset'])
1083 {
1084 $forum_data_sql['forum_password'] = '';
1085 }
1086 else if (empty($forum_data_sql['forum_password']))
1087 {
1088 unset($forum_data_sql['forum_password']);
1089 }
1090 else
1091 {
1092 // Instantiate passwords manager
1093 /* @var $passwords_manager \phpbb\passwords\manager */
1094 $passwords_manager = $phpbb_container->get('passwords.manager');
1095
1096 $forum_data_sql['forum_password'] = $passwords_manager->hash($forum_data_sql['forum_password']);
1097 }
1098 unset($forum_data_sql['forum_password_unset']);
1099
1100 $forum_data = $forum_data_ary;
1101 /**
1102 * Remove invalid values from forum_data_sql that should not be updated
1103 *
1104 * @event core.acp_manage_forums_update_data_before
1105 * @var array forum_data Array with forum data
1106 * @var array forum_data_sql Array with data we are going to update
1107 * If forum_data_sql[forum_id] is set, we update
1108 * that forum, otherwise a new one is created.
1109 * @since 3.1.0-a1
1110 */
1111 $vars = array('forum_data', 'forum_data_sql');
1112 extract($phpbb_dispatcher->trigger_event('core.acp_manage_forums_update_data_before', compact($vars)));
1113 $forum_data_ary = $forum_data;
1114 unset($forum_data);
1115
1116 $is_new_forum = !isset($forum_data_sql['forum_id']);
1117
1118 if ($is_new_forum)
1119 {
1120 // no forum_id means we're creating a new forum
1121 unset($forum_data_sql['type_action']);
1122
1123 if ($forum_data_sql['parent_id'])
1124 {
1125 $sql = 'SELECT left_id, right_id, forum_type
1126 FROM ' . FORUMS_TABLE . '
1127 WHERE forum_id = ' . $forum_data_sql['parent_id'];
1128 $result = $db->sql_query($sql);
1129 $row = $db->sql_fetchrow($result);
1130 $db->sql_freeresult($result);
1131
1132 if (!$row)
1133 {
1134 trigger_error($user->lang['PARENT_NOT_EXIST'] . adm_back_link($this->u_action . '&parent_id=' . $this->parent_id), E_USER_WARNING);
1135 }
1136
1137 if ($row['forum_type'] == FORUM_LINK)
1138 {
1139 $errors[] = $user->lang['PARENT_IS_LINK_FORUM'];
1140 return $errors;
1141 }
1142
1143 $sql = 'UPDATE ' . FORUMS_TABLE . '
1144 SET left_id = left_id + 2, right_id = right_id + 2
1145 WHERE left_id > ' . $row['right_id'];
1146 $db->sql_query($sql);
1147
1148 $sql = 'UPDATE ' . FORUMS_TABLE . '
1149 SET right_id = right_id + 2
1150 WHERE ' . $row['left_id'] . ' BETWEEN left_id AND right_id';
1151 $db->sql_query($sql);
1152
1153 $forum_data_sql['left_id'] = $row['right_id'];
1154 $forum_data_sql['right_id'] = $row['right_id'] + 1;
1155 }
1156 else
1157 {
1158 $sql = 'SELECT MAX(right_id) AS right_id
1159 FROM ' . FORUMS_TABLE;
1160 $result = $db->sql_query($sql);
1161 $row = $db->sql_fetchrow($result);
1162 $db->sql_freeresult($result);
1163
1164 $forum_data_sql['left_id'] = $row['right_id'] + 1;
1165 $forum_data_sql['right_id'] = $row['right_id'] + 2;
1166 }
1167
1168 $sql = 'INSERT INTO ' . FORUMS_TABLE . ' ' . $db->sql_build_array('INSERT', $forum_data_sql);
1169 $db->sql_query($sql);
1170
1171 $forum_data_ary['forum_id'] = $db->sql_nextid();
1172
1173 $phpbb_log->add('admin', $user->data['user_id'], $user->ip, 'LOG_FORUM_ADD', false, array($forum_data_ary['forum_name']));
1174 }
1175 else
1176 {
1177 $row = $this->get_forum_info($forum_data_sql['forum_id']);
1178
1179 if ($row['forum_type'] == FORUM_POST && $row['forum_type'] != $forum_data_sql['forum_type'])
1180 {
1181 // Has subforums and want to change into a link?
1182 if ($row['right_id'] - $row['left_id'] > 1 && $forum_data_sql['forum_type'] == FORUM_LINK)
1183 {
1184 $errors[] = $user->lang['FORUM_WITH_SUBFORUMS_NOT_TO_LINK'];
1185 return $errors;
1186 }
1187
1188 // we're turning a postable forum into a non-postable forum
1189 if ($forum_data_sql['type_action'] == 'move')
1190 {
1191 $to_forum_id = $request->variable('to_forum_id', 0);
1192
1193 if ($to_forum_id)
1194 {
1195 $errors = $this->move_forum_content($forum_data_sql['forum_id'], $to_forum_id);
1196 }
1197 else
1198 {
1199 return array($user->lang['NO_DESTINATION_FORUM']);
1200 }
1201 }
1202 else if ($forum_data_sql['type_action'] == 'delete')
1203 {
1204 $errors = $this->delete_forum_content($forum_data_sql['forum_id']);
1205 }
1206 else
1207 {
1208 return array($user->lang['NO_FORUM_ACTION']);
1209 }
1210
1211 $forum_data_sql['forum_posts_approved'] = $forum_data_sql['forum_posts_unapproved'] = $forum_data_sql['forum_posts_softdeleted'] = $forum_data_sql['forum_topics_approved'] = $forum_data_sql['forum_topics_unapproved'] = $forum_data_sql['forum_topics_softdeleted'] = 0;
1212 $forum_data_sql['forum_last_post_id'] = $forum_data_sql['forum_last_poster_id'] = $forum_data_sql['forum_last_post_time'] = 0;
1213 $forum_data_sql['forum_last_poster_name'] = $forum_data_sql['forum_last_poster_colour'] = '';
1214 }
1215 else if ($row['forum_type'] == FORUM_CAT && $forum_data_sql['forum_type'] == FORUM_LINK)
1216 {
1217 // Has subforums?
1218 if ($row['right_id'] - $row['left_id'] > 1)
1219 {
1220 // We are turning a category into a link - but need to decide what to do with the subforums.
1221 $action_subforums = $request->variable('action_subforums', '');
1222 $subforums_to_id = $request->variable('subforums_to_id', 0);
1223
1224 if ($action_subforums == 'delete')
1225 {
1226 $rows = get_forum_branch($row['forum_id'], 'children', 'descending', false);
1227
1228 foreach ($rows as $_row)
1229 {
1230 // Do not remove the forum id we are about to change. ;)
1231 if ($_row['forum_id'] == $row['forum_id'])
1232 {
1233 continue;
1234 }
1235
1236 $forum_ids[] = $_row['forum_id'];
1237 $errors = array_merge($errors, $this->delete_forum_content($_row['forum_id']));
1238 }
1239
1240 if (count($errors))
1241 {
1242 return $errors;
1243 }
1244
1245 if (count($forum_ids))
1246 {
1247 $sql = 'DELETE FROM ' . FORUMS_TABLE . '
1248 WHERE ' . $db->sql_in_set('forum_id', $forum_ids);
1249 $db->sql_query($sql);
1250
1251 $sql = 'DELETE FROM ' . ACL_GROUPS_TABLE . '
1252 WHERE ' . $db->sql_in_set('forum_id', $forum_ids);
1253 $db->sql_query($sql);
1254
1255 $sql = 'DELETE FROM ' . ACL_USERS_TABLE . '
1256 WHERE ' . $db->sql_in_set('forum_id', $forum_ids);
1257 $db->sql_query($sql);
1258
1259 // Delete forum ids from extension groups table
1260 $sql = 'SELECT group_id, allowed_forums
1261 FROM ' . EXTENSION_GROUPS_TABLE;
1262 $result = $db->sql_query($sql);
1263
1264 while ($_row = $db->sql_fetchrow($result))
1265 {
1266 if (!$_row['allowed_forums'])
1267 {
1268 continue;
1269 }
1270
1271 $allowed_forums = unserialize(trim($_row['allowed_forums']));
1272 $allowed_forums = array_diff($allowed_forums, $forum_ids);
1273
1274 $sql = 'UPDATE ' . EXTENSION_GROUPS_TABLE . "
1275 SET allowed_forums = '" . ((count($allowed_forums)) ? serialize($allowed_forums) : '') . "'
1276 WHERE group_id = {$_row['group_id']}";
1277 $db->sql_query($sql);
1278 }
1279 $db->sql_freeresult($result);
1280
1281 $cache->destroy('_extensions');
1282 }
1283 }
1284 else if ($action_subforums == 'move')
1285 {
1286 if (!$subforums_to_id)
1287 {
1288 return array($user->lang['NO_DESTINATION_FORUM']);
1289 }
1290
1291 $sql = 'SELECT forum_name
1292 FROM ' . FORUMS_TABLE . '
1293 WHERE forum_id = ' . $subforums_to_id;
1294 $result = $db->sql_query($sql);
1295 $_row = $db->sql_fetchrow($result);
1296 $db->sql_freeresult($result);
1297
1298 if (!$_row)
1299 {
1300 return array($user->lang['NO_FORUM']);
1301 }
1302
1303 $sql = 'SELECT forum_id
1304 FROM ' . FORUMS_TABLE . "
1305 WHERE parent_id = {$row['forum_id']}";
1306 $result = $db->sql_query($sql);
1307
1308 while ($_row = $db->sql_fetchrow($result))
1309 {
1310 $this->move_forum($_row['forum_id'], $subforums_to_id);
1311 }
1312 $db->sql_freeresult($result);
1313
1314 $sql = 'UPDATE ' . FORUMS_TABLE . "
1315 SET parent_id = $subforums_to_id
1316 WHERE parent_id = {$row['forum_id']}";
1317 $db->sql_query($sql);
1318 }
1319
1320 // Adjust the left/right id
1321 $sql = 'UPDATE ' . FORUMS_TABLE . '
1322 SET right_id = left_id + 1
1323 WHERE forum_id = ' . $row['forum_id'];
1324 $db->sql_query($sql);
1325 }
1326 }
1327 else if ($row['forum_type'] == FORUM_CAT && $forum_data_sql['forum_type'] == FORUM_POST)
1328 {
1329 // Changing a category to a forum? Reset the data (you can't post directly in a cat, you must use a forum)
1330 $forum_data_sql['forum_posts_approved'] = 0;
1331 $forum_data_sql['forum_posts_unapproved'] = 0;
1332 $forum_data_sql['forum_posts_softdeleted'] = 0;
1333 $forum_data_sql['forum_topics_approved'] = 0;
1334 $forum_data_sql['forum_topics_unapproved'] = 0;
1335 $forum_data_sql['forum_topics_softdeleted'] = 0;
1336 $forum_data_sql['forum_last_post_id'] = 0;
1337 $forum_data_sql['forum_last_post_subject'] = '';
1338 $forum_data_sql['forum_last_post_time'] = 0;
1339 $forum_data_sql['forum_last_poster_id'] = 0;
1340 $forum_data_sql['forum_last_poster_name'] = '';
1341 $forum_data_sql['forum_last_poster_colour'] = '';
1342 }
1343
1344 if (count($errors))
1345 {
1346 return $errors;
1347 }
1348
1349 if ($row['parent_id'] != $forum_data_sql['parent_id'])
1350 {
1351 if ($row['forum_id'] != $forum_data_sql['parent_id'])
1352 {
1353 $errors = $this->move_forum($forum_data_sql['forum_id'], $forum_data_sql['parent_id']);
1354 }
1355 else
1356 {
1357 $forum_data_sql['parent_id'] = $row['parent_id'];
1358 }
1359 }
1360
1361 if (count($errors))
1362 {
1363 return $errors;
1364 }
1365
1366 unset($forum_data_sql['type_action']);
1367
1368 if ($row['forum_name'] != $forum_data_sql['forum_name'])
1369 {
1370 // the forum name has changed, clear the parents list of all forums (for safety)
1371 $sql = 'UPDATE ' . FORUMS_TABLE . "
1372 SET forum_parents = ''";
1373 $db->sql_query($sql);
1374 }
1375
1376 // Setting the forum id to the forum id is not really received well by some dbs. ;)
1377 $forum_id = $forum_data_sql['forum_id'];
1378 unset($forum_data_sql['forum_id']);
1379
1380 $sql = 'UPDATE ' . FORUMS_TABLE . '
1381 SET ' . $db->sql_build_array('UPDATE', $forum_data_sql) . '
1382 WHERE forum_id = ' . $forum_id;
1383 $db->sql_query($sql);
1384
1385 // Add it back
1386 $forum_data_ary['forum_id'] = $forum_id;
1387
1388 $phpbb_log->add('admin', $user->data['user_id'], $user->ip, 'LOG_FORUM_EDIT', false, array($forum_data_ary['forum_name']));
1389 }
1390
1391 $forum_data = $forum_data_ary;
1392 /**
1393 * Event after a forum was updated or created
1394 *
1395 * @event core.acp_manage_forums_update_data_after
1396 * @var array forum_data Array with forum data
1397 * @var array forum_data_sql Array with data we updated
1398 * @var bool is_new_forum Did we create a forum or update one
1399 * If you want to overwrite this value,
1400 * ensure to set forum_data_sql[forum_id]
1401 * @var array errors Array of errors, should be strings and not
1402 * language key.
1403 * @since 3.1.0-a1
1404 */
1405 $vars = array('forum_data', 'forum_data_sql', 'is_new_forum', 'errors');
1406 extract($phpbb_dispatcher->trigger_event('core.acp_manage_forums_update_data_after', compact($vars)));
1407 $forum_data_ary = $forum_data;
1408 unset($forum_data);
1409
1410 return $errors;
1411 }
1412
1413 /**
1414 * Move forum
1415 */
1416 function move_forum($from_id, $to_id)
1417 {
1418 global $db, $user, $phpbb_dispatcher;
1419
1420 $errors = array();
1421
1422 // Check if we want to move to a parent with link type
1423 if ($to_id > 0)
1424 {
1425 $to_data = $this->get_forum_info($to_id);
1426
1427 if ($to_data['forum_type'] == FORUM_LINK)
1428 {
1429 $errors[] = $user->lang['PARENT_IS_LINK_FORUM'];
1430 }
1431 }
1432
1433 /**
1434 * Event when we move all children of one forum to another
1435 *
1436 * This event may be triggered, when a forum is deleted
1437 *
1438 * @event core.acp_manage_forums_move_children
1439 * @var int from_id Id of the current parent forum
1440 * @var int to_id Id of the new parent forum
1441 * @var array errors Array of errors, should be strings and not
1442 * language key.
1443 * @since 3.1.0-a1
1444 */
1445 $vars = array('from_id', 'to_id', 'errors');
1446 extract($phpbb_dispatcher->trigger_event('core.acp_manage_forums_move_children', compact($vars)));
1447
1448 // Return if there were errors
1449 if (!empty($errors))
1450 {
1451 return $errors;
1452 }
1453
1454 $db->sql_transaction('begin');
1455
1456 $moved_forums = get_forum_branch($from_id, 'children', 'descending');
1457 $from_data = $moved_forums[0];
1458 $diff = count($moved_forums) * 2;
1459
1460 $moved_ids = array();
1461 for ($i = 0, $size = count($moved_forums); $i < $size; ++$i)
1462 {
1463 $moved_ids[] = $moved_forums[$i]['forum_id'];
1464 }
1465
1466 // Resync parents
1467 $sql = 'UPDATE ' . FORUMS_TABLE . "
1468 SET right_id = right_id - $diff, forum_parents = ''
1469 WHERE left_id < " . $from_data['right_id'] . "
1470 AND right_id > " . $from_data['right_id'];
1471 $db->sql_query($sql);
1472
1473 // Resync righthand side of tree
1474 $sql = 'UPDATE ' . FORUMS_TABLE . "
1475 SET left_id = left_id - $diff, right_id = right_id - $diff, forum_parents = ''
1476 WHERE left_id > " . $from_data['right_id'];
1477 $db->sql_query($sql);
1478
1479 if ($to_id > 0)
1480 {
1481 // Retrieve $to_data again, it may have been changed...
1482 $to_data = $this->get_forum_info($to_id);
1483
1484 // Resync new parents
1485 $sql = 'UPDATE ' . FORUMS_TABLE . "
1486 SET right_id = right_id + $diff, forum_parents = ''
1487 WHERE " . $to_data['right_id'] . ' BETWEEN left_id AND right_id
1488 AND ' . $db->sql_in_set('forum_id', $moved_ids, true);
1489 $db->sql_query($sql);
1490
1491 // Resync the righthand side of the tree
1492 $sql = 'UPDATE ' . FORUMS_TABLE . "
1493 SET left_id = left_id + $diff, right_id = right_id + $diff, forum_parents = ''
1494 WHERE left_id > " . $to_data['right_id'] . '
1495 AND ' . $db->sql_in_set('forum_id', $moved_ids, true);
1496 $db->sql_query($sql);
1497
1498 // Resync moved branch
1499 $to_data['right_id'] += $diff;
1500
1501 if ($to_data['right_id'] > $from_data['right_id'])
1502 {
1503 $diff = '+ ' . ($to_data['right_id'] - $from_data['right_id'] - 1);
1504 }
1505 else
1506 {
1507 $diff = '- ' . abs($to_data['right_id'] - $from_data['right_id'] - 1);
1508 }
1509 }
1510 else
1511 {
1512 $sql = 'SELECT MAX(right_id) AS right_id
1513 FROM ' . FORUMS_TABLE . '
1514 WHERE ' . $db->sql_in_set('forum_id', $moved_ids, true);
1515 $result = $db->sql_query($sql);
1516 $row = $db->sql_fetchrow($result);
1517 $db->sql_freeresult($result);
1518
1519 $diff = '+ ' . ($row['right_id'] - $from_data['left_id'] + 1);
1520 }
1521
1522 $sql = 'UPDATE ' . FORUMS_TABLE . "
1523 SET left_id = left_id $diff, right_id = right_id $diff, forum_parents = ''
1524 WHERE " . $db->sql_in_set('forum_id', $moved_ids);
1525 $db->sql_query($sql);
1526
1527 $db->sql_transaction('commit');
1528
1529 return $errors;
1530 }
1531
1532 /**
1533 * Move forum content from one to another forum
1534 */
1535 function move_forum_content($from_id, $to_id, $sync = true)
1536 {
1537 global $db, $phpbb_dispatcher;
1538
1539 $errors = array();
1540
1541 /**
1542 * Event when we move content from one forum to another
1543 *
1544 * @event core.acp_manage_forums_move_content
1545 * @var int from_id Id of the current parent forum
1546 * @var int to_id Id of the new parent forum
1547 * @var bool sync Shall we sync the "to"-forum's data
1548 * @var array errors Array of errors, should be strings and not
1549 * language key. If this array is not empty,
1550 * The content will not be moved.
1551 * @since 3.1.0-a1
1552 */
1553 $vars = array('from_id', 'to_id', 'sync', 'errors');
1554 extract($phpbb_dispatcher->trigger_event('core.acp_manage_forums_move_content', compact($vars)));
1555
1556 // Return if there were errors
1557 if (!empty($errors))
1558 {
1559 return $errors;
1560 }
1561
1562 $table_ary = array(LOG_TABLE, POSTS_TABLE, TOPICS_TABLE, DRAFTS_TABLE, TOPICS_TRACK_TABLE);
1563
1564 /**
1565 * Perform additional actions before move forum content
1566 *
1567 * @event core.acp_manage_forums_move_content_sql_before
1568 * @var array table_ary Array of tables from which forum_id will be updated
1569 * @since 3.2.4-RC1
1570 */
1571 $vars = array('table_ary');
1572 extract($phpbb_dispatcher->trigger_event('core.acp_manage_forums_move_content_sql_before', compact($vars)));
1573
1574 foreach ($table_ary as $table)
1575 {
1576 $sql = "UPDATE $table
1577 SET forum_id = $to_id
1578 WHERE forum_id = $from_id";
1579 $db->sql_query($sql);
1580 }
1581 unset($table_ary);
1582
1583 $table_ary = array(FORUMS_ACCESS_TABLE, FORUMS_TRACK_TABLE, FORUMS_WATCH_TABLE, MODERATOR_CACHE_TABLE);
1584
1585 foreach ($table_ary as $table)
1586 {
1587 $sql = "DELETE FROM $table
1588 WHERE forum_id = $from_id";
1589 $db->sql_query($sql);
1590 }
1591
1592 /**
1593 * Event when content has been moved from one forum to another
1594 *
1595 * @event core.acp_manage_forums_move_content_after
1596 * @var int from_id Id of the current parent forum
1597 * @var int to_id Id of the new parent forum
1598 * @var bool sync Shall we sync the "to"-forum's data
1599 *
1600 * @since 3.2.9-RC1
1601 */
1602 $vars = array('from_id', 'to_id', 'sync');
1603 extract($phpbb_dispatcher->trigger_event('core.acp_manage_forums_move_content_after', compact($vars)));
1604
1605 if ($sync)
1606 {
1607 // Delete ghost topics that link back to the same forum then resync counters
1608 sync('topic_moved');
1609 sync('forum', 'forum_id', $to_id, false, true);
1610 }
1611
1612 return array();
1613 }
1614
1615 /**
1616 * Remove complete forum
1617 */
1618 function delete_forum($forum_id, $action_posts = 'delete', $action_subforums = 'delete', $posts_to_id = 0, $subforums_to_id = 0)
1619 {
1620 global $db, $user, $cache, $phpbb_log;
1621
1622 $forum_data = $this->get_forum_info($forum_id);
1623
1624 $errors = array();
1625 $log_action_posts = $log_action_forums = $posts_to_name = $subforums_to_name = '';
1626 $forum_ids = array($forum_id);
1627
1628 if ($action_posts == 'delete')
1629 {
1630 $log_action_posts = 'POSTS';
1631 $errors = array_merge($errors, $this->delete_forum_content($forum_id));
1632 }
1633 else if ($action_posts == 'move')
1634 {
1635 if (!$posts_to_id)
1636 {
1637 $errors[] = $user->lang['NO_DESTINATION_FORUM'];
1638 }
1639 else
1640 {
1641 $log_action_posts = 'MOVE_POSTS';
1642
1643 $sql = 'SELECT forum_name
1644 FROM ' . FORUMS_TABLE . '
1645 WHERE forum_id = ' . $posts_to_id;
1646 $result = $db->sql_query($sql);
1647 $row = $db->sql_fetchrow($result);
1648 $db->sql_freeresult($result);
1649
1650 if (!$row)
1651 {
1652 $errors[] = $user->lang['NO_FORUM'];
1653 }
1654 else
1655 {
1656 $posts_to_name = $row['forum_name'];
1657 $errors = array_merge($errors, $this->move_forum_content($forum_id, $posts_to_id));
1658 }
1659 }
1660 }
1661
1662 if (count($errors))
1663 {
1664 return $errors;
1665 }
1666
1667 if ($action_subforums == 'delete')
1668 {
1669 $log_action_forums = 'FORUMS';
1670 $rows = get_forum_branch($forum_id, 'children', 'descending', false);
1671
1672 foreach ($rows as $row)
1673 {
1674 $forum_ids[] = $row['forum_id'];
1675 $errors = array_merge($errors, $this->delete_forum_content($row['forum_id']));
1676 }
1677
1678 if (count($errors))
1679 {
1680 return $errors;
1681 }
1682
1683 $diff = count($forum_ids) * 2;
1684
1685 $sql = 'DELETE FROM ' . FORUMS_TABLE . '
1686 WHERE ' . $db->sql_in_set('forum_id', $forum_ids);
1687 $db->sql_query($sql);
1688
1689 $sql = 'DELETE FROM ' . ACL_GROUPS_TABLE . '
1690 WHERE ' . $db->sql_in_set('forum_id', $forum_ids);
1691 $db->sql_query($sql);
1692
1693 $sql = 'DELETE FROM ' . ACL_USERS_TABLE . '
1694 WHERE ' . $db->sql_in_set('forum_id', $forum_ids);
1695 $db->sql_query($sql);
1696 }
1697 else if ($action_subforums == 'move')
1698 {
1699 if (!$subforums_to_id)
1700 {
1701 $errors[] = $user->lang['NO_DESTINATION_FORUM'];
1702 }
1703 else
1704 {
1705 $log_action_forums = 'MOVE_FORUMS';
1706
1707 $sql = 'SELECT forum_name
1708 FROM ' . FORUMS_TABLE . '
1709 WHERE forum_id = ' . $subforums_to_id;
1710 $result = $db->sql_query($sql);
1711 $row = $db->sql_fetchrow($result);
1712 $db->sql_freeresult($result);
1713
1714 if (!$row)
1715 {
1716 $errors[] = $user->lang['NO_FORUM'];
1717 }
1718 else
1719 {
1720 $subforums_to_name = $row['forum_name'];
1721
1722 $sql = 'SELECT forum_id
1723 FROM ' . FORUMS_TABLE . "
1724 WHERE parent_id = $forum_id";
1725 $result = $db->sql_query($sql);
1726
1727 while ($row = $db->sql_fetchrow($result))
1728 {
1729 $this->move_forum($row['forum_id'], $subforums_to_id);
1730 }
1731 $db->sql_freeresult($result);
1732
1733 // Grab new forum data for correct tree updating later
1734 $forum_data = $this->get_forum_info($forum_id);
1735
1736 $sql = 'UPDATE ' . FORUMS_TABLE . "
1737 SET parent_id = $subforums_to_id
1738 WHERE parent_id = $forum_id";
1739 $db->sql_query($sql);
1740
1741 $diff = 2;
1742 $sql = 'DELETE FROM ' . FORUMS_TABLE . "
1743 WHERE forum_id = $forum_id";
1744 $db->sql_query($sql);
1745
1746 $sql = 'DELETE FROM ' . ACL_GROUPS_TABLE . "
1747 WHERE forum_id = $forum_id";
1748 $db->sql_query($sql);
1749
1750 $sql = 'DELETE FROM ' . ACL_USERS_TABLE . "
1751 WHERE forum_id = $forum_id";
1752 $db->sql_query($sql);
1753 }
1754 }
1755
1756 if (count($errors))
1757 {
1758 return $errors;
1759 }
1760 }
1761 else
1762 {
1763 $diff = 2;
1764 $sql = 'DELETE FROM ' . FORUMS_TABLE . "
1765 WHERE forum_id = $forum_id";
1766 $db->sql_query($sql);
1767
1768 $sql = 'DELETE FROM ' . ACL_GROUPS_TABLE . "
1769 WHERE forum_id = $forum_id";
1770 $db->sql_query($sql);
1771
1772 $sql = 'DELETE FROM ' . ACL_USERS_TABLE . "
1773 WHERE forum_id = $forum_id";
1774 $db->sql_query($sql);
1775 }
1776
1777 // Resync tree
1778 $sql = 'UPDATE ' . FORUMS_TABLE . "
1779 SET right_id = right_id - $diff
1780 WHERE left_id < {$forum_data['right_id']} AND right_id > {$forum_data['right_id']}";
1781 $db->sql_query($sql);
1782
1783 $sql = 'UPDATE ' . FORUMS_TABLE . "
1784 SET left_id = left_id - $diff, right_id = right_id - $diff
1785 WHERE left_id > {$forum_data['right_id']}";
1786 $db->sql_query($sql);
1787
1788 // Delete forum ids from extension groups table
1789 $sql = 'SELECT group_id, allowed_forums
1790 FROM ' . EXTENSION_GROUPS_TABLE;
1791 $result = $db->sql_query($sql);
1792
1793 while ($row = $db->sql_fetchrow($result))
1794 {
1795 if (!$row['allowed_forums'])
1796 {
1797 continue;
1798 }
1799
1800 $allowed_forums = unserialize(trim($row['allowed_forums']));
1801 $allowed_forums = array_diff($allowed_forums, $forum_ids);
1802
1803 $sql = 'UPDATE ' . EXTENSION_GROUPS_TABLE . "
1804 SET allowed_forums = '" . ((count($allowed_forums)) ? serialize($allowed_forums) : '') . "'
1805 WHERE group_id = {$row['group_id']}";
1806 $db->sql_query($sql);
1807 }
1808 $db->sql_freeresult($result);
1809
1810 $cache->destroy('_extensions');
1811
1812 $log_action = implode('_', array($log_action_posts, $log_action_forums));
1813
1814 switch ($log_action)
1815 {
1816 case 'MOVE_POSTS_MOVE_FORUMS':
1817 $phpbb_log->add('admin', $user->data['user_id'], $user->ip, 'LOG_FORUM_DEL_MOVE_POSTS_MOVE_FORUMS', false, array($posts_to_name, $subforums_to_name, $forum_data['forum_name']));
1818 break;
1819
1820 case 'MOVE_POSTS_FORUMS':
1821 $phpbb_log->add('admin', $user->data['user_id'], $user->ip, 'LOG_FORUM_DEL_MOVE_POSTS_FORUMS', false, array($posts_to_name, $forum_data['forum_name']));
1822 break;
1823
1824 case 'POSTS_MOVE_FORUMS':
1825 $phpbb_log->add('admin', $user->data['user_id'], $user->ip, 'LOG_FORUM_DEL_POSTS_MOVE_FORUMS', false, array($subforums_to_name, $forum_data['forum_name']));
1826 break;
1827
1828 case '_MOVE_FORUMS':
1829 $phpbb_log->add('admin', $user->data['user_id'], $user->ip, 'LOG_FORUM_DEL_MOVE_FORUMS', false, array($subforums_to_name, $forum_data['forum_name']));
1830 break;
1831
1832 case 'MOVE_POSTS_':
1833 $phpbb_log->add('admin', $user->data['user_id'], $user->ip, 'LOG_FORUM_DEL_MOVE_POSTS', false, array($posts_to_name, $forum_data['forum_name']));
1834 break;
1835
1836 case 'POSTS_FORUMS':
1837 $phpbb_log->add('admin', $user->data['user_id'], $user->ip, 'LOG_FORUM_DEL_POSTS_FORUMS', false, array($forum_data['forum_name']));
1838 break;
1839
1840 case '_FORUMS':
1841 $phpbb_log->add('admin', $user->data['user_id'], $user->ip, 'LOG_FORUM_DEL_FORUMS', false, array($forum_data['forum_name']));
1842 break;
1843
1844 case 'POSTS_':
1845 $phpbb_log->add('admin', $user->data['user_id'], $user->ip, 'LOG_FORUM_DEL_POSTS', false, array($forum_data['forum_name']));
1846 break;
1847
1848 default:
1849 $phpbb_log->add('admin', $user->data['user_id'], $user->ip, 'LOG_FORUM_DEL_FORUM', false, array($forum_data['forum_name']));
1850 break;
1851 }
1852
1853 return $errors;
1854 }
1855
1856 /**
1857 * Delete forum content
1858 */
1859 function delete_forum_content($forum_id)
1860 {
1861 global $db, $config, $phpbb_root_path, $phpEx, $phpbb_container, $phpbb_dispatcher;
1862
1863 include_once($phpbb_root_path . 'includes/functions_posting.' . $phpEx);
1864
1865 $db->sql_transaction('begin');
1866
1867 // Select then delete all attachments
1868 $sql = 'SELECT a.topic_id
1869 FROM ' . POSTS_TABLE . ' p, ' . ATTACHMENTS_TABLE . " a
1870 WHERE p.forum_id = $forum_id
1871 AND a.in_message = 0
1872 AND a.topic_id = p.topic_id";
1873 $result = $db->sql_query($sql);
1874
1875 $topic_ids = array();
1876 while ($row = $db->sql_fetchrow($result))
1877 {
1878 $topic_ids[] = $row['topic_id'];
1879 }
1880 $db->sql_freeresult($result);
1881
1882 /** @var \phpbb\attachment\manager $attachment_manager */
1883 $attachment_manager = $phpbb_container->get('attachment.manager');
1884 $attachment_manager->delete('topic', $topic_ids, false);
1885 unset($attachment_manager);
1886
1887 // Delete shadow topics pointing to topics in this forum
1888 delete_topic_shadows($forum_id);
1889
1890 // Before we remove anything we make sure we are able to adjust the post counts later. ;)
1891 $sql = 'SELECT poster_id
1892 FROM ' . POSTS_TABLE . '
1893 WHERE forum_id = ' . $forum_id . '
1894 AND post_postcount = 1
1895 AND post_visibility = ' . ITEM_APPROVED;
1896 $result = $db->sql_query($sql);
1897
1898 $post_counts = array();
1899 while ($row = $db->sql_fetchrow($result))
1900 {
1901 $post_counts[$row['poster_id']] = (!empty($post_counts[$row['poster_id']])) ? $post_counts[$row['poster_id']] + 1 : 1;
1902 }
1903 $db->sql_freeresult($result);
1904
1905 switch ($db->get_sql_layer())
1906 {
1907 case 'mysqli':
1908
1909 // Delete everything else and thank MySQL for offering multi-table deletion
1910 $tables_ary = array(
1911 SEARCH_WORDMATCH_TABLE => 'post_id',
1912 REPORTS_TABLE => 'post_id',
1913 WARNINGS_TABLE => 'post_id',
1914 BOOKMARKS_TABLE => 'topic_id',
1915 TOPICS_WATCH_TABLE => 'topic_id',
1916 TOPICS_POSTED_TABLE => 'topic_id',
1917 POLL_OPTIONS_TABLE => 'topic_id',
1918 POLL_VOTES_TABLE => 'topic_id',
1919 );
1920
1921 $sql = 'DELETE ' . POSTS_TABLE;
1922 $sql_using = "\nFROM " . POSTS_TABLE;
1923 $sql_where = "\nWHERE " . POSTS_TABLE . ".forum_id = $forum_id\n";
1924
1925 foreach ($tables_ary as $table => $field)
1926 {
1927 $sql .= ", $table ";
1928 $sql_using .= ", $table ";
1929 $sql_where .= "\nAND $table.$field = " . POSTS_TABLE . ".$field";
1930 }
1931
1932 $db->sql_query($sql . $sql_using . $sql_where);
1933
1934 break;
1935
1936 default:
1937
1938 // Delete everything else and curse your DB for not offering multi-table deletion
1939 $tables_ary = array(
1940 'post_id' => array(
1941 SEARCH_WORDMATCH_TABLE,
1942 REPORTS_TABLE,
1943 WARNINGS_TABLE,
1944 ),
1945
1946 'topic_id' => array(
1947 BOOKMARKS_TABLE,
1948 TOPICS_WATCH_TABLE,
1949 TOPICS_POSTED_TABLE,
1950 POLL_OPTIONS_TABLE,
1951 POLL_VOTES_TABLE,
1952 )
1953 );
1954
1955 // Amount of rows we select and delete in one iteration.
1956 $batch_size = 500;
1957
1958 foreach ($tables_ary as $field => $tables)
1959 {
1960 $start = 0;
1961
1962 do
1963 {
1964 $sql = "SELECT $field
1965 FROM " . POSTS_TABLE . '
1966 WHERE forum_id = ' . $forum_id;
1967 $result = $db->sql_query_limit($sql, $batch_size, $start);
1968
1969 $ids = array();
1970 while ($row = $db->sql_fetchrow($result))
1971 {
1972 $ids[] = $row[$field];
1973 }
1974 $db->sql_freeresult($result);
1975
1976 if (count($ids))
1977 {
1978 $start += count($ids);
1979
1980 foreach ($tables as $table)
1981 {
1982 $db->sql_query("DELETE FROM $table WHERE " . $db->sql_in_set($field, $ids));
1983 }
1984 }
1985 }
1986 while (count($ids) == $batch_size);
1987 }
1988 unset($ids);
1989
1990 break;
1991 }
1992
1993 $table_ary = array(FORUMS_ACCESS_TABLE, FORUMS_TRACK_TABLE, FORUMS_WATCH_TABLE, LOG_TABLE, MODERATOR_CACHE_TABLE, POSTS_TABLE, TOPICS_TABLE, TOPICS_TRACK_TABLE);
1994
1995 /**
1996 * Perform additional actions before forum content deletion
1997 *
1998 * @event core.delete_forum_content_before_query
1999 * @var array table_ary Array of tables from which all rows will be deleted that hold the forum_id
2000 * @var int forum_id the forum id
2001 * @var array topic_ids Array of the topic ids from the forum to be deleted
2002 * @var array post_counts Array of counts of posts in the forum, by poster_id
2003 * @since 3.1.6-RC1
2004 */
2005 $vars = array(
2006 'table_ary',
2007 'forum_id',
2008 'topic_ids',
2009 'post_counts',
2010 );
2011 extract($phpbb_dispatcher->trigger_event('core.delete_forum_content_before_query', compact($vars)));
2012
2013 foreach ($table_ary as $table)
2014 {
2015 $db->sql_query("DELETE FROM $table WHERE forum_id = $forum_id");
2016 }
2017
2018 // Set forum ids to 0
2019 $table_ary = array(DRAFTS_TABLE);
2020
2021 foreach ($table_ary as $table)
2022 {
2023 $db->sql_query("UPDATE $table SET forum_id = 0 WHERE forum_id = $forum_id");
2024 }
2025
2026 // Adjust users post counts
2027 if (count($post_counts))
2028 {
2029 foreach ($post_counts as $poster_id => $substract)
2030 {
2031 $sql = 'UPDATE ' . USERS_TABLE . '
2032 SET user_posts = 0
2033 WHERE user_id = ' . $poster_id . '
2034 AND user_posts < ' . $substract;
2035 $db->sql_query($sql);
2036
2037 $sql = 'UPDATE ' . USERS_TABLE . '
2038 SET user_posts = user_posts - ' . $substract . '
2039 WHERE user_id = ' . $poster_id . '
2040 AND user_posts >= ' . $substract;
2041 $db->sql_query($sql);
2042 }
2043 }
2044
2045 $db->sql_transaction('commit');
2046
2047 // Make sure the overall post/topic count is correct...
2048 $sql = 'SELECT COUNT(post_id) AS stat
2049 FROM ' . POSTS_TABLE . '
2050 WHERE post_visibility = ' . ITEM_APPROVED;
2051 $result = $db->sql_query($sql);
2052 $row = $db->sql_fetchrow($result);
2053 $db->sql_freeresult($result);
2054
2055 $config->set('num_posts', (int) $row['stat'], false);
2056
2057 $sql = 'SELECT COUNT(topic_id) AS stat
2058 FROM ' . TOPICS_TABLE . '
2059 WHERE topic_visibility = ' . ITEM_APPROVED;
2060 $result = $db->sql_query($sql);
2061 $row = $db->sql_fetchrow($result);
2062 $db->sql_freeresult($result);
2063
2064 $config->set('num_topics', (int) $row['stat'], false);
2065
2066 $sql = 'SELECT COUNT(attach_id) as stat
2067 FROM ' . ATTACHMENTS_TABLE;
2068 $result = $db->sql_query($sql);
2069 $row = $db->sql_fetchrow($result);
2070 $db->sql_freeresult($result);
2071
2072 $config->set('num_files', (int) $row['stat'], false);
2073
2074 $sql = 'SELECT SUM(filesize) as stat
2075 FROM ' . ATTACHMENTS_TABLE;
2076 $result = $db->sql_query($sql);
2077 $row = $db->sql_fetchrow($result);
2078 $db->sql_freeresult($result);
2079
2080 $config->set('upload_dir_size', (float) $row['stat'], false);
2081
2082 return array();
2083 }
2084
2085 /**
2086 * Move forum position by $steps up/down
2087 */
2088 function move_forum_by($forum_row, $action = 'move_up', $steps = 1)
2089 {
2090 global $db;
2091
2092 /**
2093 * Fetch all the siblings between the module's current spot
2094 * and where we want to move it to. If there are less than $steps
2095 * siblings between the current spot and the target then the
2096 * module will move as far as possible
2097 */
2098 $sql = 'SELECT forum_id, forum_name, left_id, right_id
2099 FROM ' . FORUMS_TABLE . "
2100 WHERE parent_id = {$forum_row['parent_id']}
2101 AND " . (($action == 'move_up') ? "right_id < {$forum_row['right_id']} ORDER BY right_id DESC" : "left_id > {$forum_row['left_id']} ORDER BY left_id ASC");
2102 $result = $db->sql_query_limit($sql, $steps);
2103
2104 $target = array();
2105 while ($row = $db->sql_fetchrow($result))
2106 {
2107 $target = $row;
2108 }
2109 $db->sql_freeresult($result);
2110
2111 if (!count($target))
2112 {
2113 // The forum is already on top or bottom
2114 return false;
2115 }
2116
2117 /**
2118 * $left_id and $right_id define the scope of the nodes that are affected by the move.
2119 * $diff_up and $diff_down are the values to substract or add to each node's left_id
2120 * and right_id in order to move them up or down.
2121 * $move_up_left and $move_up_right define the scope of the nodes that are moving
2122 * up. Other nodes in the scope of ($left_id, $right_id) are considered to move down.
2123 */
2124 if ($action == 'move_up')
2125 {
2126 $left_id = $target['left_id'];
2127 $right_id = $forum_row['right_id'];
2128
2129 $diff_up = $forum_row['left_id'] - $target['left_id'];
2130 $diff_down = $forum_row['right_id'] + 1 - $forum_row['left_id'];
2131
2132 $move_up_left = $forum_row['left_id'];
2133 $move_up_right = $forum_row['right_id'];
2134 }
2135 else
2136 {
2137 $left_id = $forum_row['left_id'];
2138 $right_id = $target['right_id'];
2139
2140 $diff_up = $forum_row['right_id'] + 1 - $forum_row['left_id'];
2141 $diff_down = $target['right_id'] - $forum_row['right_id'];
2142
2143 $move_up_left = $forum_row['right_id'] + 1;
2144 $move_up_right = $target['right_id'];
2145 }
2146
2147 // Now do the dirty job
2148 $sql = 'UPDATE ' . FORUMS_TABLE . "
2149 SET left_id = left_id + CASE
2150 WHEN left_id BETWEEN {$move_up_left} AND {$move_up_right} THEN -{$diff_up}
2151 ELSE {$diff_down}
2152 END,
2153 right_id = right_id + CASE
2154 WHEN right_id BETWEEN {$move_up_left} AND {$move_up_right} THEN -{$diff_up}
2155 ELSE {$diff_down}
2156 END,
2157 forum_parents = ''
2158 WHERE
2159 left_id BETWEEN {$left_id} AND {$right_id}
2160 AND right_id BETWEEN {$left_id} AND {$right_id}";
2161 $db->sql_query($sql);
2162
2163 return $target['forum_name'];
2164 }
2165
2166 /**
2167 * Display progress bar for syncinc forums
2168 */
2169 function display_progress_bar($start, $total)
2170 {
2171 global $template, $user;
2172
2173 adm_page_header($user->lang['SYNC_IN_PROGRESS']);
2174
2175 $template->set_filenames(array(
2176 'body' => 'progress_bar.html')
2177 );
2178
2179 $template->assign_vars(array(
2180 'L_PROGRESS' => $user->lang['SYNC_IN_PROGRESS'],
2181 'L_PROGRESS_EXPLAIN' => ($start && $total) ? sprintf($user->lang['SYNC_IN_PROGRESS_EXPLAIN'], $start, $total) : $user->lang['SYNC_IN_PROGRESS'])
2182 );
2183
2184 adm_page_footer();
2185 }
2186
2187 /**
2188 * Display copy permission page
2189 * Not used at the moment - we will have a look at it for 3.0.7
2190 */
2191 function copy_permission_page($forum_data)
2192 {
2193 global $phpEx, $phpbb_admin_path, $template, $user;
2194
2195 $acl_url = '&mode=setting_forum_local&forum_id[]=' . $forum_data['forum_id'];
2196 $action = append_sid($this->u_action . "&parent_id={$this->parent_id}&f={$forum_data['forum_id']}&action=copy_perm");
2197
2198 $l_acl = sprintf($user->lang['COPY_TO_ACL'], '<a href="' . append_sid("{$phpbb_admin_path}index.$phpEx", 'i=permissions' . $acl_url) . '">', '</a>');
2199
2200 $this->tpl_name = 'acp_forums_copy_perm';
2201
2202 $template->assign_vars(array(
2203 'U_ACL' => append_sid("{$phpbb_admin_path}index.$phpEx", 'i=permissions' . $acl_url),
2204 'L_ACL_LINK' => $l_acl,
2205 'L_BACK_LINK' => adm_back_link($this->u_action . '&parent_id=' . $this->parent_id),
2206 'S_COPY_ACTION' => $action,
2207 'S_FORUM_OPTIONS' => make_forum_select($forum_data['parent_id'], $forum_data['forum_id'], false, false, false),
2208 ));
2209 }
2210
2211 }
2212