Issues (207)

Security Analysis    not enabled

This project does not seem to handle request data directly as such no vulnerable execution paths were found.

  Cross-Site Scripting
Cross-Site Scripting enables an attacker to inject code into the response of a web-request that is viewed by other users. It can for example be used to bypass access controls, or even to take over other users' accounts.
  File Exposure
File Exposure allows an attacker to gain access to local files that he should not be able to access. These files can for example include database credentials, or other configuration files.
  File Manipulation
File Manipulation enables an attacker to write custom data to files. This potentially leads to injection of arbitrary code on the server.
  Object Injection
Object Injection enables an attacker to inject an object into PHP code, and can lead to arbitrary code execution, file exposure, or file manipulation attacks.
  Code Injection
Code Injection enables an attacker to execute arbitrary code on the server.
  Response Splitting
Response Splitting can be used to send arbitrary responses.
  File Inclusion
File Inclusion enables an attacker to inject custom files into PHP's file loading mechanism, either explicitly passed to include, or for example via PHP's auto-loading mechanism.
  Command Injection
Command Injection enables an attacker to inject a shell command that is execute with the privileges of the web-server. This can be used to expose sensitive data, or gain access of your server.
  SQL Injection
SQL Injection enables an attacker to execute arbitrary SQL code on your database server gaining access to user data, or manipulating user data.
  XPath Injection
XPath Injection enables an attacker to modify the parts of XML document that are read. If that XML document is for example used for authentication, this can lead to further vulnerabilities similar to SQL Injection.
  LDAP Injection
LDAP Injection enables an attacker to inject LDAP statements potentially granting permission to run unauthorized queries, or modify content inside the LDAP tree.
  Header Injection
  Other Vulnerability
This category comprises other attack vectors such as manipulating the PHP runtime, loading custom extensions, freezing the runtime, or similar.
  Regex Injection
Regex Injection enables an attacker to execute arbitrary code in your PHP process.
  XML Injection
XML Injection enables an attacker to read files on your local filesystem including configuration files, or can be abused to freeze your web-server process.
  Variable Injection
Variable Injection enables an attacker to overwrite program variables with custom data, and can lead to further vulnerabilities.
Unfortunately, the security analysis is currently not available for your project. If you are a non-commercial open-source project, please contact support to gain access.

admin/pages.php (12 issues)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
3
use Xmf\Database\TableLoad;
4
use Xmf\Database\Tables;
5
use Xmf\Request;
6
7
/**
8
 * admin/pages.php - manage wiki page revision
9
 *
10
 * @copyright  Copyright © 2013 geekwright, LLC. All rights reserved.
11
 * @license    gwiki/docs/license.txt  GNU General Public License (GPL)
12
 * @since      1.0
13
 * @author     Richard Griffith <[email protected]>
14
 * @package    gwiki
15
 */
16
include __DIR__ . '/header.php';
17
18
include_once __DIR__ . '/../include/functions.php';
19
include_once XOOPS_ROOT_PATH . '/class/xoopsformloader.php';
20
21
$moduleAdmin->displayNavigation(basename(__FILE__));
22
23
/**
24
 * @param $url
25
 * @param $params
26
 */
27
function post_clean_request($url, $params)
28
{
29
    foreach ($params as $key => &$val) {
30
        if (is_array($val)) {
31
            $val = implode(',', $val);
32
        }
33
        $post_params[] = $key . '=' . urlencode($val);
0 ignored issues
show
Coding Style Comprehensibility introduced by
$post_params was never initialized. Although not strictly required by PHP, it is generally a good practice to add $post_params = array(); before regardless.

Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code.

Let’s take a look at an example:

foreach ($collection as $item) {
    $myArray['foo'] = $item->getFoo();

    if ($item->hasBar()) {
        $myArray['bar'] = $item->getBar();
    }

    // do something with $myArray
}

As you can see in this example, the array $myArray is initialized the first time when the foreach loop is entered. You can also see that the value of the bar key is only written conditionally; thus, its value might result from a previous iteration.

This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop.

Loading history...
34
    }
35
    $post_string = implode('&', $post_params);
0 ignored issues
show
The variable $post_params 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...
36
37
    $parts = parse_url($url);
38
39
    $fp = fsockopen($parts['host'], isset($parts['port']) ? $parts['port'] : 80, $errno, $errstr, 30);
40
41
    $out = 'POST ' . $parts['path'] . " HTTP/1.1\r\n";
42
    $out .= 'Host: ' . $parts['host'] . "\r\n";
43
    $out .= "Content-Type: application/x-www-form-urlencoded\r\n";
44
    $out .= 'Content-Length: ' . strlen($post_string) . "\r\n";
45
    $out .= "Connection: Close\r\n\r\n";
46
    if (isset($post_string)) {
47
        $out .= $post_string;
48
    }
49
50
    fwrite($fp, $out);
51
    fclose($fp);
52
}
53
54
/**
55
 * @param null $message
56
 */
