Completed
Push — develop ( 5cb106...80f130 )
by Dmytro
13:36
created

processors.php ➔ saveManagerUserSettings()   C

Complexity

Conditions 15
Paths 45

Size

Total Lines 84

Duplication

Lines 13
Ratio 15.48 %

Importance

Changes 0
Metric Value
cc 15
nc 45
nop 1
dl 13
loc 84
rs 5.0824
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
if (!function_exists('getChildrenForDelete')) {
4
    /**
5
     * @param int $parent
6
     */
7
    function getChildrenForDelete($parent)
8
    {
9
        $modx = evolutionCMS();
10
        global $children;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
11
        global $site_start;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
12
        global $site_unavailable_page;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
13
        global $error_page;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
14
        global $unauthorized_page;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
15
16
        $parent = $modx->getDatabase()->escape($parent);
17
        $rs = $modx->getDatabase()->select('id', $modx->getDatabase()->getFullTableName('site_content'), "parent={$parent} AND deleted=0");
0 ignored issues
show
Comprehensibility introduced by
Avoid variables with short names like $rs. Configured minimum length is 3.

Short variable names may make your code harder to understand. Variable names should be self-descriptive. This check looks for variable names who are shorter than a configured minimum.

Loading history...
18
        // the document has children documents, we'll need to delete those too
19
        while ($childid = $modx->getDatabase()->getValue($rs)) {
0 ignored issues
show
Bug introduced by
It seems like $rs defined by $modx->getDatabase()->se...parent} AND deleted=0") on line 17 can also be of type boolean; however, EvolutionCMS\Database::getValue() does only seem to accept object<mysqli_result>|string, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
20
            if ($childid == $site_start) {
21
                $modx->webAlertAndQuit("The document you are trying to delete is a folder containing document {$childid}. This document is registered as the 'Site start' document, and cannot be deleted. Please assign another document as your 'Site start' document and try again.");
22
            }
23
            if ($childid == $site_unavailable_page) {
24
                $modx->webAlertAndQuit("The document you are trying to delete is a folder containing document {$childid}. This document is registered as the 'Site unavailable page' document, and cannot be deleted. Please assign another document as your 'Site unavailable page' document and try again.");
25
            }
26
            if ($childid == $error_page) {
27
                $modx->webAlertAndQuit("The document you are trying to delete is a folder containing document {$childid}. This document is registered as the 'Site error page' document, and cannot be deleted. Please assign another document as your 'Site error page' document and try again.");
28
            }
29
            if ($childid == $unauthorized_page) {
30
                $modx->webAlertAndQuit("The document you are trying to delete is a folder containing document {$childid}. This document is registered as the 'Site unauthorized page' document, and cannot be deleted. Please assign another document as your 'Site unauthorized page' document and try again.");
31
            }
32
            $children[] = $childid;
33
            getChildrenForDelete($childid);
34
            //echo "Found childNode of parentNode $parent: ".$childid."<br />";
0 ignored issues
show
Unused Code Comprehensibility introduced by
63% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
35
        }
36
    }
37
}
38
39
if(!function_exists('duplicateDocument')) {
40
    /**
41
     * @param int $docid
42
     * @param null|int $parent
43
     * @param int $_toplevel
44
     * @return int
45
     */
46
    function duplicateDocument($docid, $parent = null, $_toplevel = 0)
47
    {
48
        $modx = evolutionCMS();
49
        global $_lang;
50
51
        // invoke OnBeforeDocDuplicate event
52
        $evtOut = $modx->invokeEvent('OnBeforeDocDuplicate', array(
0 ignored issues
show
Unused Code introduced by
$evtOut is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
53
            'id' => $docid
54
        ));
55
56
        // if( !in_array( 'false', array_values( $evtOut ) ) ){}
0 ignored issues
show
Unused Code Comprehensibility introduced by
57% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
57
        // TODO: Determine necessary handling for duplicateDocument "return $newparent" if OnBeforeDocDuplicate were able to conditially control duplication
0 ignored issues
show
Coding Style Best Practice introduced by
Comments for TODO tasks are often forgotten in the code; it might be better to use a dedicated issue tracker.
Loading history...
58
        // [DISABLED]: Proceed with duplicateDocument if OnBeforeDocDuplicate did not return false via: $event->output('false');
0 ignored issues
show
Unused Code Comprehensibility introduced by
37% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
59
60
        $userID = $modx->getLoginUserID();
61
62
        $tblsc = $modx->getDatabase()->getFullTableName('site_content');
63
64
        // Grab the original document
65
        $rs = $modx->getDatabase()->select('*', $tblsc, "id='{$docid}'");
0 ignored issues
show
Comprehensibility introduced by
Avoid variables with short names like $rs. Configured minimum length is 3.

Short variable names may make your code harder to understand. Variable names should be self-descriptive. This check looks for variable names who are shorter than a configured minimum.

Loading history...
66
        $content = $modx->getDatabase()->getRow($rs);
0 ignored issues
show
Bug introduced by
It seems like $rs defined by $modx->getDatabase()->se...tblsc, "id='{$docid}'") on line 65 can also be of type boolean; however, EvolutionCMS\Database::getRow() does only seem to accept object<mysqli_result>, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
67
68
        // Handle incremental ID
69
        switch ($modx->config['docid_incrmnt_method']) {
70 View Code Duplication
            case '1':
71
                $from = "{$tblsc} AS T0 LEFT JOIN {$tblsc} AS T1 ON T0.id + 1 = T1.id";
72
                $rs = $modx->getDatabase()->select('MIN(T0.id)+1', $from, "T1.id IS NULL");
73
                $content['id'] = $modx->getDatabase()->getValue($rs);
0 ignored issues
show
Bug introduced by
It seems like $rs defined by $modx->getDatabase()->se...$from, 'T1.id IS NULL') on line 72 can also be of type boolean; however, EvolutionCMS\Database::getValue() does only seem to accept object<mysqli_result>|string, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
74
                break;
75
            case '2':
76
                $rs = $modx->getDatabase()->select('MAX(id)+1', $tblsc);
77
                $content['id'] = $modx->getDatabase()->getValue($rs);
0 ignored issues
show
Bug introduced by
It seems like $rs defined by $modx->getDatabase()->select('MAX(id)+1', $tblsc) on line 76 can also be of type boolean; however, EvolutionCMS\Database::getValue() does only seem to accept object<mysqli_result>|string, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
78
                break;
79
80
            default:
81
                unset($content['id']); // remove the current id.
82
        }
