XmlTrait   A
last analyzed

Complexity

Total Complexity 8

Size/Duplication

Total Lines 34
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
wmc 8
eloc 19
c 1
b 0
f 0
dl 0
loc 34
rs 10

1 Method

Rating   Name   Duplication   Size   Complexity  
B readXml() 0 22 8
1
<?php
2
declare(strict_types=1);
3
4
/**
5
 * BEdita, API-first content management framework
6
 * Copyright 2024 Atlas Srl, Chialab Srl
7
 *
8
 * This file is part of BEdita: you can redistribute it and/or modify
9
 * it under the terms of the GNU Lesser General Public License as published
10
 * by the Free Software Foundation, either version 3 of the License, or
11
 * (at your option) any later version.
12
 *
13
 * See LICENSE.LGPL or <http://gnu.org/licenses/lgpl-3.0.html> for more details.
14
 */
15
namespace BEdita\ImportTools\Utility;
16
17
use Cake\Core\InstanceConfigTrait;
18
use Generator;
19
use RuntimeException;
20
use Throwable;
21
use XMLReader;
22
23
/**
24
 * Trait for share Xml stuff.
25
 *
26
 * This provides `readXml` method to progressively read a xml file element by element.
27
 *
28
 * Usage example:
29
 * ```php
30
 * use BEdita\ImportTools\Utility\XmlTrait;
31
 *
32
 * class MyImporter
33
 * {
34
 *     use XmlTrait;
35
 *
36
 *     public function import(string $filename): void
37
 *     {
38
 *         foreach ($this->readXml($filename, 'post') as $obj) {
39
 *             // process $obj
40
 *         }
41
 *     }
42
 * }
43
 * ```
44
 */
45
trait XmlTrait
46
{
47
    use InstanceConfigTrait;
48
    use FileTrait;
49
50
    /**
51
     * Progressively read a Xml file
52
     *
53
     * @param string $path Path to Xml file
54
     * @param string $element Element name for XML files
55
     * @return \Generator<array<array-key, string>>
56
     */
57
    protected function readXml(string $path, string $element): Generator
58
    {
59
        try {
60
            $reader = new XMLReader();
61
            $reader->open($path);
62
            $process = true;
63
            while ($process) {
64
                while (!($reader->nodeType == XMLReader::ELEMENT && $reader->name == $element)) {
65
                    if (!$reader->read()) {
66
                        $process = false;
67
                        break;
68
                    }
69
                }
70
                if ($reader->nodeType == XMLReader::ELEMENT && $reader->name == $element) {
71
                    $xml = simplexml_load_string($reader->readOuterXml(), null, LIBXML_NOCDATA);
72
                    $json = json_encode($xml);
73
                    yield json_decode($json, true);
74
                    $reader->next();
75
                }
76
            }
77
        } catch (Throwable $t) {
78
            throw new RuntimeException(sprintf('Cannot open file: %s', $path), 0, $t);
79
        }
80
    }
81
}
82