57
function showPages($message = null)
58
{
59
    global $xoopsDB;
60
    echo <<<EOT
61
<style>
62
div.pagination.default {display:inline;}
63
form {display:inline;}
64
</style>
65
EOT;
66
    $total = 0;
67
    $limit = 10;
68
69
    $start = Request::getInt('start', 0, 'GET');
70
    $like = Request::getString('like', '', 'GET');
71
72
    $sql = 'SELECT COUNT(*) FROM ' . $xoopsDB->prefix('gwiki_pageids');
73
    if (!empty($like)) {
74
        $sql .= " WHERE keyword LIKE '{$like}%' ";
75
    }
76
    $result = $xoopsDB->query($sql);
77
    if ($result) {
78
        $myrow = $xoopsDB->fetchRow($result);
79
        $total = $myrow[0];
80
    }
81
82
    echo '<form method="get"><b>' . _AD_GWIKI_KEYWORD_FILTER . '</b><input type="text" name="like"><input type="submit"></form><br>';
83
    adminTableStart(_AD_GWIKI_ADMINTITLE, 4);
84
    if (!empty($message)) {
85
        echo '<tr><td colspan="4" align="center"><br><b>' . $message . '</b><br><br></td></tr>';
86
    }
87
    echo '<tr><th width="15%">' . _AD_GWIKI_KEYWORD . '</th><th>' . _MD_GWIKI_TITLE . '</th><th width="5%">' . _AD_GWIKI_REVISIONS . '</th><th width="30%">' . _AD_GWIKI_ACTION . '</th></tr>';
88
    $sqlwhere = '';
89
    if (!empty($like)) {
90
        $sqlwhere = " WHERE t1.keyword LIKE '{$like}%' ";
91
    }
92
    $sql    = 'SELECT t1.keyword, COUNT(*), t2.title, t2.admin_lock, t2.active FROM ' . $xoopsDB->prefix('gwiki_pages') . ' t1 ' . ' LEFT JOIN ' . $xoopsDB->prefix('gwiki_pages')
93
              . ' t2 on t1.keyword = t2.keyword and t2.active = 1 ' . $sqlwhere . ' GROUP BY keyword, t2.title, t2.admin_lock, t2.active ';
94
    $result = $xoopsDB->query($sql, $limit, $start);
95
96
    for ($i = 0, $iMax = $xoopsDB->getRowsNum($result); $i < $iMax; ++$i) {
97
        list($page, $revs, $title, $lock, $active) = $xoopsDB->fetchRow($result);
98
        if (empty($active)) {
99
            $title = _AD_GWIKI_NO_ACTIVE_PAGE;
100
        }
101
        //if(empty($title)) $title=_AD_GWIKI_NO_ACTIVE_PAGE;
102
        if ($lock) {
103
            $lockaction = ' | <a href="pages.php?page=' . $page . '&op=unlock">' . _AD_GWIKI_UNLOCK . '</a>';
104
        } else {
105
            $lockaction = ' | <a href="pages.php?page=' . $page . '&op=lock">' . _AD_GWIKI_LOCK . '</a>';
106
        }
107
        echo '<tr class="' . (($i % 2) ? 'even' : 'odd') . '"><td><a href="pages.php?page=' . $page . '&op=history">' . $page . '</a></td>' . '<td>' . htmlspecialchars($title, ENT_QUOTES) . '</td>'
108
             . '<td>' . $revs . '</td>' . '<td><a href="pages.php?page=' . $page . '&op=display">' . _AD_GWIKI_VIEW . '</a> | <a href="pages.php?page=' . $page . '&op=history">' . _AD_GWIKI_HISTORY
109
             . '</a>' . $lockaction . ' | <a href="pages.php?page=' . $page . '&op=delete">' . _DELETE . '</a></td></tr>';
110
    }
111
    if ($i === 0) {
112
        echo '<tr class="odd"><td colspan="3">' . _AD_GWIKI_EMPTYWIKI . '</td></tr>';
113
    }
114
115
    $endarray[_AD_GWIKI_CLEANUPDB] = 'pages.php?op=clean';
0 ignored issues
show
Coding Style Comprehensibility introduced by
$endarray was never initialized. Although not strictly required by PHP, it is generally a good practice to add $endarray = array(); before regardless.

Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code.

Let’s take a look at an example:

foreach ($collection as $item) {
    $myArray['foo'] = $item->getFoo();

    if ($item->hasBar()) {
        $myArray['bar'] = $item->getBar();
    }

    // do something with $myArray
}

As you can see in this example, the array $myArray is initialized the first time when the foreach loop is entered. You can also see that the value of the bar key is only written conditionally; thus, its value might result from a previous iteration.

This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop.

Loading history...
116
    $endarray[_AD_GWIKI_PARTITION] = 'pages.php?op=partition';
117
    $endarray[_AD_GWIKI_ADD_HELP]  = 'pages.php?op=addhelp';
118
    // set up pagenav
119
    $pager = '';
120
    if ($total > $limit) {
121
        include_once XOOPS_ROOT_PATH . '/class/pagenav.php';
122
        $likenav = '';
123
        if (!empty($like)) {
124
            $likenav = "like={$like}";
125
        }
126
        $nav = new xoopsPageNav($total, $limit, $start, 'start', $likenav);
127 View Code Duplication
        if ((int)($total / $limit) < 5) {
0 ignored issues
show
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
128
            $pager = $nav->renderNav();
129
        } else {
130
            $pager = _AD_GWIKI_PAGENAV . $nav->renderSelect(false);
131
        }
132
    }
133
    if (!empty($pager)) {
134
        $endarray['!PREFORMATTED!'] = $pager;
135
    }
136
137
    adminTableEnd($endarray);
138
}
139
140
/**
141
 * @param $page
142
 */
