[ Index ]

PHP Cross Reference of phpBB-3.3.14-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          $postcount_change = 0;
 505  
 506          // Update users postcounts
 507          foreach ($postcounts as $num_posts => $poster_ids)
 508          {
 509              if (in_array($visibility, array(ITEM_REAPPROVE, ITEM_DELETED)))
 510              {
 511                  $postcount_change -= $num_posts;
 512  
 513                  $sql = 'UPDATE ' . $this->users_table . '
 514                      SET user_posts = 0
 515                      WHERE ' . $this->db->sql_in_set('user_id', $poster_ids) . '
 516                          AND user_posts < ' . $num_posts;
 517                  $this->db->sql_query($sql);
 518  
 519                  $sql = 'UPDATE ' . $this->users_table . '
 520                      SET user_posts = user_posts - ' . $num_posts . '
 521                      WHERE ' . $this->db->sql_in_set('user_id', $poster_ids) . '
 522                          AND user_posts >= ' . $num_posts;
 523                  $this->db->sql_query($sql);
 524              }
 525              else
 526              {
 527                  $postcount_change += $num_posts;
 528  
 529                  $sql = 'UPDATE ' . $this->users_table . '
 530                      SET user_posts = user_posts + ' . $num_posts . '
 531                      WHERE ' . $this->db->sql_in_set('user_id', $poster_ids);
 532                  $this->db->sql_query($sql);
 533              }
 534          }
 535  
 536          if ($postcount_change != 0)
 537          {
 538              $this->config->increment('num_posts', $postcount_change, false);
 539          }
 540  
 541          $update_topic_postcount = true;
 542  
 543          // Sync the first/last topic information if needed
 544          if (!$is_starter && $is_latest)
 545          {
 546              if (!function_exists('update_post_information'))
 547              {
 548                  include($this->phpbb_root_path . 'includes/functions_posting.' . $this->php_ext);
 549              }
 550  
 551              // update_post_information can only update the last post info ...
 552              if ($topic_id)
 553              {
 554                  update_post_information('topic', $topic_id, false);
 555              }
 556              if ($forum_id)
 557              {
 558                  update_post_information('forum', $forum_id, false);
 559              }
 560          }
 561          else if ($is_starter && $topic_id)
 562          {
 563              if (!function_exists('sync'))
 564              {
 565                  include($this->phpbb_root_path . 'includes/functions_admin.' . $this->php_ext);
 566              }
 567  
 568              // ... so we need to use sync, if the first post is changed.
 569              // The forum is resynced recursive by sync() itself.
 570              sync('topic', 'topic_id', $topic_id, true);
 571  
 572              // sync recalculates the topic replies and forum posts by itself, so we don't do that.
 573              $update_topic_postcount = false;
 574          }
 575  
 576          $topic_update_array = array();
 577          // Update the topic's reply count and the forum's post count
 578          if ($update_topic_postcount)
 579          {
 580              $field_alias = array(
 581                  ITEM_APPROVED    => 'posts_approved',
 582                  ITEM_UNAPPROVED    => 'posts_unapproved',
 583                  ITEM_DELETED    => 'posts_softdeleted',
 584                  ITEM_REAPPROVE    => 'posts_unapproved',
 585              );
 586              $cur_posts = array_fill_keys($field_alias, 0);
 587  
 588              foreach ($postcount_visibility as $post_visibility => $visibility_posts)
 589              {
 590                  $cur_posts[$field_alias[(int) $post_visibility]] += $visibility_posts;
 591              }
 592  
 593              $sql_ary = array();
 594              $recipient_field = $field_alias[$visibility];
 595  
 596              foreach ($cur_posts as $field => $count)
 597              {
 598                  // Decrease the count for the old statuses.
 599                  if ($count && $field != $recipient_field)
 600                  {
 601                      $sql_ary[$field] = " - $count";
 602                  }
 603              }
 604              // Add up the count from all statuses excluding the recipient status.
 605              $count_increase = array_sum(array_diff($cur_posts, array($recipient_field)));
 606  
 607              if ($count_increase)
 608              {
 609                  $sql_ary[$recipient_field] = " + $count_increase";
 610              }
 611  
 612              if (count($sql_ary))
 613              {
 614                  $forum_sql = array();
 615  
 616                  foreach ($sql_ary as $field => $value_change)
 617                  {
 618                      $topic_update_array[] = 'topic_' . $field . ' = topic_' . $field . $value_change;
 619                      $forum_sql[] = 'forum_' . $field . ' = forum_' . $field . $value_change;
 620                  }
 621  
 622                  $sql = 'UPDATE ' . $this->forums_table . '
 623                      SET ' . implode(', ', $forum_sql) . '
 624                      WHERE forum_id = ' . (int) $forum_id;
 625                  $this->db->sql_query($sql);
 626              }
 627          }
 628  
 629          if ($post_id)
 630          {
 631              $sql = 'SELECT 1 AS has_attachments
 632                  FROM ' . POSTS_TABLE . '
 633                  WHERE topic_id = ' . (int) $topic_id . '
 634                      AND post_attachment = 1
 635                      AND post_visibility = ' . ITEM_APPROVED . '
 636                      AND ' . $this->db->sql_in_set('post_id', $post_id, true);
 637              $result = $this->db->sql_query_limit($sql, 1);
 638  
 639              $has_attachment = (bool) $this->db->sql_fetchfield('has_attachments');
 640              $this->db->sql_freeresult($result);
 641  
 642              if ($has_attachment && $visibility == ITEM_APPROVED)
 643              {
 644                  $topic_update_array[] = 'topic_attachment = 1';
 645              }
 646              else if (!$has_attachment && $visibility != ITEM_APPROVED)
 647              {
 648                  $topic_update_array[] = 'topic_attachment = 0';
 649              }
 650          }
 651  
 652          if (!empty($topic_update_array))
 653          {
 654              // Update the number for replies and posts, and update the attachments flag
 655              $sql = 'UPDATE ' . $this->topics_table . '
 656                  SET ' . implode(', ', $topic_update_array) . '
 657                  WHERE topic_id = ' . (int) $topic_id;
 658              $this->db->sql_query($sql);
 659          }
 660          /**
 661           * Perform actions after all steps to changing post visibility
 662           *
 663           * @event core.set_post_visibility_after
 664           * @var            int            visibility        Element of {ITEM_APPROVED, ITEM_DELETED, ITEM_REAPPROVE}
 665           * @var            array        post_id            Array containing all post IDs to be modified. If blank, all posts within the topic are modified.
 666           * @var            int            topic_id        Topic of the post IDs to be modified.
 667           * @var            int            forum_id        Forum ID that the topic_id resides in.
 668           * @var            int            user_id            User ID doing this action.
 669           * @var            int            time            Timestamp of this action.
 670           * @var            string        reason            Reason specified by the user for this change.
 671           * @var            bool        is_starter        Are we changing the topic's starter?
 672           * @var            bool        is_latest        Are we changing the topic's latest post?
 673           * @var            array        data            The data array for this action.
 674           * @since 3.1.10-RC1
 675           * @changed 3.2.2-RC1 Use time instead of non-existent timestamp
 676           */
 677          $vars = array(
 678              'visibility',
 679              'post_id',
 680              'topic_id',
 681              'forum_id',
 682              'user_id',
 683              'time',
 684              'reason',
 685              'is_starter',
 686              'is_latest',
 687              'data',
 688          );
 689          extract($this->phpbb_dispatcher->trigger_event('core.set_post_visibility_after', compact($vars)));
 690          return $data;
 691      }
 692  
 693      /**
 694      * Set topic visibility
 695      *
 696      * Allows approving (which is akin to undeleting/restore) or soft deleting an entire topic.
 697      * Calls set_post_visibility as needed.
 698      *
 699      * Note: By default, when a soft deleted topic is restored. Only posts that
 700      *        were approved at the time of soft deleting, are being restored.
 701      *        Same applies to soft deleting. Only approved posts will be marked
 702      *        as soft deleted.
 703      *        If you want to update all posts, use the force option.
 704      *
 705      * @param $visibility    int        Element of {ITEM_APPROVED, ITEM_DELETED, ITEM_REAPPROVE}
 706      * @param $topic_id        mixed    Topic ID to act on
 707      * @param $forum_id        int        Forum where $topic_id is found
 708      * @param $user_id        int        User performing the action
 709      * @param $time            int        Timestamp when the action is performed
 710      * @param $reason        string    Reason why the visibilty was changed.
 711      * @param $force_update_all    bool    Force to update all posts within the topic
 712      * @return array        Changed topic data, empty array if an error occurred.
 713      */
 714  	public function set_topic_visibility($visibility, $topic_id, $forum_id, $user_id, $time, $reason, $force_update_all = false)
 715      {
 716          if (!in_array($visibility, array(ITEM_APPROVED, ITEM_DELETED, ITEM_REAPPROVE)))
 717          {
 718              return array();
 719          }
 720  
 721          if (!$force_update_all)
 722          {
 723              $sql = 'SELECT topic_visibility, topic_delete_time
 724                  FROM ' . $this->topics_table . '
 725                  WHERE topic_id = ' . (int) $topic_id;
 726              $result = $this->db->sql_query($sql);
 727              $original_topic_data = $this->db->sql_fetchrow($result);
 728              $this->db->sql_freeresult($result);
 729  
 730              if (!$original_topic_data)
 731              {
 732                  // The topic does not exist...
 733                  return array();
 734              }
 735          }
 736  
 737          if (!function_exists('truncate_string'))
 738          {
 739              include($this->phpbb_root_path . 'includes/functions_content.' . $this->php_ext);
 740          }
 741  
 742          // Note, we do not set a reason for the posts, just for the topic
 743          $data = array(
 744              'topic_visibility'        => (int) $visibility,
 745              'topic_delete_user'        => (int) $user_id,
 746              'topic_delete_time'        => ((int) $time) ?: time(),
 747              'topic_delete_reason'    => truncate_string($reason, 255, 255, false),
 748          );
 749          /**
 750           * Perform actions right before the query to change topic visibility
 751           *
 752           * @event core.set_topic_visibility_before_sql
 753           * @var            int            visibility            Element of {ITEM_APPROVED, ITEM_DELETED, ITEM_REAPPROVE}
 754           * @var            int            topic_id            Topic of the post IDs to be modified.
 755           * @var            int            forum_id            Forum ID that the topic_id resides in.
 756           * @var            int            user_id                User ID doing this action.
 757           * @var            int            time                Timestamp of this action.
 758           * @var            string        reason                Reason specified by the user for this change.
 759           * @var            bool        force_update_all    Force an update on all posts within the topic, regardless of their current approval state.
 760           * @var            array        data                The data array for this action.
 761           * @since 3.1.10-RC1
 762           * @changed 3.2.2-RC1 Use time instead of non-existent timestamp
 763           */
 764          $vars = array(
 765              'visibility',
 766              'topic_id',
 767              'forum_id',
 768              'user_id',
 769              'time',
 770              'reason',
 771              'force_update_all',
 772              'data',
 773          );
 774          extract($this->phpbb_dispatcher->trigger_event('core.set_topic_visibility_before_sql', compact($vars)));
 775          $sql = 'UPDATE ' . $this->topics_table . '
 776              SET ' . $this->db->sql_build_array('UPDATE', $data) . '
 777              WHERE topic_id = ' . (int) $topic_id;
 778          $this->db->sql_query($sql);
 779  
 780          if (!$this->db->sql_affectedrows())
 781          {
 782              return array();
 783          }
 784  
 785          if (!$force_update_all && $original_topic_data['topic_delete_time'] && $original_topic_data['topic_visibility'] == ITEM_DELETED && $visibility == ITEM_APPROVED)
 786          {
 787              // If we're restoring a topic we only restore posts, that were soft deleted through the topic soft deletion.
 788              $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']);
 789          }
 790          else if (!$force_update_all && $original_topic_data['topic_visibility'] == ITEM_APPROVED && $visibility == ITEM_DELETED)
 791          {
 792              // If we're soft deleting a topic we only mark approved posts as soft deleted.
 793              $this->set_post_visibility($visibility, false, $topic_id, $forum_id, $user_id, $time, '', true, true, $original_topic_data['topic_visibility']);
 794          }
 795          else
 796          {
 797              $this->set_post_visibility($visibility, false, $topic_id, $forum_id, $user_id, $time, '', true, true);
 798          }
 799          /**
 800           * Perform actions after all steps to changing topic visibility
 801           *
 802           * @event core.set_topic_visibility_after
 803           * @var            int            visibility            Element of {ITEM_APPROVED, ITEM_DELETED, ITEM_REAPPROVE}
 804           * @var            int            topic_id            Topic of the post IDs to be modified.
 805           * @var            int            forum_id            Forum ID that the topic_id resides in.
 806           * @var            int            user_id                User ID doing this action.
 807           * @var            int            time                Timestamp of this action.
 808           * @var            string        reason                Reason specified by the user for this change.
 809           * @var            bool        force_update_all    Force an update on all posts within the topic, regardless of their current approval state.
 810           * @var            array        data                The data array for this action.
 811           * @since 3.1.10-RC1
 812           * @changed 3.2.2-RC1 Use time instead of non-existent timestamp
 813           */
 814          $vars = array(
 815              'visibility',
 816              'topic_id',
 817              'forum_id',
 818              'user_id',
 819              'time',
 820              'reason',
 821              'force_update_all',
 822              'data',
 823          );
 824          extract($this->phpbb_dispatcher->trigger_event('core.set_topic_visibility_after', compact($vars)));
 825          return $data;
 826      }
 827  
 828      /**
 829      * Add post to topic and forum statistics
 830      *
 831      * @param $data            array    Contains information from the topics table about given topic
 832      * @param $sql_data        array    Populated with the SQL changes, may be empty at call time (by reference)
 833      * @return null
 834      */
 835  	public function add_post_to_statistic($data, &$sql_data)
 836      {
 837          $sql_data[$this->topics_table] = (($sql_data[$this->topics_table]) ? $sql_data[$this->topics_table] . ', ' : '') . 'topic_posts_approved = topic_posts_approved + 1';
 838  
 839          $sql_data[$this->forums_table] = (($sql_data[$this->forums_table]) ? $sql_data[$this->forums_table] . ', ' : '') . 'forum_posts_approved = forum_posts_approved + 1';
 840  
 841          if ($data['post_postcount'])
 842          {
 843              $sql_data[$this->users_table] = (($sql_data[$this->users_table]) ? $sql_data[$this->users_table] . ', ' : '') . 'user_posts = user_posts + 1';
 844          }
 845  
 846          $this->config->increment('num_posts', 1, false);
 847      }
 848  
 849      /**
 850      * Remove post from topic and forum statistics
 851      *
 852      * @param $data            array    Contains information from the topics table about given topic
 853      * @param $sql_data        array    Populated with the SQL changes, may be empty at call time (by reference)
 854      * @return null
 855      */
 856  	public function remove_post_from_statistic($data, &$sql_data)
 857      {
 858          if ($data['post_visibility'] == ITEM_APPROVED)
 859          {
 860              $sql_data[$this->topics_table] = ((!empty($sql_data[$this->topics_table])) ? $sql_data[$this->topics_table] . ', ' : '') . 'topic_posts_approved = topic_posts_approved - 1';
 861              $sql_data[$this->forums_table] = ((!empty($sql_data[$this->forums_table])) ? $sql_data[$this->forums_table] . ', ' : '') . 'forum_posts_approved = forum_posts_approved - 1';
 862  
 863              if ($data['post_postcount'])
 864              {
 865                  $sql_data[$this->users_table] = ((!empty($sql_data[$this->users_table])) ? $sql_data[$this->users_table] . ', ' : '') . 'user_posts = user_posts - 1';
 866              }
 867  
 868              $this->config->increment('num_posts', -1, false);
 869          }
 870          else if ($data['post_visibility'] == ITEM_UNAPPROVED || $data['post_visibility'] == ITEM_REAPPROVE)
 871          {
 872              $sql_data[FORUMS_TABLE] = (($sql_data[FORUMS_TABLE]) ? $sql_data[FORUMS_TABLE] . ', ' : '') . 'forum_posts_unapproved = forum_posts_unapproved - 1';
 873              $sql_data[TOPICS_TABLE] = (($sql_data[TOPICS_TABLE]) ? $sql_data[TOPICS_TABLE] . ', ' : '') . 'topic_posts_unapproved = topic_posts_unapproved - 1';
 874          }
 875          else if ($data['post_visibility'] == ITEM_DELETED)
 876          {
 877              $sql_data[FORUMS_TABLE] = (($sql_data[FORUMS_TABLE]) ? $sql_data[FORUMS_TABLE] . ', ' : '') . 'forum_posts_softdeleted = forum_posts_softdeleted - 1';
 878              $sql_data[TOPICS_TABLE] = (($sql_data[TOPICS_TABLE]) ? $sql_data[TOPICS_TABLE] . ', ' : '') . 'topic_posts_softdeleted = topic_posts_softdeleted - 1';
 879          }
 880      }
 881  
 882      /**
 883      * Remove topic from forum statistics
 884      *
 885      * @param $data            array    Post and topic data
 886      * @param $sql_data        array    Populated with the SQL changes, may be empty at call time (by reference)
 887      * @return null
 888      */
 889  	public function remove_topic_from_statistic($data, &$sql_data)
 890      {
 891          if ($data['topic_visibility'] == ITEM_APPROVED)
 892          {
 893              $sql_data[FORUMS_TABLE] .= 'forum_posts_approved = forum_posts_approved - 1, forum_topics_approved = forum_topics_approved - 1';
 894  
 895              if ($data['post_postcount'])
 896              {
 897                  $sql_data[$this->users_table] = ((!empty($sql_data[$this->users_table])) ? $sql_data[$this->users_table] . ', ' : '') . 'user_posts = user_posts - 1';
 898              }
 899          }
 900          else if ($data['topic_visibility'] == ITEM_UNAPPROVED || $data['post_visibility'] == ITEM_REAPPROVE)
 901          {
 902              $sql_data[FORUMS_TABLE] .= 'forum_posts_unapproved = forum_posts_unapproved - 1, forum_topics_unapproved = forum_topics_unapproved - 1';
 903          }
 904          else if ($data['topic_visibility'] == ITEM_DELETED)
 905          {
 906              $sql_data[FORUMS_TABLE] .= 'forum_posts_softdeleted = forum_posts_softdeleted - 1, forum_topics_softdeleted = forum_topics_softdeleted - 1';
 907          }
 908  
 909      }
 910  }


Generated: Mon Nov 25 19:05:08 2024 Cross-referenced by PHPXref 0.7.1