Failed Conditions
Branch release-2.1 (4e22cf)
by Rick
06:39
created

ViewQuery.php ➔ ViewQuery()   F

Complexity

Conditions 32
Paths > 20000

Size

Total Lines 161
Code Lines 77

Duplication

Lines 24
Ratio 14.91 %

Importance

Changes 0
Metric Value
cc 32
eloc 77
nc 61460
nop 0
dl 24
loc 161
rs 2
c 0
b 0
f 0

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
/**
4
 * Functions concerned with viewing queries, and is used for debugging.
5
 *
6
 * Simple Machines Forum (SMF)
7
 *
8
 * @package SMF
9
 * @author Simple Machines http://www.simplemachines.org
10
 * @copyright 2017 Simple Machines and individual contributors
11
 * @license http://www.simplemachines.org/about/smf/license.php BSD
12
 *
13
 * @version 2.1 Beta 4
14
 */
15
16
if (!defined('SMF'))
17
	die('No direct access...');
18
19
/**
20
 * Show the database queries for debugging
21
 * What this does:
22
 * - Toggles the session variable 'view_queries'.
23
 * - Views a list of queries and analyzes them.
24
 * - Requires the admin_forum permission.
25
 * - Is accessed via ?action=viewquery.
26
 * - Strings in this function have not been internationalized.
27
 */