143
function showHistory($page)
144
{
145
    global $xoopsDB, $wikiPage;
146
147
    allowRestoration($page);
148
149
    adminTableStart(_AD_GWIKI_ADMINTITLE . ' : ' . $page, 4);
150
    echo '<tr><th>' . _MD_GWIKI_TITLE . '</th><th width="20%">' . _AD_GWIKI_MODIFIED . '</th><th width="10%">' . _AD_GWIKI_AUTHOR . '</th><th width="30%">' . _AD_GWIKI_ACTION . '</th></tr>';
151
152
    $sql    = 'SELECT gwiki_id, title, body, lastmodified, uid, active, FROM_UNIXTIME(lastmodified) FROM ' . $xoopsDB->prefix('gwiki_pages')
153
              . " WHERE keyword='{$page}' ORDER BY active DESC, lastmodified DESC";
154
    $result = $xoopsDB->query($sql);
155
156
    for ($i = 0, $iMax = $xoopsDB->getRowsNum($result); $i < $iMax; ++$i) {
157
        list($id, $title, $body, $lastmodified, $uid, $active, $modified) = $xoopsDB->fetchRow($result);
0 ignored issues
show
The assignment to $body is unused. Consider omitting it like so list($first,,$third).

This checks looks for assignemnts to variables using the list(...) function, where not all assigned variables are subsequently used.

Consider the following code example.

<?php

function returnThreeValues() {
    return array('a', 'b', 'c');
}

list($a, $b, $c) = returnThreeValues();

print $a . " - " . $c;

Only the variables $a and $c are used. There was no need to assign $b.

Instead, the list call could have been.

list($a,, $c) = returnThreeValues();
Loading history...
The assignment to $lastmodified is unused. Consider omitting it like so list($first,,$third).

This checks looks for assignemnts to variables using the list(...) function, where not all assigned variables are subsequently used.

Consider the following code example.

<?php

function returnThreeValues() {
    return array('a', 'b', 'c');
}

list($a, $b, $c) = returnThreeValues();

print $a . " - " . $c;

Only the variables $a and $c are used. There was no need to assign $b.

Instead, the list call could have been.

list($a,, $c) = returnThreeValues();
Loading history...
158
159
        echo '<tr class="' . (($i % 2) ? 'even' : 'odd') . '"><td><a href="pages.php?page=' . $page . '&op=display&id=' . $id . '">' . htmlspecialchars($title, ENT_QUOTES) . '</a></td>';
160
        echo '<td>' . $modified . ($active ? '*' : '') . '</td>';
161
        echo '<td>' . $wikiPage->getUserName($uid) . '</td>';
162
        echo '<td><a href="pages.php?page=' . $page . '&op=display&id=' . $id . '">' . _AD_GWIKI_VIEW . '</a> | <a href="javascript:restoreRevision(\'' . $id . '\');">' . _AD_GWIKI_RESTORE . '</a> ';
163
        echo ' | <a href="pages.php?page=' . $page . '&op=fix&id=' . $id . '">' . _AD_GWIKI_FIX . '</a> | <a href="pages.php?page=' . $page . '&op=tool&id=' . $id . '">' . _AD_GWIKI_PAGETOOLS
164
             . '</a>';
165
        echo ' | <a href="../edit.php?page=' . $page . '&id=' . $id . '">' . _EDIT . '</a> </td></tr>';
166
    }
167
    if ($i === 0) {
168
        echo '<tr class="odd"><td colspan="4">' . _MD_GWIKI_PAGENOTFOUND . '</td></tr>';
169
    }
170
171
    adminTableEnd(array(_BACK => 'pages.php?op=manage'));
172
}
173
174
/**
175
 * @param $page
176
 * @param $id
177
 */
