Passed
Push — master ( d1df71...c2fcdd )
by Aleksandr
01:44
created

Model::__get()   B

Complexity

Conditions 7
Paths 7

Size

Total Lines 21
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 12
CRAP Score 7.1429

Importance

Changes 0
Metric Value
eloc 13
dl 0
loc 21
ccs 12
cts 14
cp 0.8571
rs 8.8333
c 0
b 0
f 0
cc 7
nc 7
nop 1
crap 7.1429
1
<?php namespace Zenwalker\CommerceML\ORM;
2
3
use Zenwalker\CommerceML\CommerceML;
4
use Zenwalker\CommerceML\Model\Simple;
5
6
/**
7
 * Class Model
8
 *
9
 * @package Zenwalker\CommerceML\ORM
10
 * @property string id
11
 * @property string name
12
 * @property string value
13
 */
14
abstract class Model extends \ArrayObject
15
{
16
    private $namespaceRegistered = false;
17
18
    /**
19
     * @var CommerceML
20
     */
21
    public $owner;
22
    /**
23
     * @var \SimpleXMLElement
24
     */
25
    public $xml;
26
27
    /**
28
     * @return array
29
     */
30 9
    public function propertyAliases()
31
    {
32
        return [
33 9
            'Ид' => 'id',
34
            'Наименование' => 'name',
35
            'Значение' => 'value',
36
        ];
37
    }
38
39
    /**
40
     * @return string
41
     */
42 3
    public function getClearId()
43
    {
44 3
        return (string)explode('#', $this->id)[0];
45
    }
46
47
    /**
48
     * @return string
49
     */
50 1
    public function getIdSuffix()
51
    {
52 1
        return (string)\array_slice(explode('#', (string)$this->id), 1)[0];
53
    }
54
55
    /**
56
     * Model constructor.
57
     *
58
     * @param CommerceML $owner
59
     * @param \SimpleXMLElement|null $xml
60
     */
61 19
    public function __construct(CommerceML $owner, \SimpleXMLElement $xml = null)
62
    {
63 19
        $this->owner = $owner;
64 19
        $this->xml = $xml ?: $this->loadXml();
0 ignored issues
show
Bug introduced by
Are you sure the usage of $this->loadXml() targeting Zenwalker\CommerceML\ORM\Model::loadXml() seems to always return null.

This check looks for function or method calls that always return null and whose return value is used.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
if ($a->getObject()) {

The method getObject() can return nothing but null, so it makes no sense to use the return value.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
65 19
        $this->init();
66 19
        parent::__construct();
67 19
    }
68
69
    /**
70
     * @param $name
71
     * @return mixed|null|\SimpleXMLElement|string
72
     */
73 11
    public function __get($name)
74
    {
75 11
        if (method_exists($this, $method = 'get' . ucfirst($name))) {
76 8
            return \call_user_func([$this, $method]);
77
        }
78 10
        if ($this->xml) {
79 10
            $attributes = $this->xml;
80 10
            if (isset($attributes[$name])) {
81
                return trim((string)$attributes[$name]);
82
            }
83 10
            if ($value = $this->xml->{$name}) {
84 2
                return $value;
85
            }
86 9
            if ($idx = array_search($name, $this->propertyAliases())) {
87 9
                if (isset($attributes[$idx])) {
88
                    return trim((string)$attributes[$idx]);
89
                }
90 9
                return trim((string)$this->xml->{$idx});
91
            }
92
        }
93 1
        return null;
94
    }
95
96
    public function __set($name, $value)
97
    {
98
    }
99
100
    public function __isset($name)
101
    {
102
    }
103
104
    public function loadXml()
105
    {
106
        $this->registerNamespace();
107
        return null;
108
    }
109
110 19
    public function init()
111
    {
112 19
        $this->registerNamespace();
113 19
    }
114
115 19
    protected function registerNamespace()
116
    {
117 19
        if ($this->xml && !$this->namespaceRegistered && ($namespaces = $this->xml->getNamespaces())) {
118 17
            $this->namespaceRegistered = true;
119 17
            foreach ($namespaces as $namespace) {
120 17
                $this->xml->registerXPathNamespace('c', $namespace);
121
            }
122
        }
123 19
    }
124
125
    /**
126
     * Лучше использовать данный метод, вместо стандартного xpath у SimpleXMLElement,
127
     * т.к. есть проблемы с неймспейсами xmlns
128
     *
129
     * Для каждого элемента необходимо указывать наймспейс "c", например:
130
     * //c:Свойство/c:ВариантыЗначений/c:Справочник[c:ИдЗначения = ':параметр']
131
     * 
132
     * @param string $path
133
     * @param array $args - Аргументы задаём в бинд стиле ['параметр'=>'значение'] без двоеточия
134
     * @return \SimpleXMLElement[]
135
     */
136 5
    public function xpath($path, $args=[])
137
    {
138 5
        $this->registerNamespace();
139 5
        if (!$this->namespaceRegistered) {
140
            $path = str_replace('c:', '', $path);
141
        }
142 5
        if (!empty($args) and is_array($args)) {
143 2
            foreach ($args as $ka=>$kv) {
144 2
                $path = str_replace(':'.$ka, (strstr($kv,"'")?("concat('" .str_replace("'", "',\"'\",'",$kv) . "')"): "'" . $kv . "'") , $path);
145
            }
146
        }
147 5
        return $this->xml->xpath($path);
148
    }
149
}
150