| @@ -10,8 +10,9 @@ | ||
| 10 | 10 | */ |
| 11 | 11 | declare (strict_types=1); |
| 12 | 12 | namespace WindPress\WindPress\Core; |
| 13 | 13 | |
| 14 | +use Exception; | |
| 14 | 15 | use WIND_PRESS; |
| 15 | 16 | use WindPress\WindPress\Utils\Cache as UtilsCache; |
| 16 | 17 | use WindPress\WindPress\Utils\Common; |
| 17 | 18 | /** |
| @@ -22,13 +23,19 @@ | ||
| 22 | 23 | /** |
| 23 | 24 | * @var string |
| 24 | 25 | */ |
| 25 | 26 | public const CSS_CACHE_FILE = 'tailwind.css'; |
| 27 | + /** | |
| 28 | + * @var string | |
| 29 | + */ | |
| 30 | + public const CSS_SOURCEMAP_FILE = 'tailwind.css.map'; | |
| 31 | + public const THEME_JSON_FILE = 'theme.json'; | |
| 26 | 32 | public static function get_providers(): array |
| 27 | 33 | { |
| 28 | 34 | /** |
| 29 | 35 | * Register cache providers. |
| 30 | - * @param array $providers The list of cache providers. Each provider should have `id`, `name`, `description`, and `callback` keys. | |
| 36 | + * Each provider should have `id`, `name`, `description`, and `callback` keys. | |
| 37 | + * Providers supporting stable source identities opt in with `source_index` => 1. | |
| 31 | 38 | */ |
| 32 | 39 | return apply_filters('f!windpress/core/cache:compile.providers', []); |
| 33 | 40 | } |
| 34 | 41 | public static function get_cache_path(string $file_path = ''): string |
| @@ -45,10 +52,31 @@ | ||
| 45 | 52 | Common::save_file($payload, self::get_cache_path(self::CSS_CACHE_FILE)); |
| 46 | 53 | } catch (\Throwable $throwable) { |
| 47 | 54 | throw $throwable; |
| 48 | 55 | } |
| 56 | + do_action('a!windpress/core/cache:save_cache.after', $payload); | |
| 49 | 57 | UtilsCache::flush_cache_plugin(); |
| 50 | 58 | } |
| 59 | + public static function save_sourcemap(string $payload) | |
| 60 | + { | |
| 61 | + try { | |
| 62 | + Common::save_file($payload, self::get_cache_path(self::CSS_SOURCEMAP_FILE)); | |
| 63 | + } catch (\Throwable $throwable) { | |
| 64 | + throw $throwable; | |
| 65 | + } | |
| 66 | + do_action('a!windpress/core/cache:save_sourcemap.after', $payload); | |
| 67 | + UtilsCache::flush_cache_plugin(); | |
| 68 | + } | |
| 69 | + public static function save_theme_json(string $payload) | |
| 70 | + { | |
| 71 | + try { | |
| 72 | + Common::save_file($payload, self::get_cache_path(self::THEME_JSON_FILE)); | |
| 73 | + } catch (\Throwable $throwable) { | |
| 74 | + throw $throwable; | |
| 75 | + } | |
| 76 | + do_action('a!windpress/core/cache:save_theme_json.after', $payload); | |
| 77 | + UtilsCache::flush_cache_plugin(); | |
| 78 | + } | |
| 51 | 79 | public static function fetch_contents($callback, $metadata = []) |
| 52 | 80 | { |
| 53 | 81 | // if class has an "__invoke" method. |
| 54 | 82 | if (is_string($callback) && class_exists($callback) && method_exists($callback, '__invoke')) { |
| @@ -56,18 +84,34 @@ | ||
| 56 | 84 | } |
| 57 | 85 | try { |
| 58 | 86 | $result = call_user_func($callback, $metadata); |
| 59 | 87 | if (!is_array($result)) { |
| 60 | - throw new \Exception('The callback should return an array'); | |
| 88 | + throw new Exception(__('The callback should return an array', 'windpress')); | |
| 61 | 89 | } |
| 62 | 90 | $_metadata = array_key_exists('metadata', $result) ? $result['metadata'] : []; |
| 63 | 91 | $_contents = array_key_exists('contents', $result) ? $result['contents'] : $result; |
| 92 | + if (!is_array($_metadata) || !is_array($_contents)) { | |
| 93 | + throw new Exception(__('The provider metadata and contents must be arrays.', 'windpress')); | |
| 94 | + } | |
| 64 | 95 | $_contents = array_map(static function ($content) { |
| 96 | + if (!is_array($content) || !array_key_exists('content', $content)) { | |
| 97 | + throw new Exception(__('A scan source is missing its content.', 'windpress')); | |
| 98 | + } | |
| 99 | + $content_type = $content['type'] ?? null; | |
| 65 | 100 | if (is_array($content['content']) || is_object($content['content'])) { |
| 66 | 101 | $content['content'] = wp_json_encode($content['content']); |
| 67 | 102 | $content['type'] = 'json'; |
| 103 | + } elseif (is_string($content['content']) && $content_type !== 'json') { | |
| 104 | + // Check if the string is already valid JSON | |
| 105 | + $decoded = json_decode($content['content'], \true); | |
| 106 | + if (json_last_error() === \JSON_ERROR_NONE && ($decoded !== null || $content['content'] === 'null')) { | |
| 107 | + $content['type'] = 'json'; | |
| 108 | + } | |
| 68 | 109 | } |
| 69 | - $content['content'] = is_string($content['content']) ? base64_encode($content['content']) : null; | |
| 110 | + if (!is_string($content['content'])) { | |
| 111 | + throw new Exception(__('A scan source could not be encoded as text.', 'windpress')); | |
| 112 | + } | |
| 113 | + $content['content'] = base64_encode($content['content']); | |
| 70 | 114 | return $content; |
| 71 | 115 | }, $_contents); |
| 72 | 116 | } catch (\Throwable $throwable) { |
| 73 | 117 | throw $throwable; |