178
function showPage($page, $id)
179
{
180
    global $xoopsModuleConfig, $wikiPage, $xoTheme;
181
182
    $dir = basename(dirname(__DIR__));
183
    if (is_object($xoTheme)) {
184
        $xoTheme->addStylesheet(XOOPS_URL . '/modules/' . $dir . '/assets/css/module.css');
185
    }
186
187
    //    xoops_cp_header();
188
    allowRestoration($page);
189
190
    $wikiPage->setWikiLinkURL('pages.php?page=%s&op=history');
191
    $wikiPage->getPage($page, $id);
192
    if (empty($id)) {
193
        $id = $wikiPage->gwiki_id;
194
    }
195
196
    adminTableStart(_AD_GWIKI_SHOWPAGE, 1);
197
    echo '<tr><td width="100%" >';
198
    echo '<div style="width: 94%; margin: 2em;">';
199
    echo '<p style="padding-bottom: 2px; border-bottom: 1px solid #000000;">' . _MD_GWIKI_PAGE . ": <strong>{$page}</strong> - " . _MD_GWIKI_LASTMODIFIED . ' <i>'
200
         . date($xoopsModuleConfig['date_format'], $wikiPage->lastmodified) . '</i> ' . _MD_GWIKI_BY . ' <i>' . $wikiPage->getUserName($wikiPage->uid) . '</i></p>';
201
202
    echo '<div id="wikipage"><h1 class="wikititle" id="toc0">' . htmlspecialchars($wikiPage->title) . '</h1>';
203
    echo $wikiPage->renderPage();
204
    echo '</div>';
205
206
    echo '</div>';
207
    echo '</td></tr>';
208
    adminTableEnd(array(
209
                      _BACK               => "pages.php?page={$page}&op=history",
210
                      _AD_GWIKI_RESTORE   => "javascript:restoreRevision('{$id}');",
211
                      _AD_GWIKI_PAGETOOLS => "pages.php?page={$page}&op=tool&id={$id}",
212
                      _AD_GWIKI_FIX       => "pages.php?page={$page}&op=fix&id={$id}"
213
                  ));
214
}
215
216
/**
217
 * @param $page
218
 * @param $id
219
 */
