1<?php
2
3
4namespace ComboStrap;
5
6use dokuwiki\Cache\Cache;
7
8/**
9 * Class Cache
10 * A wrapper around {@link \dokuwiki\Cache\Cache}
11 * @package ComboStrap
12 * that takes into account the arguments / properties of the media
13 * to create the cache file
14 */
15class FetcherCache
16{
17
18    const CANONICAL = "fetcher:cache";
19
20
21    /**
22     * @var Cache
23     */
24    private Cache $fileCache;
25
26
27    private array $fileDependencies = [];
28    private IFetcher $fetcher;
29
30
31    /**
32     * @param IFetcher $fetcher
33     * @param String[] $keys - extra cache keys that are not in the url because they are retrieved from a database
34     * This is the case of the {@link FetcherPage::getRequestedTemplate()} as it can be changed in the database
35     * but we don't want to see it in the URL.
36     */
37    public function __construct(IFetcher $fetcher, array $keys = [])
38    {
39
40        $this->fetcher = $fetcher;
41        /**
42         * Cache Key Construction
43         */
44        $cacheKey = $fetcher->getFetchUrl()->toAbsoluteUrlString();
45        foreach ($keys as $key) {
46            $cacheKey .= $key;
47        }
48        $this->fileCache = new Cache($cacheKey, ".{$fetcher->getMime()->getExtension()}");
49
50    }
51
52    /**
53     * @param IFetcher $fetch
54     * @param String[] $cacheKeys - extra cache keys that are not in the url because they are retrieved from a database
55     * @return FetcherCache
56     */
57    public static function createFrom(IFetcher $fetch, array $cacheKeys = []): FetcherCache
58    {
59        return new FetcherCache($fetch, $cacheKeys);
60    }
61
62
63    /**
64     * Cache file depends on code version and configuration
65     * @return bool
66     */
67    public function isCacheUsable(): bool
68    {
69
70        $this->addFileDependency(DirectoryLayout::getPluginInfoPath());
71        $files = $this->fileDependencies;
72        $dependencies = array('files' => $files);
73
74        /**
75         * Cache Attribute
76         */
77        try {
78            $requestedCache = $this->fetcher->getRequestedCache();
79            $maxAge = $this->fetcher->getCacheMaxAgeInSec($requestedCache);
80            $dependencies['age'] = $maxAge;
81        } catch (ExceptionNotFound $e) {
82            // no requested cache
83        }
84        return $this->fileCache->useCache($dependencies);
85
86    }
87
88
89    public function storeCache($content)
90    {
91        $this->fileCache->storeCache($content);
92    }
93
94    public function getFile(): LocalPath
95    {
96        return LocalPath::createFromPathString($this->fileCache->cache);
97    }
98
99    public function addFileDependency(Path $path): FetcherCache
100    {
101        try {
102            $this->fileDependencies[] = LocalPath::createFromPathObject($path)->toAbsolutePath()->toAbsoluteId();
103        } catch (ExceptionCast|ExceptionBadArgument $e) {
104            LogUtility::internalError("The path seems to be not local, it should never happen.", self::CANONICAL, $e);
105        }
106        return $this;
107    }
108
109
110}
111