Passed
Push — master ( 370e98...e2a47d )
by Thomas
02:33
created

NamespaceStack::pop()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 7
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 6
CRAP Score 2

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 2
eloc 5
c 1
b 0
f 0
nc 2
nop 0
dl 0
loc 7
ccs 6
cts 6
cp 1
crap 2
rs 9.4285
1
<?php
2
3
namespace FluentDOM {
4
5
  use FluentDOM\XMLWriter\NamespaceDefinition;
6
  use FluentDOM\XMLWriter\NamespaceStack;
7
8
  class XMLWriter extends \XMLWriter {
9
10
    /**
11
     * @var Namespaces
12
     */
13
    private $_namespaces;
14
15
    /**
16
     * @var XMLWriter\NamespaceStack
17
     */
18
    private $_xmlnsStack;
19
20 2
    public function __construct() {
21 2
      $this->_namespaces = new Namespaces();
22 2
      $this->_xmlnsStack = new XMLWriter\NamespaceStack();
23 2
    }
24
25
    /**
26
     * register a namespace prefix for the xml reader, it will be used in
27
     * next() and other methods with a tag name argument
28
     *
29
     * @param string $prefix
30
     * @param string $namespace
31
     * @throws \LogicException
32
     */
33 1
    public function registerNamespace($prefix, $namespace) {
34 1
      $this->_namespaces[$prefix] = $namespace;
35 1
    }
36
37 2
    public function startElement($name) {
38 2
      list($prefix, $localName) = QualifiedName::split($name);
39 2
      $namespaceUri = $this->_namespaces->resolveNamespace($prefix);
0 ignored issues
show
Security Bug introduced by
It seems like $prefix defined by \FluentDOM\QualifiedName::split($name) on line 38 can also be of type false; however, FluentDOM\Namespaces::resolveNamespace() does only seem to accept string, did you maybe forget to handle an error condition?

This check looks for type mismatches where the missing type is false. This is usually indicative of an error condtion.

Consider the follow example

<?php

function getDate($date)
{
    if ($date !== null) {
        return new DateTime($date);
    }

    return false;
}

This function either returns a new DateTime object or false, if there was an error. This is a typical pattern in PHP programming to show that an error has occurred without raising an exception. The calling code should check for this returned false before passing on the value to another function or method that may not be able to handle a false.

Loading history...
40 2
      return $this->startElementNS((string)$prefix, $localName, $namespaceUri);
41
    }
42
43 2
    public function writeElement($name, $content = NULL) {
44 2
      list($prefix, $localName) = QualifiedName::split($name);
45 2
      $namespaceUri = $this->_namespaces->resolveNamespace($prefix);
0 ignored issues
show
Security Bug introduced by
It seems like $prefix defined by \FluentDOM\QualifiedName::split($name) on line 44 can also be of type false; however, FluentDOM\Namespaces::resolveNamespace() does only seem to accept string, did you maybe forget to handle an error condition?

This check looks for type mismatches where the missing type is false. This is usually indicative of an error condtion.

Consider the follow example

<?php

function getDate($date)
{
    if ($date !== null) {
        return new DateTime($date);
    }

    return false;
}

This function either returns a new DateTime object or false, if there was an error. This is a typical pattern in PHP programming to show that an error has occurred without raising an exception. The calling code should check for this returned false before passing on the value to another function or method that may not be able to handle a false.

Loading history...
46 2
      return $this->writeElementNS((string)$prefix, $localName, $namespaceUri, $content);
47
    }
48
49 2
    public function startElementNS($prefix, $name, $namespaceUri) {
50 2
      $this->_xmlnsStack->push();
51 2
      if ($this->_xmlnsStack->isDefined($prefix, $namespaceUri)) {
52 2
        parent::startElement(
0 ignored issues
show
Comprehensibility Bug introduced by
It seems like you call parent on a different method (startElement() instead of startElementNS()). Are you sure this is correct? If so, you might want to change this to $this->startElement().

This check looks for a call to a parent method whose name is different than the method from which it is called.

Consider the following code:

class Daddy
{
    protected function getFirstName()
    {
        return "Eidur";
    }

    protected function getSurName()
    {
        return "Gudjohnsen";
    }
}

class Son
{
    public function getFirstName()
    {
        return parent::getSurname();
    }
}

The getFirstName() method in the Son calls the wrong method in the parent class.

Loading history...
53 2
          empty($prefix) ? $name : $prefix.':'.$name
54 2
        );
55 2
      } else {
56 1
        parent::startElementNS($prefix, $name, $namespaceUri);
57 1
        $this->_xmlnsStack->add($prefix, $namespaceUri);
58
      }
59 2
    }
60
61 2 View Code Duplication
    public function writeElementNS($prefix, $name, $uri, $content = NULL) {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
62 2
      if ($this->_xmlnsStack->isDefined($prefix, $uri)) {
63 2
        parent::writeElement(
0 ignored issues
show
Comprehensibility Bug introduced by
It seems like you call parent on a different method (writeElement() instead of writeElementNS()). Are you sure this is correct? If so, you might want to change this to $this->writeElement().

This check looks for a call to a parent method whose name is different than the method from which it is called.

Consider the following code:

class Daddy
{
    protected function getFirstName()
    {
        return "Eidur";
    }

    protected function getSurName()
    {
        return "Gudjohnsen";
    }
}

class Son
{
    public function getFirstName()
    {
        return parent::getSurname();
    }
}

The getFirstName() method in the Son calls the wrong method in the parent class.

Loading history...
64 2
          empty($prefix) ? $name : $prefix.':'.$name, $content
65 2
        );
66 2
      } else {
67
        parent::writeElementNS($prefix, $name, $uri, $content);
68
      }
69 2
    }
70
71 2
    public function endElement() {
72 2
      $this->_xmlnsStack->pop();
73 2
      parent::endElement();
74 2
    }
75
76
    public function startAttribute($name) {
77
      list($prefix) = QualifiedName::split($name);
78
      $this->startAttributeNS($prefix, $name, $this->_namespaces->resolveNamespace($prefix));
0 ignored issues
show
Security Bug introduced by
It seems like $prefix defined by \FluentDOM\QualifiedName::split($name) on line 77 can also be of type false; however, FluentDOM\Namespaces::resolveNamespace() does only seem to accept string, did you maybe forget to handle an error condition?

This check looks for type mismatches where the missing type is false. This is usually indicative of an error condtion.

Consider the follow example

<?php

function getDate($date)
{
    if ($date !== null) {
        return new DateTime($date);
    }

    return false;
}

This function either returns a new DateTime object or false, if there was an error. This is a typical pattern in PHP programming to show that an error has occurred without raising an exception. The calling code should check for this returned false before passing on the value to another function or method that may not be able to handle a false.

Loading history...
79
    }
80
81 1
    public function writeAttribute($name, $value) {
82 1
      list($prefix) = QualifiedName::split($name);
83 1
      $this->writeAttributeNS($prefix, $name, $this->_namespaces->resolveNamespace($prefix), $value);
0 ignored issues
show
Security Bug introduced by
It seems like $prefix defined by \FluentDOM\QualifiedName::split($name) on line 82 can also be of type false; however, FluentDOM\Namespaces::resolveNamespace() does only seem to accept string, did you maybe forget to handle an error condition?

This check looks for type mismatches where the missing type is false. This is usually indicative of an error condtion.

Consider the follow example

<?php

function getDate($date)
{
    if ($date !== null) {
        return new DateTime($date);
    }

    return false;
}

This function either returns a new DateTime object or false, if there was an error. This is a typical pattern in PHP programming to show that an error has occurred without raising an exception. The calling code should check for this returned false before passing on the value to another function or method that may not be able to handle a false.

Loading history...
84 1
    }
85
86 View Code Duplication
    public function startAttributeNS($prefix, $name, $uri) {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
87
      if (empty($prefix)) {
88
        parent::startAttribute($name);
0 ignored issues
show
Comprehensibility Bug introduced by
It seems like you call parent on a different method (startAttribute() instead of startAttributeNS()). Are you sure this is correct? If so, you might want to change this to $this->startAttribute().

This check looks for a call to a parent method whose name is different than the method from which it is called.

Consider the following code:

class Daddy
{
    protected function getFirstName()
    {
        return "Eidur";
    }

    protected function getSurName()
    {
        return "Gudjohnsen";
    }
}

class Son
{
    public function getFirstName()
    {
        return parent::getSurname();
    }
}

The getFirstName() method in the Son calls the wrong method in the parent class.

Loading history...
89
      } elseif ($this->_xmlnsStack->isDefined($prefix, $uri)) {
90
        parent::startAttribute($prefix.':'.$name);
1 ignored issue
show
Comprehensibility Bug introduced by
It seems like you call parent on a different method (startAttribute() instead of startAttributeNS()). Are you sure this is correct? If so, you might want to change this to $this->startAttribute().

This check looks for a call to a parent method whose name is different than the method from which it is called.

Consider the following code:

class Daddy
{
    protected function getFirstName()
    {
        return "Eidur";
    }

    protected function getSurName()
    {
        return "Gudjohnsen";
    }
}

class Son
{
    public function getFirstName()
    {
        return parent::getSurname();
    }
}

The getFirstName() method in the Son calls the wrong method in the parent class.

Loading history...
91
      } else {
92
        parent::startAttributeNS($prefix, $name, $uri);
93
      }
94
    }
95
96 1 View Code Duplication
    public function writeAttributeNS($prefix, $name, $uri, $content) {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
97 1
      if (empty($prefix)) {
98 1
        parent::writeAttribute($name, $content);
1 ignored issue
show
Comprehensibility Bug introduced by
It seems like you call parent on a different method (writeAttribute() instead of writeAttributeNS()). Are you sure this is correct? If so, you might want to change this to $this->writeAttribute().

This check looks for a call to a parent method whose name is different than the method from which it is called.

Consider the following code:

class Daddy
{
    protected function getFirstName()
    {
        return "Eidur";
    }

    protected function getSurName()
    {
        return "Gudjohnsen";
    }
}

class Son
{
    public function getFirstName()
    {
        return parent::getSurname();
    }
}

The getFirstName() method in the Son calls the wrong method in the parent class.

Loading history...
99 1
      } elseif ($this->_xmlnsStack->isDefined($prefix, $uri)) {
100
        parent::writeAttribute($prefix.':'.$name, $content);
1 ignored issue
show
Comprehensibility Bug introduced by
It seems like you call parent on a different method (writeAttribute() instead of writeAttributeNS()). Are you sure this is correct? If so, you might want to change this to $this->writeAttribute().

This check looks for a call to a parent method whose name is different than the method from which it is called.

Consider the following code:

class Daddy
{
    protected function getFirstName()
    {
        return "Eidur";
    }

    protected function getSurName()
    {
        return "Gudjohnsen";
    }
}

class Son
{
    public function getFirstName()
    {
        return parent::getSurname();
    }
}

The getFirstName() method in the Son calls the wrong method in the parent class.

Loading history...
101
      } else {
102
        parent::writeAttributeNS($prefix, $name, $uri, $content);
103
      }
104 1
    }
105
  }
106
}
107
108
namespace FluentDOM\XMLWriter {
109
110
  class NamespaceStack {
111
112
    private $_stack = [];
113
114
    /**
115
     * @var NamespaceDefinition
116
     */
117
    private $_current;
118
119 2
    public function __construct() {
120 2
      $this->clear();
121 2
    }
122
123 2
    public function clear() {
124 2
      $this->_stack = [];
125 2
      $this->_current = new NamespaceDefinition();
126 2
    }
127
128 2
    public function push() {
129 2
      $this->_current->increaseDepth();
130 2
    }
131
132 2
    public function pop() {
133 2
      if ($this->_current->getDepth() < 1) {
134 1
        $this->_current = end($this->_stack);
135 1
      } else {
136 2
        $this->_current->decreaseDepth();
137
      }
138 2
    }
139
140 2
    public function isDefined($prefix, $namespaceUri) {
141 2
      return ($this->_current->resolveNamespace((string)$prefix) === $namespaceUri);
142
    }
143
144 1
    public function add($prefix, $namespaceUri) {
145 1
      if ($this->_current->getDepth() > 0) {
146 1
        $this->_stack[] = $this->_current;
147 1
        $this->_current = new NamespaceDefinition($this->_current);
148 1
      }
149 1
      $this->_current->registerNamespace($prefix, $namespaceUri);
150 1
    }
151
  }
152
153
  class NamespaceDefinition {
154
155
    /**
156
     * @var int
157
     */
158
    private $_indent;
159
    /**
160
     * @var \FluentDOM\Namespaces
161
     */
162
    private $_namespaces;
163
164 2
    public function __construct($inherit = NULL) {
165 2
      $this->_indent = 0;
166 2
      $this->_namespaces = new \FluentDOM\Namespaces($inherit);
167 2
    }
168
169 2
    public function getDepth() {
170 2
      return $this->_indent;
171
    }
172
173 2
    public function increaseDepth() {
174 2
      return ++$this->_indent;
175
    }
176
177 2
    public function decreaseDepth() {
178 2
      if ($this->_indent > 0) {
179 2
        return --$this->_indent;
180
      }
181
      throw new \LogicException('Did not resolve namespace levels properly.');
182
    }
183
184 1
    public function registerNamespace($prefix, $namespaceUri) {
185 1
      $this->_namespaces[$prefix] = $namespaceUri;
186 1
    }
187
188 2
    public function resolveNamespace($prefix) {
189
      try {
190 2
        return $this->_namespaces->resolveNamespace($prefix);
191 1
      } catch (\LogicException $e) {
192 1
        return '';
193
      }
194
    }
195
  }
196
}