ComVariantWrapper::canIterateObject()   A
last analyzed

Complexity

Conditions 3
Paths 2

Size

Total Lines 11
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 12

Importance

Changes 0
Metric Value
eloc 6
dl 0
loc 11
ccs 0
cts 6
cp 0
rs 10
c 0
b 0
f 0
cc 3
nc 2
nop 0
crap 12
1
<?php
2
3
namespace PhpWinTools\Support\COM;
4
5
use ArrayIterator;
6
use COM as ComExt;
7
use IteratorAggregate;
8
use VARIANT as VariantExt;
9
use PhpWinTools\Support\COM\Testing\COMObjectFake;
10
use PhpWinTools\WmiScripting\Configuration\Config;
11
use PhpWinTools\Support\COM\Testing\ComVariantWrapperFake;
12
use PhpWinTools\WmiScripting\Support\ApiObjects\VariantInterfaces\AllVariantsInterface;
13
14
class ComVariantWrapper implements IteratorAggregate
15
{
16
    /** @var ComExt|VariantExt */
17
    protected $comObject;
18
19
    protected $config;
20
21 2
    public function __construct($comObject, Config $config = null)
22
    {
23 2
        $this->comObject = $comObject;
24 2
        $this->config = $config ?? Config::instance();
25 2
    }
26
27
    public static function comToString(self $com)
28
    {
29
        ob_start();
30
        com_print_typeinfo($com->getComObject());
31
        $com_string = ob_get_contents();
32
        ob_end_clean();
33
34
        return $com_string;
35
    }
36
37 2
    public static function getComClassName(self $com)
38
    {
39 2
        if ($com->getComObject() instanceof COMObjectFake) {
0 ignored issues
show
introduced by
$com->getComObject() is never a sub-type of PhpWinTools\Support\COM\Testing\COMObjectFake.
Loading history...
40 2
            return ComVariantWrapperFake::comToString($com);
41
        }
42
43
        preg_match('~(?<=\bclass\s)(\w+)~', self::comToString($com), $matches, 0, 0);
44
45
        return $matches[0];
46
    }
47
48 2
    public function getComObject()
49
    {
50 2
        return $this->comObject;
51
    }
52
53
    public function canIterateObject()
54
    {
55
        try {
56
            foreach ($this->comObject as $item) {
57
                return true;
58
            }
59
        } catch (\Exception $exception) {
0 ignored issues
show
Unused Code introduced by
catch (\Exception $exception) is not reachable.

This check looks for unreachable code. It uses sophisticated control flow analysis techniques to find statements which will never be executed.

Unreachable code is most often the result of return, die or exit statements that have been added for debug purposes.

function fx() {
    try {
        doSomething();
        return true;
    }
    catch (\Exception $e) {
        return false;
    }

    return false;
}

In the above example, the last return false will never be executed, because a return statement has already been met in every possible execution path.

Loading history...
60
            return false;
61
        }
62
63
        return true;
64
    }
65
66 2
    public function propertyExists(string $property)
67
    {
68
        try {
69 2
            $this->comObject->{$property};
70
71 2
            return true;
72
        } catch (\Exception $exception) {
0 ignored issues
show
Unused Code introduced by
catch (\Exception $exception) is not reachable.

This check looks for unreachable code. It uses sophisticated control flow analysis techniques to find statements which will never be executed.

Unreachable code is most often the result of return, die or exit statements that have been added for debug purposes.

function fx() {
    try {
        doSomething();
        return true;
    }
    catch (\Exception $e) {
        return false;
    }

    return false;
}

In the above example, the last return false will never be executed, because a return statement has already been met in every possible execution path.

Loading history...
73
            return false;
74
        }
75
    }
76
77 2
    public function canIterateProperty(string $property)
78
    {
79 2
        if (!$this->propertyExists($property)) {
80
            return false;
81
        }
82
83
        try {
84 2
            foreach ($this->comObject->{$property} as $item) {
85 2
                return true;
86
            }
87
        } catch (\Exception $exception) {
0 ignored issues
show
Unused Code introduced by
catch (\Exception $exception) is not reachable.

This check looks for unreachable code. It uses sophisticated control flow analysis techniques to find statements which will never be executed.

Unreachable code is most often the result of return, die or exit statements that have been added for debug purposes.

function fx() {
    try {
        doSomething();
        return true;
    }
    catch (\Exception $e) {
        return false;
    }

    return false;
}

In the above example, the last return false will never be executed, because a return statement has already been met in every possible execution path.

Loading history...
88
            return false;
89
        }
90
91
        return true;
92
    }
93
94 2
    public function propertyToArray(string $property)
95
    {
96 2
        if (!$this->canIterateProperty($property)) {
97
            return [];
98
        }
99
100 2
        $items = [];
101
102 2
        foreach ($this->comObject->{$property} as $item) {
103 2
            $items[] = $this->transformResult($item);
104
        }
105
106 2
        return $items;
107
    }
108
109
    /**
110
     * @param $property
111
     *
112
     * @return mixed|AllVariantsInterface|ComWrapper|VariantWrapper
113
     */
114 2
    public function __get($property)
115
    {
116 2
        $result = $this->comObject->{$property};
117
        // this could fail so add exception
118
119 2
        return $this->transformResult($result);
120
    }
121
122
    /**
123
     * @param $method
124
     * @param $arguments
125
     *
126
     * @return mixed|AllVariantsInterface|ComWrapper|VariantWrapper
127
     */
128 2
    public function __call($method, $arguments)
129
    {
130 2
        $result = $this->comObject->{$method}(...$arguments);
131
        // this could fail so add exception
132
133 2
        return $this->transformResult($result);
134
    }
135
136
    protected function resolve(string $class = null, ...$parameters)
137
    {
138
        return ($this->config)($class, $parameters);
139
    }
140
141
    /**
142
     * @param $result
143
     *
144
     * @return mixed|AllVariantsInterface|ComWrapper|VariantWrapper
145
     */
146 2
    protected function transformResult($result)
147
    {
148 2
        if ($result instanceof VariantExt) {
149
            $result = $this->resolve()->variantWrapper($result, $this->config);
150
        }
151
152 2
        if ($result instanceof ComExt) {
153
            $result = $this->resolve()->comWrapper($result, $this->config);
154
        }
155
156 2
        return $result;
157
    }
158
159 2
    public function getIterator()
160
    {
161 2
        $items = [];
162
163 2
        foreach ($this->comObject as $item) {
164 2
            $items[] = $this->transformResult($item);
165
        }
166
167 2
        return new ArrayIterator($items);
168
    }
169
}
170