Completed
Push — master ( 74a8a3...46dc92 )
by Victor
13s
created

Status::parseResponse()   C

Complexity

Conditions 15
Paths 23

Size

Total Lines 57
Code Lines 39

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 33
CRAP Score 15.2842

Importance

Changes 0
Metric Value
dl 0
loc 57
ccs 33
cts 37
cp 0.8919
rs 6.5498
c 0
b 0
f 0
cc 15
eloc 39
nc 23
nop 2
crap 15.2842

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
 * Copyright (c) 2014 Viktar Dubiniuk <[email protected]>
4
 * This file is licensed under the Affero General Public License version 3 or
5
 * later.
6
 * See the COPYING-README file.
7
 */
8
9
namespace OCA\Files_Antivirus;
10
11
class Status {
12
	
13
	/*
14
	 *  The file was not checked (e.g. because the AV daemon wasn't running).
15
	 */
16
	const SCANRESULT_UNCHECKED = -1;
17
18
	/*
19
	 *  The file was checked and found to be clean.
20
	 */
21
	const SCANRESULT_CLEAN = 0;
22
23
	/*
24
	 *  The file was checked and found to be infected.
25
	 */
26
	const SCANRESULT_INFECTED = 1;
27
	
28
	/*
29
	 * Should be SCANRESULT_UNCHECKED | SCANRESULT_INFECTED | SCANRESULT_CLEAN
30
	 */
31
	protected $numericStatus;
32
	
33
	/*
34
	 * Virus name or error message
35
	 */
36
	protected $details = "";
37
	
38
	protected $ruleMapper;
39
	
40 10
	public function __construct(){
41 10
		$this->numericStatus = self::SCANRESULT_UNCHECKED;
42 10
		$this->ruleMapper = new Db\RuleMapper(\OC::$server->getDb());
43 10
	}
44
	
45
	/**
46
	 * Get scan status as integer
47
	 * @return int
48
	 */
49 8
	public function getNumericStatus(){
50 8
		return $this->numericStatus;
51
	}
52
	
53
	/**
54
	 * Get scan status as string
55
	 * @return string
56
	 */
57 4
	public function getDetails(){
58 4
		return $this->details;
59
	}
60
	
61
	/**
62
	 * @param string $rawResponse
63
	 * @param integer $result
64
	 */
65 8
	public function parseResponse($rawResponse, $result = null){
66 8
		$matches = array();
67 8
		$ruleMapper = new Db\RuleMapper(\OC::$server->getDb());
68 8
		if (is_null($result)){ // Daemon or socket mode
69
			try{
70 5
				$allRules = $this->getResponseRules();
71
			} catch (\Exception $e){
72
				\OCP\Util::writeLog('files_antivirus', __METHOD__.', exception: '.$e->getMessage(), \OCP\Util::ERROR);
73
				return;
74
			}
75
			
76 5
			$isMatched = false;
77 5
			foreach ($allRules as $rule){
78 5
				if (preg_match($rule->getMatch(), $rawResponse, $matches)){
79 4
					$isMatched = true;
80 4
					$this->numericStatus = intval($rule->getStatus());
81 4
					if (intval($rule->getStatus())===self::SCANRESULT_CLEAN){
82 1
						$this->details = '';
83
					} else {
84 4
						$this->details = isset($matches[1]) ? $matches[1] : 'unknown';
85
					}
86 5
					break;
87
				}
88
			}
89
			
90 5
			if (!$isMatched){
91 3
				$this->numericStatus = self::SCANRESULT_UNCHECKED;
92 5
				$this->details = 'No matching rules. Please check antivirus rules.';
93
			}
94
			
95
		} else { // Executable mode
96 4
			$scanStatus = $ruleMapper->findByResult($result);
97 4
			if (is_array($scanStatus) && count($scanStatus)){
98 4
				$this->numericStatus = intval($scanStatus[0]->getStatus());
99 4
				$this->details = $scanStatus[0]->getDescription();
100
			}
101
			
102 4
			switch($this->numericStatus) {
103 4
				case self::SCANRESULT_INFECTED:
104 2
					$report = array();
105 2
					$rawResponse = explode("\n", $rawResponse);
106
					
107 2
					foreach ($rawResponse as $line){	
108 2
						if (preg_match('/.*: (.*) FOUND\s*$/', $line, $matches)) {
109 2
							$report[] = $matches[1];
110
						}
111
					}
112 2
					$this->details = implode(', ', $report);
113
					
114 2
					break;
115 4
				case self::SCANRESULT_UNCHECKED:
116 1
					if (!$this->details) {
117
						$this->details = 'No matching rule for exit code ' .  $this->numericStatus .'. Please check antivirus rules configuration.' ;
118
					}
119
			}
120
		}
121 8
	}
122
	
123 5
	protected function getResponseRules(){
124 5
		$infectedRules = $this->ruleMapper->findAllMatchedByStatus(self::SCANRESULT_INFECTED);
125 5
		$uncheckedRules = $this->ruleMapper->findAllMatchedByStatus(self::SCANRESULT_UNCHECKED);
126 5
		$cleanRules = $this->ruleMapper->findAllMatchedByStatus(self::SCANRESULT_CLEAN);
127
		
128 5
		$infectedRules = $infectedRules ? $infectedRules : array();
129 5
		$uncheckedRules = $uncheckedRules ? $uncheckedRules : array();
130 5
		$cleanRules = $cleanRules ? $cleanRules : array();
131
		
132
		// order: clean, infected, try to guess error
133 5
		$allRules = array_merge($cleanRules, $infectedRules, $uncheckedRules);
134 5
		return $allRules;
135
	}
136
	
137
	public function dispatch($item, $isBackground = false){
138
		switch($this->getNumericStatus()) {
139
			case self::SCANRESULT_UNCHECKED:
140
				$item->processUnchecked($this, $isBackground);
141
				break;
142
			case self::SCANRESULT_INFECTED:
143
				$item->processInfected($this, $isBackground);
144
				break;
145
			case self::SCANRESULT_CLEAN:
146
				$item->processClean($this, $isBackground);
147
				break;
148
		}
149
	}
150
}
151