Completed
Push — master ( 83f82b...f3d39e )
by Rafał
01:39
created

Context::setPreviewMode()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 4
rs 10
c 0
b 0
f 0
cc 1
eloc 2
nc 1
nop 1
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\Context;
16
17
use Doctrine\Common\Cache\Cache;
18
use SWP\Component\TemplatesSystem\Gimme\Meta\Meta;
19
use Symfony\Component\Finder\Finder;
20
use Symfony\Component\Yaml\Parser;
21
22
class Context implements \ArrayAccess
23
{
24
    /**
25
     * Array with current page information's.
26
     *
27
     * @var Meta
28
     */
29
    protected $currentPage;
30
31
    /**
32
     * Array will all registered meta types.
33
     *
34
     * @var Meta[]
35
     */
36
    protected $registeredMeta = [];
37
38
    /**
39
     * Array with available meta configs.
40
     *
41
     * @var array
42
     */
43
    protected $availableConfigs = [];
44
45
    /**
46
     * @var Cache
47
     */
48
    protected $metadataCache;
49
50
    /**
51
     * @var string
52
     */
53
    protected $configsPath;
54
55
    /**
56
     * @var array
57
     */
58
    private $temporaryMeta = [];
59
60
    /**
61
     * @var bool
62
     */
63
    private $previewMode = false;
64
65
    /**
66
     * Context constructor.
67
     *
68
     * @param Cache  $metadataCache
69
     * @param string $configsPath
70
     */
71
    public function __construct(Cache $metadataCache, $configsPath = null)
72
    {
73
        $this->metadataCache = $metadataCache;
74
        $this->configsPath = $configsPath;
75
    }
76
77
    /**
78
     * @return array
79
     */
80
    public function getAvailableConfigs()
81
    {
82
        if (0 === count($this->availableConfigs)) {
83
            $this->loadConfigsFromPath($this->configsPath);
84
        }
85
86
        return $this->availableConfigs;
87
    }
88
89
    /**
90
     * @param array $configuration
91
     *
92
     * @return bool
93
     */
94
    public function addAvailableConfig(array $configuration)
95
    {
96
        if (isset($configuration['class']) && !isset($this->availableConfigs[$configuration['class']])) {
97
            $this->availableConfigs[$configuration['class']] = $configuration;
98
99
            return true;
100
        }
101
102
        return false;
103
    }
104
105
    /**
106
     * @param array $availableConfigs
107
     *
108
     * @return Context
109
     */
110
    public function setAvailableConfigs(array $availableConfigs)
111
    {
112
        $this->availableConfigs = $availableConfigs;
113
114
        return $this;
115
    }
116
117
    /**
118
     * @param string $configsPath
119
     */
120
    public function loadConfigsFromPath($configsPath)
121
    {
122
        if (file_exists($configsPath)) {
123
            $finder = new Finder();
124
            $finder->in($configsPath)->files()->name('*.yml');
125
126
            foreach ($finder as $file) {
127
                $this->addNewConfig($file->getRealPath());
128
            }
129
        }
130
    }
131
132
    /**
133
     * @param mixed $value
134
     *
135
     * @return array
136
     *
137
     * @throws \Exception
138
     */
139
    public function getConfigurationForValue($value)
140
    {
141
        if (false === is_object($value)) {
142
            throw new \Exception('Context supports configuration loading only for objects');
143
        }
144
145
        foreach ($this->getAvailableConfigs() as $class => $configuration) {
146
            if ($value instanceof $class) {
147
                return $configuration;
148
            }
149
        }
150
151
        return [];
152
    }
153
154
    /**
155
     * @param mixed $value
156
     *
157
     * @return Meta
158
     */
159
    public function getMetaForValue($value)
160
    {
161
        return new Meta($this, $value, $this->getConfigurationForValue($value));
162
    }
163
164
    /**
165
     * @param mixed $value
166
     *
167
     * @return bool
168
     */
169
    public function isSupported($value)
170
    {
171
        if (!is_object($value)) {
172
            return false;
173
        }
174
175
        return count($this->getConfigurationForValue($value)) > 0 ? true : false;
176
    }
177
178
    /**
179
     * @param string $filePath
180
     *
181
     * @return $this
182
     */
183
    public function addNewConfig($filePath)
184
    {
185
        $cacheKey = md5($filePath);
186
        if (!$this->metadataCache->contains($cacheKey)) {
187
            if (!is_readable($filePath)) {
188
                throw new \InvalidArgumentException('Configuration file is not readable for parser');
189
            }
190
            $parser = new Parser();
191
            $configuration = $parser->parse(file_get_contents($filePath));
192
            $this->metadataCache->save($cacheKey, $configuration);
193
        } else {
194
            $configuration = $this->metadataCache->fetch($cacheKey);
195
        }
196
197
        $this->addAvailableConfig($configuration);
198
199
        return $configuration;
200
    }
201
202
    /**
203
     * Set current context page information's.
204
     *
205
     * @param Meta $currentPage
206
     *
207
     * @return self
208
     */
209
    public function setCurrentPage(Meta $currentPage)
210
    {
211
        $this->currentPage = $currentPage;
212
213
        return $this;
214
    }
215
216
    /**
217
     * Get current context page information's.
218
     *
219
     * @return Meta
220
     */
221
    public function getCurrentPage()
222
    {
223
        return $this->currentPage;
224
    }
225
226
    /**
227
     * Register new meta type, registration is required before setting new value for meta.
228
     *
229
     * @param Meta|null $meta Meta object
230
     *
231
     * @throws \Exception if already registered
232
     *
233
     * @return bool if registered successfully
234
     */
235
    public function registerMeta(Meta $meta = null)
236
    {
237
        $configuration = $meta->getConfiguration();
0 ignored issues
show
Bug introduced by
It seems like $meta is not always an object, but can also be of type null. Maybe add an additional type check?

If a variable is not always an object, we recommend to add an additional type check to ensure your method call is safe:

function someFunction(A $objectMaybe = null)
{
    if ($objectMaybe instanceof A) {
        $objectMaybe->doSomething();
    }
}
Loading history...
238
        $name = $configuration['name'];
239
        if (!array_key_exists($name, $this->registeredMeta)) {
240
            $this->registeredMeta[$name] = $configuration;
241
242
            if (null !== $meta) {
243
                $this[$name] = $meta;
244
            }
245
246
            return true;
247
        }
248
249
        return false;
250
    }
251
252
    /**
253
     * @return Meta[]
254
     */
255
    public function getRegisteredMeta()
256
    {
257
        return $this->registeredMeta;
258
    }
259
260
    /**
261
     * @return bool
262
     */
263
    public function isPreviewMode(): bool
264
    {
265
        return $this->previewMode;
266
    }
267
268
    /**
269
     * @param bool $previewMode
270
     */
271
    public function setPreviewMode(bool $previewMode)
272
    {
273
        $this->previewMode = $previewMode;
274
    }
275
276
    /**
277
     * {@inheritdoc}
278
     */
279
    public function offsetSet($name, $meta)
280
    {
281
        if (array_key_exists($name, $this->registeredMeta)) {
282
            $this->$name = $meta;
283
        }
284
285
        return true;
286
    }
287
288
    /**
289
     * {@inheritdoc}
290
     */
291
    public function offsetExists($name)
292
    {
293
        return isset($this->$name);
294
    }
295
296
    /**
297
     * {@inheritdoc}
298
     */
299
    public function offsetUnset($name)
300
    {
301
        unset($this->$name);
302
303
        return true;
304
    }
305
306
    /**
307
     * {@inheritdoc}
308
     */
309
    public function offsetGet($name)
310
    {
311
        if (array_key_exists($name, $this->registeredMeta) && isset($this->$name)) {
312
            return $this->$name;
313
        }
314
315
        return false;
316
    }
317
318
    /**
319
     * @param array $keys
320
     *
321
     * @return string
322
     */
323
    public function temporaryUnset(array $keys)
324
    {
325
        $metas = [];
326
        $keysId = md5(serialize($keys));
327
328
        if (count($keys) === 0) {
329
            foreach ($this->registeredMeta as $key => $configuration) {
330
                if (isset($this[$key])) {
331
                    $metas[$key] = $this[$key];
332
                    unset($this[$key]);
333
                }
334
            }
335
        }
336
337
        foreach ($keys as $key) {
338
            if (array_key_exists($key, $this->registeredMeta)) {
339
                $metas[$key] = $this[$key];
340
                unset($this[$key]);
341
            }
342
        }
343
        $this->temporaryMeta[$keysId] = $metas;
344
345
        return $keysId;
346
    }
347
348
    /**
349
     * @param string $id
350
     *
351
     * @return null|true
352
     */
353
    public function restoreTemporaryUnset($id)
354
    {
355
        $metas = $this->temporaryMeta[$id];
356
        if (!is_array($metas)) {
357
            return;
358
        }
359
360
        foreach ($metas as $key => $value) {
361
            $this[$key] = $value;
362
        }
363
364
        return true;
365
    }
366
}
367