Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
18 / 18
100.00% covered (success)
100.00%
3 / 3
CRAP
100.00% covered (success)
100.00%
1 / 1
ToJson
100.00% covered (success)
100.00%
18 / 18
100.00% covered (success)
100.00%
3 / 3
14
100.00% covered (success)
100.00%
1 / 1
 invoke
100.00% covered (success)
100.00%
5 / 5
100.00% covered (success)
100.00%
1 / 1
3
 verifySignature
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
2
 resolv
100.00% covered (success)
100.00%
12 / 12
100.00% covered (success)
100.00%
1 / 1
9
1<?php
2/**
3 * ToJson class implementation file
4 * @package Code\Simplify
5 * @author Felipe Gaspar <felipesouzalimagaspar@gmail.com>
6 */
7declare(strict_types=1);
8namespace Code\Simplify;
9
10#[\Attribute(\Attribute::TARGET_CLASS)]
11/**
12 * Implements a ToJson method
13 * @final
14 */
15final class ToJson implements MagicallyInvokedMethod {
16    /**
17     * Invokes a method from an instance with the given parameters
18     * @access public
19     * @param object $instance Object on which the method will be invoked
20     * @param string $name Method name
21     * @param array $arguments Method arguments
22     * @return mixed The return varies according to the invoked method
23     */
24    public function invoke(object $instance, string $name, array $arguments = []) : mixed {
25        $tmp = [];
26        foreach (\Code\Property\Analyzer::getAllProperties($instance) as $prop)
27            try{ $tmp[$prop->getName()] = $this->resolv($prop->getValue($instance)); }
28            catch(\TypeError $te) { continue; }
29        return json_encode($tmp, JSON_UNESCAPED_UNICODE);
30    }
31    /**
32     * Checks if the called method has the matching signature
33     * @access public
34     * @param string $name Method name
35     * @param array $arguments Method arguments
36     * @return bool The called method has the matching signature or not
37     */
38    public function verifySignature(string $name, array $arguments = []) : bool {
39        return in_array($name, ['toJson', 'toJson']) && count($arguments) === 0;
40    }
41    /**
42     * Verify and parse object properties to json format
43     * @access private
44     * @param mixed $prop Object property
45     * @return mixed The value for use in json format
46     * @throws TypeError When property is not serializable this error is throwable
47     */
48    private function resolv(mixed $prop) : mixed {
49        if($prop instanceof \JsonSerializable) {
50            return $prop->jsonSerialize();
51        } else if(
52            \Code\Type\Analyzer::isScalar($prop) || 
53            (\Code\Type\Analyzer::isObject($prop) && !($prop instanceof \Closure))
54        ) {
55            return $prop;
56        } else if(\Code\Type\Analyzer::isArray($prop) || $prop instanceof \iterable) {
57            $tmp = [];
58            foreach ($prop as $key => $value) {
59                try { $tmp[$key] = $this->resolv($value);}
60                catch(\TypeError $te) { continue; }
61            }
62            return $tmp;
63        }
64        throw new \TypeError(\Code\Type\Analyzer::getType($prop) . ' is not serializable');
65    }
66}