28
function ViewQuery()
29
{
30
	global $scripturl, $settings, $context, $db_connection, $boarddir, $smcFunc, $txt, $db_show_debug;
31
32
	// We should have debug mode enabled, as well as something to display!
33
	if (!isset($db_show_debug) || $db_show_debug !== true || !isset($_SESSION['debug']))
34
		fatal_lang_error('no_access', false);
35
36
	// Don't allow except for administrators.
37
	isAllowedTo('admin_forum');
38
39
	// If we're just hiding/showing, do it now.
40
	if (isset($_REQUEST['sa']) && $_REQUEST['sa'] == 'hide')
41
	{
42
		$_SESSION['view_queries'] = $_SESSION['view_queries'] == 1 ? 0 : 1;
43
44 View Code Duplication
		if (strpos($_SESSION['old_url'], 'action=viewquery') !== false)
45
			redirectexit();
46
		else
47
			redirectexit($_SESSION['old_url']);
48
	}
49
50
	call_integration_hook('integrate_egg_nog');
51
52
	$query_id = isset($_REQUEST['qq']) ? (int) $_REQUEST['qq'] - 1 : -1;
53
54
	echo '<!DOCTYPE html>
55
<html', $context['right_to_left'] ? ' dir="rtl"' : '', '>
56
	<head>
57
		<title>', $context['forum_name_html_safe'], '</title>
58
		<link rel="stylesheet" href="', $settings['theme_url'], '/css/index', $context['theme_variant'], '.css?alp21">
59
		<style>
60
			body
61
			{
62
				margin: 1ex;
63
			}
64
			body, td, th, .normaltext
65
			{
66
				font-size: x-small;
67
			}
68
			.smalltext
69
			{
70
				font-size: xx-small;
71
			}
72
		</style>
73
	</head>
74
	<body id="help_popup">
75
		<div class="tborder windowbg description">';
76
77
	foreach ($_SESSION['debug'] as $q => $query_data)
78
	{
79
		// Fix the indentation....
80
		$query_data['q'] = ltrim(str_replace("\r", '', $query_data['q']), "\n");
81
		$query = explode("\n", $query_data['q']);
82
		$min_indent = 0;
83
		foreach ($query as $line)
84
		{
85
			preg_match('/^(\t*)/', $line, $temp);
86
			if (strlen($temp[0]) < $min_indent || $min_indent == 0)
87
				$min_indent = strlen($temp[0]);
88
		}
89
		foreach ($query as $l => $dummy)
90
			$query[$l] = substr($dummy, $min_indent);
91
		$query_data['q'] = implode("\n", $query);
92
93
		// Make the filenames look a bit better.
94 View Code Duplication
		if (isset($query_data['f']))
95
			$query_data['f'] = preg_replace('~^' . preg_quote($boarddir, '~') . '~', '...', $query_data['f']);
96
97
		$is_select_query = substr(trim($query_data['q']), 0, 6) == 'SELECT';
98
		if ($is_select_query)
99
			$select = $query_data['q'];
100 View Code Duplication
		elseif (preg_match('~^INSERT(?: IGNORE)? INTO \w+(?:\s+\([^)]+\))?\s+(SELECT .+)$~s', trim($query_data['q']), $matches) != 0)
101
		{
102
			$is_select_query = true;
103
			$select = $matches[1];
104
		}
105 View Code Duplication
		elseif (preg_match('~^CREATE TEMPORARY TABLE .+?(SELECT .+)$~s', trim($query_data['q']), $matches) != 0)
106
		{
107
			$is_select_query = true;
108
			$select = $matches[1];
109
		}
110
		// Temporary tables created in earlier queries are not explainable.
111
		if ($is_select_query)
112
		{
113 View Code Duplication
			foreach (array('log_topics_unread', 'topics_posted_in', 'tmp_log_search_topics', 'tmp_log_search_messages') as $tmp)
114
				if (strpos($select, $tmp) !== false)
0 ignored issues
show
Bug introduced by
The variable $select does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
115
				{
116
					$is_select_query = false;
117
					break;
118
				}
119
		}
120
121
		echo '
122
		<div id="qq', $q, '" style="margin-bottom: 2ex;">
123
			<a', $is_select_query ? ' href="' . $scripturl . '?action=viewquery;qq=' . ($q + 1) . '#qq' . $q . '"' : '', ' style="font-weight: bold; text-decoration: none;">
124
				', nl2br(str_replace("\t", '&nbsp;&nbsp;&nbsp;', $smcFunc['htmlspecialchars']($query_data['q']))), '
125
			</a><br>';
126
127 View Code Duplication
		if (!empty($query_data['f']) && !empty($query_data['l']))
128
			echo sprintf($txt['debug_query_in_line'], $query_data['f'], $query_data['l']);
129
130
		if (isset($query_data['s'], $query_data['t']) && isset($txt['debug_query_which_took_at']))
131
			echo sprintf($txt['debug_query_which_took_at'], round($query_data['t'], 8), round($query_data['s'], 8));
132
		else
133
			echo sprintf($txt['debug_query_which_took'], round($query_data['t'], 8));
134
135
		echo '
136
		</div>';
137
138
		// Explain the query.
139
		if ($query_id == $q && $is_select_query)
140
		{
141
			$result = $smcFunc['db_query']('', '
142
				EXPLAIN '.($smcFunc['db_title'] == 'PostgreSQL' ? 'ANALYZE ' : '') . $select,
143
				array(
144
				)
145
			);
146
			if ($result === false)
147
			{
148
				echo '
149
		<table>
150
			<tr><td>', $smcFunc['db_error']($db_connection), '</td></tr>
151
		</table>';
152
				continue;
153
			}
154
155
			echo '
156
		<table>';
157
158
			$row = $smcFunc['db_fetch_assoc']($result);
159
160
			echo '
161
			<tr>
162
				<th>' . implode('</th>
163
				<th>', array_keys($row)) . '</th>
164
			</tr>';
165
166
			$smcFunc['db_data_seek']($result, 0);
167
			while ($row = $smcFunc['db_fetch_assoc']($result))
168
			{
169
				echo '
170
			<tr>
171
				<td>' . implode('</td>
172
				<td>', $row) . '</td>
173
			</tr>';
174
			}
175
			$smcFunc['db_free_result']($result);
176
177
			echo '
178
		</table>';
179
		}
180
	}
181
182
	echo '
183
		</div>
184
	</body>
185
</html>';
186
187
	obExit(false);
188
}
189
190
?>