Passed
Push — master ( 863f0a...b0d82b )
by Darío
01:40
created

Storage::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 1
dl 0
loc 3
rs 10
c 0
b 0
f 0
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
    public function __construct($outputFile)
39
    {
40
        $this->outputFile = $outputFile;
41
    }
42
43
    /**
44
     * Stores the exception serializing the object
45
     *
46
     * @param Exception $exception
47
     *
48
     * @return string|boolean
49
     */
50
    public function store(\Exception $exception)
51
    {
52
        # simple way to generate a unique id
53
        $id = time() . uniqid();
54
55
        $data = [];
56
57
        if (file_exists($this->outputFile))
58
        {
59
            $string = file_get_contents($this->outputFile);
60
61
            if (!empty($string))
62
            {
63
                $data   = json_decode($string, true);
64
65
                # json_encode can return TRUE, FALSE or NULL (http://php.net/manual/en/function.json-decode.php)
66
                if (is_null($data) || $data === false)
67
                {
68
                    $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

68
                    $this->/** @scrutinizer ignore-call */ 
69
                           error(Errno::JSON_DECODE_ERROR, $this->outputFile);
Loading history...
69
                    return false;
70
                }
71
            }
72
        }
73
        else
74
        {
75
            $directory = strstr($this->outputFile, basename($this->outputFile), true);
76
77
            if (!file_exists($directory))
78
            {
79
                $this->error(Errno::FILE_NOT_FOUND, $directory);
80
                return false;
81
            }
82
        }
83
84
        $data[$id] = [
85
            "message" => $exception->getMessage(),
86
            "object"  => serialize($exception)
87
        ];
88
89
        if (!function_exists('mb_detect_encoding'))
90
            throw new \RuntimeException("mbstring library is not installed!");
91
92
        /*
93
         * Encodes to UTF8 all messages. It ensures JSON encoding.
94
         */
95
        if (!mb_detect_encoding($data[$id]["message"], 'UTF-8', true))
96
            $data[$id]["message"] = utf8_encode($data[$id]["message"]);
97
98
        if (!mb_detect_encoding($data[$id]["object"], 'UTF-8', true))
99
            $data[$id]["object"] = utf8_decode($data[$id]["object"]);
100
101
        if (($encoded_data = json_encode($data)) === false)
102
        {
103
            $this->error(Errno::JSON_ENCODE_ERROR, $this->outputFile);
104
            return false;
105
        }
106
107
        $hd = @fopen($this->outputFile, "w+");
108
109
        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...
110
        {
111
            $this->error(Errno::FILE_PERMISSION_DENIED, $this->outputFile);
112
            return false;
113
        }
114
115
        @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

115
        /** @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...
116
117
        return $id;
118
    }
119
}