Passed
Push — master ( 33ba89...d68d30 )
by Smoren
02:11
created

ObjectTypeCaster::cast()   A

Complexity

Conditions 4
Paths 3

Size

Total Lines 22
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 12
CRAP Score 4

Importance

Changes 1
Bugs 0 Features 1
Metric Value
eloc 11
c 1
b 0
f 1
dl 0
loc 22
ccs 12
cts 12
cp 1
rs 9.9
cc 4
nc 3
nop 2
crap 4
1
<?php
2
3
namespace Smoren\TypeTools;
4
5
use TypeError;
6
7
/**
8
 * Tool for casting types of objects.
9
 */
10
class ObjectTypeCaster
11
{
12
    /**
13
     * Cast object to another relative type (upcast or downcast).
14
     *
15
     * @param object $sourceObject
16
     * @param class-string $destinationClass
0 ignored issues
show
Documentation Bug introduced by
The doc comment class-string at position 0 could not be parsed: Unknown type name 'class-string' at position 0 in class-string.
Loading history...
17
     *
18
     * @return mixed
19
     */
20 13
    public static function cast(object $sourceObject, string $destinationClass)
21
    {
22 13
        if(!class_exists($destinationClass)) {
23 4
            throw new TypeError("Class '{$destinationClass}' does not exist");
24
        }
25
26 9
        $sourceClass = get_class($sourceObject);
27
28
        // Unfortunately PHPstan has a problem with function is_subclass_of(). So:
29
        // @phpstan-ignore-next-line
30 9
        if(!is_subclass_of($sourceClass, $destinationClass) && !is_subclass_of($destinationClass, $sourceClass)) {
31 7
            throw new TypeError("Classes '{$sourceClass}' and '{$destinationClass}' must be relatives");
32
        }
33
34
        /** @var string $serialized */
35 2
        $serialized = strstr(serialize($sourceObject), '"');
36
37 2
        return unserialize(sprintf(
38 2
            'O:%d:"%s"%s',
39 2
            strlen($destinationClass),
40 2
            $destinationClass,
41 2
            strstr($serialized, ':')
42 2
        ));
43
    }
44
}
45