GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.
Completed
Push — master ( a5cd88...85bafa )
by Marco
02:37
created

function.php ➔ printTableHeader()   C

Complexity

Conditions 11
Paths 12

Size

Total Lines 34
Code Lines 26

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 11
eloc 26
nc 12
nop 4
dl 0
loc 34
rs 5.2653
c 0
b 0
f 0

How to fix   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
function imapFolder($cf, $username) {
4
	$open='{'.$cf['mailhost'].':143/imap/novalidate-cert/authuser='.$cf['authuser'].'}';
5
        $m_mail = imap_open($open, $username, $cf['authpassword'], OP_READONLY)
6
                or syslog (LOG_EMERG, $cf['user'].': Error in IMAP connection to <'.$cf['mailhost'].'>: ' . imap_last_error());
7
        if ( !$m_mail ) exit(254);
0 ignored issues
show
Coding Style Compatibility introduced by
The function imapFolder() contains an exit expression.

An exit expression should only be used in rare cases. For example, if you write a short command line script.

In most cases however, using an exit expression makes the code untestable and often causes incompatibilities with other libraries. Thus, unless you are absolutely sure it is required here, we recommend to refactor your code to avoid its usage.

Loading history...
8
9
10
        syslog (LOG_INFO,$cf['user'].': Successfully connected to <'.$cf['mailhost'].'>; Listing folders of account <'.$username.'>...');
11
        //get all folder
12
	$list = imap_list($m_mail, $open, "*");
13
	imap_close($m_mail);
14
	if (is_array($list))
15
		foreach ($list as $mbox)
16
			$return[] = explode($open,$mbox,2)[1];
0 ignored issues
show
Coding Style Comprehensibility introduced by
$return was never initialized. Although not strictly required by PHP, it is generally a good practice to add $return = 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...
17
	else
18
		syslog (LOG_INFO,$cf['user'] . ': imap_list failed: ' . imap_last_error() );
19
	return $return;
0 ignored issues
show
Bug introduced by
The variable $return 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...
20
}
21
22
function imapFind ($cf, $username, $folder) {
23
	$head=array();
24
	$m_mail = imap_open('{'.$cf['mailhost'].':143/imap/novalidate-cert/authuser='.$cf['authuser'].'}'.$folder, $username,$cf['authpassword'], OP_READONLY)
25
        	or syslog (LOG_EMERG, $cf['user'].': Error in IMAP connection to <'.$cf['mailhost'].'>: ' . imap_last_error());
0 ignored issues
show
Comprehensibility Best Practice introduced by
Using logical operators such as or instead of || is generally not recommended.

PHP has two types of connecting operators (logical operators, and boolean operators):

  Logical Operators Boolean Operator
AND - meaning and &&
OR - meaning or ||

The difference between these is the order in which they are executed. In most cases, you would want to use a boolean operator like &&, or ||.

Let’s take a look at a few examples:

// Logical operators have lower precedence:
$f = false or true;

// is executed like this:
($f = false) or true;


// Boolean operators have higher precedence:
$f = false || true;

// is executed like this:
$f = (false || true);

Logical Operators are used for Control-Flow

One case where you explicitly want to use logical operators is for control-flow such as this:

$x === 5
    or die('$x must be 5.');

// Instead of
if ($x !== 5) {
    die('$x must be 5.');
}

Since die introduces problems of its own, f.e. it makes our code hardly testable, and prevents any kind of more sophisticated error handling; you probably do not want to use this in real-world code. Unfortunately, logical operators cannot be combined with throw at this point:

// The following is currently a parse error.
$x === 5
    or throw new RuntimeException('$x must be 5.');

These limitations lead to logical operators rarely being of use in current PHP code.

Loading history...
26
	if ( !$m_mail ) exit(254);
0 ignored issues
show
Coding Style Compatibility introduced by
The function imapFind() contains an exit expression.

An exit expression should only be used in rare cases. For example, if you write a short command line script.

In most cases however, using an exit expression makes the code untestable and often causes incompatibilities with other libraries. Thus, unless you are absolutely sure it is required here, we recommend to refactor your code to avoid its usage.

Loading history...
27
		
28
29
	syslog (LOG_INFO,$cf['user'].': Successfully connected to <'.$cf['mailhost'].">; Reading <$folder> messages of last ".$cf['oldestday'].' days on account <'.$username.'>...');
30
	//get all messages
31
	$dateTh = date ( "d-M-Y", strToTime ( '-'.$cf['oldestday'].' days' ) );
32
	$m_search=imap_search ($m_mail, "SINCE \"$dateTh\" TEXT \"Authentication-Results: \"" );
33
34
35
	// Order results starting from newest message
36
	if ( empty($m_search) ) {
37
		syslog (LOG_INFO,$cf['user'].": No suitable mail found in <$folder> folder.");
38 View Code Duplication
	        if ( $ierr = imap_errors() )
0 ignored issues
show
Duplication introduced by
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...
39
	                foreach ( $ierr as $thiserr )
40
	                        syslog (LOG_ERR, $cf['user'].": IMAP Error: $thiserr");
41 View Code Duplication
	        if ( $ierr = imap_alerts() )
0 ignored issues
show
Duplication introduced by
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...
42
	                foreach ( $ierr as $thiserr )
43
	                        syslog (LOG_ALERT, $cf['user'].": IMAP Alert: $thiserr");
44
		imap_close( $m_mail );
45
		return FALSE;
46
	}
47
	$nmes = count ($m_search);
48
	syslog (LOG_INFO,$cf['user'].": Found $nmes mail in <$folder> folder.");
49
	if ($nmes>0) rsort($m_search);
50
51
        // loop for each message
52
	foreach ($m_search as $onem) 
53
		$head[] = imap_fetchheader($m_mail, $onem );
54
	imap_close($m_mail);
55
	return $head;
56
}
57
58
function dspamLevel($prob, $conf) {
59
/* Calculate DSPAM Level as the Spamassassin Plugin */
60
	if (is_null($prob) or is_null($conf)) return '-';
0 ignored issues
show
Comprehensibility Best Practice introduced by
Using logical operators such as or instead of || is generally not recommended.

PHP has two types of connecting operators (logical operators, and boolean operators):

  Logical Operators Boolean Operator
AND - meaning and &&
OR - meaning or ||

The difference between these is the order in which they are executed. In most cases, you would want to use a boolean operator like &&, or ||.

Let’s take a look at a few examples:

// Logical operators have lower precedence:
$f = false or true;

// is executed like this:
($f = false) or true;


// Boolean operators have higher precedence:
$f = false || true;

// is executed like this:
$f = (false || true);

Logical Operators are used for Control-Flow

One case where you explicitly want to use logical operators is for control-flow such as this:

$x === 5
    or die('$x must be 5.');

// Instead of
if ($x !== 5) {
    die('$x must be 5.');
}

Since die introduces problems of its own, f.e. it makes our code hardly testable, and prevents any kind of more sophisticated error handling; you probably do not want to use this in real-world code. Unfortunately, logical operators cannot be combined with throw at this point:

// The following is currently a parse error.
$x === 5
    or throw new RuntimeException('$x must be 5.');

These limitations lead to logical operators rarely being of use in current PHP code.

Loading history...
61
	$t_prob = abs((($prob - 0.5) * 2) * 100);
62
	return round(($t_prob + ($conf*100)) / 2);
63
}
64
65
function imapInfo($header,$ARhosts,$dpl=false, $learn=false) {
66
/* Get relevant Info from header's mail */
67
/* Each line must end with /r/n         */
68
69
        $dateC = NULL;
0 ignored issues
show
Unused Code introduced by
$dateC 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...
70
	$mid = NULL;
0 ignored issues
show
Unused Code introduced by
$mid 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...
71
	$result = array(
72
                'date' => NULL,
73
                'from' => NULL,
74
                'messageid' => NULL,
75
		'dmarc' => array(
76
			'result' => NULL,
77
			'dom'	=> NULL
78
			),
79
		'spf' => array(
80
                        'result' => NULL,
81
                        'dom'   => NULL
82
                        ),
83
		'dkim' => array(
84
                        'result' => NULL,
85
                        'dom'   => NULL
86
                        ),
87
                'spam' => array(
88
                        'status' => NULL,
89
                        'score' => NULL,
90
                        'th'    => NULL,
91
                        ),
92
                'dspam' => array(
93
                        'type' => NULL,
94
                        'level' => NULL,
95
			'learn' => NULL
96
                        ),
97
		'warn' => NULL
98
        );
99
		
100
101 View Code Duplication
        if ( preg_match_all ('/^Authentication\-Results:\s+(?<host>[\w\.]+);(?:\s+|\r\n\s+)dmarc=(?<dmarc>\w+)\s+\(p=\w+\s+dis=\w+\)\s+header\.from=(?<DMARCfrom>[\w\.]+)/m',$header,$received) ) {
0 ignored issues
show
Duplication introduced by
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...
102
		$k=0;
103
                for ($i = count($received[0])-1;$i>=0;$i--) {
104
	                foreach ($ARhosts as $mx) {
105
				if ($mx == $received['host'][$i]) {
106
					/* This is a trusted AR result */
107
					$result['dmarc']['result']=$received['dmarc'][$i];
108
					$result['dmarc']['dom'] = $received['DMARCfrom'][$i];
109
					$k++;
110
				}
111
                	}
112
		}
113
        }
114
	$received=NULL;
115
	if ($k>1) $result['warn'][] = 'The trusted DMARC AR Headers are present more than once. Something wrong.';
0 ignored issues
show
Bug introduced by
The variable $k 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...
116
117 View Code Duplication
        if ( preg_match_all('/^Authentication\-Results:\s+(?<host>[\w\.]+);(?:\s+|\r\n\s+)spf=(?<spf>\w+)\s+smtp\.(?:mailfrom|helo)=(?<SPFfrom>[\w\.]+)/m',$header,$received) ) {
0 ignored issues
show
Duplication introduced by
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...
118
		$k=0;
119
		for ($i = count($received[0])-1;$i>=0;$i--) {
120
			foreach ($ARhosts as $mx) {
121
				if ($mx == $received['host'][$i]) {
122
					/* This is a trusted AR result */
123
					$result['spf']['result']=$received['spf'][$i];
124
					$result['spf']['dom'] = $received['SPFfrom'][$i];
125
					$k++;
126
                        	}
127
                	}
128
        	}
129
	}
130
	$received=NULL;
131
	if ($k>1) $result['warn'][] = 'The trusted SPF AR Headers are present more than once. Something wrong.';
132
133 View Code Duplication
        if ( preg_match_all('/^Authentication\-Results:\s+(?<host>[\w\.]+);(?:\s+|\r\n\s+)dkim=(?<dkim>\w+)\s+[\w\s\(\)\-]+header\.d=(?<DKIMdom>[\w\.]+)/m',$header,$received) ) {
0 ignored issues
show
Duplication introduced by
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...
134
		$k=0;
135
		for ($i = count($received[0])-1;$i>=0;$i--) {
136
	                foreach ($ARhosts as $mx) {
137
        	                if ($mx == $received['host'][$i]) {
138
                	                /* This is a trusted AR result */
139
                        	        $result['dkim']['result']=$received['dkim'][$i];
140
                                	$result['dkim']['dom'] = $received['DKIMdom'][$i];
141
					$k++;
142
                        	}
143
                	}
144
        	}
145
	}
146
	$received=NULL;
147
	if ($k>1) $result['warn'][] = 'The trusted DKIM AR Headers are present more than once. Something wrong.';
148
149
	if ($dpl) { /* Use Spamassassin Plugin */
150
		if ( preg_match_all('/^X\-Spam\-Status:\s(?P<spamstatus>\w+)\,(?:\s+|\r\n\s+)score=(?P<score>[\-\.\d]+)(?:\s+|\r\n\s+)tagged_above=\-{0,1}\d+(?:\s+|\r\n\s+)required=(?P<th>[\-\.\d]+)(?:\s+|\r\n\s+)tests=\[(?:.|\r\n\s+)*DSPAM_(?P<dtype>SPAM|HAM)_(?P<dlevel>\d\d)(?:.|\r\n\s+)*\]/m',$header,$received) ) {
151
			$result['spam']['status']=$received['spamstatus'][0];
152
                	$result['spam']['score'] = $received['score'][0];
153
			$result['spam']['th'] = $received['th'][0];
154
			$result['dspam']['type'] = $received['dtype'][0];
155
			$result['dspam']['level'] =$received['dlevel'][0];
156
        	}
157
        	if (count($received[0])>1) $result['warn'][] = 'The Spamassassin Headers are present more than once. I consider only the last one.';
158
	}
159
	else { /* Parse apart all DSPAM Header and calculate a level */
160
		if ( preg_match_all('/^X\-Spam\-Status:\s(?P<spamstatus>\w+)\,(?:\s+|\r\n\s+)score=(?P<score>[\-\.\d]+)(?:\s+|\r\n\s+)tagged_above=\-{0,1}\d+(?:\s+|\r\n\s+)required=(?P<th>[\-\.\d]+)(?:\s+|\r\n\s+)tests=\[(?:.|\r\n\s+)*\]/m',$header,$received) ) {
161
                        $result['spam']['status']=$received['spamstatus'][0];
162
                        $result['spam']['score'] = $received['score'][0];
163
                        $result['spam']['th'] = $received['th'][0];
164
			if (count($received[0])>1)
165
				$result['warn'][]= 'The Spamassassin Headers are present more than once. I consider only the last one.';
166
		}
167 View Code Duplication
		if ( preg_match ('/\r\nX\-DSPAM\-Result:\s(?P<result>.*)\r\n/',$header,$received) != 1)
0 ignored issues
show
Duplication introduced by
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...
168
	                $result['warn'] = 'DSPAM Result invalid, not present or present more than once.';
169
	        else
170
                	$result['dspam']['type']=$received['result'];
171
		$prob = NULL;
172
		$conf = NULL;
173 View Code Duplication
                if ( preg_match ('/\r\nX\-DSPAM\-Probability:\s(?P<prob>.*)\r\n/',$header,$received) != 1)
0 ignored issues
show
Duplication introduced by
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...
174
                        $result['warn'][] = 'DSPAM Probability invalid, not present or present more than once.';
175
		else
176
			$prob = $received['prob'];
177 View Code Duplication
		if ( preg_match ('/\r\nX\-DSPAM\-Confidence:\s(?P<conf>.*)\r\n/',$header,$received) != 1)
0 ignored issues
show
Duplication introduced by
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...
178
                        $result['warn'][] = 'DSPAM Confidence invalid, not present or present more than once.';
179
		else
180
			$conf = $received['conf'];
181
		$result['dspam']['level'] = dspamLevel($prob,$conf);
182
	}
183
	$received=NULL;
184 View Code Duplication
	if ( preg_match ('/\r\nFrom:\s(?P<from>.*)\r\n/',$header,$received) != 1)
0 ignored issues
show
Duplication introduced by
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...
185
                $result['warn'][] = 'From header invalid or not present';
186
        else
187
                $result['from'] = $received['from'];
188
189 View Code Duplication
        if ( preg_match ('/\r\nDate:\s(?P<date>.*)\r\n/',$header,$received) != 1)
0 ignored issues
show
Duplication introduced by
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...
190
                $result['warn'][] = 'Date header invalid or not present';
191
	else
192
		$result['date'] = $received['date'];
193
194
	$received=NULL;
195 View Code Duplication
        if ( preg_match ('/\r\nMessage\-I(?:D|d):\s(?P<mid>.*)\r\n/',$header,$received) != 1)
0 ignored issues
show
Duplication introduced by
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...
196
                $result['warn'][] = 'Message-ID invalid, not present or present more than once.';
197
	else
198
		$result['messageid']=$received['mid'];
199
200
        $received=NULL;
201
202
        switch ($learn) {
203
		case 'dspamc':
204 View Code Duplication
        		if ( preg_match ('/\r\nX\-DSPAM\-Signature:\s(?P<sig>.*)\r\n/',$header,$received) != 1)
0 ignored issues
show
Duplication introduced by
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...
205
				$result['warn'] = 'DSPAM Signature invalid, not present or present more than once.';
206
			else
207
				$result['dspam']['learn']=$received['sig'];			
208
			break;
209
		case false:
210
			break;
211
		default:
212
			syslog (LOG_INFO,$user.': Error in "learn" imap configuration value. Please, set "dspamc" or "false".');
0 ignored issues
show
Bug introduced by
The variable $user does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
213
	}
214
	
215
        return $result;
216
}
217
218
219
220
221
function printTableHeader($title,$content,$footer=FALSE,$fcontent) {
222
        print <<<END
223
	<caption>$title</caption>
224
	<thead>
225
	<tr>
226
END;
227
	$kcontent = array_keys($content);
228
        $cols = count($kcontent);
229
        for ($i=0; $i<$cols; $i++) {
230
		$key = $kcontent[$i];
231
                printf ('<th colspan="%d" rowspan="%d">%s</th>',
232
			!is_array($content[$key]) ?:
233
			count(array_keys($content[$key])) ?: '1',
234
			!is_array($content[$key]) ?:
235
			empty(array_keys($content[$key])) ? '2' : '1',
236
			$kcontent[$i]);
237
	}
238
	print '</tr><tr>';
239
	for ($i=0; $i<$cols; $i++) {
240
		$key = $kcontent[$i];
241
		if (is_array($content[$key])&&($hs = array_keys($content[$key]))) {
242
			foreach ($hs as $h)
243
				printf('<th>%s</th>',$h);
244
		}
245
	}
246
		
247
        print '</tr></thead>';
248
        if ($footer) {
249
                print '<tfoot><tr>';
250
                print "<th colspan=\"$cols\">".$fcontent.'</th>';
251
                print '</tr></tfoot>';
252
        }
253
        return TRUE;
254
}
255
256
257
function formatVal($val, $learn) {
258
	foreach (array_keys($val) as $key) {
259
		if (is_array($val["$key"]) and ($key!='warn'))
0 ignored issues
show
Comprehensibility Best Practice introduced by
Using logical operators such as and instead of && is generally not recommended.

PHP has two types of connecting operators (logical operators, and boolean operators):

  Logical Operators Boolean Operator
AND - meaning and &&
OR - meaning or ||

The difference between these is the order in which they are executed. In most cases, you would want to use a boolean operator like &&, or ||.

Let’s take a look at a few examples:

// Logical operators have lower precedence:
$f = false or true;

// is executed like this:
($f = false) or true;


// Boolean operators have higher precedence:
$f = false || true;

// is executed like this:
$f = (false || true);

Logical Operators are used for Control-Flow

One case where you explicitly want to use logical operators is for control-flow such as this:

$x === 5
    or die('$x must be 5.');

// Instead of
if ($x !== 5) {
    die('$x must be 5.');
}

Since die introduces problems of its own, f.e. it makes our code hardly testable, and prevents any kind of more sophisticated error handling; you probably do not want to use this in real-world code. Unfortunately, logical operators cannot be combined with throw at this point:

// The following is currently a parse error.
$x === 5
    or throw new RuntimeException('$x must be 5.');

These limitations lead to logical operators rarely being of use in current PHP code.

Loading history...
260
			$val["$key"] = formatVal($val["$key"], $learn);
261
		else {
262
			switch ($key) {
263
				case 'warn':
264
					if (empty($val["$key"]))
265
						$val["$key"] = '-';
266
					else 
267
						$val["$key"] = sprintf('<div title="%s">Y</div>',implode($val["$key"],"\n"));
268
					break;
269
				case 'learn':
270
					$val["$key"] = formLearn($learn, $val);
271
					break;
272
				default:
273
					$val["$key"] = htmlentities($val["$key"]);
274
			}
275
		}
276
	}
277
	return $val;
278
}
279
280
function formLearn($type, $par) {
281
	$return = NULL;
282
	switch ($type) {
283
		case 'dspamc':
0 ignored issues
show
Coding Style introduced by
There must be a comment when fall-through is intentional in a non-empty case body
Loading history...
284
			$classes = array('Spam', 'Innocent');
285
			foreach ($classes as $class) {
286
				$par['class'] = $class;
287
				$val["$class"] = sprintf('dspamc --user dspam --deliver=summary --class=%s --source=error --signature=%s',
0 ignored issues
show
Coding Style Comprehensibility introduced by
$val was never initialized. Although not strictly required by PHP, it is generally a good practice to add $val = 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...
288
							strtolower($class), $par['learn']);
289
				if (($class != $par['type'])||($par['level']<99))
290
					$return .= sprintf(file_get_contents('formLearnDSPAM.htm'),
291
						$class,$class,$val["$class"],base64_encode(json_encode($par)),$class);
0 ignored issues
show
Bug introduced by
The variable $val 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...
292
			}
293
		default:
294
			return $return;
295
	}
296
	return $return;
0 ignored issues
show
Unused Code introduced by
return $return; does not seem to be reachable.

This check looks for unreachable code. It uses sophisticated control flow analysis techniques to find statements which will never be executed.

Unreachable code is most often the result of return, die or exit statements that have been added for debug purposes.

function fx() {
    try {
        doSomething();
        return true;
    }
    catch (\Exception $e) {
        return false;
    }

    return false;
}

In the above example, the last return false will never be executed, because a return statement has already been met in every possible execution path.

Loading history...
297
}
298
299
function printTableRow($row, $learn, $init=true) {
300
	$bg = NULL;
0 ignored issues
show
Unused Code introduced by
$bg 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...
301
	$color = 'inherit';
302
	if ($init) 
303
		$row=formatVal($row,$learn);
304
	foreach( $row as $key => $val) {
305
		if (is_array($val))
306
			printTableRow($val, $learn, false);
307
		else {
308
			/* DSPAM format */
309
			if (isset($row['type']))
310
				switch($row['type']) {
311
					case 'Innocent':
312
					case 'HAM':
313
						$color = 'rgba(0,255,0, %.1f)';
314
						break;
315
					case 'Spam':
316
					case 'SPAM':
317
						$color = 'rgba(255,0,0,%.1f)';
318
			}
319
			/* DMARC, DKIM, SPF format */
320
			if (isset($row['result']))
321
				switch($row['result']) {
322
					case 'pass':
323
						$color = 'rgba(0,255,0, %.1f)';
324
						break;
325
					case 'fail':
326
						$color = 'rgba(255,0,0,%.1f)';
327
				}
328
			/* Spamassassin format */
329
			if (isset($row['status']))
330
	                        switch($row['status']) {
331
					case 'No':
332
						$color = 'rgba(0,255,0, %.1f)';
333
						break;
334
					case 'Yes':
335
						$color = 'rgba(255,0,0,%.1f)';
336
				}	
337
				
338
			$alpha = (is_numeric($val)AND($key=='type')) ? round($val/100,1) : 1.0;
0 ignored issues
show
Comprehensibility Best Practice introduced by
Using logical operators such as and instead of && is generally not recommended.

PHP has two types of connecting operators (logical operators, and boolean operators):

  Logical Operators Boolean Operator
AND - meaning and &&
OR - meaning or ||

The difference between these is the order in which they are executed. In most cases, you would want to use a boolean operator like &&, or ||.

Let’s take a look at a few examples:

// Logical operators have lower precedence:
$f = false or true;

// is executed like this:
($f = false) or true;


// Boolean operators have higher precedence:
$f = false || true;

// is executed like this:
$f = (false || true);

Logical Operators are used for Control-Flow

One case where you explicitly want to use logical operators is for control-flow such as this:

$x === 5
    or die('$x must be 5.');

// Instead of
if ($x !== 5) {
    die('$x must be 5.');
}

Since die introduces problems of its own, f.e. it makes our code hardly testable, and prevents any kind of more sophisticated error handling; you probably do not want to use this in real-world code. Unfortunately, logical operators cannot be combined with throw at this point:

// The following is currently a parse error.
$x === 5
    or throw new RuntimeException('$x must be 5.');

These limitations lead to logical operators rarely being of use in current PHP code.

Loading history...
339
			$bg = sprintf(" style=\"background-color: $color\"", $alpha);		
340
			printf ('<td%s>%s</td>',$bg, $val);
341
		}
342
	}
343
}
344
?>
0 ignored issues
show
Best Practice introduced by
It is not recommended to use PHP's closing tag ?> in files other than templates.

Using a closing tag in PHP files that only contain PHP code is not recommended as you might accidentally add whitespace after the closing tag which would then be output by PHP. This can cause severe problems, for example headers cannot be sent anymore.

A simple precaution is to leave off the closing tag as it is not required, and it also has no negative effects whatsoever.

Loading history...
345