[ Index ]

PHP Cross Reference of phpBB-3.3.0-deutsch

title

Body

[close]

/phpbb/ -> content_visibility.php (source)

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


Generated: Tue Apr 7 19:44:41 2020 Cross-referenced by PHPXref 0.7.1