Completed
Push — master ( c971cd...af3488 )
by Andrea Marco
01:50
created

JsonObjects::from()   A

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