83
84
        // Once we've grabbed the document object, start doing some modifications
85
        if ($_toplevel == 0) {
86
            // count duplicates
87
            $pagetitle = $modx->getDatabase()->getValue($modx->getDatabase()->select('pagetitle', $modx->getDatabase()->getFullTableName('site_content'),
0 ignored issues
show
Bug introduced by
It seems like $modx->getDatabase()->se...ent'), "id='{$docid}'") targeting EvolutionCMS\Database::select() can also be of type boolean; however, EvolutionCMS\Database::getValue() does only seem to accept object<mysqli_result>|string, maybe add an additional type check?

This check looks at variables that are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
88
                "id='{$docid}'"));
89
            $pagetitle = $modx->getDatabase()->escape($pagetitle);
90
            $count = $modx->getDatabase()->getRecordCount($modx->getDatabase()->select('pagetitle', $modx->getDatabase()->getFullTableName('site_content'),
0 ignored issues
show
Bug introduced by
It seems like $modx->getDatabase()->se...agetitle} Duplicate%'") targeting EvolutionCMS\Database::select() can also be of type boolean; however, EvolutionCMS\Database::getRecordCount() does only seem to accept object<mysqli_result>, maybe add an additional type check?

This check looks at variables that are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
91
                "pagetitle LIKE '{$pagetitle} Duplicate%'"));
92
            if ($count >= 1) {
93
                $count = ' ' . ($count + 1);
94
            } else {
95
                $count = '';
96
            }
97
98
            $content['pagetitle'] = $_lang['duplicated_el_suffix'] . $count . ' ' . $content['pagetitle'];
99
            $content['alias'] = null;
100
        } elseif ($modx->config['friendly_urls'] == 0 || $modx->config['allow_duplicate_alias'] == 0) {
101
            $content['alias'] = null;
102
        }
103
104
        // change the parent accordingly
105
        if ($parent !== null) {
106
            $content['parent'] = $parent;
107
        }
108
109
        // Change the author
110
        $content['createdby'] = $userID;
111
        $content['createdon'] = time();
112
        // Remove other modification times
113
        $content['editedby'] = $content['editedon'] = $content['deleted'] = $content['deletedby'] = $content['deletedon'] = 0;
114
115
        // [FS#922] Should the published status be honored? - sirlancelot
0 ignored issues
show
Unused Code Comprehensibility introduced by
58% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
116
//	if ($modx->hasPermission('publish_document')) {
117
//		if ($modx->config['publish_default'])
118
//			$content['pub_date'] = $content['pub_date']; // should this be changed to 1?
119
//		else	$content['pub_date'] = 0;
120
//	} else {
121
        // User can't publish documents
122
//		$content['published'] = $content['pub_date'] = 0;
123
//	}
124
125
        // Set the published status to unpublished by default (see above ... commit #3388)
126
        $content['published'] = $content['pub_date'] = 0;
127
128
        // Escape the proper strings
129
        $content = $modx->getDatabase()->escape($content);
130
131
        // Duplicate the Document
132
        $newparent = $modx->getDatabase()->insert($content, $tblsc);
133
134
        // duplicate document's TVs
135
        duplicateTVs($docid, $newparent);
136
        duplicateAccess($docid, $newparent);
137
138
        // invoke OnDocDuplicate event
139
        $evtOut = $modx->invokeEvent('OnDocDuplicate', array(
0 ignored issues
show
Unused Code introduced by
$evtOut is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
140
            'id'     => $docid,
141
            'new_id' => $newparent
142
        ));
143
144
        // Start duplicating all the child documents that aren't deleted.
145
        $_toplevel++;
146
        $rs = $modx->getDatabase()->select('id', $tblsc, "parent='{$docid}' AND deleted=0", 'id ASC');
