Passed
Pull Request — develop (#2)
by Andreas
02:32
created

JSONCatalogReader::parseJSON()   B

Complexity

Conditions 6
Paths 6

Size

Total Lines 26
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 10
CRAP Score 6.8395

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 26
ccs 10
cts 14
cp 0.7143
rs 8.439
cc 6
eloc 14
nc 6
nop 1
crap 6.8395
1
<?php
2
3
namespace Wambo\Catalog;
4
5
use League\Flysystem\FilesystemInterface;
6
use Wambo\Catalog\Error\CatalogException;
7
use Wambo\Catalog\Error\JSONException;
8
use Wambo\Catalog\Mapper\CatalogMapper;
9
use Wambo\Catalog\Model\Catalog;
10
11
/**
12
 * Class JSONCatalogReader reads product and catalog data from an JSON file.
13
 */
14
class JSONCatalogReader implements CatalogReaderInterface
15
{
16
    /**
17
     * @var FilesystemInterface $filesystem The filesystem this Catalog instance works on
18
     */
19
    private $filesystem;
20
21
    /**
22
     * @var string $catalogFilePath The path to the JSON file containing the catalog in the given $filesystem
23
     */
24
    private $catalogFilePath;
25
26
    /**
27
     * @var CatalogMapper A catalog mapper for converting unstructured catalog data into Catalog models
28
     */
29
    private $catalogMapper;
30
31
    /**
32
     * Creates a new instance of the JSONCatalogReader class.
33
     *
34
     * @param FilesystemInterface $filesystem      The filesystem this Catalog instance works on
35
     * @param string              $catalogFilePath The path to the JSON file containing the catalog in the given
36
     *                                             $filesystem
37
     *
38
     * @param CatalogMapper       $catalogMapper   A catalog mapper for converting unstructured catalog data into
39
     *                                             Catalog models
40
     */
41 14
    public function __construct(FilesystemInterface $filesystem, string $catalogFilePath, CatalogMapper $catalogMapper)
42
    {
43 14
        $this->filesystem = $filesystem;
44 14
        $this->catalogFilePath = $catalogFilePath;
45 14
        $this->catalogMapper = $catalogMapper;
46 14
    }
47
48
    /**
49
     * Get the product catalog.
50
     *
51
     * @return Catalog
52
     *
53
     * @throws CatalogException If the catalog could not be created.
54
     */
55 14
    public function getCatalog()
56
    {
57 14
        if ($this->filesystem->has($this->catalogFilePath) === false) {
58 1
            return new Catalog([]);
59
        }
60
61
        try {
62
63 13
            $json = $this->filesystem->read($this->catalogFilePath);
64
65
            // handle read errors
66 13
            if ($json === false) {
67 1
               throw new CatalogException(sprintf("Failed to read %s", $this->catalogFilePath));
68
            }
69
70 12
            $catalogData = $this->parseJSON($json);
71
72
            // convert the catalog data into a Catalog model
73 7
            $catalog = $this->catalogMapper->getCatalog($catalogData);
74
75 5
            return $catalog;
76
77 8
        } catch (\Exception $catalogException) {
78 8
            throw new CatalogException(sprintf("Unable to read catalog from %s: ", $this->catalogFilePath,
79 8
                $catalogException->getMessage()), $catalogException);
80
        }
81
    }
82
83
    /**
84
     * Parse the given JSON and convert it into an array.
85
     *
86
     * @param string $json JSON code
87
     *
88
     * @return array
89
     *
90
     * @throws JSONException If the given JSON could not be parsed
91
     */
92 12
    private function parseJSON($json)
93
    {
94 12
        $catalogData = json_decode($json, true);
95
96
        // handle errors
97 12
        switch (json_last_error()) {
98
99 12
            case JSON_ERROR_DEPTH:
100
                throw new JSONException("The maximum stack depth has been exceeded");
101
102 12
            case JSON_ERROR_STATE_MISMATCH:
103
                throw new JSONException("Invalid or malformed JSON");
104
105 12
            case JSON_ERROR_CTRL_CHAR:
106
                throw new JSONException("Control character error, possibly incorrectly encoded");
107
108 12
            case JSON_ERROR_SYNTAX:
109 5
                throw new JSONException("Syntax error");
110
111 7
            case JSON_ERROR_UTF8:
112
                throw new JSONException("Malformed UTF-8 characters, possibly incorrectly encoded");
113
114
        }
115
116 7
        return $catalogData;
117
    }
118
}