PluginProbe
WindPress – Tailwind CSS integration for WordPress / 3.2.89
WindPress – Tailwind CSS integration for WordPress v3.2.89
3.2.89 3.2.88 3.2.87 3.2.86 3.2.85 3.2.84 3.2.83 3.2.82 3.2.81 trunk 3.0.0 3.0.1 3.0.10 3.0.11 3.0.12 3.0.13 3.0.14 3.0.15 3.0.16 3.0.17 3.0.2 3.0.3 3.0.4 3.0.5 3.0.6 All 143 releases
← All changes | src/Api/Admin/Settings/Cache.php +62 -17 3.2.843.2.89 View file →
@@ -14,8 +14,11 @@
14 14 use WIND_PRESS;
15 15 use WindPress\WindPress\Api\AbstractApi;
16 16 use WindPress\WindPress\Api\ApiInterface;
17 17 use WindPress\WindPress\Core\Cache as CoreCache;
18 +use WindPress\WindPress\Core\Scanner\BuildState;
19 +use WindPress\WindPress\Core\Scanner\SourceIndex;
20 +use WindPress\WindPress\Core\Scanner\SourceRevision;
18 21 use WindPress\WindPress\Utils\Common;
19 22 use WindPress\WindPress\Utils\Debug;
20 23 use WP_REST_Request;
21 24 use WP_REST_Response;
@@ -38,17 +41,16 @@
38 41 }
39 42 public function index(WP_REST_Request $wprestRequest): WP_REST_Response
40 43 {
41 44 $cache_path = CoreCache::get_cache_path(CoreCache::CSS_CACHE_FILE);
42 - $cache = ['last_generated' => null, 'last_full_build' => null, 'file_url' => null, 'file_size' => \false];
45 + clearstatcache(\true, $cache_path);
46 + $build_state = BuildState::get();
47 + $cache = ['last_generated' => null, 'last_full_build' => null, 'file_url' => null, 'file_size' => \false, 'generation' => $build_state['generation'], 'source_revision' => SourceRevision::get()];
43 48 if (file_exists($cache_path) && is_readable($cache_path)) {
44 49 $cache['file_url'] = CoreCache::get_cache_url(CoreCache::CSS_CACHE_FILE);
45 50 $cache['last_generated'] = filemtime($cache_path);
46 51 $cache['file_size'] = filesize($cache_path);
47 - $last_full_build = wp_cache_get('last_full_build', 'windpress', \true);
48 - if ($last_full_build) {
49 - $cache['last_full_build'] = $last_full_build;
50 - }
52 + $cache['last_full_build'] = $build_state['last_full_build'] ?? null;
51 53 }
52 54 return new WP_REST_Response(['cache' => $cache]);
53 55 }
54 56 public function store(WP_REST_Request $wprestRequest): WP_REST_Response
@@ -53,14 +55,30 @@
53 55 }
54 56 public function store(WP_REST_Request $wprestRequest): WP_REST_Response
55 57 {
56 58 $payload = $wprestRequest->get_json_params();
59 + if (!is_array($payload) || !isset($payload['content']) || !is_string($payload['content']) || isset($payload['expected_generation']) && !is_string($payload['expected_generation']) || isset($payload['expected_source_revision']) && !is_string($payload['expected_source_revision']) || isset($payload['sourcemap']) && !is_string($payload['sourcemap']) || isset($payload['full_build']) && !is_bool($payload['full_build']) && !is_int($payload['full_build'])) {
60 + return new WP_REST_Response(['status' => 'KO', 'message' => __('The cache payload is invalid.', 'windpress')], 400);
61 + }
62 + $content = base64_decode($payload['content'], \true);
63 + $sourcemapContent = !empty($payload['sourcemap']) ? base64_decode($payload['sourcemap'], \true) : null;
64 + if ($content === \false || $sourcemapContent === \false) {
65 + return new WP_REST_Response(['status' => 'KO', 'message' => __('The cache content is not valid base64.', 'windpress')], 400);
66 + }
67 + $lease = BuildState::acquire();
68 + if ($lease === null) {
69 + return new WP_REST_Response(['status' => 'KO', 'message' => __('Another cache build is being saved. Retry the build.', 'windpress')], 409);
70 + }
57 71 try {
58 - $content = base64_decode($payload['content']);
59 - if (isset($payload['sourcemap']) && $payload['sourcemap']) {
60 - $sourcemapContent = base64_decode($payload['sourcemap']);
72 + if (isset($payload['expected_generation']) && !BuildState::matches($payload['expected_generation'])) {
73 + return new WP_REST_Response(['status' => 'KO', 'message' => __('The scan generation has changed. Restart the build.', 'windpress')], 409);
74 + }
75 + if (isset($payload['expected_source_revision']) && !SourceRevision::matches($payload['expected_source_revision'])) {
76 + return new WP_REST_Response(['status' => 'KO', 'message' => __('Source content changed during the scan. Restart the build.', 'windpress')], 409);
77 + }
78 + if ($sourcemapContent !== null) {
61 79 CoreCache::save_sourcemap($sourcemapContent);
62 - $content .= "\n/*# sourceMappingURL=" . CoreCache::CSS_SOURCEMAP_FILE . " */";
80 + $content .= "\n/*# sourceMappingURL=" . CoreCache::CSS_SOURCEMAP_FILE . ' */';
63 81 } else {
64 82 // add a comment at the top of the file
65 83 $comment = sprintf("/*! %s v%s | %s | %s */\n", strtolower(Common::plugin_data('Name')), WIND_PRESS::VERSION, gmdate('Y-m-d H:i:s', time()), strtolower(Common::plugin_data('PluginURI')));
66 84 $content = $comment . $content;
@@ -65,15 +83,17 @@
65 83 $comment = sprintf("/*! %s v%s | %s | %s */\n", strtolower(Common::plugin_data('Name')), WIND_PRESS::VERSION, gmdate('Y-m-d H:i:s', time()), strtolower(Common::plugin_data('PluginURI')));
66 84 $content = $comment . $content;
67 85 }
68 86 CoreCache::save_cache($content);
87 + if (!empty($payload['full_build'])) {
88 + BuildState::complete_full_build();
89 + }
90 + return $this->index($wprestRequest);
69 91 } catch (\Throwable $throwable) {
70 92 return new WP_REST_Response(['status' => 'KO', 'message' => __('Save cache error: ', 'windpress') . $throwable->getMessage()], 500);
93 + } finally {
94 + BuildState::release($lease);
71 95 }
72 - if (isset($payload['full_build']) && $payload['full_build']) {
73 - wp_cache_set('last_full_build', $payload['full_build'], 'windpress');
74 - }
75 - return $this->index($wprestRequest);
76 96 }
77 97 public function providers(WP_REST_Request $wprestRequest): WP_REST_Response
78 98 {
79 99 $providers = CoreCache::get_providers();
@@ -89,8 +109,20 @@
89 109 {
90 110 $stopwatch = Debug::stopwatch();
91 111 $provider_id = $wprestRequest->get_param('provider_id');
92 112 $metadata = $wprestRequest->get_param('metadata') ?? [];
113 + if (!is_string($provider_id) || !is_array($metadata) || isset($metadata['generation']) && !is_string($metadata['generation']) || isset($metadata['source_revision']) && !is_string($metadata['source_revision'])) {
114 + return new WP_REST_Response(['status' => 'KO', 'message' => __('The scan request is invalid.', 'windpress')], 400);
115 + }
116 + $generation = BuildState::get()['generation'];
117 + $source_revision = SourceRevision::get();
118 + if (isset($metadata['generation']) && !hash_equals($generation, $metadata['generation'])) {
119 + return new WP_REST_Response(['status' => 'KO', 'message' => __('The scan generation has changed. Restart the build.', 'windpress')], 409);
120 + }
121 + if (isset($metadata['source_revision']) && !hash_equals($source_revision, $metadata['source_revision'])) {
122 + return new WP_REST_Response(['status' => 'KO', 'message' => __('Source content changed during the scan. Restart the build.', 'windpress')], 409);
123 + }
124 + $metadata += ['next_batch' => \false];
93 125 $provider = array_filter(CoreCache::get_providers(), static fn($provider) => $provider['id'] === $provider_id);
94 126 if ($provider === []) {
95 127 return new WP_REST_Response(['status' => 'KO', 'message' => __('The provider not found', 'windpress')], 404);
96 128 }
@@ -96,12 +128,25 @@
96 128 }
97 129 $provider = array_shift($provider);
98 130 $stopwatch->start('cache-provider:' . $provider['id'], 'cache-provider-scan');
99 131 try {
100 - $result = CoreCache::fetch_contents($provider['callback'], $metadata);
132 + if (array_key_exists('source_index', $metadata)) {
133 + if (($provider['source_index'] ?? 0) !== 1) {
134 + throw new \InvalidArgumentException(__('This provider does not support source indexing.', 'windpress'));
135 + }
136 + $result = SourceIndex::scan('provider:' . $provider_id, $metadata, static function (array $page_metadata) use ($provider): array {
137 + return CoreCache::fetch_contents($provider['callback'], $page_metadata);
138 + });
139 + } else {
140 + $result = CoreCache::fetch_contents($provider['callback'], $metadata);
141 + }
142 + if (isset($metadata['source_revision']) && !SourceRevision::matches($source_revision)) {
143 + throw new \RuntimeException(__('Source content changed during the scan. Restart the build.', 'windpress'), 409);
144 + }
101 145 } catch (\Throwable $throwable) {
102 - return new WP_REST_Response(['status' => 'KO', 'message' => __('Provider error: ', 'windpress') . $throwable->__toString()], 500);
146 + return new WP_REST_Response(['status' => 'KO', 'message' => __('Provider error: ', 'windpress') . $throwable->getMessage()], $throwable instanceof \InvalidArgumentException ? 400 : ($throwable->getCode() === 409 ? 409 : 500));
147 + } finally {
148 + $stopwatchEvent = $stopwatch->stop('cache-provider:' . $provider['id']);
103 149 }
104 - $stopwatchEvent = $stopwatch->stop('cache-provider:' . $provider['id']);
105 - return new WP_REST_Response(['metadata' => ['provider_id' => $provider['id'], 'provider_name' => $provider['name'], 'profiling' => ['unix_timestamp' => time(), 'duration' => $stopwatchEvent->getDuration() . ' ms', 'memory' => sprintf('%.2F MiB', $stopwatchEvent->getMemory() / 1024 / 1024)], 'next_batch' => $result['metadata']['next_batch'] ?? \false, 'total_batches' => $result['metadata']['total_batches'] ?? \false], 'contents' => $result['contents'], 'status' => 'OK']);
150 + return new WP_REST_Response(['metadata' => array_merge($result['metadata'], ['provider_id' => $provider['id'], 'provider_name' => $provider['name'], 'generation' => $generation, 'source_revision' => $source_revision, 'profiling' => ['unix_timestamp' => time(), 'duration' => $stopwatchEvent->getDuration() . ' ms', 'memory' => sprintf('%.2F MiB', $stopwatchEvent->getMemory() / 1024 / 1024)], 'next_batch' => $result['metadata']['next_batch'] ?? \false, 'total_batches' => $result['metadata']['total_batches'] ?? \false]), 'contents' => $result['contents'], 'status' => 'OK']);
106 151 }
107 152 }