-
Notifications
You must be signed in to change notification settings - Fork 19
/
wp-facebook-ogp.php
358 lines (308 loc) · 16 KB
/
wp-facebook-ogp.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
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
<?php
/*
Plugin Name: WP Facebook Open Graph protocol
Plugin URI: http://wordpress.org/plugins/wp-facebook-open-graph-protocol/
Description: Adds proper Facebook Open Graph Meta tags and values to your site so when links are shared it looks awesome! Works on Google + and Linkedin too!
Version: 2.0.13
Author: Chuck Reynolds
Author URI: http://chuckreynolds.us
License: GPLv2 or later
License URI: http://www.gnu.org/licenses/gpl-2.0.html
Copyright 2014 Chuck Reynolds (email : chuck@rynoweb.com)
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License, version 2, as
published by the Free Software Foundation.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
define( 'WPFBOGP_VERSION', '2.0.13' );
wpfbogp_admin_warnings();
// add OGP namespace per ogp.me schema
function wpfbogp_namespace($output) {
return $output.' prefix="og: http://ogp.me/ns#"';
}
add_filter('language_attributes','wpfbogp_namespace');
// function to call first uploaded image in content
function wpfbogp_find_images() {
global $post, $posts;
if( !is_object($post) || get_class($post) != 'WP_Post' ) {
return array();
}
// Grab content and match first image
$content = $post->post_content;
$output = preg_match_all( '/<img.+src=[\'"]([^\'"]+)[\'"].*>/i', $content, $matches );
// Make sure there was an image that was found, otherwise return false
if ( $output === FALSE ) {
return false;
}
$wpfbogp_images = array();
foreach ( $matches[1] as $match ) {
// If the image path is relative, add the site url to the beginning
if ( ! preg_match('/^https?:\/\//', $match ) ) {
// Remove any starting slash with ltrim() and add one to the end of site_url()
$match = site_url( '/' ) . ltrim( $match, '/' );
}
$wpfbogp_images[] = $match;
}
return $wpfbogp_images;
}
function wpfbogp_start_ob() {
// Start the buffer before any output
if ( ! is_feed() ) {
ob_start( 'wpfbogp_callback' );
}
}
function wpfbogp_callback( $content ) {
// Grab the page title and meta description
$title = preg_match( '/<title>(.*)<\/title>/', $content, $title_matches );
$description = preg_match( '/<meta name="description" content="(.*)"/', $content, $description_matches );
// Take page title and meta description and place it in the ogp meta tags
if ( $title !== FALSE && count( $title_matches ) == 2 ) {
$content = preg_replace( '/<meta property="og:title" content="(.*)">/', '<meta property="og:title" content="' . $title_matches[1] . '">', $content );
}
if ( $description !== FALSE && count( $description_matches ) == 2 ) {
$content = preg_replace( '/<meta property="og:description" content="(.*)">/', '<meta property="og:description" content="' . $description_matches[1] . '">', $content );
}
return $content;
}
function wpfbogp_flush_ob() {
if ( ! is_feed() ) {
ob_end_flush();
}
}
add_action( 'init', 'wpfbogp_start_ob', 0 );
add_action( 'wp_footer', 'wpfbogp_flush_ob', 10000 ); // Fire after other plugins (which default to priority 10)
// build ogp meta
function wpfbogp_build_head() {
global $post;
if( !is_object($post) || get_class($post) != 'WP_Post' ) {
return '';
}
$options = get_option('wpfbogp');
// check to see if you've filled out one of the required fields and announce if not
if ( ( ! isset( $options['wpfbogp_admin_ids'] ) || empty( $options['wpfbogp_admin_ids'] ) ) && ( ! isset( $options['wpfbogp_app_id'] ) || empty( $options['wpfbogp_app_id'] ) ) ) {
echo "\n<!-- Facebook Open Graph protocol plugin NEEDS an admin or app ID to work, please visit the plugin settings page! -->\n";
} else {
echo "\n<!-- WordPress Facebook Open Graph protocol plugin (WPFBOGP v".WPFBOGP_VERSION.") http://rynoweb.com/wordpress-plugins/ -->\n";
// do fb verification fields
if ( isset( $options['wpfbogp_admin_ids'] ) && ! empty( $options['wpfbogp_admin_ids'] ) ) {
echo '<meta property="fb:admins" content="' . esc_attr( apply_filters( 'wpfbogp_app_id', $options['wpfbogp_admin_ids'] ) ) . '"/>' . "\n";
}
if ( isset( $options['wpfbogp_app_id'] ) && ! empty( $options['wpfbogp_app_id'] ) ) {
echo '<meta property="fb:app_id" content="' . esc_attr( apply_filters( 'wpfbogp_app_id', $options['wpfbogp_app_id'] ) ) . '"/>' . "\n";
}
// do url stuff
if ( is_front_page() ) {
$wpfbogp_url = home_url();
} else {
$wpfbogp_url = 'http' . ( is_ssl() ? 's' : '' ) . '://' . $_SERVER['SERVER_NAME'] . $_SERVER['REQUEST_URI'];
}
echo '<meta property="og:url" content="' . esc_url( user_trailingslashit( trailingslashit( apply_filters( 'wpfbogp_url', $wpfbogp_url ) ) ) ) . '"/>' . "\n";
// do title stuff
if ( is_home() || is_front_page() ) {
$wpfbogp_title = get_bloginfo( 'name' );
} else {
$wpfbogp_title = get_the_title();
}
echo '<meta property="og:title" content="' . esc_attr( apply_filters( 'wpfbogp_title', $wpfbogp_title ) ) . '"/>' . "\n";
// do additional randoms
echo '<meta property="og:site_name" content="' . get_bloginfo( 'name' ) . '"/>' . "\n";
// do descriptions
if ( is_singular() ) {
if ( has_excerpt( $post->ID ) ) {
$wpfbogp_description = strip_tags( get_the_excerpt() );
} else {
$wpfbogp_description = str_replace( "\r\n", ' ' , substr( strip_tags( strip_shortcodes( $post->post_content ) ), 0, 160 ) );
}
} else {
$wpfbogp_description = get_bloginfo( 'description' );
}
echo '<meta property="og:description" content="' . esc_attr( apply_filters( 'wpfbogp_description', $wpfbogp_description ) ) . '"/>' . "\n";
// do ogp type
if ( is_single() ) {
$wpfbogp_type = 'article';
} else {
$wpfbogp_type = 'website';
}
echo '<meta property="og:type" content="' . esc_attr( apply_filters( 'wpfbpogp_type', $wpfbogp_type ) ) . '"/>' . "\n";
// Find/output any images for use in the OGP tags
$wpfbogp_images = array();
// Only find images if it isn't the homepage and the fallback isn't being forced
if ( ! is_home() && $options['wpfbogp_force_fallback'] != 1 ) {
// Find featured thumbnail of the current post/page
if ( function_exists( 'has_post_thumbnail' ) && has_post_thumbnail( $post->ID ) ) {
$thumbnail_src = wp_get_attachment_image_src( get_post_thumbnail_id( $post->ID ), 'large' );
$link = $thumbnail_src[0];
if ( ! preg_match( '/^https?:\/\//', $link ) ) {
// Remove any starting slash with ltrim() and add one to the end of site_url()
$link = site_url( '/' ) . ltrim( $link, '/' );
}
$wpfbogp_images[] = $link; // Add to images array
}
if ( wpfbogp_find_images() !== false && is_singular() ) { // Use our function to find post/page images
$wpfbogp_images = array_merge( $wpfbogp_images, wpfbogp_find_images() ); // Returns an array already, so merge into existing
}
}
// Add the fallback image to the images array (which is empty if it's being forced)
if ( isset( $options['wpfbogp_fallback_img'] ) && $options['wpfbogp_fallback_img'] != '') {
if ( is_array( $wpfbogp_images ) )
{
$wpfbogp_images[] = $options['wpfbogp_fallback_img']; // Add to images array
$wpfbogp_images = array_reverse($wpfbogp_images);
}
else {
$wpfbogp_images = array( $options['wpfbogp_fallback_img'] ); // Create image array with default image as index 0
}
}
// Make sure there were images passed as an array and loop through/output each
if ( ! empty( $wpfbogp_images ) && is_array( $wpfbogp_images ) ) {
foreach ( $wpfbogp_images as $image ) {
echo '<meta property="og:image" content="' . esc_url( apply_filters( 'wpfbogp_image', $image ) ) . '"/>' . "\n";
}
} else {
// No images were outputted because they have no default image (at the very least)
echo "<!-- There is not an image here as you haven't set a default image in the plugin settings! -->\n";
}
// do locale // make lower case cause facebook freaks out and shits parser mismatched metadata warning
echo '<meta property="og:locale" content="' . strtolower( esc_attr( get_locale() ) ) . '"/>' . "\n";
echo "<!-- // end wpfbogp -->\n";
}
}
add_action('wp_head','wpfbogp_build_head',50);
add_action('admin_init','wpfbogp_init');
add_action('admin_menu','wpfbogp_add_page');
// register settings and sanitization callback
function wpfbogp_init() {
register_setting('wpfbogp_options','wpfbogp','wpfbogp_validate');
}
// add admin page to menu
function wpfbogp_add_page() {
add_options_page('Facebook Open Graph protocol plugin','Facebook OGP','manage_options','wpfbogp','wpfbogp_buildpage');
}
// build admin page
function wpfbogp_buildpage() {
?>
<div class="wrap">
<h2>Facebook Open Graph protocol plugin <em>v<?php echo WPFBOGP_VERSION; ?></em></h2>
<div id="poststuff" class="metabox-holder has-right-sidebar">
<div id="side-info-column" class="inner-sidebar">
<div class="meta-box-sortables">
<div id="about" class="postbox">
<h3 class="hndle" id="about-sidebar"><?php _e('About the Plugin:') ?></h3>
<div class="inside">
<p>Talk to <a href="https://twitter.com/chuckreynolds" target="_blank">@ChuckReynolds</a> on twitter or please fill out the <a href="http://rynoweb.com/wordpress-plugins/" target="_blank">plugin support form</a> for bugs or feature requests.</p>
<p><?php _e('<strong>Enjoy the plugin?</strong>') ?><br />
<a href="https://twitter.com/?status=I'm using @chuckreynolds's WordPress Facebook Open Graph plugin - check it out! http://rynoweb.com/wordpress-plugins/" target="_blank"><?php _e('Tweet about it') ?></a> <?php _e('and consider donating.') ?></p>
<p><?php _e('<strong>Donate:</strong> A lot of hard work goes into building plugins - support your open source developers. Include your twitter username and I\'ll send you a shout out for your generosity. Thank you!') ?><br />
<form action="https://www.paypal.com/cgi-bin/webscr" method="post">
<input type="hidden" name="cmd" value="_s-xclick">
<input type="hidden" name="hosted_button_id" value="GWGGBTBJTJMPW">
<input type="image" src="https://www.paypalobjects.com/en_US/i/btn/btn_donate_SM.gif" border="0" name="submit" alt="PayPal - The safer, easier way to pay online!">
<img alt="" border="0" src="https://www.paypalobjects.com/en_US/i/scr/pixel.gif" width="1" height="1">
</form></p>
</div>
</div>
</div>
<div class="meta-box-sortables">
<div id="about" class="postbox">
<h3 class="hndle" id="about-sidebar"><?php _e('Relevant Information:') ?></h3>
<div class="inside">
<p><a href="http://ogp.me" target="_blank">The Open Graph Protocol</a><br />
<a href="https://developers.facebook.com/docs/sharing/best-practices" target="_blank">Sharing Best Practices for Websites</a><br />
<a href="https://developers.facebook.com/docs/platforminsights/domains" target="_blank">Domain Insights</a><br />
<a href="https://developers.facebook.com/docs/plugins/like-button" target="_blank">How To Add a Like Button</a></p>
</div>
</div>
</div>
</div> <!-- // #side-info-column .inner-sidebar -->
<div id="post-body" class="has-sidebar">
<div id="post-body-content" class="has-sidebar-content">
<div id="normal-sortables" class="meta-box-sortables">
<div id="about" class="postbox">
<div class="inside">
<form method="post" action="options.php">
<?php settings_fields('wpfbogp_options'); ?>
<?php $options = get_option('wpfbogp'); ?>
<table class="form-table">
<tr valign="top">
<th scope="row"><?php _e('Facebook User Account ID:') ?></th>
<td><input type="text" name="wpfbogp[wpfbogp_admin_ids]" value="<?php echo $options['wpfbogp_admin_ids']; ?>" class="regular-text" /><br />
<?php _e('For personal sites use your Facebook User ID here. <em>(You can enter multiple by separating each with a comma)</em>, if you want to receive Insights about the Like Buttons. The meta values will not display in your site until you\'ve completed this box.<br />
<strong>Find your ID</strong> by going to the URL like this: https://graph.facebook.com/yourusername') ?></td>
</tr>
<tr valign="top">
<th scope="row"><?php _e('Facebook Application ID:') ?></th>
<td><input type="text" name="wpfbogp[wpfbogp_app_id]" value="<?php echo $options['wpfbogp_app_id']; ?>" class="regular-text" /><br />
<?php _e('For business and/or brand sites use Insights on an App ID as to not associate it with a particular person. You can use this with or without the User ID field. Create an app and use the "App ID": <a href="https://developers.facebook.com/quickstarts/" target="_blank">Create FB App</a>.') ?></td>
</tr>
<tr valign="top">
<th scope="row"><?php _e('Default Image URL to use:') ?></th>
<td><input type="text" name="wpfbogp[wpfbogp_fallback_img]" value="<?php echo $options['wpfbogp_fallback_img']; ?>" class="large-text" /><br />
<?php _e('Full URL including http:// to the default image to use if your posts/pages don\'t have a featured image or an image in the content. <strong>The image is recommended to be 200px by 200px</strong>.<br />
You can use the WordPress <a href="media-new.php">media uploader</a> if you wish, just copy the location of the image and put it here.') ?></td>
</tr>
<tr valign="top">
<th scope="row"><?php _e('Force Fallback Image as Default') ?></th>
<td><input type="checkbox" name="wpfbogp[wpfbogp_force_fallback]" value="1" <?php if ($options['wpfbogp_force_fallback'] == 1) echo 'checked="checked"'; ?>) /> <?php _e('Use this if you want to use the Default Image for everything instead of looking for featured/content images.') ?></label></td>
</tr>
</table>
<input type="submit" class="button-primary" value="<?php _e('Save Changes') ?>" />
</form>
<br class="clear" />
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<?php
}
// sanitize inputs. accepts an array, return a sanitized array.
function wpfbogp_validate($input) {
$input['wpfbogp_admin_ids'] = wp_filter_nohtml_kses($input['wpfbogp_admin_ids']);
$input['wpfbogp_app_id'] = wp_filter_nohtml_kses($input['wpfbogp_app_id']);
$input['wpfbogp_fallback_img'] = wp_filter_nohtml_kses($input['wpfbogp_fallback_img']);
$input['wpfbogp_force_fallback'] = ($input['wpfbogp_force_fallback'] == 1) ? 1 : 0;
return $input;
}
// run admin notices on activation or if settings not set
function wpfbogp_admin_warnings() {
global $wpfbogp_admins;
$wpfbogp_data = get_option('wpfbogp');
if ((empty($wpfbogp_data['wpfbogp_admin_ids']) || $wpfbogp_data['wpfbogp_admin_ids'] == '') && (empty($wpfbogp_data['wpfbogp_app_id']) || $wpfbogp_data['wpfbogp_app_id'] == '')) {
function wpfbogp_warning() {
echo "<div id='wpfbogp-warning' class='updated fade'><p><strong>".__('WP FB OGP is almost ready.')."</strong> ".sprintf(__('You must <a href="%1$s">enter your Facebook User ID or App ID</a> for it to work.'), "options-general.php?page=wpfbogp")."</p></div>";
}
add_action('admin_notices', 'wpfbogp_warning');
}
}
// twentyten and twentyeleven add crap to the excerpt so lets check for that and remove
add_action('after_setup_theme','wpfbogp_fix_excerpts_exist');
function wpfbogp_fix_excerpts_exist() {
remove_filter('get_the_excerpt','twentyten_custom_excerpt_more');
remove_filter('get_the_excerpt','twentyeleven_custom_excerpt_more');
}
// add settings link to plugins list
function wpfbogp_add_settings_link($links, $file) {
static $this_plugin;
if (!$this_plugin) $this_plugin = plugin_basename(__FILE__);
if ($file == $this_plugin){
$settings_link = '<a href="options-general.php?page=wpfbogp">'.__("Settings","wpfbogp").'</a>';
array_unshift($links, $settings_link);
}
return $links;
}
add_filter('plugin_action_links','wpfbogp_add_settings_link', 10, 2 );
// lets offer an actual clean uninstall and rem db row on uninstall
if (function_exists('register_uninstall_hook')) {
register_uninstall_hook(__FILE__, 'wpfbogp_uninstall_hook');
function wpfbogp_uninstall_hook() {
delete_option('wpfbogp');
}
}