Completed
Branch master (c971cd)
by Andrea Marco
03:24 queued 01:30
created

JsonObjects::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 2
nc 1
nop 2
dl 0
loc 5
ccs 3
cts 3
cp 1
crap 1
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace Cerbero\JsonObjects;
4
5
use Exception;
6
use JsonStreamingParser\Parser;
7
use Cerbero\JsonObjects\Listeners\AbstractListener;
8
use Cerbero\JsonObjects\Listeners\ChunkListener;
9
use Cerbero\JsonObjects\Listeners\ObjectListener;
10
11
/**
12
 * The JSON objects main class.
13
 *
14
 */
15
class JsonObjects
16
{
17
    /**
18
     * The JSON stream.
19
     *
20
     * @var resource
21
     */
22
    protected $stream;
23
24
    /**
25
     * The key containing the JSON objects.
26
     *
27
     * @var string|null
28
     */
29
    protected $key;
30
31
    /**
32
     * Set the dependencies.
33
     *
34
     * @param resource|string $source
35
     * @param string|null $key
36
     *
37
     * @throws JsonObjectsException
38
     */
39 39
    public function __construct($source, string $key = null)
40
    {
41 39
        $this->setStreamFromSource($source);
42
43 33
        $this->key = $key;
44 33
    }
45
46
    /**
47
     * Set the JSON stream from the given source
48
     *
49
     * @param mixed $source
50
     * @return void
51
     *
52
     * @throws JsonObjectsException
53
     */
54 39
    protected function setStreamFromSource($source) : void
55
    {
56 39
        if (is_resource($source)) {
57 6
            $this->stream = $source;
58 6
            return;
59
        }
60
61 33
        if (!is_string($source)) {
62 3
            throw new JsonObjectsException('Unable to create a stream from the given source.');
63
        }
64
65 30
        $this->stream = extension_loaded('zlib') ? @gzopen($source, 'rb') : @fopen($source, 'rb');
0 ignored issues
show
Documentation Bug introduced by
It seems like extension_loaded('zlib')...: @fopen($source, 'rb') can also be of type false. However, the property $stream is declared as type resource. Maybe add an additional type check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.

For example, imagine you have a variable $accountId that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to the id property of an instance of the Account class. This class holds a proper account, so the id value must no longer be false.

Either this assignment is in error or a type check should be added for that assignment.

class Id
{
    public $id;

    public function __construct($id)
    {
        $this->id = $id;
    }

}

class Account
{
    /** @var  Id $id */
    public $id;
}

$account_id = false;

if (starsAreRight()) {
    $account_id = new Id(42);
}

$account = new Account();
if ($account instanceof Id)
{
    $account->id = $account_id;
}
Loading history...
66
67 30
        if ($this->stream === false) {
68 3
            throw new JsonObjectsException("Failed to open stream from: {$source}");
69
        }
70 27
    }
71
72
    /**
73
     * Create a new instance while easing method chaining
74
     *
75
     * @param resource|string $source
76
     * @param string|null $key
77
     * @return self
78
     *
79
     * @throws JsonObjectsException
80
     */
81 24
    public static function from($source, string $key = null) : self
82
    {
83 24
        return new static($source, $key);
84
    }
85
86
    /**
87
     * Process each JSON object separately
88
     *
89
     * @param callable $callback
90
     * @return void
91
     *
92
     * @throws JsonObjectsException
93
     */
94 12
    public function each(callable $callback) : void
95
    {
96 12
        $this->parseStreamWithListener(new ObjectListener($callback));
97
    }
98
99
    /**
100
     * Parse the JSON stream with the given listener
101
     *
102
     * @param AbstractListener $listener
103
     * @return void
104
     *
105
     * @throws JsonObjectsException
106
     */
107 21
    protected function parseStreamWithListener(AbstractListener $listener) : void
108
    {
109 21
        if ($this->key !== null) {
110 12
            $listener->setTargetFromKey($this->key);
111
        }
112
113
        try {
114 21
            (new Parser($this->stream, $listener))->parse();
115 21
        } catch (Exception $e) {
116 21
            throw new JsonObjectsException($e->getMessage());
117
        } finally {
118 21
            extension_loaded('zlib') ? gzclose($this->stream) : fclose($this->stream);
119
        }
120
    }
121
122
    /**
123
     * Process JSON objects in chunks
124
     *
125
     * @param int $size
126
     * @param callable $callback
127
     * @return void
128
     *
129
     * @throws JsonObjectsException
130
     */
131 9
    public function chunk(int $size, callable $callback) : void
132
    {
133 9
        $this->parseStreamWithListener(new ChunkListener($size, $callback));
134
    }
135
}
136