Passed
Push — master ( 79a565...3021fc )
by Jean Paul
05:50
created

JsonExtractor::extract()   B

Complexity

Conditions 8
Paths 8

Size

Total Lines 35
Code Lines 19

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 19
c 1
b 0
f 0
dl 0
loc 35
rs 8.4444
cc 8
nc 8
nop 0
1
<?php
2
3
namespace Coco\SourceWatcher\Core\Extractors;
4
5
use Coco\SourceWatcher\Core\Extractor;
6
use Coco\SourceWatcher\Core\Row;
7
use Coco\SourceWatcher\Core\SourceWatcherException;
8
use Flow\JSONPath\JSONPath;
9
use Flow\JSONPath\JSONPathException;
10
11
/**
12
 * Class JsonExtractor
13
 * @package Coco\SourceWatcher\Core\Extractors
14
 */
15
class JsonExtractor extends Extractor
16
{
17
    /**
18
     * @var array
19
     */
20
    private array $columns = [];
21
22
    /**
23
     * @var array
24
     */
25
    protected array $availableOptions = [ "columns" ];
26
27
    /**
28
     * @return array
29
     */
30
    public function getColumns () : array
31
    {
32
        return $this->columns;
33
    }
34
35
    /**
36
     * @param array $columns
37
     */
38
    public function setColumns ( array $columns ) : void
39
    {
40
        $this->columns = $columns;
41
    }
42
43
    /**
44
     * @return array|mixed
45
     * @throws JSONPathException
46
     * @throws SourceWatcherException
47
     */
48
    public function extract ()
49
    {
50
        if ( $this->input == null ) {
51
            throw new SourceWatcherException( "An input must be provided." );
52
        }
53
54
        $result = array();
55
56
        if ( !file_exists( $this->input ) ) {
57
            throw new SourceWatcherException( "The file " . $this->input . " could not be found." );
58
        }
59
60
        $data = json_decode( file_get_contents( $this->input ), true );
61
62
        if ( $this->columns ) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $this->columns of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
63
            try {
64
                $jsonPath = new JSONPath( $data );
65
            } catch ( JSONPathException $jsonPathException ) {
66
                throw new SourceWatcherException( "Something went wrong trying to extract the JSON file: " . $jsonPathException->getMessage() );
67
            } catch ( Exception $exception ) {
0 ignored issues
show
Bug introduced by
The type Coco\SourceWatcher\Core\Extractors\Exception was not found. Did you mean Exception? If so, make sure to prefix the type with \.
Loading history...
68
                throw new SourceWatcherException( "Something unexpected went wrong trying to extract the JSON file: " . $exception->getMessage() );
69
            }
70
71
            foreach ( $this->columns as $key => $path ) {
72
                $this->columns[$key] = $jsonPath->find( $path )->data();
73
            }
74
75
            $data = $this->transpose( $this->columns );
76
        }
77
78
        foreach ( $data as $row ) {
79
            array_push( $result, new Row( $row ) );
80
        }
81
82
        return $result;
83
    }
84
85
    /**
86
     * @param $columns
87
     * @return array
88
     */
89
    private function transpose ( $columns )
90
    {
91
        $data = [];
92
93
        foreach ( $columns as $column => $items ) {
94
            foreach ( $items as $row => $item ) {
95
                $data[$row][$column] = $item;
96
            }
97
        }
98
99
        return $data;
100
    }
101
}
102