[ Index ]

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


Generated: Thu Jan 11 00:25:41 2018 Cross-referenced by PHPXref 0.7.1