Xml   A
last analyzed

Complexity

Total Complexity 7

Size/Duplication

Total Lines 99
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 3

Test Coverage

Coverage 93.75%

Importance

Changes 1
Bugs 1 Features 0
Metric Value
wmc 7
lcom 1
cbo 3
dl 0
loc 99
ccs 15
cts 16
cp 0.9375
rs 10
c 1
b 1
f 0

5 Methods

Rating   Name   Duplication   Size   Complexity  
A parse() 0 22 3
A getSupportedFileExtensions() 0 4 1
A loadFile() 0 11 1
A exportFormat() 0 6 1
A __toString() 0 4 1
1
<?php
2
3
/**
4
 * Konfig.
5
 *
6
 * Yet another simple configuration loader library.
7
 *
8
 * PHP version 5
9
 *
10
 * @category Library
11
 * @package  Konfig
12
 * @author   Xeriab Nabil (aka KodeBurner) <[email protected]>
13
 * @license  https://raw.github.com/xeriab/konfig/master/LICENSE MIT
14
 * @link     https://xeriab.github.io/projects/konfig
15
 */
16
17
namespace Exen\Konfig\FileParser;
18
19
use Exception;
20
use Exen\Konfig\Exception\ParseException;
21
use Exen\Konfig\Utils;
22
23
/**
24
 * Konfig's XML parser class.
25
 *
26
 * @category FileParser
27
 * @package  Konfig
28
 * @author   Xeriab Nabil (aka KodeBurner) <[email protected]>
29
 * @license  https://raw.github.com/xeriab/konfig/master/LICENSE MIT
30
 * @link     https://xeriab.github.io/projects/konfig
31
 *
32
 * @implements Exen\Konfig\FileParser\AbstractFileParser
33
 */
34
class Xml extends AbstractFileParser
35
{
36
    /**
37
     * Loads a XML file as an array.
38
     *
39
     * @param string $path File path
40
     *
41
     * @throws ParseException If there is an error parsing XML file
42
     *
43
     * @return array The parsed data
44
     *
45
     * @since 0.1.0
46
     */
47 6
    public function parse($path)
48
    {
49 6
        $data = $this->loadFile($path);
50
51 6
        if ($data === false) {
52 3
            $lastError = libxml_get_last_error();
53
54 3
            if ($lastError !== false) {
55 3
                throw new ParseException(
56
                    [
57 3
                        'message' => $lastError->message,
58 3
                        'type' => $lastError->level,
59 3
                        'code' => $lastError->code,
60 3
                        'file' => $lastError->file,
61 3
                        'line' => $lastError->line,
62
                    ]
63 1
                );
64
            }
65
        }
66
67 3
        return json_decode(json_encode($data), true);
68
    }
69
70
    /**
71
     * {@inheritdoc}
72
     *
73
     * @return array Supported extensions
74
     *
75
     * @since 0.1.0
76
     */
77 3
    public function getSupportedFileExtensions()
78
    {
79 3
        return ['xml'];
80
    }
81
82
    /**
83
     * Loads in the given file and parses it.
84
     *
85
     * @param string $file File to load
86
     *
87
     * @return array|SimpleXMLElement The parsed file data
88
     *
89
     * @since              0.2.4
90
     * @codeCoverageIgnore
91
     */
92
    protected function loadFile($file = null)
93
    {
94
        $this->file = $file;
95
        $contents = $this->parseVars(Utils::getContent($file));
96
97
        return simplexml_load_string(
0 ignored issues
show
Bug Best Practice introduced by
The return type of return simplexml_load_st...NING | LIBXML_NOERROR); (SimpleXMLElement) is incompatible with the return type declared by the abstract method Exen\Konfig\FileParser\A...actFileParser::loadFile of type array.

If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.

Let’s take a look at an example:

class Author {
    private $name;

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

    public function getName() {
        return $this->name;
    }
}

abstract class Post {
    public function getAuthor() {
        return 'Johannes';
    }
}

class BlogPost extends Post {
    public function getAuthor() {
        return new Author('Johannes');
    }
}

class ForumPost extends Post { /* ... */ }

function my_function(Post $post) {
    echo strtoupper($post->getAuthor());
}

Our function my_function expects a Post object, and outputs the author of the post. The base class Post returns a simple string and outputting a simple string will work just fine. However, the child class BlogPost which is a sub-type of Post instead decided to return an object, and is therefore violating the SOLID principles. If a BlogPost were passed to my_function, PHP would not complain, but ultimately fail when executing the strtoupper call in its body.

Loading history...
98
            $contents,
99
            'SimpleXMLElement',
100
            LIBXML_NOWARNING | LIBXML_NOERROR
101
        );
102
    }
103
104
    /**
105
     * Returns the formatted configuration file contents.
106
     *
107
     * @param array $contents configuration array
108
     *
109
     * @return string formatted configuration file contents
110
     *
111
     * @since              0.2.4
112
     * @codeCoverageIgnore
113
     */
114
    protected function exportFormat($contents = null)
115
    {
116
        throw new Exception(
117
            'Saving configuration to `XML` is not supported at this time'
118
        );
119
    }
120
121
    /**
122
     * __toString.
123
     *
124
     * @return             string
125
     * @since              0.1.2
126
     * @codeCoverageIgnore
127
     */
128
    public function __toString()
129
    {
130
        return 'Exen\Konfig\FileParser\Xml' . PHP_EOL;
131
    }
132
}
133
134
// END OF ./src/FileParser/Xml.php FILE
135