Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 125
0.00% covered (danger)
0.00%
0 / 9
CRAP
0.00% covered (danger)
0.00%
0 / 1
softdelete_p1
0.00% covered (danger)
0.00%
0 / 125
0.00% covered (danger)
0.00%
0 / 9
240
0.00% covered (danger)
0.00%
0 / 1
 effectively_installed
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 depends_on
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 update_schema
0.00% covered (danger)
0.00%
0 / 36
0.00% covered (danger)
0.00%
0 / 1
2
 revert_schema
0.00% covered (danger)
0.00%
0 / 31
0.00% covered (danger)
0.00%
0 / 1
2
 update_data
0.00% covered (danger)
0.00%
0 / 8
0.00% covered (danger)
0.00%
0 / 1
2
 update_post_visibility
0.00% covered (danger)
0.00%
0 / 3
0.00% covered (danger)
0.00%
0 / 1
2
 update_topic_visibility
0.00% covered (danger)
0.00%
0 / 3
0.00% covered (danger)
0.00%
0 / 1
2
 update_topics_post_counts
0.00% covered (danger)
0.00%
0 / 8
0.00% covered (danger)
0.00%
0 / 1
2
 update_forums_topic_and_post_counts
0.00% covered (danger)
0.00%
0 / 34
0.00% covered (danger)
0.00%
0 / 1
56
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
14namespace phpbb\db\migration\data\v310;
15
16class softdelete_p1 extends \phpbb\db\migration\migration
17{
18    public function effectively_installed()
19    {
20        return $this->db_tools->sql_column_exists($this->table_prefix . 'posts', 'post_visibility');
21    }
22
23    public static function depends_on()
24    {
25        return array('\phpbb\db\migration\data\v310\dev');
26    }
27
28    public function update_schema()
29    {
30        return array(
31            'add_columns'        => array(
32                $this->table_prefix . 'forums'        => array(
33                    'forum_posts_approved'        => array('UINT', 0),
34                    'forum_posts_unapproved'    => array('UINT', 0),
35                    'forum_posts_softdeleted'    => array('UINT', 0),
36                    'forum_topics_approved'        => array('UINT', 0),
37                    'forum_topics_unapproved'    => array('UINT', 0),
38                    'forum_topics_softdeleted'    => array('UINT', 0),
39                ),
40                $this->table_prefix . 'posts'        => array(
41                    'post_visibility'        => array('TINT:3', 0),
42                    'post_delete_time'        => array('TIMESTAMP', 0),
43                    'post_delete_reason'    => array('STEXT_UNI', ''),
44                    'post_delete_user'        => array('UINT', 0),
45                ),
46                $this->table_prefix . 'topics'        => array(
47                    'topic_visibility'        => array('TINT:3', 0),
48                    'topic_delete_time'        => array('TIMESTAMP', 0),
49                    'topic_delete_reason'    => array('STEXT_UNI', ''),
50                    'topic_delete_user'        => array('UINT', 0),
51                    'topic_posts_approved'        => array('UINT', 0),
52                    'topic_posts_unapproved'    => array('UINT', 0),
53                    'topic_posts_softdeleted'    => array('UINT', 0),
54                ),
55            ),
56            'add_index'        => array(
57                $this->table_prefix . 'posts'        => array(
58                    'post_visibility'        => array('post_visibility'),
59                ),
60                $this->table_prefix . 'topics'        => array(
61                    'topic_visibility'        => array('topic_visibility'),
62                    'forum_vis_last'        => array('forum_id', 'topic_visibility', 'topic_last_post_id'),
63                ),
64            ),
65        );
66    }
67
68    public function revert_schema()
69    {
70        return array(
71            'drop_columns'        => array(
72                $this->table_prefix . 'forums'        => array(
73                    'forum_posts_approved',
74                    'forum_posts_unapproved',
75                    'forum_posts_softdeleted',
76                    'forum_topics_approved',
77                    'forum_topics_unapproved',
78                    'forum_topics_softdeleted',
79                ),
80                $this->table_prefix . 'posts'        => array(
81                    'post_visibility',
82                    'post_delete_time',
83                    'post_delete_reason',
84                    'post_delete_user',
85                ),
86                $this->table_prefix . 'topics'        => array(
87                    'topic_visibility',
88                    'topic_delete_time',
89                    'topic_delete_reason',
90                    'topic_delete_user',
91                    'topic_posts_approved',
92                    'topic_posts_unapproved',
93                    'topic_posts_softdeleted',
94                ),
95            ),
96            'drop_keys'        => array(
97                $this->table_prefix . 'posts'        => array('post_visibility'),
98                $this->table_prefix . 'topics'    => array('topic_visibility', 'forum_vis_last'),
99            ),
100        );
101    }
102
103    public function update_data()
104    {
105        return array(
106            array('custom', array(array($this, 'update_post_visibility'))),
107            array('custom', array(array($this, 'update_topic_visibility'))),
108            array('custom', array(array($this, 'update_topics_post_counts'))),
109            array('custom', array(array($this, 'update_forums_topic_and_post_counts'))),
110
111            array('permission.add', array('f_softdelete', false)),
112            array('permission.add', array('m_softdelete', false)),
113        );
114    }
115
116    public function update_post_visibility()
117    {
118        $sql = 'UPDATE ' . $this->table_prefix . 'posts
119            SET post_visibility = post_approved';
120        $this->sql_query($sql);
121    }
122
123    public function update_topic_visibility()
124    {
125        $sql = 'UPDATE ' . $this->table_prefix . 'topics
126            SET topic_visibility = topic_approved';
127        $this->sql_query($sql);
128    }
129
130    public function update_topics_post_counts()
131    {
132        /*
133        * Using sql_case here to avoid "BIGINT UNSIGNED value is out of range" errors.
134        * As we update all topics in 2 queries, one broken topic would stop the conversion
135        * for all topics and the suppressed error will cause the admin to not even notice it.
136        */
137        $sql = 'UPDATE ' . $this->table_prefix . 'topics
138            SET topic_posts_approved = topic_replies + 1,
139                topic_posts_unapproved = ' . $this->db->sql_case('topic_replies_real > topic_replies', 'topic_replies_real - topic_replies', '0') . '
140            WHERE topic_visibility = ' . ITEM_APPROVED;
141        $this->sql_query($sql);
142
143        $sql = 'UPDATE ' . $this->table_prefix . 'topics
144            SET topic_posts_approved = 0,
145                topic_posts_unapproved = (' . $this->db->sql_case('topic_replies_real > topic_replies', 'topic_replies_real - topic_replies', '0') . ') + 1
146            WHERE topic_visibility = ' . ITEM_UNAPPROVED;
147        $this->sql_query($sql);
148    }
149
150    public function update_forums_topic_and_post_counts($start)
151    {
152        $start = (int) $start;
153        $limit = 10;
154        $converted_forums = 0;
155
156        if (!$start)
157        {
158            // Preserve the forum_posts value for link forums as it represents redirects.
159            $sql = 'UPDATE ' . $this->table_prefix . 'forums
160                SET forum_posts_approved = forum_posts
161                WHERE forum_type = ' . FORUM_LINK;
162            $this->db->sql_query($sql);
163        }
164
165        $sql = 'SELECT forum_id, topic_visibility, COUNT(topic_id) AS sum_topics, SUM(topic_posts_approved) AS sum_posts_approved, SUM(topic_posts_unapproved) AS sum_posts_unapproved
166            FROM ' . $this->table_prefix . 'topics
167            GROUP BY forum_id, topic_visibility
168            ORDER BY forum_id, topic_visibility';
169        $result = $this->db->sql_query_limit($sql, $limit, $start);
170
171        $update_forums = array();
172        while ($row = $this->db->sql_fetchrow($result))
173        {
174            $converted_forums++;
175
176            $forum_id = (int) $row['forum_id'];
177            if (!isset($update_forums[$forum_id]))
178            {
179                $update_forums[$forum_id] = array(
180                    'forum_posts_approved'        => 0,
181                    'forum_posts_unapproved'    => 0,
182                    'forum_topics_approved'        => 0,
183                    'forum_topics_unapproved'    => 0,
184                );
185            }
186
187            $update_forums[$forum_id]['forum_posts_approved'] += (int) $row['sum_posts_approved'];
188            $update_forums[$forum_id]['forum_posts_unapproved'] += (int) $row['sum_posts_unapproved'];
189
190            $update_forums[$forum_id][(($row['topic_visibility'] == ITEM_APPROVED) ? 'forum_topics_approved' : 'forum_topics_unapproved')] += (int) $row['sum_topics'];
191        }
192        $this->db->sql_freeresult($result);
193
194        foreach ($update_forums as $forum_id => $forum_data)
195        {
196            $sql = 'UPDATE ' . FORUMS_TABLE . '
197                SET ' . $this->db->sql_build_array('UPDATE', $forum_data) . '
198                WHERE forum_id = ' . $forum_id;
199            $this->sql_query($sql);
200        }
201
202        if ($converted_forums < $limit)
203        {
204            // There are no more topics, we are done
205            return;
206        }
207
208        // There are still more topics to query, return the next start value
209        return $start + $limit;
210    }
211}