Meta::getContext()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 4
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 0
1
<?php
2
3
/*
4
 * This file is part of the Superdesk Web Publisher Templates System.
5
 *
6
 * Copyright 2015 Sourcefabric z.ú. and contributors.
7
 *
8
 * For the full copyright and license information, please see the
9
 * AUTHORS and LICENSE files distributed with this source code.
10
 *
11
 * @copyright 2015 Sourcefabric z.ú
12
 * @license http://www.superdesk.org/license
13
 */
14
15
namespace SWP\Component\TemplatesSystem\Gimme\Meta;
16
17
use SWP\Component\TemplatesSystem\Gimme\Context\Context;
18
use SWP\Component\TemplatesSystem\Gimme\Event\MetaEvent;
19
20
class Meta implements MetaInterface
21
{
22
    protected $values;
23
24
    protected $context;
25
26
    protected $configuration;
27
28
    private $copiedValues = [];
29
30
    public function __construct(Context $context, $values, $configuration)
31
    {
32
        $this->context = $context;
33
        $this->values = $values;
34
        $this->configuration = $configuration;
35
36
        $this->context->registerMeta($this);
37
    }
38
39
    /**
40
     * Use to_string property from configuration if provided, json with exposed properties otherwise.
41
     *
42
     * @return string
43
     */
44
    public function __toString()
45
    {
46
        if (array_key_exists('to_string', $this->configuration)) {
47
            $toStringProperty = $this->configuration['to_string'];
48
            $this->load($toStringProperty);
49
            if (isset($this->copiedValues[$toStringProperty])) {
50
                return (string) $this->copiedValues[$toStringProperty];
51
            }
52
        }
53
54
        return gettype($this->values);
55
    }
56
57
    /**
58
     * @param string $name
59
     *
60
     * @return bool
61
     */
62
    public function __isset(string $name)
63
    {
64
        $this->load($name);
65
        if (array_key_exists($name, $this->copiedValues)) {
66
            return true;
67
        }
68
69
        return false;
70
    }
71
72
    /**
73
     * @param string $name
74
     * @param mixed  $value
75
     */
76
    public function __set($name, $value)
77
    {
78
        if ($value instanceof \Traversable || is_array($value)) {
79
            $newValue = [];
80
81
            foreach ($value as $key => $item) {
82
                $newValue[$key] = $this->getValueOrMeta($item);
83
            }
84
85
            $this->copiedValues[$name] = $newValue;
86
87
            return;
88
        }
89
90
        $this->copiedValues[$name] = $this->getValueOrMeta($value);
91
    }
92
93
    /**
94
     * @param string $name
95
     *
96
     * @return mixed|null
97
     */
98
    public function __get(string $name)
99
    {
100
        if (array_key_exists($name, $this->copiedValues)) {
101
            return $this->copiedValues[$name];
102
        }
103
        $this->load($name);
104
105
        return $this->copiedValues[$name];
106
    }
107
108
    /**
109
     * @return array|object|string
110
     */
111
    public function getValues()
112
    {
113
        return $this->values;
114
    }
115
116
    public function getConfiguration(): array
117
    {
118
        return $this->configuration;
119
    }
120
121
    public function setConfiguration(array $configuration): void
122
    {
123
        $this->configuration = $configuration;
124
    }
125
126
    public function getContext(): Context
127
    {
128
        return $this->context;
129
    }
130
131
    public function __sleep()
132
    {
133
        unset($this->values, $this->context, $this->configuration);
134
135
        return array_keys(get_object_vars($this));
136
    }
137
138
    private function fillFromArray(array $values, array $configuration, string $name): void
139
    {
140
        if (isset($configuration['properties'][$name], $values[$name]) && count($values) > 0) {
141
            $this->$name = $values[$name];
142
        }
143
    }
144
145
    private function fillFromObject($values, array $configuration, string $name): void
146
    {
147
        if (!isset($configuration['properties'][$name])) {
148
            return;
149
        }
150
151
        $event = new MetaEvent($this->getValues(), $name);
152
        $this->context->dispatchMetaEvent($event);
153
        if ($event->isResultSet()) {
154
            $this->$name = $event->getResult();
155
156
            return;
157
        }
158
159
        $getterName = 'get'.ucfirst($name);
160
        if ('bool' === $configuration['properties'][$name]['type']) {
161
            $getterName = (0 !== strpos($name, 'is')) ? 'is'.ucfirst($name) : $name;
162
        }
163
164
        if (method_exists($values, $getterName)) {
165
            $this->$name = $values->$getterName();
166
        }
167
    }
168
169
    private function isJson(string $string): bool
170
    {
171
        json_decode($string, false);
172
173
        return JSON_ERROR_NONE === json_last_error();
174
    }
175
176
    /**
177
     * @param mixed $value
178
     *
179
     * @return mixed|Meta
180
     */
181
    private function getValueOrMeta($value)
182
    {
183
        if ($this->context->isSupported($value)) {
184
            return $this->context->getMetaForValue($value);
185
        }
186
187
        return $value;
188
    }
189
190
    private function load(string $name): void
191
    {
192
        if (is_array($this->values)) {
193
            $this->fillFromArray($this->values, $this->configuration, $name);
194
        } elseif (is_string($this->values) && $this->isJson($this->values)) {
195
            $this->fillFromArray(json_decode($this->values, true), $this->configuration, $name);
196
        } elseif (is_object($this->values)) {
197
            $this->fillFromObject($this->values, $this->configuration, $name);
198
        }
199
    }
200
}
201