-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathzuidwest-cache-manager.php
252 lines (225 loc) · 8.28 KB
/
zuidwest-cache-manager.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
<?php
/**
* Plugin Name: ZuidWest Cache Manager
* Description: Purges cache for high-priority URLs immediately on post publishing and edits. Also queues associated taxonomy URLs for low-priority batch processing via WP-Cron.
* Version: 0.2
* Author: Streekomroep ZuidWest
*/
add_action('admin_menu', 'zwcache_add_admin_menu');
function zwcache_add_admin_menu()
{
add_options_page('ZuidWest Cache Manager Settings', 'ZuidWest Cache', 'manage_options', 'zwcache_manager', 'zwcache_options_page');
}
add_action('admin_init', 'zwcache_settings_init');
function zwcache_settings_init()
{
register_setting('zwcachePlugin', 'zwcache_settings');
add_settings_section('zwcache_pluginPage_section', 'API Settings', 'zwcache_settings_section_callback', 'zwcachePlugin');
$fields = [
['zwcache_zone_id', 'Zone ID', 'text'],
['zwcache_api_key', 'API Key', 'text'],
['zwcache_batch_size', 'Batch Size', 'number', 30],
['zwcache_debug_mode', 'Debug Mode', 'checkbox', 1]
];
foreach ($fields as $field) {
add_settings_field($field[0], $field[1], 'zwcache_render_settings_field', 'zwcachePlugin', 'zwcache_pluginPage_section', ['label_for' => $field[0], 'type' => $field[2], 'default' => $field[3] ?? '']);
}
}
function zwcache_render_settings_field($args)
{
$options = get_option('zwcache_settings');
$value = $options[$args['label_for']] ?? $args['default'];
$checked = ($value) ? 'checked' : '';
echo match ($args['type']) {
'text', 'number' => "<input type='" . $args['type'] . "' id='" . $args['label_for'] . "' name='zwcache_settings[" . $args['label_for'] . "]' value='" . $value . "'>",
'checkbox' => "<input type='checkbox' id='" . $args['label_for'] . "' name='zwcache_settings[" . $args['label_for'] . "]' value='1' " . $checked . '>',
default => ''
};
}
function zwcache_settings_section_callback()
{
echo 'Enter your settings below:';
}
function zwcache_options_page()
{
?>
<div class="wrap">
<h2>ZuidWest Cache Manager Settings</h2>
<form action="options.php" method="post">
<?php
settings_fields('zwcachePlugin');
do_settings_sections('zwcachePlugin');
submit_button();
?>
</form>
</div>
<?php
}
function zwcache_get_option($option_name, $default = false)
{
$options = get_option('zwcache_settings');
return $options[$option_name] ?? $default;
}
/**
* Custom log function.
*
* @param string $message The message to log.
*/
function zwcache_debug_log($message)
{
if (zwcache_get_option('zwcache_debug_mode', true)) {
error_log('ZuidWest Cache Manager: ' . $message);
}
}
define('ZWCACHE_LOW_PRIORITY_STORE', 'zwcache_purge_urls');
define('ZWCACHE_CRON_HOOK', 'zwcache_manager_cron_hook');
register_activation_hook(__FILE__, 'zwcache_activate');
register_deactivation_hook(__FILE__, 'zwcache_deactivate');
/**
* Adds custom cron schedule if it doesn't already exist.
*
* @param array $schedules The existing schedules.
* @return array The modified schedules.
*/
function zwcache_add_cron_interval($schedules)
{
if (!isset($schedules['every_minute'])) {
$schedules['every_minute'] = [
'interval' => 60,
'display' => esc_html__('Every minute'),
];
}
return $schedules;
}
add_filter('cron_schedules', 'zwcache_add_cron_interval');
/**
* Activates the plugin and schedules a WP-Cron event if not already scheduled.
*/
function zwcache_activate()
{
if (!wp_next_scheduled(ZWCACHE_CRON_HOOK)) {
wp_schedule_event(time(), 'every_minute', ZWCACHE_CRON_HOOK);
}
zwcache_debug_log('Plugin activated and cron job scheduled.');
}
/**
* Deactivates the plugin, clears the scheduled WP-Cron event, and deletes the option storing low-priority URLs.
*/
function zwcache_deactivate()
{
wp_clear_scheduled_hook(ZWCACHE_CRON_HOOK);
delete_option(ZWCACHE_LOW_PRIORITY_STORE);
zwcache_debug_log('Plugin deactivated and cron job cleared.');
}
add_action('transition_post_status', 'zwcache_handle_post_status_change', 10, 3);
/**
* Handles the transition of a post's status and purges or queues URLs for purging as necessary.
*
* @param string $new_status New status of the post.
* @param string $old_status Old status of the post.
* @param WP_Post $post Post object.
*/
function zwcache_handle_post_status_change($new_status, $old_status, $post)
{
zwcache_debug_log('Post status changed from ' . $old_status . ' to ' . $new_status . ' for post ID ' . $post->ID . '.');
if ($new_status === 'publish' || $old_status === 'publish') {
zwcache_purge_urls([get_permalink($post->ID), get_home_url()]);
zwcache_queue_low_priority_urls(zwcache_get_associated_taxonomy_urls($post->ID));
}
}
/**
* Queues URLs for low-priority batch processing.
*
* @param array $urls URLs to be queued.
*/
function zwcache_queue_low_priority_urls($urls)
{
$queued_urls = get_option(ZWCACHE_LOW_PRIORITY_STORE, []);
$new_urls = array_filter($urls, function ($url) use ($queued_urls) {
return !in_array($url, $queued_urls);
});
if (!empty($new_urls)) {
update_option(ZWCACHE_LOW_PRIORITY_STORE, array_merge($queued_urls, $new_urls));
zwcache_debug_log('Queued new URLs for low-priority purging.');
}
}
add_action(ZWCACHE_CRON_HOOK, 'zwcache_process_queued_low_priority_urls');
/**
* Processes queued URLs in batches for low-priority purging.
*/
function zwcache_process_queued_low_priority_urls()
{
zwcache_debug_log('Processing queued low-priority URLs.');
$queued_urls = get_option(ZWCACHE_LOW_PRIORITY_STORE, []);
if (empty($queued_urls)) {
zwcache_debug_log('No URLs in queue to process.');
return;
}
$batch_size = zwcache_get_option('zwcache_batch_size', 30);
$total_urls = count($queued_urls);
for ($i = 0; $i < $total_urls; $i += $batch_size) {
$batch = array_slice($queued_urls, $i, $batch_size);
if (zwcache_purge_urls($batch)) {
$queued_urls = array_diff($queued_urls, $batch);
zwcache_debug_log('Removed processed URLs from batch');
}
}
update_option(ZWCACHE_LOW_PRIORITY_STORE, $queued_urls);
}
/**
* Retrieves URLs for all taxonomies associated with a given post.
*
* @param int $post_id ID of the post.
* @return array URLs associated with the post's taxonomies.
*/
function zwcache_get_associated_taxonomy_urls($post_id)
{
zwcache_debug_log('Retrieving associated taxonomy URLs for post ID ' . $post_id . '.');
$urls = [];
$taxonomies = get_post_taxonomies($post_id);
foreach ($taxonomies as $taxonomy) {
$terms = get_the_terms($post_id, $taxonomy);
if ($terms && !is_wp_error($terms)) {
foreach ($terms as $term) {
$term_link = get_term_link($term, $taxonomy);
if (!is_wp_error($term_link)) {
$urls[] = $term_link;
}
}
}
}
zwcache_debug_log(sprintf('Found %d associated taxonomy URLs.', count($urls)));
return $urls;
}
/**
* Purges the specified URLs through the Cloudflare API.
*
* @param array $urls URLs to be purged.
* @return bool True if purge was successful, false otherwise.
*/
function zwcache_purge_urls($urls)
{
zwcache_debug_log('Attempting to purge URLs: ' . implode(', ', $urls));
$zone_id = zwcache_get_option('zwcache_zone_id');
$api_key = zwcache_get_option('zwcache_api_key');
// Check if either the zone ID or API key is empty
if (empty($zone_id) || empty($api_key)) {
zwcache_debug_log('Zone ID or API Key is not set. Aborting cache purge.');
return false; // Exit the function if either is not set
}
$apiEndpoint = 'https://api.cloudflare.com/client/v4/zones/' . $zone_id . '/purge_cache';
$response = wp_remote_post($apiEndpoint, [
'headers' => [
'Authorization' => 'Bearer ' . $api_key,
'Content-Type' => 'application/json',
],
'body' => json_encode(['files' => $urls]),
]);
if (is_wp_error($response) || wp_remote_retrieve_response_code($response) != 200) {
zwcache_debug_log('Cache purge failed: ' . wp_remote_retrieve_body($response));
return false;
} else {
zwcache_debug_log('Successfully purged URLs.');
return true;
}
}