-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathplugin.php
247 lines (208 loc) · 7.03 KB
/
plugin.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
<?php
/**
* Plugin Name: WP Post Thumbnail Endpoint
* Plugin URI: http://github.com/xemlock/wp-post-thumbnail-endpoint
* Description:
* Author: xemlock <xemlock@gmail.com>
* Author URI: http://xemlock.github.io
* Version: 1.0.0-dev
* License: MIT
* License URI: https://opensource.org/licenses/MIT
*
* This plugin provides a special URL dependent only on Post ID (an endpoint),
* that redirects to the Post Thumbnail (aka Featured Image) corresponding to
* the provided ID.
*
* This can particularly be useful when implementing client-side JavaScript
* features that only have post ID and want to display Post Thumbnail without
* sending additional AJAX request to retrieve the thumbnail's location.
*
* This plugin is intended for use by theme/plugin developers rather than
* WordPress end-users.
*/
if (defined('ABSPATH') && !defined('WP_POST_THUMBNAIL_ENDPOINT')) {
define('WP_POST_THUMBNAIL_ENDPOINT', __FILE__);
abstract class WP_Post_Thumbnail_Endpoint
{
const POST_THUMBNAIL = 'post_thumbnail';
const PERMALINK_PREFIX = self::POST_THUMBNAIL;
const VAR_POST_THUMBNAIL = self::POST_THUMBNAIL;
const VAR_SIZE = 'size';
const TAG_POST_ID = '%post_id%';
const TAG_SIZE = '%size%';
/**
* Should rewrite rules be flushed whenever 'wp' action is triggered
* @var bool
*/
protected static $_flush_rewrite_rules = false;
/**
* Setup action and filter hooks provided by the plugin
*/
public static function init()
{
add_action('init', array(__CLASS__, 'setup_rewrite_rules'));
add_action('wp_loaded', array(__CLASS__, 'flush_rewrite_rules'));
add_action('wp', array(__CLASS__, 'handle_post_thumbnail'));
add_filter('query_vars', array(__CLASS__, 'register_query_vars'));
register_deactivation_hook(__FILE__, 'flush_rewrite_rules');
}
/**
* Register query variables required for post thumbnail URL handling
*
* This method is triggered by 'query_vars' filter.
*
* @param array $vars
* @return array
*/
public static function register_query_vars(array $vars)
{
$vars[] = self::VAR_POST_THUMBNAIL;
$vars[] = self::VAR_SIZE;
return $vars;
}
/**
* Setup rewrite rule for post thumbnail URL
*
* When not already present, the required rule is added and rewrite
* rules are marked for flushing.
*
* This method is triggered by 'init' action.
*/
public static function setup_rewrite_rules()
{
global $wp_rewrite;
$pattern = sprintf('%s/(\d+)(/([^/]+))?', self::PERMALINK_PREFIX);
$target = sprintf(
'index.php?%s=$matches[1]&%s=$matches[3]',
self::VAR_POST_THUMBNAIL,
self::VAR_SIZE
);
// retrieve rewrite rules, results of this function are cached
// internally by WP_Rewrite, so we can assume it is not expensive
$rules = $wp_rewrite->wp_rewrite_rules();
// check if rewrite rule is present and valid, otherwise mark
// rewrite rules for flushing
if (!isset($rules[$pattern]) || $rules[$pattern] !== $target) {
self::$_flush_rewrite_rules = true;
}
add_rewrite_rule($pattern, $target, 'top');
}
/**
* Flush rewrite rules if they are marked for flushing
*/
public static function flush_rewrite_rules()
{
if (self::$_flush_rewrite_rules) {
flush_rewrite_rules(false);
}
}
/**
* Redirect to post thumbnail image if the 'post_thumbnail' query variable
* containing Post ID is provided
*/
public static function handle_post_thumbnail()
{
// default value can be provided to get_query_var() since 3.9.0
$post_id = get_query_var(self::VAR_POST_THUMBNAIL, null);
if ($post_id === null) {
// query var required for triggering post thumbnail handler
// was not provided, nothing to do here...
return;
}
$post = get_post((int) $post_id);
if (empty($post)) {
status_header(404);
exit;
}
$size = get_query_var(self::VAR_SIZE);
// handle 'thumb' alias for 'thumbnail' image size mentioned in
// https://codex.wordpress.org/Post_Thumbnails#Thumbnail_Sizes
if ($size === 'thumb') {
$size = 'thumbnail';
}
$post_thumbnail_id = get_post_thumbnail_id($post_id);
// if post thumbnail cannot be determined, use the post itself as a thumbnail
// providing that it is an image attachment
if (empty($post_thumbnail_id) && $post->post_type === 'attachment') {
$post_thumbnail_id = $post->ID;
}
$img = wp_get_attachment_image_src($post_thumbnail_id, $size);
if ($img) {
// [0 => url, 1 => width, 2 => height]
wp_redirect($img[0]);
} else {
status_header(404);
}
exit;
}
/**
* Retrieve post thumbnail endpoint structure
*
* @return string
*/
public static function get_endpoint_structure()
{
global $wp_rewrite;
// check if pretty permalinks are enabled
if ($wp_rewrite->using_permalinks()) {
return sprintf(
'/%s/%s/%s',
self::PERMALINK_PREFIX,
self::TAG_POST_ID,
self::TAG_SIZE
);
}
return sprintf(
'/index.php?%s=%s&%s=%s',
self::VAR_POST_THUMBNAIL,
self::TAG_POST_ID,
self::VAR_SIZE,
self::TAG_SIZE
);
}
/**
* Retrieve post thumbnail endpoint for the given post ID
*
* @param int $post_id
* @param string $size OPTIONAL
* @return string
*/
public static function get_endpoint($post_id, $size = null)
{
$url = strtr(self::get_endpoint_structure(), array(
self::TAG_POST_ID => (int) $post_id,
self::TAG_SIZE => urlencode(trim($size)),
));
// strip off dangling slash if empty 'size' value is provided
// (when pretty permalinks are enabled)
$url = rtrim($url, '/');
// strip off empty 'size' query variable (pretty permalinks disabled)
$suffix = sprintf('&%s=', self::VAR_SIZE);
if (substr($url, -strlen($suffix)) === $suffix) {
$url = substr($url, 0, -strlen($suffix));
}
return get_site_url() . $url;
}
}
/**
* Retrieve post thumbnail endpoint for the given post ID
*
* @param int $post_id
* @param string $size OPTIONAL
* @return string
*/
function get_post_thumbnail_endpoint($post_id, $size = null)
{
return WP_Post_Thumbnail_Endpoint::get_endpoint($post_id, $size);
}
/**
* Retrieve post thumbnail endpoint structure
*
* @return string
*/
function get_post_thumbnail_endpoint_structure()
{
return WP_Post_Thumbnail_Endpoint::get_endpoint_structure();
}
WP_Post_Thumbnail_Endpoint::init();
} // WP_POST_THUMBNAIL_ENDPOINT