147
        while ($row = $modx->getDatabase()->getRow($rs)) {
0 ignored issues
show
Bug introduced by
It seems like $rs defined by $modx->getDatabase()->se...D deleted=0", 'id ASC') on line 146 can also be of type boolean; however, EvolutionCMS\Database::getRow() does only seem to accept object<mysqli_result>, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
148
            duplicateDocument($row['id'], $newparent, $_toplevel);
149
        }
150
151
        // return the new doc id
152
        return $newparent;
153
    }
154
}
155
156 View Code Duplication
if(!function_exists('duplicateTVs')) {
157
    /**
158
     * Duplicate Document TVs
159
     *
160
     * @param int $oldid
161
     * @param int $newid
162
     */
163
    function duplicateTVs($oldid, $newid)
164
    {
165
        $modx = evolutionCMS();
166
167
        $tbltvc = $modx->getDatabase()->getFullTableName('site_tmplvar_contentvalues');
168
169
        $newid = (int)$newid;
170
        $oldid = (int)$oldid;
171
172
        $modx->getDatabase()->insert(
173
            array('contentid' => '', 'tmplvarid' => '', 'value' => ''), $tbltvc, // Insert into
174
            "{$newid}, tmplvarid, value", $tbltvc, "contentid='{$oldid}'" // Copy from
175
        );
176
    }
177
}
178
179 View Code Duplication
if(!function_exists('duplicateAccess')) {
180
    /**
181
     * Duplicate Document Access Permissions
182
     *
183
     * @param int $oldid
184
     * @param int $newid
185
     */
186
    function duplicateAccess($oldid, $newid)
187
    {
188
        $modx = evolutionCMS();
189
190
        $tbldg = $modx->getDatabase()->getFullTableName('document_groups');
191
192
        $newid = (int)$newid;
193
        $oldid = (int)$oldid;
194
195
        $modx->getDatabase()->insert(
196
            array('document' => '', 'document_group' => ''), $tbldg, // Insert into
197
            "{$newid}, document_group", $tbldg, "document='{$oldid}'" // Copy from
198
        );
199
    }
200
}
201
202
if(!function_exists('evalModule')) {
203
    /**
204
     * evalModule
205
     *
206
     * @param string $moduleCode
207
     * @param array $params
208
     * @return string
209
     */
210
    function evalModule($moduleCode, $params)
0 ignored issues
show
Coding Style introduced by
evalModule uses the super-global variable $_SESSION which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
211
    {
212
        $modx = evolutionCMS();
213
        $modx->event->params = &$params; // store params inside event object
214
        if (is_array($params)) {
215
            extract($params, EXTR_SKIP);
216
        }
217
        ob_start();
218
        $mod = eval($moduleCode);
0 ignored issues
show
Coding Style introduced by
The function evalModule() contains an eval expression.

On one hand, eval might be exploited by malicious users if they somehow manage to inject dynamic content. On the other hand, with the emergence of faster PHP runtimes like the HHVM, eval prevents some optimization that they perform.

Loading history...
219
        $msg = ob_get_contents();
220
        ob_end_clean();
221
        if (isset($php_errormsg)) {
222
            $error_info = error_get_last();
223 View Code Duplication
            switch ($error_info['type']) {
224
                case E_NOTICE :
0 ignored issues
show
Coding Style introduced by
There must be no space before the colon in a CASE statement

As per the PSR-2 coding standard, there must not be a space in front of the colon in case statements.

switch ($selector) {
    case "A": //right
        doSomething();
        break;
    case "B" : //wrong
        doSomethingElse();
        break;
}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
Coding Style introduced by
There must be a comment when fall-through is intentional in a non-empty case body
Loading history...
225
                    $error_level = 1;
226
                case E_USER_NOTICE :
0 ignored issues
show
Coding Style introduced by
There must be no space before the colon in a CASE statement

As per the PSR-2 coding standard, there must not be a space in front of the colon in case statements.

switch ($selector) {
    case "A": //right
        doSomething();
        break;
    case "B" : //wrong
        doSomethingElse();
        break;
}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
227
                    break;
228
                case E_DEPRECATED :
0 ignored issues
show
Coding Style introduced by
There must be no space before the colon in a CASE statement

As per the PSR-2 coding standard, there must not be a space in front of the colon in case statements.

switch ($selector) {
    case "A": //right
        doSomething();
        break;
    case "B" : //wrong
        doSomethingElse();
        break;
}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
229
                case E_USER_DEPRECATED :
0 ignored issues
show
Coding Style introduced by
There must be no space before the colon in a CASE statement

As per the PSR-2 coding standard, there must not be a space in front of the colon in case statements.

switch ($selector) {
    case "A": //right
        doSomething();
        break;
    case "B" : //wrong
        doSomethingElse();
        break;
}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
230
                case E_STRICT :
0 ignored issues
show
Coding Style introduced by
There must be no space before the colon in a CASE statement

As per the PSR-2 coding standard, there must not be a space in front of the colon in case statements.

switch ($selector) {
    case "A": //right
        doSomething();
        break;
    case "B" : //wrong
        doSomethingElse();
        break;
}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
231
                    $error_level = 2;
232
                    break;
233
                default:
234
                    $error_level = 99;
235
            }
236
            if ($modx->config['error_reporting'] === '99' || 2 < $error_level) {
237
                $modx->messageQuit('PHP Parse Error', '', true, $error_info['type'], $error_info['file'],
238
                    $_SESSION['itemname'] . ' - Module', $error_info['message'], $error_info['line'], $msg);
239
                $modx->event->alert("An error occurred while loading. Please see the event log for more information<p>{$msg}</p>");
240
            }
241
        }
242
        unset($modx->event->params);
243
244
        return $mod . $msg;
245
    }
246
}
247
248
if(!function_exists('allChildren')) {
249
    /**
250
     * @param int $currDocID
251
     * @return array
252
     */
253
    function allChildren($currDocID)
254
    {
255
        $modx = evolutionCMS();
256
        $children = array();
257
        $currDocID = $modx->getDatabase()->escape($currDocID);
258
        $rs = $modx->getDatabase()->select('id', $modx->getDatabase()->getFullTableName('site_content'), "parent = '{$currDocID}'");
0 ignored issues
show
Comprehensibility introduced by
Avoid variables with short names like $rs. Configured minimum length is 3.

Short variable names may make your code harder to understand. Variable names should be self-descriptive. This check looks for variable names who are shorter than a configured minimum.

Loading history...
259
        while ($child = $modx->getDatabase()->getRow($rs)) {
0 ignored issues
show
Bug introduced by
It seems like $rs defined by $modx->getDatabase()->se...rent = '{$currDocID}'") on line 258 can also be of type boolean; however, EvolutionCMS\Database::getRow() does only seem to accept object<mysqli_result>, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
260
            $children[] = $child['id'];
261
            $children = array_merge($children, allChildren($child['id']));
262
        }
263
264
        return $children;
265
    }
266
}
267
268
if(!function_exists('jsAlert')) {
269
    /**
270
     * show javascript alert
271
     *
272
     * @param string $msg
273
     */
274
    function jsAlert($msg)
0 ignored issues
show
Coding Style introduced by
jsAlert uses the super-global variable $_POST which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
275
    {
276
        $modx = evolutionCMS();
277
        if ($_POST['ajax'] != 1) {
278
            echo "<script>window.setTimeout(\"alert('" . addslashes($modx->getDatabase()->escape($msg)) . "')\",10);history.go(-1)</script>";
279
        } else {
280
            echo $msg . "\n";
281
        }
282
    }
283
}
284
285
if(!function_exists('login')) {
286
    /**
287
     * @param string $username
288
     * @param string $givenPassword
289
     * @param string $dbasePassword
290
     * @return bool
291
     */
292
    function login($username, $givenPassword, $dbasePassword)
0 ignored issues
show
Unused Code introduced by
The parameter $username is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
293
    {
294
        $modx = evolutionCMS();
295
296
        return $modx->getPasswordHash()->CheckPassword($givenPassword, $dbasePassword);
297
    }
298
}
299
300
if(!function_exists('loginV1')) {
301
    /**
302
     * @param int $internalKey
303
     * @param string $givenPassword
304
     * @param string $dbasePassword
305
     * @param string $username
306
     * @return bool
307
     */
308
    function loginV1($internalKey, $givenPassword, $dbasePassword, $username)
309
    {
310
        $modx = evolutionCMS();
311
312
        $user_algo = $modx->getManagerApi()->getV1UserHashAlgorithm($internalKey);
313
314 View Code Duplication
        if (!isset($modx->config['pwd_hash_algo']) || empty($modx->config['pwd_hash_algo'])) {
315
            $modx->config['pwd_hash_algo'] = 'UNCRYPT';
316
        }
317
318
        if ($user_algo !== $modx->config['pwd_hash_algo']) {
319
            $bk_pwd_hash_algo = $modx->config['pwd_hash_algo'];
0 ignored issues
show
Unused Code introduced by
$bk_pwd_hash_algo is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
320
            $modx->config['pwd_hash_algo'] = $user_algo;
321
        }
322
323
        if ($dbasePassword != $modx->getManagerApi()->genV1Hash($givenPassword, $internalKey)) {
324
            return false;
325
        }
326
327
        updateNewHash($username, $givenPassword);
328
329
        return true;
330
    }
331
}
332
333
if(!function_exists('loginMD5')) {
334
    /**
335
     * @param int $internalKey
336
     * @param string $givenPassword
337
     * @param string $dbasePassword
338
     * @param string $username
339
     * @return bool
340
     */
341
    function loginMD5($internalKey, $givenPassword, $dbasePassword, $username)
0 ignored issues
show
Unused Code introduced by
The parameter $internalKey is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
342
    {
343
        $modx = evolutionCMS();
0 ignored issues
show
Unused Code introduced by
$modx is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
344
345
        if ($dbasePassword != md5($givenPassword)) {
346
            return false;
347
        }
348
        updateNewHash($username, $givenPassword);
349
350
        return true;
351
    }
352
}
353
354 View Code Duplication
if(!function_exists('updateNewHash')) {
355
    /**
356
     * @param string $username
357
     * @param string $password
358
     */
359
    function updateNewHash($username, $password)
360
    {
361
        $modx = evolutionCMS();
362
363
        $field = array();
364
        $field['password'] = $modx->getPasswordHash()->HashPassword($password);
365
        $modx->getDatabase()->update(
366
            $field,
367
            $modx->getDatabase()->getFullTableName('manager_users'),
368
            "username='{$username}'"
369
        );
370
    }
371
}
372
373
if(!function_exists('incrementFailedLoginCount')) {
374
    /**
375
     * @param int $internalKey
376
     * @param int $failedlogins
377
     * @param int $failed_allowed
378
     * @param int $blocked_minutes
379
     */
380
    function incrementFailedLoginCount($internalKey, $failedlogins, $failed_allowed, $blocked_minutes)
381
    {
382
        $modx = evolutionCMS();
383
384
        $failedlogins += 1;
0 ignored issues
show
Coding Style introduced by
Increment operators should be used where possible; found "$failedlogins += 1;" but expected "$failedlogins++"
Loading history...
385
386
        $fields = array('failedlogincount' => $failedlogins);
387
        if ($failedlogins >= $failed_allowed) //block user for too many fail attempts
388
        {
389
            $fields['blockeduntil'] = time() + ($blocked_minutes * 60);
390
        }
391
392
        $modx->getDatabase()->update(
393
            $fields,
394
            $modx->getDatabase()->getFullTableName('user_attributes'),
395
            "internalKey='{$internalKey}'"
396
        );
397
398
        if ($failedlogins < $failed_allowed) {
399
            //sleep to help prevent brute force attacks
400
            $sleep = (int)$failedlogins / 2;
401
            if ($sleep > 5) {
402
                $sleep = 5;
403
            }
404
            sleep($sleep);
405
        }
406
        @session_destroy();
407
        session_unset();
408
409
        return;
410
    }
411
}
412
413
if(!function_exists('saveUserGroupAccessPermissons')) {
414
    /**
415
     * saves module user group access
416
     */
417
    function saveUserGroupAccessPermissons()
0 ignored issues
show
Coding Style introduced by
saveUserGroupAccessPermissons uses the super-global variable $_POST which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
418
    {
419
        $modx = evolutionCMS();
420
        global $id, $newid;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
421
        global $use_udperms;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
422
423
        if ($newid) {
424
            $id = $newid;
425
        }
426
        $usrgroups = $_POST['usrgroups'];
427
428
        // check for permission update access
429
        if ($use_udperms == 1) {
430
            // delete old permissions on the module
431
            $modx->getDatabase()->delete($modx->getDatabase()->getFullTableName("site_module_access"), "module='{$id}'");
432
            if (is_array($usrgroups)) {
433
                foreach ($usrgroups as $value) {
434
                    $modx->getDatabase()->insert(array(
435
                        'module'    => $id,
436
                        'usergroup' => stripslashes($value),
437
                    ), $modx->getDatabase()->getFullTableName('site_module_access'));
438
                }
439
            }
440
        }
441
    }
442
}
443
444
if(!function_exists('saveEventListeners')) {
445
# Save Plugin Event Listeners
0 ignored issues
show
Coding Style introduced by
Perl-style comments are not allowed. Use "// Comment." or "/* comment */" instead.
Loading history...
446
    function saveEventListeners($id, $sysevents, $mode)
447
    {
448
        $modx = evolutionCMS();
449
        // save selected system events
450
        $formEventList = array();
451
        foreach ($sysevents as $evtId) {
452
            if (!preg_match('@^[1-9][0-9]*$@', $evtId)) {
453
                $evtId = getEventIdByName($evtId);
454
            }
455
            if ($mode == '101') {
456
                $rs = $modx->getDatabase()->select(
457
                    'max(priority) as priority',
458
                    $modx->getDatabase()->getFullTableName('site_plugin_events'),
459
                    "evtid='{$evtId}'"
460
                );
461
            } else {
462
                $rs = $modx->getDatabase()->select(
463
                    'priority',
464
                    $modx->getDatabase()->getFullTableName('site_plugin_events'),
465
                    "evtid='{$evtId}' and pluginid='{$id}'"
466
                );
467
            }
468
            $prevPriority = $modx->getDatabase()->getValue($rs);
0 ignored issues
show
Bug introduced by
It seems like $rs can also be of type boolean; however, EvolutionCMS\Database::getValue() does only seem to accept object<mysqli_result>|string, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
469
            if ($mode == '101') {
470
                $priority = isset($prevPriority) ? $prevPriority + 1 : 1;
471
            } else {
472
                $priority = isset($prevPriority) ? $prevPriority : 1;
473
            }
474
            $formEventList[] = array('pluginid' => $id, 'evtid' => $evtId, 'priority' => $priority);
475
        }
476
477
        $evtids = array();
478
        foreach ($formEventList as $eventInfo) {
479
            $where = vsprintf("pluginid='%s' AND evtid='%s'", $eventInfo);
480
            $modx->getDatabase()->save(
481
                $eventInfo,
482
                $modx->getDatabase()->getFullTableName('site_plugin_events'),
483
                $where
484
            );
485
            $evtids[] = $eventInfo['evtid'];
486
        }
487
488
        $rs = $modx->getDatabase()->select(
489
            '*',
490
            $modx->getDatabase()->getFullTableName('site_plugin_events'),
491
            sprintf("pluginid='%s'", $id)
492
        );
493
        $dbEventList = array();
0 ignored issues
show
Unused Code introduced by
$dbEventList is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
494
        $del = array();
495
        while ($row = $modx->getDatabase()->getRow($rs)) {
0 ignored issues
show
Bug introduced by
It seems like $rs defined by $modx->getDatabase()->se...pluginid=\'%s\'', $id)) on line 488 can also be of type boolean; however, EvolutionCMS\Database::getRow() does only seem to accept object<mysqli_result>, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
496
            if (!in_array($row['evtid'], $evtids)) {
497
                $del[] = $row['evtid'];
498
            }
499
        }
