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

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

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
}