Passed
Push — master ( 9fda08...16baae )
by Sebastian
06:39
created

XMLHelper_SimpleXML::toJSON()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 1
c 0
b 0
f 0
dl 0
loc 3
rs 10
cc 1
nc 1
nop 0
1
<?php
2
/**
3
 * File containing the {@see XMLHelper_SimpleXML} class.
4
 * 
5
 * @package AppUtils
6
 * @subpackage XMLHelper
7
 * @see XMLHelper_SimpleXML
8
 */
9
10
declare(strict_types=1);
11
12
namespace AppUtils;
13
14
/**
15
 * Utility class to create SimpleXML elements, with
16
 * easier error handling. 
17
 * 
18
 * @package AppUtils
19
 * @subpackage XMLHelper
20
 * @author Sebastian Mordziol <[email protected]>
21
 */
22
class XMLHelper_SimpleXML
23
{
24
    const ERROR_NOT_LOADED_YET = 56501;
25
    
26
   /**
27
    * @var \SimpleXMLElement|NULL
28
    */
29
    private $element = null;
30
    
31
   /**
32
    * @var XMLHelper_SimpleXML_Error[]
33
    */
34
    private $errors = array();
35
    
36
   /**
37
    * Creates a simplexml instance from an XML string.
38
    *
39
    * NOTE: returns false in case of a fatal error.
40
    *
41
    * @param string $string
42
    * @return \SimpleXMLElement|NULL
43
    */
44
    public function loadString(string $string) : ?\SimpleXMLElement
45
    {
46
        return $this->load('string', $string);
47
    }
48
    
49
   /**
50
    * Creates a simplexml instance from an XML file.
51
    * 
52
    * NOTE: returns false in case of a fatal error.
53
    * 
54
    * @param string $file
55
    * @return \SimpleXMLElement|NULL
56
    */
57
    public function loadFile(string $file) : ?\SimpleXMLElement
58
    {
59
        return $this->load('file', $file);
60
    }
61
    
62
    private function load(string $mode, string $subject) : ?\SimpleXMLElement
63
    { 
64
        $this->errors = array();
65
        
66
        // to be able to fetch errors, we have to 
67
        // enable the internal errors.
68
        $use_errors = libxml_use_internal_errors(true);
69
        
70
        $this->element = $this->createInstance($mode, $subject);
71
        
72
        $this->detectErrors();
73
        
74
        // restore the previous setting just in case
75
        libxml_use_internal_errors($use_errors);
76
        
77
        return $this->element;
78
    }
79
    
80
    private function detectErrors() : void
81
    {
82
        // add any errors that were triggered, using the
83
        // error wrappers.
84
        $errors = libxml_get_errors();
85
        
86
        foreach($errors as $error) 
87
        {
88
            $this->errors[] = new XMLHelper_SimpleXML_Error($this, $error);
89
        }
90
        
91
        libxml_clear_errors();
92
    }
93
    
94
    private function createInstance(string $mode, string $subject) : ?\SimpleXMLElement
95
    {
96
        $function = 'simplexml_load_'.$mode;
97
        
98
        $xml = $function($subject);
99
        
100
        if($xml instanceof \SimpleXMLElement)
101
        {
102
            return $xml;
103
        }
104
        
105
        return null;
106
    }
107
    
108
    public function getConverter() : XMLHelper_Converter
109
    {
110
        if($this->element instanceof \SimpleXMLElement)
111
        {
112
            return XMLHelper::convertElement($this->element);
113
        }
114
        
115
        throw $this->createNotLoadedException(); 
116
    }
117
     
118
    public function toArray() : array
119
    {
120
        return $this->getConverter()->toArray();
121
    }
122
    
123
    public function toJSON() : string
124
    {
125
        return $this->getConverter()->toJSON();
126
    }
127
    
128
    public function dispose() : void
129
    {
130
        $this->element = null;
131
        $this->errors = array();
132
    }
133
    
134
    public function hasErrors() : bool
135
    {
136
        return !empty($this->errors);
137
    }
138
    
139
    /**
140
     * Retrieves all errors (if any) recorded during parsing.
141
     * @return XMLHelper_SimpleXML_Error[]
142
     */
143
    public function getErrorMessages()
144
    {
145
        return $this->errors;
146
    }
147
    
148
    private function createNotLoadedException() : XMLHelper_Exception
149
    {
150
        return new XMLHelper_Exception(
151
            'No SimpleXML element loaded.',
152
            'No element has been loaded yet. The loadFile() or loadString() method must be called first.',
153
            self::ERROR_NOT_LOADED_YET
154
        );
155
    }
156
}
157