220
function showPageTool($page, $id)
221
{
222
    global $xoopsModuleConfig, $wikiPage, $xoTheme;
223
224
    $dir = basename(dirname(__DIR__));
225
    if (is_object($xoTheme)) {
226
        $xoTheme->addStylesheet(XOOPS_URL . '/modules/' . $dir . '/assets/css/module.css');
227
    }
228
229
    //    xoops_cp_header();
230
    allowRestoration($page);
231
232
    $wikiPage->setWikiLinkURL("javascript:alert('%s');");
233
    $wikiPage->getPage($page, $id);
234
235
    $form = new XoopsThemeForm(_AD_GWIKI_PAGETOOLS . ": {$page}", 'gwikiform', "pages.php?page={$page}");
236
    $form->addElement(new XoopsFormSelectUser('user', 'uid', true, $wikiPage->uid));
237
    $form->addElement(new XoopsFormDateTime(_MD_GWIKI_LASTMODIFIED, 'lastmodified', $size = 15, $wikiPage->lastmodified));
238
    $form->addElement(new XoopsFormHidden('op', 'toolupdate'));
239
    $form->addElement(new XoopsFormHidden('page', $page));
240
    $form->addElement(new XoopsFormHidden('id', $id));
241
    $form->addElement(new XoopsFormButton('', 'submit', _SUBMIT, 'submit'));
242
    //$form->addElement(new XoopsFormText(_MD_GWIKI_TITLE, "title", 40, 250, $title));
243
    //$form->addElement(new XoopsFormTextArea(_MD_GWIKI_BODY, 'body', $body, 20, 80));
244
    //$var_name = strtotime($var_name['date']) + $var_name['time'];
245
246
    adminTableStart(_AD_GWIKI_PAGETOOLS, 1);
247
    echo '<tr><td width="100%" >';
248
    echo '<div style="width: 94%; margin: 2em;">';
249
    echo '<p style="padding-bottom: 2px; border-bottom: 1px solid #000000;">' . _MD_GWIKI_PAGE . ": <strong>{$page}</strong> - " . _MD_GWIKI_LASTMODIFIED . ' <i>'
250
         . date($xoopsModuleConfig['date_format'], $wikiPage->lastmodified) . '</i> ' . _MD_GWIKI_BY . ' <i>' . $wikiPage->getUserName($wikiPage->uid) . '</i></p>';
251
    echo $form->render();
252
    echo '<br><div id="wikipage" style="height: 120px; overflow: auto;" ><h1 class="wikititle" id="toc0">' . htmlspecialchars($wikiPage->title) . '</h1>';
253
    echo $wikiPage->renderPage();
254
    echo '</div>';
255
256
    echo '</div>';
257
    echo '</td></tr>';
258
    adminTableEnd(array(
259
                      _BACK             => "pages.php?page={$page}&op=history",
260
                      _AD_GWIKI_RESTORE => "javascript:restoreRevision('{$id}');",
261
                      _AD_GWIKI_FIX     => "pages.php?page={$page}&op=fix&id={$id}"
262
                  ));
263
}
264
265
/**
266
 * @param $page
267
 * @param $id
268
 *
269
 * @return mixed
270
 */
271
function pageToolUpdate($page, $id)
272
{
273
    global $xoopsDB;
274
275
    if (isset($_POST['uid'])) {
276
        $uid = (int)$_POST['uid'];
277
    }
278
    if (isset($_POST['lastmodified'])) {
279
        $modified = $_POST['lastmodified'];
280
    }
281
    if (empty($uid) || empty($modified)) {
282
        return false;
283
    }
284
    $lastmodified = strtotime($modified['date']) + $modified['time'];
285
    //print_r($modified);
286
    $sql    = 'UPDATE ' . $xoopsDB->prefix('gwiki_pages') . " SET uid = {$uid}, lastmodified = {$lastmodified}  WHERE keyword='{$page}' AND gwiki_id='{$id}'";
287
    $result = $xoopsDB->query($sql);
288
289
    return $result;
290
}
291
292
/**
293
 * @param        $action
294
 * @param string $keyword
295
 * @param        $id
296
 */
297
function confirmAction($action, $keyword = '', $id = -1)
298
{
299
    adminTableStart(_AD_GWIKI_CONFIRM, 1);
300
    echo '<tr><td width="100%" >';
301
    echo '<div class="confirmMsg">';
302
    echo '<form method="post" action="pages.php">';
303
304
    switch ($action) {
305
        case 'clean':
306
            echo '<input type="hidden" name="op" value="cleanit" />';
307
            $confMsg = _AD_GWIKI_CONFIRM_CLEAN;
308
            break;
309
        case 'delete':
310
            echo '<input type="hidden" name="page" value="' . $keyword . '" />';
311
            echo '<input type="hidden" id="op" name="op" value="deleteit" />';
312
            $confMsg = sprintf(_AD_GWIKI_CONFIRM_DEL, $keyword);
313
            break;
314
        case 'fix':
315
            echo '<input type="hidden" name="page" value="' . $keyword . '" />';
316
            echo '<input type="hidden" id="id" name="id" value="' . $id . '" />
317
                <input type="hidden" id="op" name="op" value="fixit" />';
318
            $confMsg = sprintf(_AD_GWIKI_CONFIRM_FIX, $keyword);
319
            break;
320
        case 'lock':
321
            echo '<input type="hidden" name="page" value="' . $keyword . '" />';
322
            echo '<input type="hidden" id="op" name="op" value="lockit" />';
323
            $confMsg = sprintf(_AD_GWIKI_CONFIRM_LOCK, $keyword);
324
            break;
325
        case 'unlock':
326
            echo '<input type="hidden" name="page" value="' . $keyword . '" />';
327
            echo '<input type="hidden" id="op" name="op" value="unlockit" />';
328
            $confMsg = sprintf(_AD_GWIKI_CONFIRM_UNLOCK, $keyword);
329
            break;
330
        case 'partition':
331
            //          echo '<input type="hidden" name="page" value="'.$keyword.'" />';
332
            echo '<input type="hidden" id="op" name="op" value="partitionit" />';
333
            $confMsg = _AD_GWIKI_CONFIRM_PARTITION;
334
            break;
335
        case 'addhelp':
336
            //          echo '<input type="hidden" name="page" value="'.$keyword.'" />';
337
            echo '<input type="hidden" id="op" name="op" value="addhelpit" />';
338
            $confMsg = _AD_GWIKI_CONFIRM_ADD_HELP;
339
            break;
340
    }
341
342
    echo '<p align="center">' . $confMsg . '<br><br>
0 ignored issues
show
The variable $confMsg 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...
343
        <input type="submit" value="' . _YES . '">
344
        <input type="button" onclick="history.back();" value="' . _NO . '"></p></form></div>';
345
    echo '</td></tr>';
346
    adminTableEnd(array(_BACK => 'pages.php?op=manage'));
347
}
348
349
/**
350
 * @param $page
351
 * @param $id
352
 *
353
 * @return mixed
354
 */
355
function getRevision($page, $id)
356
{
357
    global $xoopsDB;
358
359
    $sql    = 'SELECT title, body, lastmodified, uid FROM ' . $xoopsDB->prefix('gwiki_pages') . " WHERE gwiki_id='{$id}' AND keyword='{$page}'";
360
    $result = $xoopsDB->query($sql);
361
362
    return $xoopsDB->fetchRow($result);
363
}
364
365
/**
366
 * @param $page
367
 * @param $id
368
 *
369
 * @return mixed
370
 */
371
function fixRevision($page, $id)
372
{
373
    global $xoopsDB, $wikiPage;
374
375
    $result = $wikiPage->setRevision($page, $id);
376
    if ($result) {
377
        $sql    = 'DELETE FROM ' . $xoopsDB->prefix('gwiki_pages') . " WHERE keyword='{$page}' AND active=0 ";
378
        $result = $xoopsDB->query($sql);
379
    }
380
381
    return $result;
382
}
383
384
/**
385
 * @return bool
386
 */
387
function checkForPartitions()
388
{
389
    global $xoopsDB;
390
391
    $sql        = 'SELECT PARTITION_NAME FROM INFORMATION_SCHEMA.PARTITIONS WHERE TABLE_SCHEMA = \'' . XOOPS_DB_NAME . '\' AND TABLE_NAME  = \'' . $xoopsDB->prefix('gwiki_pages') . '\'';
392
    $result     = $xoopsDB->query($sql);
393
    $partitions = $xoopsDB->getRowsNum($result);
394
395
    return $partitions > 1;
396
}
397
398
/**
399
 * @return string
400
 */
401
function createPartitions()
402
{
403
    global $xoopsDB;
404
405
    if (checkForPartitions()) {
406
        $message = _AD_GWIKI_PARTITION_ALREADY;
407
    } else {
408
        $tablename = $xoopsDB->prefix('gwiki_pages');
409
        $sql       = 'ALTER TABLE ' . $tablename . ' PARTITION BY LIST (active) ';
410
        $sql .= '(PARTITION ' . $tablename . '_inactive VALUES IN (0), ';
411
        $sql .= ' PARTITION ' . $tablename . '_active VALUES IN (1) )';
412
        $result  = $xoopsDB->query($sql);
413
        $message = _AD_GWIKI_PARTITION_FAILED;
414
        if ($result) {
415
            $message = _AD_GWIKI_PARTITION_OK;
416
        }
417
    }
418
419
    return $message;
420
}
421
422
/**
423
 * @return string
424
 */
425
function createHelpPages()
426
{
427
    // make any existing help pages inactive
428
    $criteria = new Criteria('page_set_home', 'Help:Index', '=');
429
    if (0 < TableLoad::countRows('gwiki_pages', $criteria)) {
430
        $migrate = new Tables();
431
        $values = array('active' => '0');
432
        $migrate->useTable('gwiki_pages');
433
        $migrate->update('gwiki_pages', $values, $criteria);
434
        $migrate->executeQueue(true);
435
    }
436
437
    // delete help: to help: page links
438
    $criteria = new CriteriaCompo(new Criteria('from_keyword', 'help:%', 'LIKE'));
439
    $criteria->add(new Criteria('to_keyword', 'help:%', 'LIKE'), 'AND');
440
    if (0 < TableLoad::countRows('gwiki_pagelinks', $criteria)) {
441
        $migrate = new Tables();
442
        $migrate->useTable('gwiki_pagelinks');
443
        $migrate->delete('gwiki_pagelinks', $criteria);
444
        $migrate->executeQueue(true);
445
    }
446
447
    // load fresh help pages
448
    $result = TableLoad::loadTableFromYamlFile('gwiki_pages', '../sql/helppages.yml');
449
    $message = _AD_GWIKI_ADD_HELP_FAILED;
450
    if ($result) {
451
        $result = TableLoad::loadTableFromYamlFile('gwiki_pagelinks', '../sql/helplinks.yml');
452
        if ($result) {
453
            $message = _AD_GWIKI_ADD_HELP_OK;
454
        }
455
    }
456
457
    // make sure the new help pages have an entry in pageids (for comments, notifications, etc)
458
    $criteria = new CriteriaCompo(new Criteria('page_set_home', 'Help:Index', '='));
459
    $criteria->add(new Criteria('active', '1', '='), 'AND');
460
    $rows = TableLoad::extractRows('gwiki_pages', $criteria, array('body', 'search_body', 'toc_cache'));
461
    $insertRows = array();
462
    $time = time();
463
    foreach ($rows as $row) {
464
        $insertRows[] = array('keyword' => $row['keyword'], 'created' => $time, 'hit_count' => '0');
465
    }
466
    TableLoad::loadTableFromArray('gwiki_pageids', $insertRows);
467
468
    return $message;
469
}
470
471
/**
472
 * @param $page
473
 */