500
501
        if (empty($del)) {
502
            return;
503
        }
504
505
        foreach ($del as $delid) {
506
            $modx->getDatabase()->delete(
507
                $modx->getDatabase()->getFullTableName('site_plugin_events'),
508
                sprintf("evtid='%s' AND pluginid='%s'", $delid, $id)
509
            );
510
        }
511
    }
512
}
513
514
if(!function_exists('getEventIdByName')) {
515
    /**
516
     * @param string $name
517
     * @return string|int
518
     */
519
    function getEventIdByName($name)
520
    {
521
        $modx = evolutionCMS();
522
        static $eventIds = array();
523
524
        if (isset($eventIds[$name])) {
525
            return $eventIds[$name];
526
        }
527
528
        $rs = $modx->getDatabase()->select(
0 ignored issues
show
Comprehensibility introduced by
Avoid variables with short names like $rs. Configured minimum length is 3.

Short variable names may make your code harder to understand. Variable names should be self-descriptive. This check looks for variable names who are shorter than a configured minimum.

Loading history...
529
            'id, name',
530
            $modx->getDatabase()->getFullTableName('system_eventnames')
531
        );
532
        while ($row = $modx->getDatabase()->getRow($rs)) {
0 ignored issues
show
Bug introduced by
It seems like $rs defined by $modx->getDatabase()->se...e('system_eventnames')) on line 528 can also be of type boolean; however, EvolutionCMS\Database::getRow() does only seem to accept object<mysqli_result>, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
533
            $eventIds[$row['name']] = $row['id'];
534
        }
535
536
        return $eventIds[$name];
537
    }
