• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

diego-ninja / granite / 16608963009

29 Jul 2025 10:37PM UTC coverage: 50.423%. First build
16608963009

Pull #5

github

web-flow
Merge 43d8840d7 into 6a6caca51
Pull Request #5: code: adds phpstan level max, pint with per and github actions

321 of 632 new or added lines in 77 files covered. (50.79%)

1132 of 2245 relevant lines covered (50.42%)

9.88 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
/src/Mapping/Cache/PersistentMappingCache.php
1
<?php
2

3
namespace Ninja\Granite\Mapping\Cache;
4

5
use Exception;
6
use Ninja\Granite\Mapping\Contracts\MappingCache;
7
use ReflectionClass;
8

9
/**
10
 * File-based persistent mapping cache.
11
 */
12
class PersistentMappingCache implements MappingCache
13
{
14
    /**
15
     * In-memory cache for current request.
16
     */
17
    private InMemoryMappingCache $memoryCache;
18

19
    /**
20
     * Path to cache file.
21
     */
22
    private string $cachePath;
23

24
    /**
25
     * Whether the cache is dirty and needs saving.
26
     */
27
    private bool $isDirty = false;
28

29
    /**
30
     * Constructor.
31
     *
32
     * @param string $cachePath Path to cache file
33
     */
34
    public function __construct(string $cachePath)
×
35
    {
36
        $this->memoryCache = new InMemoryMappingCache();
×
37
        $this->cachePath = $cachePath;
×
38
        $this->loadCache();
×
39

40
        // Register shutdown function to save cache automatically
41
        register_shutdown_function([$this, 'saveIfDirty']);
×
42
    }
43

44
    /**
45
     * Check if a mapping configuration exists in cache.
46
     *
47
     * @param string $sourceType Source type name
48
     * @param string $destinationType Destination type name
49
     * @return bool Whether the mapping exists in cache
50
     */
51
    public function has(string $sourceType, string $destinationType): bool
×
52
    {
53
        return $this->memoryCache->has($sourceType, $destinationType);
×
54
    }
55

56
    /**
57
     * Get a mapping configuration from cache.
58
     *
59
     * @param string $sourceType Source type name
60
     * @param string $destinationType Destination type name
61
     * @return array|null Mapping configuration or null if not found
62
     */
63
    public function get(string $sourceType, string $destinationType): ?array
×
64
    {
65
        return $this->memoryCache->get($sourceType, $destinationType);
×
66
    }
67

68
    /**
69
     * Store a mapping configuration in cache.
70
     *
71
     * @param string $sourceType Source type name
72
     * @param string $destinationType Destination type name
73
     * @param array $config Mapping configuration
74
     * @return void
75
     */
76
    public function put(string $sourceType, string $destinationType, array $config): void
×
77
    {
78
        $this->memoryCache->put($sourceType, $destinationType, $config);
×
79
        $this->isDirty = true;
×
80
    }
81

82
    /**
83
     * Clear all cached mapping configurations.
84
     *
85
     * @return void
86
     */
87
    public function clear(): void
×
88
    {
89
        $this->memoryCache->clear();
×
90
        $this->isDirty = true;
×
91
        $this->save(); // Save immediately when clearing
×
92
    }
93

94
    /**
95
     * Save cache to file.
96
     *
97
     * @return bool Whether the save was successful
98
     */
99
    public function save(): bool
×
100
    {
101
        try {
102
            $cacheDir = dirname($this->cachePath);
×
NEW
103
            if ( ! is_dir($cacheDir)) {
×
104
                mkdir($cacheDir, 0755, true);
×
105
            }
106

107
            $tmpFile = $this->cachePath . '.tmp';
×
108
            $result = file_put_contents($tmpFile, serialize($this->extractCacheData()), LOCK_EX);
×
109

NEW
110
            if (false !== $result) {
×
111
                rename($tmpFile, $this->cachePath);
×
112
                $this->isDirty = false;
×
113
                return true;
×
114
            }
NEW
115
        } catch (Exception $e) {
×
116
            // Ignore errors, just return false
117
        }
118

119
        return false;
×
120
    }
121

122
    /**
123
     * Save cache if dirty when shutting down.
124
     *
125
     * @return void
126
     */
127
    public function saveIfDirty(): void
×
128
    {
129
        if ($this->isDirty) {
×
130
            $this->save();
×
131
        }
132
    }
133

134
    /**
135
     * Load cache from file.
136
     *
137
     * @return void
138
     */
NEW
139
    private function loadCache(): void
×
140
    {
NEW
141
        if ( ! file_exists($this->cachePath)) {
×
NEW
142
            return;
×
143
        }
144

145
        try {
NEW
146
            $cacheData = file_get_contents($this->cachePath);
×
NEW
147
            if (false === $cacheData) {
×
NEW
148
                return;
×
149
            }
150

NEW
151
            $data = unserialize($cacheData);
×
NEW
152
            if ( ! is_array($data)) {
×
NEW
153
                return;
×
154
            }
155

NEW
156
            foreach ($data as $key => $config) {
×
NEW
157
                if (is_string($key) && is_array($config)) {
×
NEW
158
                    $parts = explode('->', $key, 2);
×
NEW
159
                    if (2 === count($parts)) {
×
NEW
160
                        [$sourceType, $destinationType] = $parts;
×
NEW
161
                        $this->memoryCache->put($sourceType, $destinationType, $config);
×
162
                    }
163
                }
164
            }
NEW
165
        } catch (Exception $e) {
×
166
            // If loading fails, just start with an empty cache
NEW
167
            $this->memoryCache->clear();
×
168
        }
169
    }
170

171
    /**
172
     * Extract cache data from memory cache.
173
     *
174
     * @return array Cache data
175
     */
176
    private function extractCacheData(): array
×
177
    {
178
        $reflection = new ReflectionClass($this->memoryCache);
×
179
        $cacheProperty = $reflection->getProperty('cache');
×
180
        $cacheProperty->setAccessible(true);
×
181

NEW
182
        $cacheData = $cacheProperty->getValue($this->memoryCache);
×
183

NEW
184
        return is_array($cacheData) ? $cacheData : [];
×
185
    }
186
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc