[ Index ]

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


Generated: Thu Jan 11 23:14:31 2018 Cross-referenced by PHPXref 0.7.1