538
}
539
540
if(!function_exists('saveTemplateAccess')) {
541
    /**
542
     * @param int $id
543
     */
544
    function saveTemplateAccess($id)
0 ignored issues
show
Coding Style introduced by
saveTemplateAccess uses the super-global variable $_POST which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
545
    {
546
        $modx = evolutionCMS();
547
        if ($_POST['tvsDirty'] == 1) {
548
            $newAssignedTvs = $_POST['assignedTv'];
549
550
            // Preserve rankings of already assigned TVs
551
            $rs = $modx->getDatabase()->select("tmplvarid, rank", $modx->getDatabase()->getFullTableName('site_tmplvar_templates'),
0 ignored issues
show
Comprehensibility introduced by
Avoid variables with short names like $rs. Configured minimum length is 3.

Short variable names may make your code harder to understand. Variable names should be self-descriptive. This check looks for variable names who are shorter than a configured minimum.

Loading history...
552
                "templateid='{$id}'", "");
553
554
            $ranksArr = array();
555
            $highest = 0;
556
            while ($row = $modx->getDatabase()->getRow($rs)) {
0 ignored issues
show
Bug introduced by
It seems like $rs defined by $modx->getDatabase()->se...emplateid='{$id}'", '') on line 551 can also be of type boolean; however, EvolutionCMS\Database::getRow() does only seem to accept object<mysqli_result>, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
557
                $ranksArr[$row['tmplvarid']] = $row['rank'];
558
                $highest = $highest < $row['rank'] ? $row['rank'] : $highest;
559
            };
560
561
            $modx->getDatabase()->delete($modx->getDatabase()->getFullTableName('site_tmplvar_templates'), "templateid='{$id}'");
562
            if (empty($newAssignedTvs)) {
563
                return;
564
            }
565
            foreach ($newAssignedTvs as $tvid) {
566
                if (!$id || !$tvid) {
567
                    continue;
568
                }    // Dont link zeros
569
                $modx->getDatabase()->insert(array(
570
                    'templateid' => $id,
571
                    'tmplvarid'  => $tvid,
572
                    'rank'       => isset($ranksArr[$tvid]) ? $ranksArr[$tvid] : $highest += 1 // append TVs to rank
573
                ), $modx->getDatabase()->getFullTableName('site_tmplvar_templates'));
574
            }
575
        }
576
    }
577
}
578
579
if(!function_exists('saveTemplateVarAccess')) {
580
    /**
581
     * @return void
582
     */
583
    function saveTemplateVarAccess()
0 ignored issues
show
Coding Style introduced by
saveTemplateVarAccess uses the super-global variable $_POST which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
584
    {
585
        global $id, $newid;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
586
        $modx = evolutionCMS();
587
588
        if ($newid) {
589
            $id = $newid;
590
        }
591
        $templates = $_POST['template']; // get muli-templates based on S.BRENNAN mod
592
593
        // update template selections
594
        $tbl_site_tmplvar_templates = $modx->getDatabase()->getFullTableName('site_tmplvar_templates');
595
596
        $getRankArray = array();
597
598
        $getRank = $modx->getDatabase()->select("templateid, rank", $tbl_site_tmplvar_templates, "tmplvarid='{$id}'");
599
600
        while ($row = $modx->getDatabase()->getRow($getRank)) {
0 ignored issues
show
Bug introduced by
It seems like $getRank defined by $modx->getDatabase()->se...s, "tmplvarid='{$id}'") on line 598 can also be of type boolean; however, EvolutionCMS\Database::getRow() does only seem to accept object<mysqli_result>, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
601
            $getRankArray[$row['templateid']] = $row['rank'];
602
        }
603
604
        $modx->getDatabase()->delete($tbl_site_tmplvar_templates, "tmplvarid = '{$id}'");
605
        if (!empty($templates)) {
606
            for ($i = 0; $i < count($templates); $i++) {
607
                $setRank = ($getRankArray[$templates[$i]]) ? $getRankArray[$templates[$i]] : 0;
608
                $modx->getDatabase()->insert(array(
609
                    'tmplvarid'  => $id,
610
                    'templateid' => $templates[$i],
611
                    'rank'       => $setRank,
612
                ), $tbl_site_tmplvar_templates);
613
            }
614
        }
615
    }
