Completed
Push — master ( dac95d...cf9e7d )
by Thomas
02:37
created

src/FluentDOM/Loader/JSONx.php (1 issue)

Labels
Severity

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
/**
3
 * A loader that converts JSONx into JsonDOM
4
 *
5
 * @license http://www.opensource.org/licenses/mit-license.php The MIT License
6
 * @copyright Copyright (c) 2009-2014 Bastian Feder, Thomas Weinert
7
 */
8
9
namespace FluentDOM\Loader {
10
11
  use FluentDOM\Document;
12
  use FluentDOM\DocumentFragment;
13
  use FluentDOM\Element;
14
  use FluentDOM\Loadable;
15
  use FluentDOM\QualifiedName;
16
17
  /**
18
   * A lazy load group for php class loaders
19
   *
20
   * This defines loaders for PHP classes like SimpleXML
21
   */
22
  class JSONx implements Loadable {
23
24
    use Supports\Libxml;
25
26
    const XMLNS_JSONX = 'http://www.ibm.com/xmlns/prod/2009/jsonx';
27
    const XMLNS_JSONDOM = 'urn:carica-json-dom.2013';
28
    const DEFAULT_QNAME = '_';
29
30
    /**
31
     * @return string[]
32
     */
33 14
    public function getSupported() {
34 14
      return array('jsonx', 'application/xml+jsonx');
35
    }
36
37
    /**
38
     * @see Loadable::load
39
     * @param string $source
40
     * @param string $contentType
41
     * @param array|\Traversable|Options $options
42
     * @return Document|Result|NULL
43
     */
44 12
    public function load($source, $contentType, $options = []) {
45 12
      if ($this->supports($contentType) && !empty($source)) {
46 11
        $document = (new Libxml\Errors())->capture(
47 11
          function() use ($source, $contentType, $options) {
48 11
            $document = new Document();
49 11
            $document->preserveWhiteSpace = FALSE;
50 11
            $document->registerNamespace('jx', self::XMLNS_JSONX);
51 11
            $options = $this->getOptions($options);
0 ignored issues
show
Consider using a different name than the imported variable $options, or did you forget to import by reference?

It seems like you are assigning to a variable which was imported through a use statement which was not imported by reference.

For clarity, we suggest to use a different name or import by reference depending on whether you would like to have the change visibile in outer-scope.

Change not visible in outer-scope

$x = 1;
$callable = function() use ($x) {
    $x = 2; // Not visible in outer scope. If you would like this, how
            // about using a different variable name than $x?
};

$callable();
var_dump($x); // integer(1)

Change visible in outer-scope

$x = 1;
$callable = function() use (&$x) {
    $x = 2;
};

$callable();
var_dump($x); // integer(2)
Loading history...
52 11
            $options->isAllowed($sourceType = $options->getSourceType($source));
53
            switch ($sourceType) {
54 11
            case Options::IS_FILE :
55 1
              $document->load($source, $options[Options::LIBXML_OPTIONS]);
56 1
              break;
57 10
            case Options::IS_STRING :
58 10
            default :
59 10
              $document->loadXML($source, $options[Options::LIBXML_OPTIONS]);
60 10
              break;
61
            }
62 11
            return $document;
63
          }
64 11
        );
65 11
        $target = new Document();
66 11
        $target->registerNamespace('json', self::XMLNS_JSONDOM);
67 11
        if (isset($document->documentElement)) {
68 11
          $this->transferNode($document->documentElement, $target);
69 11
        }
70 11
        return $target;
71
      }
72 1
      return NULL;
73
    }
74
75
     /**
76
      * @see Loadable::loadFragment
77
      *
78
      * @param string $source
79
      * @param string $contentType
80
      * @param array|\Traversable|Options $options
81
      * @return DocumentFragment|NULL
82
      */
83 2
    public function loadFragment($source, $contentType, $options = []) {
84 2
      if ($this->supports($contentType) && !empty($source)) {
85 1
        $document = new Document();
86 1
        $document->preserveWhiteSpace = FALSE;
87 1
        $document->registerNamespace('jx', self::XMLNS_JSONX);
88 1
        $sourceFragment = $document->createDocumentFragment();
89 1
        $sourceFragment->appendXml($source);
90 1
        $target = new Document();
91 1
        $target->registerNamespace('json', self::XMLNS_JSONDOM);
92 1
        $targetFragment = $target->createDocumentFragment();
93 1
        foreach ($sourceFragment->childNodes as $node) {
94 1
          $this->transferNode($node, $targetFragment);
95 1
        }
96 1
        return $targetFragment;
97
      }
98 1
      return NULL;
99
    }
100
101
    /**
102
     * @param \DOMNode|Element $node
103
     * @param \DOMNode|Document|Element $target
104
     */
105 12
    private function transferNode(\DOMNode $node, \DOMNode $target) {
106 12
      if ($node->namespaceURI === self::XMLNS_JSONX) {
107 12
        if ($target instanceOf Document) {
108 11
          $normalizedName = $name = 'json:json';
109 11
        } else {
110 12
          $name = $node->getAttribute('name');
111 12
          $normalizedName = QualifiedName::normalizeString($name, self::DEFAULT_QNAME);
112
        }
113 12
        $type = $node->localName;
114 12
        $newNode = $target->appendElement($normalizedName);
115 12
        if ($name !== $normalizedName && $name !== '') {
116 1
          $newNode->setAttribute('json:name', $name);
117 1
        }
118
        switch ($type) {
119 12
        case 'object' :
120 11
          if ($node('count(*) > 0')) {
121 11
            foreach ($node('*') as $childNode) {
122 11
              $this->transferNode($childNode, $newNode);
123 11
            }
124 11
            return;
125
          }
126 1
          break;
127 11
        case 'array' :
128 3
          foreach ($node('*') as $childNode) {
129 3
            $this->transferNode($childNode, $newNode);
130 3
          }
131 3
          break;
132 11
        case 'string' :
133 7
          $newNode->append((string)$node);
134 7
          return;
135 5
        default :
136 5
          $newNode->append((string)$node);
137 5
          break;
138 5
        }
139 11
        $newNode->setAttribute('json:type', $type);
140 8
      }
141 11
    }
142
  }
143
}