Storage::store()   C
last analyzed

Complexity

Conditions 12
Paths 41

Size

Total Lines 67
Code Lines 32

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 24
CRAP Score 14.25

Importance

Changes 5
Bugs 1 Features 0
Metric Value
cc 12
eloc 32
c 5
b 1
f 0
nc 41
nop 1
dl 0
loc 67
ccs 24
cts 32
cp 0.75
crap 14.25
rs 6.9666

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
 * DronePHP (http://www.dronephp.com)
4
 *
5
 * @link      http://github.com/Pleets/DronePHP
6
 * @copyright Copyright (c) 2016-2018 Pleets. (http://www.pleets.org)
7
 * @license   http://www.dronephp.com/license
8
 * @author    Darío Rivera <[email protected]>
9
 */
10
11
namespace Drone\Exception;
12
13
use Drone\Error\Errno;
14
15
/**
16
 * Storage class
17
 *
18
 * This is a helper class to store exceptions
19
 */
20
class Storage
21
{
22
    use \Drone\Error\ErrorTrait;
23
24
    /**
25
     * Output file
26
     *
27
     * @var string
28
     */
29
    protected $outputFile;
30
31
    /**
32
     * Constructor
33
     *
34
     * @param string $outputFile
35
     *
36
     * @return null
37
     */
38 3
    public function __construct($outputFile)
39
    {
40 3
        $this->outputFile = $outputFile;
41 3
    }
42
43
    /**
44
     * Stores the exception serializing the object
45
     *
46
     * @param Exception $exception
47
     *
48
     * @return string|boolean
49
     */
50 3
    public function store(\Exception $exception)
51
    {
52
        # simple way to generate a unique id
53 3
        $id = time() . uniqid();
54
55 3
        $data = [];
56
57 3
        if (file_exists($this->outputFile)) {
58 1
            $string = file_get_contents($this->outputFile);
59
60 1
            if (!empty($string)) {
61 1
                $data   = json_decode($string, true);
62
63
                # json_encode can return TRUE, FALSE or NULL (http://php.net/manual/en/function.json-decode.php)
64 1
                if (is_null($data) || $data === false) {
65
                    $this->error(Errno::JSON_DECODE_ERROR, $this->outputFile);
0 ignored issues
show
Bug introduced by
The method error() does not exist on Drone\Exception\Storage. Since you implemented __call, consider adding a @method annotation. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

65
                    $this->/** @scrutinizer ignore-call */ 
66
                           error(Errno::JSON_DECODE_ERROR, $this->outputFile);
Loading history...
66
67 1
                    return false;
68
                }
69
            }
70
        } else {
71 3
            $directory = strstr($this->outputFile, basename($this->outputFile), true);
72
73 3
            if (!file_exists($directory)) {
74 1
                $this->error(Errno::FILE_NOT_FOUND, $directory);
75
76 1
                return false;
77
            }
78
        }
79
80 2
        $data[$id] = [
81 2
            "message" => $exception->getMessage(),
82 2
            "object"  => serialize($exception),
83
        ];
84
85 2
        if (!function_exists('mb_detect_encoding')) {
86
            throw new \RuntimeException("mbstring library is not installed!");
87
        }
88
89
        /*
90
         * Encodes to UTF8 all messages. It ensures JSON encoding.
91
         */
92 2
        if (!mb_detect_encoding($data[$id]["message"], 'UTF-8', true)) {
93
            $data[$id]["message"] = utf8_encode($data[$id]["message"]);
94
        }
95
96 2
        if (!mb_detect_encoding($data[$id]["object"], 'UTF-8', true)) {
97
            $data[$id]["object"] = utf8_decode($data[$id]["object"]);
98
        }
99
100 2
        if (($encoded_data = json_encode($data)) === false) {
101
            $this->error(Errno::JSON_ENCODE_ERROR, $this->outputFile);
102
103
            return false;
104
        }
105
106 2
        $hd = @fopen($this->outputFile, "w+");
107
108 2
        if (!$hd || !@fwrite($hd, $encoded_data)) {
0 ignored issues
show
introduced by
$hd is of type false|resource, thus it always evaluated to false.
Loading history...
109
            $this->error(Errno::FILE_PERMISSION_DENIED, $this->outputFile);
110
111
            return false;
112
        }
113
114 2
        @fclose($hd);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition for fclose(). This can introduce security issues, and is generally not recommended. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unhandled  annotation

114
        /** @scrutinizer ignore-unhandled */ @fclose($hd);

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
115
116 2
        return $id;
117
    }
118
}
119