616
}
617
618
if(!function_exists('saveDocumentAccessPermissons')) {
619
    function saveDocumentAccessPermissons()
0 ignored issues
show
Coding Style introduced by
saveDocumentAccessPermissons uses the super-global variable $_POST which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
620
    {
621
        global $id, $newid;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
622
        $modx = evolutionCMS();
623
        global $use_udperms;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
624
625
        $tbl_site_tmplvar_templates = $modx->getDatabase()->getFullTableName('site_tmplvar_access');
626
627
        if ($newid) {
628
            $id = $newid;
629
        }
630
        $docgroups = $_POST['docgroups'];
631
632
        // check for permission update access
633
        if ($use_udperms == 1) {
634
            // delete old permissions on the tv
635
            $modx->getDatabase()->delete($tbl_site_tmplvar_templates, "tmplvarid='{$id}'");
636
            if (is_array($docgroups)) {
637
                foreach ($docgroups as $value) {
638
                    $modx->getDatabase()->insert(array(
639
                        'tmplvarid'     => $id,
640
                        'documentgroup' => stripslashes($value),
641
                    ), $tbl_site_tmplvar_templates);
642
                }
643
            }
644
        }
645
    }
646
}
647
648
if (!function_exists('sendMailMessageForUser')) {
649
    /**
650
     * Send an email to the user
651
     *
652
     * @param string $email
653
     * @param string $uid
654
     * @param string $pwd
655
     * @param string $ufn
656
     */
657
    function sendMailMessageForUser($email, $uid, $pwd, $ufn, $message, $url)
658
    {
659
        $modx = evolutionCMS();
660
        global $_lang;
661
        global $emailsubject, $emailsender;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
662
        global $site_name;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
663
        $message = sprintf($message, $uid, $pwd); // use old method
664
        // replace placeholders
665
        $message = str_replace("[+uid+]", $uid, $message);
666
        $message = str_replace("[+pwd+]", $pwd, $message);
667
        $message = str_replace("[+ufn+]", $ufn, $message);
668
        $message = str_replace("[+sname+]", $modx->getPhpCompat()->entities($site_name), $message);
669
        $message = str_replace("[+saddr+]", $emailsender, $message);
670
        $message = str_replace("[+semail+]", $emailsender, $message);
671
        $message = str_replace("[+surl+]", $url, $message);
672
673
        $param = array();
674
        $param['from'] = "{$site_name}<{$emailsender}>";
675
        $param['subject'] = $emailsubject;
676
        $param['body'] = $message;
677
        $param['to'] = $email;
678
        $param['type'] = 'text';
679
        $rs = $modx->sendmail($param);
0 ignored issues
show
Comprehensibility introduced by
Avoid variables with short names like $rs. Configured minimum length is 3.

Short variable names may make your code harder to understand. Variable names should be self-descriptive. This check looks for variable names who are shorter than a configured minimum.

Loading history...
680
        if (!$rs) {
681
            $modx->getManagerApi()->saveFormValues();
682
            $modx->messageQuit("{$email} - {$_lang['error_sending_email']}");
683
        }
684
    }
685
}
686
687
if (!function_exists('saveWebUserSettings')) {
688
// Save User Settings
689
    function saveWebUserSettings($id)
0 ignored issues
show
Coding Style introduced by
saveWebUserSettings uses the super-global variable $_POST which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
690
    {
691
        $modx = evolutionCMS();
692
        $tbl_web_user_settings = $modx->getDatabase()->getFullTableName('web_user_settings');
693
694
        $settings = array(
695
            "login_home",
696
            "allowed_ip",
697
            "allowed_days"
698
        );
699
700
        $modx->getDatabase()->delete($tbl_web_user_settings, "webuser='{$id}'");
701
702 View Code Duplication
        foreach ($settings as $n) {
703
            $vl = $_POST[$n];
704
            if (is_array($vl)) {
705
                $vl = implode(",", $vl);
706
            }
707
            if ($vl != '') {
708
                $f = array();
709
                $f['webuser'] = $id;
710
                $f['setting_name'] = $n;
711
                $f['setting_value'] = $vl;
712
                $f = $modx->getDatabase()->escape($f);
713
                $modx->getDatabase()->insert($f, $tbl_web_user_settings);
714
            }
715
        }
716
    }
717
}
718
719
if (!function_exists('saveManagerUserSettings')) {
720
    /**
721
     * Save User Settings
722
     *
723
     * @param int $id
724
     */
725
    function saveManagerUserSettings($id)
0 ignored issues
show
Coding Style introduced by
saveManagerUserSettings uses the super-global variable $_POST which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
726
    {
727
        $modx = evolutionCMS();
728
        $tbl_user_settings = $modx->getDatabase()->getFullTableName('user_settings');
729
730
        $ignore = array(
731
            'id',
732
            'oldusername',
733
            'oldemail',
734
            'newusername',
735
            'fullname',
736
            'newpassword',
737
            'newpasswordcheck',
738
            'passwordgenmethod',
739
            'passwordnotifymethod',
740
            'specifiedpassword',
741
            'confirmpassword',
742
            'email',
743
            'phone',
744
            'mobilephone',
745
            'fax',
746
            'dob',
747
            'country',
748
            'street',
749
            'city',
750
            'state',
751
            'zip',
752
            'gender',
753
            'photo',
754
            'comment',
755
            'role',
756
            'failedlogincount',
757
            'blocked',
758
            'blockeduntil',
759
            'blockedafter',
760
            'user_groups',
761
            'mode',
762
            'blockedmode',
763
            'stay',
764
            'save',
765
            'theme_refresher'
766
        );
767
768
        // determine which settings can be saved blank (based on 'default_{settingname}' POST checkbox values)
769
        $defaults = array(
770
            'upload_images',
771
            'upload_media',
772
            'upload_flash',
773
            'upload_files'
774
        );
775
776
        // get user setting field names
777
        $settings = array();
778
        foreach ($_POST as $n => $v) {
779
            if (in_array($n, $ignore) || (!in_array($n, $defaults) && is_scalar($v) && trim($v) == '') || (!in_array($n,
780
                        $defaults) && is_array($v) && empty($v))) {
781
                continue;
782
            } // ignore blacklist and empties
783
            $settings[$n] = $v; // this value should be saved
784
        }
785
786
        foreach ($defaults as $k) {
787
            if (isset($settings['default_' . $k]) && $settings['default_' . $k] == '1') {
788
                unset($settings[$k]);
789
            }
790
            unset($settings['default_' . $k]);
791
        }
792
793
        $modx->getDatabase()->delete($tbl_user_settings, "user='{$id}'");
794
795 View Code Duplication
        foreach ($settings as $n => $vl) {
796
            if (is_array($vl)) {
797
                $vl = implode(",", $vl);
798
            }
799
            if ($vl != '') {
800
                $f = array();
801
                $f['user'] = $id;
802
                $f['setting_name'] = $n;
803
                $f['setting_value'] = $vl;
804
                $f = $modx->getDatabase()->escape($f);
805
                $modx->getDatabase()->insert($f, $tbl_user_settings);
806
            }
807
        }
808
    }
809
}
810
811
if (!function_exists('webAlertAndQuit')) {
812
    /**
813
     * Web alert -  sends an alert to web browser
814
     *
815
     * @param $msg
816
     */
817
    function webAlertAndQuit($msg, $action)
0 ignored issues
show
Coding Style introduced by
webAlertAndQuit uses the super-global variable $_POST which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
818
    {
819
        global $id, $modx;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
820
        $mode = $_POST['mode'];
821
        $modx->getManagerApi()->saveFormValues($mode);
822
        $modx->webAlertAndQuit($msg, "index.php?a={$mode}" . ($mode === $action ? "&id={$id}" : ''));
823
    }
824
}
825
826
if (!function_exists('getChildrenForUnDelete')) {
827
    /**
828
     * @param int $parent
829
     */
830
    function getChildrenForUnDelete($parent)
831
    {
832
833
        $modx = evolutionCMS();
834
        global $children;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
835
        global $deltime;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
836
837
        $rs = $modx->getDatabase()->select('id', $modx->getDatabase()->getFullTableName('site_content'),
0 ignored issues
show
Comprehensibility introduced by
Avoid variables with short names like $rs. Configured minimum length is 3.

Short variable names may make your code harder to understand. Variable names should be self-descriptive. This check looks for variable names who are shorter than a configured minimum.

Loading history...
838
            "parent='" . (int)$parent . "' AND deleted=1 AND deletedon='" . (int)$deltime . "'");
839
        // the document has children documents, we'll need to delete those too
840
        while ($row = $modx->getDatabase()->getRow($rs)) {
0 ignored issues
show
Bug introduced by
It seems like $rs defined by $modx->getDatabase()->se... (int) $deltime . '\'') on line 837 can also be of type boolean; however, EvolutionCMS\Database::getRow() does only seem to accept object<mysqli_result>, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
841
            $children[] = $row['id'];
842
            getChildrenForUnDelete($row['id']);
843
            //echo "Found childNode of parentNode $parent: ".$row['id']."<br />";
0 ignored issues
show
Unused Code Comprehensibility introduced by
73% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
844
        }
845
    }
846
}
847