474
function allowRestoration($page)
475
{
476
    echo '<script type="text/javascript">
477
    <!--
478
        function restoreRevision(id)
479
        {
480
            document.restore.id.value = id;
481
            document.restore.submit();
482
        }
483
    // -->
484
    </script>
485
    <form id="restore" name="restore" action="pages.php" method="post">
486
    <input type="hidden" id="op" name="op" value="restore" />
487
    <input type="hidden" id="page" name="page" value="' . $page . '" />
488
    <input type="hidden" id="id" name="id" value="" />
489
    </form>';
490
}
491
492
// page, op, id
493
$page = Request::getString('page', '', 'GET');
494
$op = Request::getCmd('op', '', 'GET');
495
496
// $_POST variables we use
497
$op = Request::getCmd('op', $op, 'POST');
498
$page = Request::getString('page', $page, 'POST');
499
$id = Request::getInt('id', 0, 'POST');
500
501
switch ($op) {
502
    case 'history':
503
        showHistory($page);
504
        break;
505
506
    case 'display':
507
        $id = Request::getInt('id', null, 'GET');
508
        showPage($page, $id);
509
        break;
510
511 View Code Duplication
    case 'restore':
0 ignored issues
show
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
512
        $success = $wikiPage->setRevision($page, $id);
513
        redirect_header('pages.php?page=' . $page . '&op=history', 2, $success ? _MD_GWIKI_DBUPDATED : _MD_GWIKI_ERRORINSERT);
514
        break;
515
516
    case 'fix':
517
        confirmAction('fix', $page, Request::getInt('id', 0, 'GET'));
518
        break;
519
520 View Code Duplication
    case 'fixit':
0 ignored issues
show
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
521
        $success = fixRevision($page, $id);
522
        redirect_header('pages.php?page=' . $page . '&op=history', 2, $success ? _MD_GWIKI_DBUPDATED : _MD_GWIKI_ERRORINSERT);
523
        break;
524
525
    case 'tool':
526
        showPageTool($page, Request::getInt('id', 0, 'GET'));
527
        break;
528
529
    case 'toolupdate':
530
        $success = pageToolUpdate($page, $id);
531
        $message = $success ? _MD_GWIKI_DBUPDATED : _MD_GWIKI_ERRORINSERT;
532
        $op      = '';
533
        showPages($message);
534
        break;
535
536
    case 'delete':
537
        confirmAction('delete', $page);
538
        break;
539
540 View Code Duplication
    case 'deleteit':
0 ignored issues
show
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
541
        //  mark all versions inactive -- these will disappear as they age and the database is cleaned
542
        $sql = 'UPDATE ' . $xoopsDB->prefix('gwiki_pages') . " SET active = 0 WHERE keyword='{$page}' ";
543
544
        $success = $xoopsDB->query($sql);
545
        redirect_header('pages.php?op=manage', 2, $success ? _MD_GWIKI_DBUPDATED : _MD_GWIKI_ERRORINSERT);
546
        break;
547
548
    case 'clean':
549
        confirmAction('clean');
550
        break;
551
552
    case 'cleanit':
553
        // delete inactive pages older than config option retain_days
554
        $retaindays = (int)$xoopsModuleConfig['retain_days'];
555
        if ($retaindays > 0) {
556
            $dir    = basename(dirname(__DIR__));
557
            $url    = XOOPS_URL . '/modules/' . $dir . '/cleanit.php';
558
            $params = array('check' => $retaindays);
559
            post_clean_request($url, $params);
560
            $message = _MD_GWIKI_CLEAN_STARTED;
561
        } else {
562
            $message = _MD_GWIKI_CLEAN_DISABLED;
563
        }
564
        $op = '';
565
        showPages($message);
566
        break;
567
568
    case 'lock':
569
        confirmAction('lock', $page);
570
        break;
571
572 View Code Duplication
    case 'lockit':
0 ignored issues
show
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
573
        $sql = 'UPDATE ' . $xoopsDB->prefix('gwiki_pages') . " SET admin_lock = 1 WHERE keyword='{$page}' ";
574
575
        $success = $xoopsDB->query($sql);
576
        redirect_header('pages.php?op=manage', 2, $success ? _MD_GWIKI_DBUPDATED : _MD_GWIKI_ERRORINSERT);
577
        break;
578
579
    case 'unlock':
580
        confirmAction('unlock', $page);
581
        break;
582
583 View Code Duplication
    case 'unlockit':
0 ignored issues
show
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
584
        $sql = 'UPDATE ' . $xoopsDB->prefix('gwiki_pages') . " SET admin_lock = 0 WHERE keyword='{$page}' ";
585
586
        $success = $xoopsDB->query($sql);
587
        redirect_header('pages.php?op=manage', 2, $success ? _MD_GWIKI_DBUPDATED : _MD_GWIKI_ERRORINSERT);
588
        break;
589
590
    case 'partition':
591
        if (checkForPartitions()) {
592
            showPages(_AD_GWIKI_PARTITION_ALREADY);
593
        } else {
594
            confirmAction('partition', '');
595
        }
596
        break;
597
598
    case 'partitionit':
599
        $message = createPartitions();
600
        showPages($message);
601
        break;
602
603
    case 'addhelp':
604
        confirmAction('addhelp', '');
605
        break;
606
607
    case 'addhelpit':
608
        $message = createHelpPages();
609
        showPages($message);
610
        break;
611
612
    case 'manage':
613
    default:
614
        showPages();
615
        break;
616
617
}
618
619
include __DIR__ . '/footer.php';
620