Passed
Push — main ( 31af8b...652a21 )
by Thierry
04:07
created

MetadataCache::encode()   A

Complexity

Conditions 5
Paths 3

Size

Total Lines 21
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 5
eloc 11
c 0
b 0
f 0
nc 3
nop 1
dl 0
loc 21
rs 9.6111
1
<?php
2
3
/**
4
 * Cache.php
5
 *
6
 * Cache for callable class metadata.
7
 *
8
 * @package jaxon-core
9
 * @author Thierry Feuzeu <[email protected]>
10
 * @copyright 2024 Thierry Feuzeu <[email protected]>
11
 * @license https://opensource.org/licenses/BSD-3-Clause BSD 3-Clause License
12
 * @link https://github.com/jaxon-php/jaxon-core
13
 */
14
15
namespace Jaxon\App\Metadata;
16
17
use function count;
18
use function file_put_contents;
19
use function implode;
20
use function is_callable;
21
use function str_replace;
22
use function strtolower;
23
24
class MetadataCache
25
{
26
    /**
27
     * @param string $sCacheDir
28
     */
29
    public function __construct(private string $sCacheDir)
30
    {}
31
32
    /**
33
     * @param string $sClass
34
     *
35
     * @return string
36
     */
37
    private function filepath(string $sClass): string
38
    {
39
        $sFilename = str_replace(['\\', '.'], '_', strtolower($sClass));
40
        return "{$this->sCacheDir}/jaxon_metadata_{$sFilename}.php";
41
    }
42
43
    /**
44
     * Generate the PHP code to create a metadata object.
45
     *
46
     * @return array
47
     */
48
    private function encode(Metadata $xMetadata): array
49
    {
50
        $sVar = '$'; // The dollar char.
51
        $aCalls = ["{$sVar}xMetadata = new " . Metadata::class . '();'];
52
        foreach($xMetadata->getAttributes() as $sType => $aValues)
53
        {
54
            if(count($aValues) === 0)
55
            {
56
                continue;
57
            }
58
            foreach($aValues as $sMethod => $xData)
59
            {
60
                $aCalls[] = "{$sVar}xData = {$sVar}xMetadata->{$sType}('$sMethod');";
61
                foreach($xData->encode("{$sVar}xData") as $sCall)
62
                {
63
                    $aCalls[] = $sCall;
64
                }
65
            }
66
        }
67
        $aCalls[] = "return {$sVar}xMetadata;";
68
        return $aCalls;
69
    }
70
71
    /**
72
     * @param string $sClass
73
     * @param Metadata $xMetadata
74
     *
75
     * @return void
76
     */
77
    public function save(string $sClass, Metadata $xMetadata): void
78
    {
79
        $sDataCode = implode("\n    ", $this->encode($xMetadata));
80
        $sPhpCode = <<<CODE
81
<?php
82
83
return function() {
84
    $sDataCode
85
};
86
87
CODE;
88
        file_put_contents($this->filepath($sClass), $sPhpCode);
89
    }
90
91
    /**
92
     * @param string $sClass
93
     *
94
     * @return Metadata|null
95
     */
96
    public function read(string $sClass): ?Metadata
97
    {
98
        $fCreator = require $this->filepath($sClass);
99
        return !is_callable($fCreator) ? null : $fCreator();
100
    }
101
}
102