[ Index ] |
PHP Cross Reference of phpBB-3.2.11-deutsch |
[Summary view] [Print] [Text view]
1 <?php 2 /** 3 * 4 * This file is part of the phpBB Forum Software package. 5 * 6 * @copyright (c) phpBB Limited <https://www.phpbb.com> 7 * @license GNU General Public License, version 2 (GPL-2.0) 8 * 9 * For full copyright and license information, please see 10 * the docs/CREDITS.txt file. 11 * 12 */ 13 14 namespace phpbb; 15 16 /** 17 * phpbb_visibility 18 * Handle fetching and setting the visibility for topics and posts 19 */ 20 class content_visibility 21 { 22 /** 23 * Database object 24 * @var \phpbb\db\driver\driver_interface 25 */ 26 protected $db; 27 28 /** 29 * User object 30 * @var \phpbb\user 31 */ 32 protected $user; 33 34 /** 35 * Auth object 36 * @var \phpbb\auth\auth 37 */ 38 protected $auth; 39 40 /** 41 * config object 42 * @var \phpbb\config\config 43 */ 44 protected $config; 45 46 /** 47 * Event dispatcher object 48 * @var \phpbb\event\dispatcher_interface 49 */ 50 protected $phpbb_dispatcher; 51 52 /** 53 * phpBB root path 54 * @var string 55 */ 56 protected $phpbb_root_path; 57 58 /** 59 * PHP Extension 60 * @var string 61 */ 62 protected $php_ext; 63 64 /** 65 * Constructor 66 * 67 * @param \phpbb\auth\auth $auth Auth object 68 * @param \phpbb\config\config $config Config object 69 * @param \phpbb\event\dispatcher_interface $phpbb_dispatcher Event dispatcher object 70 * @param \phpbb\db\driver\driver_interface $db Database object 71 * @param \phpbb\user $user User object 72 * @param string $phpbb_root_path Root path 73 * @param string $php_ext PHP Extension 74 * @param string $forums_table Forums table name 75 * @param string $posts_table Posts table name 76 * @param string $topics_table Topics table name 77 * @param string $users_table Users table name 78 */ 79 public function __construct(\phpbb\auth\auth $auth, \phpbb\config\config $config, \phpbb\event\dispatcher_interface $phpbb_dispatcher, \phpbb\db\driver\driver_interface $db, \phpbb\user $user, $phpbb_root_path, $php_ext, $forums_table, $posts_table, $topics_table, $users_table) 80 { 81 $this->auth = $auth; 82 $this->config = $config; 83 $this->phpbb_dispatcher = $phpbb_dispatcher; 84 $this->db = $db; 85 $this->user = $user; 86 $this->phpbb_root_path = $phpbb_root_path; 87 $this->php_ext = $php_ext; 88 $this->forums_table = $forums_table; 89 $this->posts_table = $posts_table; 90 $this->topics_table = $topics_table; 91 $this->users_table = $users_table; 92 } 93 94 /** 95 * Can the current logged-in user soft-delete posts? 96 * 97 * @param $forum_id int Forum ID whose permissions to check 98 * @param $poster_id int Poster ID of the post in question 99 * @param $post_locked bool Is the post locked? 100 * @return bool 101 */ 102 public function can_soft_delete($forum_id, $poster_id, $post_locked) 103 { 104 if ($this->auth->acl_get('m_softdelete', $forum_id)) 105 { 106 return true; 107 } 108 else if ($this->auth->acl_get('f_softdelete', $forum_id) && $poster_id == $this->user->data['user_id'] && !$post_locked) 109 { 110 return true; 111 } 112 113 return false; 114 } 115 116 /** 117 * Get the topics post count or the forums post/topic count based on permissions 118 * 119 * @param $mode string One of topic_posts, forum_posts or forum_topics 120 * @param $data array Array with the topic/forum data to calculate from 121 * @param $forum_id int The forum id is used for permission checks 122 * @return int Number of posts/topics the user can see in the topic/forum 123 */ 124 public function get_count($mode, $data, $forum_id) 125 { 126 if (!$this->auth->acl_get('m_approve', $forum_id)) 127 { 128 return (int) $data[$mode . '_approved']; 129 } 130 131 return (int) $data[$mode . '_approved'] + (int) $data[$mode . '_unapproved'] + (int) $data[$mode . '_softdeleted']; 132 } 133 134 135 /** 136 * Check topic/post visibility for a given forum ID 137 * 138 * Note: Read permissions are not checked. 139 * 140 * @param $mode string Either "topic" or "post" 141 * @param $forum_id int The forum id is used for permission checks 142 * @param $data array Array with item information to check visibility 143 * @return bool True if the item is visible, false if not 144 */ 145 public function is_visible($mode, $forum_id, $data) 146 { 147 $is_visible = $this->auth->acl_get('m_approve', $forum_id) || $data[$mode . '_visibility'] == ITEM_APPROVED; 148 149 /** 150 * Allow changing the result of calling is_visible 151 * 152 * @event core.phpbb_content_visibility_is_visible 153 * @var bool is_visible Default visibility condition, to be modified by extensions if needed. 154 * @var string mode Either "topic" or "post" 155 * @var int forum_id Forum id of the current item 156 * @var array data Array of item information 157 * @since 3.2.2-RC1 158 */ 159 $vars = array( 160 'is_visible', 161 'mode', 162 'forum_id', 163 'data', 164 ); 165 extract($this->phpbb_dispatcher->trigger_event('core.phpbb_content_visibility_is_visible', compact($vars))); 166 167 return $is_visible; 168 } 169 170 /** 171 * Create topic/post visibility SQL for a given forum ID 172 * 173 * Note: Read permissions are not checked. 174 * 175 * @param $mode string Either "topic" or "post" 176 * @param $forum_id int The forum id is used for permission checks 177 * @param $table_alias string Table alias to prefix in SQL queries 178 * @return string The appropriate combination SQL logic for topic/post_visibility 179 */ 180 public function get_visibility_sql($mode, $forum_id, $table_alias = '') 181 { 182 $where_sql = ''; 183 184 $get_visibility_sql_overwrite = false; 185 186 /** 187 * Allow changing the result of calling get_visibility_sql 188 * 189 * @event core.phpbb_content_visibility_get_visibility_sql_before 190 * @var string where_sql Extra visibility conditions. It must end with either an SQL "AND" or an "OR" 191 * @var string mode Either "topic" or "post" depending on the query this is being used in 192 * @var array forum_id The forum id in which the search is made. 193 * @var string table_alias Table alias to prefix in SQL queries 194 * @var mixed get_visibility_sql_overwrite If a string, forces the function to return get_forums_visibility_sql_overwrite after executing the event 195 * If false, get_visibility_sql continues normally 196 * It must be either boolean or string 197 * @since 3.1.4-RC1 198 */ 199 $vars = array( 200 'where_sql', 201 'mode', 202 'forum_id', 203 'table_alias', 204 'get_visibility_sql_overwrite', 205 ); 206 extract($this->phpbb_dispatcher->trigger_event('core.phpbb_content_visibility_get_visibility_sql_before', compact($vars))); 207 208 if ($get_visibility_sql_overwrite !== false) 209 { 210 return $get_visibility_sql_overwrite; 211 } 212 213 if ($this->auth->acl_get('m_approve', $forum_id)) 214 { 215 $where_sql .= '1 = 1'; 216 } 217 else 218 { 219 $where_sql .= $table_alias . $mode . '_visibility = ' . ITEM_APPROVED; 220 } 221 222 return '(' . $where_sql . ')'; 223 } 224 225 /** 226 * Create topic/post visibility SQL for a set of forums 227 * 228 * Note: Read permissions are not checked. Forums without read permissions 229 * should not be in $forum_ids 230 * 231 * @param $mode string Either "topic" or "post" 232 * @param $forum_ids array Array of forum ids which the posts/topics are limited to 233 * @param $table_alias string Table alias to prefix in SQL queries 234 * @return string The appropriate combination SQL logic for topic/post_visibility 235 */ 236 public function get_forums_visibility_sql($mode, $forum_ids = array(), $table_alias = '') 237 { 238 $where_sql = ''; 239 240 $approve_forums = array_keys($this->auth->acl_getf('m_approve', true)); 241 if (!empty($forum_ids) && !empty($approve_forums)) 242 { 243 $approve_forums = array_intersect($forum_ids, $approve_forums); 244 $forum_ids = array_diff($forum_ids, $approve_forums); 245 } 246 247 $get_forums_visibility_sql_overwrite = false; 248 /** 249 * Allow changing the result of calling get_forums_visibility_sql 250 * 251 * @event core.phpbb_content_visibility_get_forums_visibility_before 252 * @var string where_sql Extra visibility conditions. It must end with either an SQL "AND" or an "OR" 253 * @var string mode Either "topic" or "post" depending on the query this is being used in 254 * @var array forum_ids Array of forum ids which the posts/topics are limited to 255 * @var string table_alias Table alias to prefix in SQL queries 256 * @var array approve_forums Array of forums where the user has m_approve permissions 257 * @var mixed get_forums_visibility_sql_overwrite If a string, forces the function to return get_forums_visibility_sql_overwrite after executing the event 258 * If false, get_forums_visibility_sql continues normally 259 * It must be either boolean or string 260 * @since 3.1.3-RC1 261 */ 262 $vars = array( 263 'where_sql', 264 'mode', 265 'forum_ids', 266 'table_alias', 267 'approve_forums', 268 'get_forums_visibility_sql_overwrite', 269 ); 270 extract($this->phpbb_dispatcher->trigger_event('core.phpbb_content_visibility_get_forums_visibility_before', compact($vars))); 271 272 if ($get_forums_visibility_sql_overwrite !== false) 273 { 274 return $get_forums_visibility_sql_overwrite; 275 } 276 277 // Moderator can view all posts/topics in the moderated forums 278 $where_sql .= '(' . $this->db->sql_in_set($table_alias . 'forum_id', $approve_forums, false, true) . ' OR '; 279 // Normal user can view approved items only 280 $where_sql .= '(' . $table_alias . $mode . '_visibility = ' . ITEM_APPROVED . ' 281 AND ' . $this->db->sql_in_set($table_alias . 'forum_id', $forum_ids, false, true) . '))'; 282 283 return '(' . $where_sql . ')'; 284 } 285 286 /** 287 * Create topic/post visibility SQL for all forums on the board 288 * 289 * Note: Read permissions are not checked. Forums without read permissions 290 * should be in $exclude_forum_ids 291 * 292 * @param $mode string Either "topic" or "post" 293 * @param $exclude_forum_ids array Array of forum ids which are excluded 294 * @param $table_alias string Table alias to prefix in SQL queries 295 * @return string The appropriate combination SQL logic for topic/post_visibility 296 */ 297 public function get_global_visibility_sql($mode, $exclude_forum_ids = array(), $table_alias = '') 298 { 299 $where_sqls = array(); 300 301 $approve_forums = array_diff(array_keys($this->auth->acl_getf('m_approve', true)), $exclude_forum_ids); 302 303 $visibility_sql_overwrite = null; 304 305 /** 306 * Allow changing the result of calling get_global_visibility_sql 307 * 308 * @event core.phpbb_content_visibility_get_global_visibility_before 309 * @var array where_sqls Array of extra visibility conditions. Will be joined by imploding with "OR". 310 * @var string mode Either "topic" or "post" depending on the query this is being used in 311 * @var array exclude_forum_ids Array of forum ids the current user doesn't have access to 312 * @var string table_alias Table alias to prefix in SQL queries 313 * @var array approve_forums Array of forums where the user has m_approve permissions 314 * @var string visibility_sql_overwrite If not empty, forces the function to return visibility_sql_overwrite after executing the event 315 * @since 3.1.3-RC1 316 */ 317 $vars = array( 318 'where_sqls', 319 'mode', 320 'exclude_forum_ids', 321 'table_alias', 322 'approve_forums', 323 'visibility_sql_overwrite', 324 ); 325 extract($this->phpbb_dispatcher->trigger_event('core.phpbb_content_visibility_get_global_visibility_before', compact($vars))); 326 327 if ($visibility_sql_overwrite) 328 { 329 return $visibility_sql_overwrite; 330 } 331 332 // Include approved items in all forums but the excluded 333 $where_sqls[] = '(' . $this->db->sql_in_set($table_alias . 'forum_id', $exclude_forum_ids, true, true) . ' 334 AND ' . $table_alias . $mode . '_visibility = ' . ITEM_APPROVED . ')'; 335 336 // If user has moderator permissions, add everything in the moderated forums 337 if (count($approve_forums)) 338 { 339 $where_sqls[] = $this->db->sql_in_set($table_alias . 'forum_id', $approve_forums); 340 } 341 342 return '(' . implode(' OR ', $where_sqls) . ')'; 343 } 344 345 /** 346 * Change visibility status of one post or all posts of a topic 347 * 348 * @param $visibility int Element of {ITEM_APPROVED, ITEM_DELETED, ITEM_REAPPROVE} 349 * @param $post_id mixed Post ID or array of post IDs to act on, 350 * if it is empty, all posts of topic_id will be modified 351 * @param $topic_id int Topic where $post_id is found 352 * @param $forum_id int Forum where $topic_id is found 353 * @param $user_id int User performing the action 354 * @param $time int Timestamp when the action is performed 355 * @param $reason string Reason why the visibility was changed. 356 * @param $is_starter bool Is this the first post of the topic changed? 357 * @param $is_latest bool Is this the last post of the topic changed? 358 * @param $limit_visibility mixed Limit updating per topic_id to a certain visibility 359 * @param $limit_delete_time mixed Limit updating per topic_id to a certain deletion time 360 * @return array Changed post data, empty array if an error occurred. 361 */ 362 public function set_post_visibility($visibility, $post_id, $topic_id, $forum_id, $user_id, $time, $reason, $is_starter, $is_latest, $limit_visibility = false, $limit_delete_time = false) 363 { 364 if (!in_array($visibility, array(ITEM_APPROVED, ITEM_DELETED, ITEM_REAPPROVE))) 365 { 366 return array(); 367 } 368 369 if ($post_id) 370 { 371 if (is_array($post_id)) 372 { 373 $where_sql = $this->db->sql_in_set('post_id', array_map('intval', $post_id)); 374 } 375 else 376 { 377 $where_sql = 'post_id = ' . (int) $post_id; 378 } 379 $where_sql .= ' AND topic_id = ' . (int) $topic_id; 380 } 381 else 382 { 383 $where_sql = 'topic_id = ' . (int) $topic_id; 384 385 // Limit the posts to a certain visibility and deletion time 386 // This allows us to only restore posts, that were approved 387 // when the topic got soft deleted. So previous soft deleted 388 // and unapproved posts are still soft deleted/unapproved 389 if ($limit_visibility !== false) 390 { 391 $where_sql .= ' AND post_visibility = ' . (int) $limit_visibility; 392 } 393 394 if ($limit_delete_time !== false) 395 { 396 $where_sql .= ' AND post_delete_time = ' . (int) $limit_delete_time; 397 } 398 } 399 400 $sql = 'SELECT poster_id, post_id, post_postcount, post_visibility 401 FROM ' . $this->posts_table . ' 402 WHERE ' . $where_sql; 403 $result = $this->db->sql_query($sql); 404 405 $post_ids = $poster_postcounts = $postcounts = $postcount_visibility = array(); 406 while ($row = $this->db->sql_fetchrow($result)) 407 { 408 $post_ids[] = (int) $row['post_id']; 409 410 if ($row['post_visibility'] != $visibility) 411 { 412 if ($row['post_postcount'] && !isset($poster_postcounts[(int) $row['poster_id']])) 413 { 414 $poster_postcounts[(int) $row['poster_id']] = 1; 415 } 416 else if ($row['post_postcount']) 417 { 418 $poster_postcounts[(int) $row['poster_id']]++; 419 } 420 421 if (!isset($postcount_visibility[$row['post_visibility']])) 422 { 423 $postcount_visibility[$row['post_visibility']] = 1; 424 } 425 else 426 { 427 $postcount_visibility[$row['post_visibility']]++; 428 } 429 } 430 } 431 $this->db->sql_freeresult($result); 432 433 if (empty($post_ids)) 434 { 435 return array(); 436 } 437 438 if (!function_exists('truncate_string')) 439 { 440 include($this->phpbb_root_path . 'includes/functions_content.' . $this->php_ext); 441 } 442 443 $data = array( 444 'post_visibility' => (int) $visibility, 445 'post_delete_user' => (int) $user_id, 446 'post_delete_time' => ((int) $time) ?: time(), 447 'post_delete_reason' => truncate_string($reason, 255, 255, false), 448 ); 449 /** 450 * Perform actions right before the query to change post visibility 451 * 452 * @event core.set_post_visibility_before_sql 453 * @var int visibility Element of {ITEM_APPROVED, ITEM_DELETED, ITEM_REAPPROVE} 454 * @var array post_id Array containing all post IDs to be modified. If blank, all posts within the topic are modified. 455 * @var int topic_id Topic of the post IDs to be modified. 456 * @var int forum_id Forum ID that the topic_id resides in. 457 * @var int user_id User ID doing this action. 458 * @var int time Timestamp of this action. 459 * @var string reason Reason specified by the user for this change. 460 * @var bool is_starter Are we changing the topic's starter? 461 * @var bool is_latest Are we changing the topic's latest post? 462 * @var array data The data array for this action. 463 * @since 3.1.10-RC1 464 * @changed 3.2.2-RC1 Use time instead of non-existent timestamp 465 */ 466 $vars = array( 467 'visibility', 468 'post_id', 469 'topic_id', 470 'forum_id', 471 'user_id', 472 'time', 473 'reason', 474 'is_starter', 475 'is_latest', 476 'data', 477 ); 478 extract($this->phpbb_dispatcher->trigger_event('core.set_post_visibility_before_sql', compact($vars))); 479 $sql = 'UPDATE ' . $this->posts_table . ' 480 SET ' . $this->db->sql_build_array('UPDATE', $data) . ' 481 WHERE ' . $this->db->sql_in_set('post_id', $post_ids); 482 $this->db->sql_query($sql); 483 484 // Group the authors by post count, to reduce the number of queries 485 foreach ($poster_postcounts as $poster_id => $num_posts) 486 { 487 $postcounts[$num_posts][] = $poster_id; 488 } 489 490 // Update users postcounts 491 foreach ($postcounts as $num_posts => $poster_ids) 492 { 493 if (in_array($visibility, array(ITEM_REAPPROVE, ITEM_DELETED))) 494 { 495 $sql = 'UPDATE ' . $this->users_table . ' 496 SET user_posts = 0 497 WHERE ' . $this->db->sql_in_set('user_id', $poster_ids) . ' 498 AND user_posts < ' . $num_posts; 499 $this->db->sql_query($sql); 500 501 $sql = 'UPDATE ' . $this->users_table . ' 502 SET user_posts = user_posts - ' . $num_posts . ' 503 WHERE ' . $this->db->sql_in_set('user_id', $poster_ids) . ' 504 AND user_posts >= ' . $num_posts; 505 $this->db->sql_query($sql); 506 } 507 else 508 { 509 $sql = 'UPDATE ' . $this->users_table . ' 510 SET user_posts = user_posts + ' . $num_posts . ' 511 WHERE ' . $this->db->sql_in_set('user_id', $poster_ids); 512 $this->db->sql_query($sql); 513 } 514 } 515 516 $update_topic_postcount = true; 517 518 // Sync the first/last topic information if needed 519 if (!$is_starter && $is_latest) 520 { 521 if (!function_exists('update_post_information')) 522 { 523 include($this->phpbb_root_path . 'includes/functions_posting.' . $this->php_ext); 524 } 525 526 // update_post_information can only update the last post info ... 527 if ($topic_id) 528 { 529 update_post_information('topic', $topic_id, false); 530 } 531 if ($forum_id) 532 { 533 update_post_information('forum', $forum_id, false); 534 } 535 } 536 else if ($is_starter && $topic_id) 537 { 538 if (!function_exists('sync')) 539 { 540 include($this->phpbb_root_path . 'includes/functions_admin.' . $this->php_ext); 541 } 542 543 // ... so we need to use sync, if the first post is changed. 544 // The forum is resynced recursive by sync() itself. 545 sync('topic', 'topic_id', $topic_id, true); 546 547 // sync recalculates the topic replies and forum posts by itself, so we don't do that. 548 $update_topic_postcount = false; 549 } 550 551 $topic_update_array = array(); 552 // Update the topic's reply count and the forum's post count 553 if ($update_topic_postcount) 554 { 555 $field_alias = array( 556 ITEM_APPROVED => 'posts_approved', 557 ITEM_UNAPPROVED => 'posts_unapproved', 558 ITEM_DELETED => 'posts_softdeleted', 559 ITEM_REAPPROVE => 'posts_unapproved', 560 ); 561 $cur_posts = array_fill_keys($field_alias, 0); 562 563 foreach ($postcount_visibility as $post_visibility => $visibility_posts) 564 { 565 $cur_posts[$field_alias[(int) $post_visibility]] += $visibility_posts; 566 } 567 568 $sql_ary = array(); 569 $recipient_field = $field_alias[$visibility]; 570 571 foreach ($cur_posts as $field => $count) 572 { 573 // Decrease the count for the old statuses. 574 if ($count && $field != $recipient_field) 575 { 576 $sql_ary[$field] = " - $count"; 577 } 578 } 579 // Add up the count from all statuses excluding the recipient status. 580 $count_increase = array_sum(array_diff($cur_posts, array($recipient_field))); 581 582 if ($count_increase) 583 { 584 $sql_ary[$recipient_field] = " + $count_increase"; 585 } 586 587 if (count($sql_ary)) 588 { 589 $forum_sql = array(); 590 591 foreach ($sql_ary as $field => $value_change) 592 { 593 $topic_update_array[] = 'topic_' . $field . ' = topic_' . $field . $value_change; 594 $forum_sql[] = 'forum_' . $field . ' = forum_' . $field . $value_change; 595 } 596 597 $sql = 'UPDATE ' . $this->forums_table . ' 598 SET ' . implode(', ', $forum_sql) . ' 599 WHERE forum_id = ' . (int) $forum_id; 600 $this->db->sql_query($sql); 601 } 602 } 603 604 if ($post_id) 605 { 606 $sql = 'SELECT 1 AS has_attachments 607 FROM ' . POSTS_TABLE . ' 608 WHERE topic_id = ' . (int) $topic_id . ' 609 AND post_attachment = 1 610 AND post_visibility = ' . ITEM_APPROVED . ' 611 AND ' . $this->db->sql_in_set('post_id', $post_id, true); 612 $result = $this->db->sql_query_limit($sql, 1); 613 614 $has_attachment = (bool) $this->db->sql_fetchfield('has_attachments'); 615 $this->db->sql_freeresult($result); 616 617 if ($has_attachment && $visibility == ITEM_APPROVED) 618 { 619 $topic_update_array[] = 'topic_attachment = 1'; 620 } 621 else if (!$has_attachment && $visibility != ITEM_APPROVED) 622 { 623 $topic_update_array[] = 'topic_attachment = 0'; 624 } 625 } 626 627 if (!empty($topic_update_array)) 628 { 629 // Update the number for replies and posts, and update the attachments flag 630 $sql = 'UPDATE ' . $this->topics_table . ' 631 SET ' . implode(', ', $topic_update_array) . ' 632 WHERE topic_id = ' . (int) $topic_id; 633 $this->db->sql_query($sql); 634 } 635 /** 636 * Perform actions after all steps to changing post visibility 637 * 638 * @event core.set_post_visibility_after 639 * @var int visibility Element of {ITEM_APPROVED, ITEM_DELETED, ITEM_REAPPROVE} 640 * @var array post_id Array containing all post IDs to be modified. If blank, all posts within the topic are modified. 641 * @var int topic_id Topic of the post IDs to be modified. 642 * @var int forum_id Forum ID that the topic_id resides in. 643 * @var int user_id User ID doing this action. 644 * @var int time Timestamp of this action. 645 * @var string reason Reason specified by the user for this change. 646 * @var bool is_starter Are we changing the topic's starter? 647 * @var bool is_latest Are we changing the topic's latest post? 648 * @var array data The data array for this action. 649 * @since 3.1.10-RC1 650 * @changed 3.2.2-RC1 Use time instead of non-existent timestamp 651 */ 652 $vars = array( 653 'visibility', 654 'post_id', 655 'topic_id', 656 'forum_id', 657 'user_id', 658 'time', 659 'reason', 660 'is_starter', 661 'is_latest', 662 'data', 663 ); 664 extract($this->phpbb_dispatcher->trigger_event('core.set_post_visibility_after', compact($vars))); 665 return $data; 666 } 667 668 /** 669 * Set topic visibility 670 * 671 * Allows approving (which is akin to undeleting/restore) or soft deleting an entire topic. 672 * Calls set_post_visibility as needed. 673 * 674 * Note: By default, when a soft deleted topic is restored. Only posts that 675 * were approved at the time of soft deleting, are being restored. 676 * Same applies to soft deleting. Only approved posts will be marked 677 * as soft deleted. 678 * If you want to update all posts, use the force option. 679 * 680 * @param $visibility int Element of {ITEM_APPROVED, ITEM_DELETED, ITEM_REAPPROVE} 681 * @param $topic_id mixed Topic ID to act on 682 * @param $forum_id int Forum where $topic_id is found 683 * @param $user_id int User performing the action 684 * @param $time int Timestamp when the action is performed 685 * @param $reason string Reason why the visibilty was changed. 686 * @param $force_update_all bool Force to update all posts within the topic 687 * @return array Changed topic data, empty array if an error occured. 688 */ 689 public function set_topic_visibility($visibility, $topic_id, $forum_id, $user_id, $time, $reason, $force_update_all = false) 690 { 691 if (!in_array($visibility, array(ITEM_APPROVED, ITEM_DELETED, ITEM_REAPPROVE))) 692 { 693 return array(); 694 } 695 696 if (!$force_update_all) 697 { 698 $sql = 'SELECT topic_visibility, topic_delete_time 699 FROM ' . $this->topics_table . ' 700 WHERE topic_id = ' . (int) $topic_id; 701 $result = $this->db->sql_query($sql); 702 $original_topic_data = $this->db->sql_fetchrow($result); 703 $this->db->sql_freeresult($result); 704 705 if (!$original_topic_data) 706 { 707 // The topic does not exist... 708 return array(); 709 } 710 } 711 712 if (!function_exists('truncate_string')) 713 { 714 include($this->phpbb_root_path . 'includes/functions_content.' . $this->php_ext); 715 } 716 717 // Note, we do not set a reason for the posts, just for the topic 718 $data = array( 719 'topic_visibility' => (int) $visibility, 720 'topic_delete_user' => (int) $user_id, 721 'topic_delete_time' => ((int) $time) ?: time(), 722 'topic_delete_reason' => truncate_string($reason, 255, 255, false), 723 ); 724 /** 725 * Perform actions right before the query to change topic visibility 726 * 727 * @event core.set_topic_visibility_before_sql 728 * @var int visibility Element of {ITEM_APPROVED, ITEM_DELETED, ITEM_REAPPROVE} 729 * @var int topic_id Topic of the post IDs to be modified. 730 * @var int forum_id Forum ID that the topic_id resides in. 731 * @var int user_id User ID doing this action. 732 * @var int time Timestamp of this action. 733 * @var string reason Reason specified by the user for this change. 734 * @var bool force_update_all Force an update on all posts within the topic, regardless of their current approval state. 735 * @var array data The data array for this action. 736 * @since 3.1.10-RC1 737 * @changed 3.2.2-RC1 Use time instead of non-existent timestamp 738 */ 739 $vars = array( 740 'visibility', 741 'topic_id', 742 'forum_id', 743 'user_id', 744 'time', 745 'reason', 746 'force_update_all', 747 'data', 748 ); 749 extract($this->phpbb_dispatcher->trigger_event('core.set_topic_visibility_before_sql', compact($vars))); 750 $sql = 'UPDATE ' . $this->topics_table . ' 751 SET ' . $this->db->sql_build_array('UPDATE', $data) . ' 752 WHERE topic_id = ' . (int) $topic_id; 753 $this->db->sql_query($sql); 754 755 if (!$this->db->sql_affectedrows()) 756 { 757 return array(); 758 } 759 760 if (!$force_update_all && $original_topic_data['topic_delete_time'] && $original_topic_data['topic_visibility'] == ITEM_DELETED && $visibility == ITEM_APPROVED) 761 { 762 // If we're restoring a topic we only restore posts, that were soft deleted through the topic soft deletion. 763 $this->set_post_visibility($visibility, false, $topic_id, $forum_id, $user_id, $time, '', true, true, $original_topic_data['topic_visibility'], $original_topic_data['topic_delete_time']); 764 } 765 else if (!$force_update_all && $original_topic_data['topic_visibility'] == ITEM_APPROVED && $visibility == ITEM_DELETED) 766 { 767 // If we're soft deleting a topic we only mark approved posts as soft deleted. 768 $this->set_post_visibility($visibility, false, $topic_id, $forum_id, $user_id, $time, '', true, true, $original_topic_data['topic_visibility']); 769 } 770 else 771 { 772 $this->set_post_visibility($visibility, false, $topic_id, $forum_id, $user_id, $time, '', true, true); 773 } 774 /** 775 * Perform actions after all steps to changing topic visibility 776 * 777 * @event core.set_topic_visibility_after 778 * @var int visibility Element of {ITEM_APPROVED, ITEM_DELETED, ITEM_REAPPROVE} 779 * @var int topic_id Topic of the post IDs to be modified. 780 * @var int forum_id Forum ID that the topic_id resides in. 781 * @var int user_id User ID doing this action. 782 * @var int time Timestamp of this action. 783 * @var string reason Reason specified by the user for this change. 784 * @var bool force_update_all Force an update on all posts within the topic, regardless of their current approval state. 785 * @var array data The data array for this action. 786 * @since 3.1.10-RC1 787 * @changed 3.2.2-RC1 Use time instead of non-existent timestamp 788 */ 789 $vars = array( 790 'visibility', 791 'topic_id', 792 'forum_id', 793 'user_id', 794 'time', 795 'reason', 796 'force_update_all', 797 'data', 798 ); 799 extract($this->phpbb_dispatcher->trigger_event('core.set_topic_visibility_after', compact($vars))); 800 return $data; 801 } 802 803 /** 804 * Add post to topic and forum statistics 805 * 806 * @param $data array Contains information from the topics table about given topic 807 * @param &$sql_data array Populated with the SQL changes, may be empty at call time 808 * @return null 809 */ 810 public function add_post_to_statistic($data, &$sql_data) 811 { 812 $sql_data[$this->topics_table] = (($sql_data[$this->topics_table]) ? $sql_data[$this->topics_table] . ', ' : '') . 'topic_posts_approved = topic_posts_approved + 1'; 813 814 $sql_data[$this->forums_table] = (($sql_data[$this->forums_table]) ? $sql_data[$this->forums_table] . ', ' : '') . 'forum_posts_approved = forum_posts_approved + 1'; 815 816 if ($data['post_postcount']) 817 { 818 $sql_data[$this->users_table] = (($sql_data[$this->users_table]) ? $sql_data[$this->users_table] . ', ' : '') . 'user_posts = user_posts + 1'; 819 } 820 821 $this->config->increment('num_posts', 1, false); 822 } 823 824 /** 825 * Remove post from topic and forum statistics 826 * 827 * @param $data array Contains information from the topics table about given topic 828 * @param &$sql_data array Populated with the SQL changes, may be empty at call time 829 * @return null 830 */ 831 public function remove_post_from_statistic($data, &$sql_data) 832 { 833 if ($data['post_visibility'] == ITEM_APPROVED) 834 { 835 $sql_data[$this->topics_table] = ((!empty($sql_data[$this->topics_table])) ? $sql_data[$this->topics_table] . ', ' : '') . 'topic_posts_approved = topic_posts_approved - 1'; 836 $sql_data[$this->forums_table] = ((!empty($sql_data[$this->forums_table])) ? $sql_data[$this->forums_table] . ', ' : '') . 'forum_posts_approved = forum_posts_approved - 1'; 837 838 if ($data['post_postcount']) 839 { 840 $sql_data[$this->users_table] = ((!empty($sql_data[$this->users_table])) ? $sql_data[$this->users_table] . ', ' : '') . 'user_posts = user_posts - 1'; 841 } 842 843 $this->config->increment('num_posts', -1, false); 844 } 845 else if ($data['post_visibility'] == ITEM_UNAPPROVED || $data['post_visibility'] == ITEM_REAPPROVE) 846 { 847 $sql_data[FORUMS_TABLE] = (($sql_data[FORUMS_TABLE]) ? $sql_data[FORUMS_TABLE] . ', ' : '') . 'forum_posts_unapproved = forum_posts_unapproved - 1'; 848 $sql_data[TOPICS_TABLE] = (($sql_data[TOPICS_TABLE]) ? $sql_data[TOPICS_TABLE] . ', ' : '') . 'topic_posts_unapproved = topic_posts_unapproved - 1'; 849 } 850 else if ($data['post_visibility'] == ITEM_DELETED) 851 { 852 $sql_data[FORUMS_TABLE] = (($sql_data[FORUMS_TABLE]) ? $sql_data[FORUMS_TABLE] . ', ' : '') . 'forum_posts_softdeleted = forum_posts_softdeleted - 1'; 853 $sql_data[TOPICS_TABLE] = (($sql_data[TOPICS_TABLE]) ? $sql_data[TOPICS_TABLE] . ', ' : '') . 'topic_posts_softdeleted = topic_posts_softdeleted - 1'; 854 } 855 } 856 857 /** 858 * Remove topic from forum statistics 859 * 860 * @param $data array Post and topic data 861 * @param &$sql_data array Populated with the SQL changes, may be empty at call time 862 * @return null 863 */ 864 public function remove_topic_from_statistic($data, &$sql_data) 865 { 866 if ($data['topic_visibility'] == ITEM_APPROVED) 867 { 868 $sql_data[FORUMS_TABLE] .= 'forum_posts_approved = forum_posts_approved - 1, forum_topics_approved = forum_topics_approved - 1'; 869 870 if ($data['post_postcount']) 871 { 872 $sql_data[$this->users_table] = ((!empty($sql_data[$this->users_table])) ? $sql_data[$this->users_table] . ', ' : '') . 'user_posts = user_posts - 1'; 873 } 874 } 875 else if ($data['topic_visibility'] == ITEM_UNAPPROVED || $data['post_visibility'] == ITEM_REAPPROVE) 876 { 877 $sql_data[FORUMS_TABLE] .= 'forum_posts_unapproved = forum_posts_unapproved - 1, forum_topics_unapproved = forum_topics_unapproved - 1'; 878 } 879 else if ($data['topic_visibility'] == ITEM_DELETED) 880 { 881 $sql_data[FORUMS_TABLE] .= 'forum_posts_softdeleted = forum_posts_softdeleted - 1, forum_topics_softdeleted = forum_topics_softdeleted - 1'; 882 } 883 884 } 885 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Wed Nov 11 20:33:01 2020 | Cross-referenced by PHPXref 0.7.1 |