Storage::__construct()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 1
Bugs 1 Features 0
Metric Value
cc 1
eloc 1
c 1
b 1
f 0
nc 1
nop 1
dl 0
loc 3
ccs 2
cts 2
cp 1
crap 1
rs 10
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