PluginProbe ʕ •ᴥ•ʔ
Advanced Ads – Ad Manager & AdSense / 1.8
Advanced Ads – Ad Manager & AdSense v1.8
2.0.23 2.0.22 2.0.21 1.38.0 1.39.0 1.39.1 1.39.2 1.39.3 1.39.4 1.4.0 1.4.1 1.4.2 1.4.3 1.4.4 1.4.5 1.4.6 1.4.7 1.4.8 1.4.9 1.40.0 1.40.1 1.40.2 1.41.0 1.42.0 1.42.1 1.42.2 1.43.0 1.44.0 1.44.1 1.45.0 1.45.1 1.46.0 1.47.0 1.47.1 1.47.2 1.47.3 1.47.4 1.47.5 1.48.0 1.48.1 1.49.0 1.5.0 1.5.0.1 1.5.1 1.5.2 1.5.2.1 1.5.4 1.5.4.1 1.5.5 1.50.0 1.51.0 1.51.1 1.51.2 1.51.3 1.52.0 1.52.1 1.52.2 1.52.3 1.52.4 1.53.0 1.53.1 1.53.2 1.54.0 1.54.1 1.55.0 1.56.0 1.56.1 1.56.2 1.56.3 1.56.4 1.6 1.6.1 1.6.10 1.6.10.1 1.6.10.2 1.6.11 1.6.11.1 1.6.12 1.6.13 1.6.14 1.6.15 1.6.16 1.6.17 1.6.17.1 1.6.17.2 1.6.2 1.6.2.1 1.6.3 1.6.4 1.6.4.1 1.6.5 1.6.6 1.6.6.1 1.6.7 1.6.7.1 1.6.8 1.6.8.1 1.6.8.2 1.6.8.3 1.6.9 1.6.9.1 1.6.9.2 1.6.9.3 1.6.9.4 1.7 1.7.0.1 1.7.0.2 1.7.0.3 1.7.1 1.7.1.1 1.7.1.2 1.7.1.3 1.7.1.4 1.7.1.5 1.7.10 trunk 1.7.11 1.0.1 1.7.12 1.0.2 1.7.13 1.0.3 1.7.14 1.1.0 1.7.15 1.1.1 1.7.16 1.1.2 1.7.17 1.1.3 1.7.18 1.10 1.7.19 1.10.1 1.7.2 1.10.10 1.7.2.1 1.10.11 1.7.20 1.10.12 1.7.21 1.10.2 1.7.22 1.10.3 1.7.23 1.10.4 1.7.24 1.10.5 1.7.25 1.10.6 1.7.3 1.10.7 1.7.4 1.10.8 1.7.4.1 1.10.9 1.7.4.2 1.11 1.7.4.3 1.11.1 1.7.4.4 1.11.2 1.7.4.5 1.12 1.7.5 1.13 1.7.5.1 1.13.1 1.7.6 1.13.2 1.7.7 1.13.3 1.7.8 1.13.4 1.7.9 1.13.5 1.7.9.1 1.13.6 1.7.9.2 1.13.7 1.7.9.3 1.13.8 1.8 1.14 1.8.1 1.14.1 1.8.10 1.14.10 1.8.11 1.14.11 1.8.12 1.14.2 1.8.13 1.14.3 1.8.14 1.14.4 1.8.15 1.14.5 1.8.16 1.14.6 1.8.17 1.14.7 1.8.18 1.14.8 1.8.19 1.14.9 1.8.2 1.15 1.8.20 1.16 1.8.21 1.16.1 1.8.22 1.17 1.8.23 1.17.1 1.8.24 1.17.10 1.8.25 1.17.10-rc.1 1.8.26 1.17.11 1.8.27 1.17.12 1.8.28 1.17.12-rc.1 1.8.29 1.17.2 1.8.3 1.17.3 1.8.30 1.17.4 1.8.4 1.17.5 1.8.5 1.17.6 1.8.6 1.17.7 1.8.7 1.17.8 1.8.8 1.17.9 1.8.9 1.17.9-beta.1 1.9 1.18.0 2.0.0 1.19.0 2.0.1 1.19.1 2.0.10 1.2 2.0.11 1.2.1 2.0.12 1.2.2 2.0.13 1.2.3 2.0.14 1.2.4 2.0.15 1.2.5 2.0.16 1.2.6 2.0.17 1.2.7 2.0.18 1.20.0 2.0.19 1.20.0-rc.1 2.0.2 1.20.0-rc.2 2.0.20 1.20.1 2.0.3 1.20.2 2.0.4 1.20.3 2.0.5 1.21.0 2.0.6 1.21.1 2.0.7 1.22.0 2.0.8 1.22.1 2.0.9 1.22.2 1.23.0 1.23.1 1.23.2 1.24.0 1.24.1 1.24.2 1.25.0 1.25.1 1.26.0 1.27.0 1.28.0 1.29.0 1.29.1 1.3 1.3.1 1.3.10 1.3.11 1.3.12 1.3.13 1.3.14 1.3.15 1.3.16 1.3.17 1.3.18 1.3.2 1.3.3 1.3.4 1.3.5 1.3.6 1.3.7 1.3.8 1.3.9 1.30.0 1.30.1 1.30.2 1.30.2-rc.1 1.30.3 1.30.4 1.30.4-rc.1 1.30.5 1.31.0 1.31.1 1.32.0 1.32.0-rc.1 1.33.0 1.33.1 1.33.2 1.34.0 1.35.0 1.35.1 1.36.0 1.36.1 1.36.2 1.36.3 1.37.0 1.37.1 1.37.2
advanced-ads / modules / import-export / classes / XmlEncoder.php
advanced-ads / modules / import-export / classes Last commit date
XmlEncoder.php 9 years ago export.php 9 years ago import.php 9 years ago
XmlEncoder.php
325 lines
1 <?php
2 /*
3 * Encodes XML data.
4 *
5 * Based on code from the Symfony package
6 *
7 * Copyright (c) 2004-2016 Fabien Potencier <fabien@symfony.com>
8 *
9 * Permission is hereby granted, free of charge, to any person obtaining a copy
10 * of this software and associated documentation files (the "Software"), to deal
11 * in the Software without restriction, including without limitation the rights
12 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13 * copies of the Software, and to permit persons to whom the Software is furnished
14 * to do so, subject to the following conditions:
15
16 * The above copyright notice and this permission notice shall be included in all
17 * copies or substantial portions of the Software.
18
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25 * THE SOFTWARE.
26 *
27 * @author Jordi Boggiano <j.boggiano@seld.be>
28 * @author John Wards <jwards@whiteoctober.co.uk>
29 * @author Fabian Vogler <fabian@equivalence.ch>
30 * @author Kévin Dunglas <dunglas@gmail.com>
31 */
32 class Advanced_Ads_XmlEncoder
33 {
34 /**
35 * @var DOMDocument
36 */
37 private $dom;
38
39 /**
40 * @var Advanced_Ads_XmlEncoder
41 */
42 private static $instance;
43
44 private function __construct() {}
45
46 /**
47 * @return Advanced_Ads_XmlEncoder
48 */
49 public static function get_instance()
50 {
51 if ( ! isset(self::$instance) ) {
52 self::$instance = new self;
53 }
54
55 return self::$instance;
56 }
57
58
59 public function encode( $data, $options = array()) {
60 if ( ! extension_loaded( 'simplexml' ) ) {
61 throw new Exception( sprintf( __( 'The %s extension(s) is not loaded', 'advanced-ads' ), 'simplexml' ) );
62 }
63 if ( ! extension_loaded( 'dom' ) ) {
64 throw new Exception( sprintf( __( 'The %s extension(s) is not loaded', 'advanced-ads' ), 'dom' ) );
65 }
66
67 $this->dom = new DOMDocument();
68 $this->dom->preserveWhiteSpace = false;
69 $this->dom->formatOutput = true;
70 if (isset($options['encoding'])) {
71 $this->dom->encoding = $options['encoding'];
72 }
73
74 if ( ! is_array($data) ) {
75 throw new UnexpectedValueException( _x( 'The data must be an array', 'import_export', 'advanced-ads' ) );
76 }
77
78 if (isset($options['skip_root'])) {
79 $this->buildXml($this->dom, $data );
80 } else {
81 // create root <advads-export> tag
82 $root = $this->dom->createElement('advads-export');
83 $this->dom->appendChild($root);
84 $this->buildXml($root, $data );
85 }
86
87
88 return $this->dom->saveXML();
89 }
90
91 /**
92 * Parse the data and convert it to DOMElements.
93 */
94 private function buildXml(DOMNode $parentNode, $data ) {
95 $append = true;
96
97 foreach ($data as $key => $data) {
98 if (is_numeric($key) ) {
99 $append = $this->appendNode($parentNode, $data, 'item', $key);
100 } elseif ( $this->isElementNameValid($key) ) {
101 $append = $this->appendNode($parentNode, $data, $key);
102 } else {
103 throw new UnexpectedValueException( sprintf( _x( 'The key %s is not valid', 'import_export', 'advanced-ads' ), $key ) );
104 }
105 }
106
107 return $append;
108 }
109
110
111 /**
112 * Selects the type of node to create and appends it to the parent.
113 *
114 * @param DOMNode $parentNode
115 * @param array|object $data
116 * @param string $nodeName
117 * @param string $key
118 *
119 * @return bool
120 */
121 private function appendNode(DOMNode $parentNode, $data, $nodeName, $key = null) {
122 $node = $this->dom->createElement($nodeName);
123
124 if (null !== $key) {
125 $node->setAttribute('key', $key);
126 }
127
128 $appendNode = false;
129 if (is_array($data)) {
130 $node->setAttribute('type', 'array' );
131 $appendNode = $this->buildXml($node, $data);
132 } elseif (is_numeric($data)) {
133 $node->setAttribute('type', is_string( $data) ? 'string' : 'numeric' );
134 $appendNode = $this->appendText($node, (string) $data);
135 } elseif (is_string($data)) {
136 $node->setAttribute('type', 'string');
137 $appendNode = $this->needsCdataWrapping($data) ? $this->appendCData($node, $data) : $this->appendText($node, $data);
138 } elseif (is_bool($data)) {
139 $node->setAttribute('type', 'boolean');
140 $appendNode = $this->appendText($node, (int) $data);
141 } elseif (is_null($data)) {
142 $node->setAttribute('type', 'null');
143 $appendNode = $this->appendText($node, '');
144 }
145
146 if ($appendNode) {
147 $parentNode->appendChild($node);
148 } else {
149 throw new UnexpectedValueException( sprintf( _x( 'An unexpected value could not be serialized: %s', 'import_export', 'advanced-ads' ), var_export($data, true) ) );
150 }
151
152 return $appendNode;
153 }
154
155 final protected function appendText(DOMNode $node, $val) {
156 $nodeText = $this->dom->createTextNode($val);
157 $node->appendChild($nodeText);
158
159 return true;
160 }
161
162 final protected function appendCData(DOMNode $node, $val) {
163 $nodeText = $this->dom->createCDATASection($val);
164 $node->appendChild($nodeText);
165
166 return true;
167 }
168
169 /**
170 * Checks if a value contains any characters which would require CDATA wrapping.
171 *
172 * @param string $val
173 *
174 * @return bool
175 */
176 private function needsCdataWrapping($val) {
177 return preg_match('/[<>&]/', $val);
178 }
179
180 /**
181 * Checks the name is a valid xml element name.
182 *
183 * @param string $name
184 *
185 * @return bool
186 */
187 final protected function isElementNameValid($name) {
188 return $name && false === strpos($name, ' ') && preg_match('#^[\pL_][\pL0-9._:-]*$#ui', $name);
189 }
190
191 public function decode($data) {
192 if ( ! extension_loaded( 'simplexml' ) ) {
193 throw new Exception( sprintf( __( 'The %s extension(s) is not loaded', 'advanced-ads' ), 'simplexml' ) );
194 }
195 if ( ! extension_loaded( 'dom' ) ) {
196 throw new Exception( sprintf( __( 'The %s extension(s) is not loaded', 'advanced-ads' ), 'dom' ) );
197 }
198
199
200 if ('' === trim($data)) {
201 throw new UnexpectedValueException( _x( 'Invalid XML data, it can not be empty', 'import_export', 'advanced-ads' ) );
202 }
203
204 $internalErrors = libxml_use_internal_errors(true);
205 $disableEntities = libxml_disable_entity_loader(true);
206 libxml_clear_errors();
207
208 $dom = new DOMDocument();
209
210 if ( strpos( $data, '<advads-export>' ) === false ) {
211 $data = preg_replace('/^<\?xml.*?\?>/', '', $data );
212 $data = '<advads-export>' . $data . '</advads-export>';
213 }
214
215 $dom->loadXML($data, LIBXML_NONET | LIBXML_NOBLANKS);
216
217 libxml_use_internal_errors($internalErrors);
218 libxml_disable_entity_loader($disableEntities);
219
220 if ($error = libxml_get_last_error()) {
221 libxml_clear_errors();
222
223 throw new UnexpectedValueException( sprintf( _x( 'XML error: %s', 'import_export', 'advanced-ads' ), $error->message ) );
224
225 }
226
227 // <advads-export>
228 $rootNode = $dom->firstChild;
229
230 if ($rootNode->hasChildNodes()) {
231 return $this->parseXml($rootNode);
232 }
233 }
234
235 /**
236 * Parse the input DOMNode into an array or a string.
237 *
238 * @param DOMNode $node xml to parse
239 *
240 * @return array|string
241 */
242 private function parseXml(DOMNode $node) {
243 // Parse the input DOMNode value (content and children) into an array or a string
244 $data = array();
245 if ( $node->hasAttributes() ) {
246 foreach ($node->attributes as $attr) {
247 if (ctype_digit($attr->nodeValue)) {
248 $data['@'.$attr->nodeName] = (int) $attr->nodeValue;
249 } else {
250 $data['@'.$attr->nodeName] = $attr->nodeValue;
251 }
252 }
253 }
254
255 $text_type = isset($data['@type']) ? $data['@type'] : null;
256 unset( $data['@type'] );
257
258 // Parse the input DOMNode value (content and children) into an array or a string.
259 if (!$node->hasChildNodes()) {
260 $value = $node->nodeValue;
261 } elseif (1 === $node->childNodes->length && in_array($node->firstChild->nodeType, array(XML_TEXT_NODE, XML_CDATA_SECTION_NODE))) {
262 $value = $node->firstChild->nodeValue;
263 } else {
264
265
266 $value = array();
267
268 foreach ($node->childNodes as $subnode) {
269 $val = $this->parseXml($subnode);
270
271 if ('item' === $subnode->nodeName && is_array($val) && isset($val['@key'])) {
272 $a = $val['@key'];
273 if (isset($val['#'])) {
274 $value[$a] = $val['#'] !== 'null' ? $val['#'] : null;
275 } else {
276 $value[$a] = $val !== 'null' ? $val : null;
277 }
278
279 } else {
280 $value[$subnode->nodeName][] = $val === 'null' ? null : $val;
281 }
282 }
283 foreach ($value as $key => $val) {
284 if (is_array($val) && 1 === count($val)) {
285 $value[$key] = current($val);
286 } else if ( is_array( $value[$key] ) && isset( $value[$key]['@key'] ) ) {
287 unset( $value[$key]['@key'] );
288 }
289 }
290 }
291
292 if (!count($data)) {
293 $value = $this->changeType( $value, $text_type );
294 return $value;
295 }
296
297 if (!is_array($value)) {
298 $value = $this->changeType( $value, $text_type );
299 $data['#'] = $value;
300 return $data;
301 }
302
303 if (1 === count($value) && key($value)) {
304 $data[key($value)] = current($value);
305
306 return $data;
307 }
308
309 foreach ($value as $key => $val) {
310 $data[$key] = $val;
311 }
312
313 return $data;
314 }
315
316 private function changeType( $text, $type ) {
317 if ( $type === 'string' ) return (string) $text;
318 if ( $type === 'numeric' ) return 0 + $text;
319 if ( $type === 'boolean' ) return (boolean) $text;
320 if ( $type === 'array' && $text=== '' ) return array();
321 if ( $type === 'null' ) return 'null';
322 return $text;
323 }
324
325 }