summaryrefslogtreecommitdiffstats
path: root/library/Director/PlainObjectRenderer.php
blob: e613f1f9db23b22f0120790c59211b6be5de602a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
<?php

namespace Icinga\Module\Director;

class PlainObjectRenderer
{
    const INDENTATION = '  ';

    public static function render($object)
    {
        return self::renderObject($object);
    }

    protected static function renderBoolean($value)
    {
        return $value ? 'true' : 'false';
    }

    protected static function renderInteger($value)
    {
        return (string) $value;
    }

    protected static function renderFloat($value)
    {
        // Render .0000 floats as integers, mainly because of some JSON
        // implementations:
        if ((string) (int) $value === (string) $value) {
            return static::renderInteger((int) $value);
        } else {
            return sprintf('%F', $value);
        }
    }

    protected static function renderNull()
    {
        return 'null';
    }

    protected static function renderString($value)
    {
        return '"' . addslashes($value) . '"';
    }

    protected static function renderArray($array, $prefix = '')
    {
        if (empty($array)) {
            return '[]';
        }

        $vals = array();

        foreach ($array as $val) {
            $vals[] = $prefix
                    . self::INDENTATION
                    . self::renderObject($val, $prefix . self::INDENTATION);
        }
        return "[\n" . implode(",\n", $vals) . "\n$prefix]";
    }

    protected static function renderHash($hash, $prefix = '')
    {
        $vals = array();
        $hash = (array) $hash;
        if (empty($hash)) {
            return '{}';
        }

        if (count($hash) === 1) {
            $current = self::renderObject(current($hash), $prefix . self::INDENTATION);
            if (strlen($current) < 62) {
                return sprintf(
                    '{ %s: %s }',
                    key($hash),
                    $current
                );
            }
        }

        ksort($hash);
        foreach ($hash as $key => $val) {
            $vals[] = $prefix
                    . self::INDENTATION
                    . $key
                    . ': '
                    . self::renderObject($val, $prefix . self::INDENTATION);
        }
        return "{\n" . implode(",\n", $vals) . "\n$prefix}";
    }

    protected static function renderObject($object, $prefix = '')
    {
        if (is_null($object)) {
            return self::renderNull();
        } elseif (is_bool($object)) {
            return self::renderBoolean($object);
        } elseif (is_integer($object)) {
            return self::renderInteger($object);
        } elseif (is_float($object)) {
            return self::renderFloat($object);
        } elseif (is_object($object) || static::isAssocArray($object)) {
            return self::renderHash($object, $prefix);
        } elseif (is_array($object)) {
            return self::renderArray($object, $prefix);
        } elseif (is_string($object)) {
            return self::renderString($object);
        } else {
            return '(UNKNOWN TYPE) ' . var_export($object, true);
        }
    }

    /**
     * Check if an array contains assoc keys
     *
     * @from https://stackoverflow.com/questions/173400/how-to-check-if-php-array-is-associative-or-sequential
     * @param $arr
     * @return bool
     */
    protected static function isAssocArray($arr)
    {
        if (! is_array($arr)) {
            return false;
        }
        if (array() === $arr) {
            return false;
        }

        return array_keys($arr) !== range(0, count($arr) - 1);
    }
}