WordPress Google Photos embed handler
<?php
/*
Plugin Name: Google Photos embed handler
Plugin URI: https://www.faircode.eu/
Description: Google photos embed handler
Version: 0.1
Author: Marcel Bokhorst
Author URI: https://www.faircode.eu/
*/
/*
Copyright 2016 Marcel Bokhorst
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
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
*/
add_action('admin_init', 'm66b_embed_admin_init');
add_action('admin_menu', 'm66b_embed_admin_menu');
add_action('init', 'm66b_init_embed_gphotos');
function m66b_embed_admin_init() {
register_setting(
'gphotos-embed-options',
'gphotos-embed-timeout'
);
register_setting(
'gphotos-embed-options',
'gphotos-embed-cache'
);
add_settings_section(
'gphotos-embed-general-section',
'General',
'm66b_embed_general_section_render',
'gphotos-embed-options'
);
add_settings_field(
'gphotos-embed-timeout',
'Connection time-out',
'm66b_embed_connection_timeout_render',
'gphotos-embed-options',
'gphotos-embed-general-section'
);
add_settings_field(
'gphotos-embed-cache',
'Cache time',
'm66b_embed_cache_time_render',
'gphotos-embed-options',
'gphotos-embed-general-section'
);
}
function m66b_embed_general_section_render() {
}
function m66b_embed_connection_timeout_render() {
$setting = esc_attr(get_option('gphotos-embed-timeout'));
echo '<input name="gphotos-embed-timeout" type="text" value="' . $setting . '" /> seconds';
echo '<p>Default 20 seconds</p>';
}
function m66b_embed_cache_time_render() {
$setting = esc_attr(get_option('gphotos-embed-cache'));
echo '<input name="gphotos-embed-cache" type="text" value="' . $setting . '" /> seconds';
echo '<p>Default 24 hours; -1 disables caching</p>';
}
function m66b_embed_admin_menu() {
add_options_page(
'Google Photos',
'Google Photos',
'manage_options',
'gphotos-embed-options',
'm66b_embed_options_page'
);
}
function m66b_embed_options_page() {
?>
<div class="wrap">
<h1>Google Photos</h1>
<form method="POST" action="options.php">
<?php
settings_fields('gphotos-embed-options');
do_settings_sections('gphotos-embed-options');
submit_button();
?>
</form>
</div>
<?php
}
function m66b_init_embed_gphotos() {
wp_embed_register_handler('m66b_handle_gphotos_embed', '#https\://goo\.gl/photos/(.+)#i', 'm66b_handle_gphotos_embed', 1);
}
/*
<meta property="og:title" content="Herfst 2016">
<meta property="og:type" content="google_photos:photo_album">
<meta property="og:url" content="https://photos.google.com/share/AF1QipMgDv2lQHWV6ExEblT-3DiZpjkLaivhLZfgofb_ebijt5321F1huWMrwi6Bde6YXQ?key=dkpJSWlFLUF2TXFrcmFWeC05VGFiQi02UGJoT1Vn">
<meta property="og:image" content="https://lh3.googleusercontent.com/3Y-pWKaVuVUkkVcWnpEITJGBqRq2tZRz4uPyUO_U15no9eZSkJPU8W9edIRSRkTkMoHfBXJVzXIC=w600-h315-p-k">
<meta property="og:image:width" content="600">
<meta property="og:image:height" content="315">
<meta property="og:description" content="40 new photos · Album by Marcel Bokhorst">
*/
function m66b_handle_gphotos_embed($matches, $attr, $url, $rawattr) {
// Check cache
$transient_name = 'm66b_gp_' . md5($url);
$cache_time = get_option('gphotos-embed-cache');
$cache_time = (empty($cache_time) ? 24 * 60 * 60 : $cache_time);
$meta = ($cache_time < 0 ? false : get_transient($transient_name));
$cached = ($meta !== false);
if (!$cached) {
// Fetch album page
$timeout = get_option('gphotos-embed-timeout');
$timeout = (empty($timeout) ? 20 : $timeout);
$response = wp_safe_remote_get($url, array(
'timeout' => $timeout,
'httpversion' => '1.1',
'sslverify' => true,
'headers' => array('Accept-Language' => get_bloginfo('language') . ', en;q=0.7, *;q=0.5')
));
if (is_wp_error($response) || $response['response']['code'] !== 200)
return '<a href="' . esc_attr($url) . '">' . esc_html($url) . '</a> error=' . print_r($response, true);
// Get ogp tags
libxml_use_internal_errors(true);
$doc = new DomDocument();
$doc->loadHTML(mb_convert_encoding($response['body'], 'HTML-ENTITIES', 'UTF-8'));
$xpath = new DOMXPath($doc);
$meta = array();
foreach ($xpath->query('//*/meta[starts-with(@property, \'og:\')]') as $xmeta)
$meta[$xmeta->getAttribute('property')] = $xmeta->getAttribute('content');
// Update cache
if ($cache_time > 0)
set_transient($transient_name, $meta, $cache_time);
else
delete_transient($transient_name);
}
// Check for required fields
if (!isset($meta['og:image']) ||
(!isset($meta['og:title']) && !isset($meta['og:description'])))
return '<a href="' . esc_attr($url) . '">' . esc_html($url) . '</a> meta=' . print_r($meta, true);
// Build title
$title = (isset($meta['og:title']) ? $meta['og:title'] : null);
if (isset($meta['og:description']))
$title .= ($title == null ? '' : ' · ') . $meta['og:description'];
// Get image size
$width = (isset($meta['og:image:width']) ? ' width="' . esc_attr($meta['og:image:width']) . '"' : '');
$height = (isset($meta['og:image:height']) ? ' height="' . esc_attr($meta['og:image:height']) . '"' : '');
// Embed image
return
'<figure style="text-align: center;">' .
'<a href="' . esc_attr($url) . '">' .
'<img src="' . esc_attr($meta['og:image']) . '"' . $width . $height . ' title="' . esc_attr($title) . '" alt="' . esc_attr($title) . '">' .
'</a>' .
'<figcaption><a href="' . esc_attr($url) . '">' . $title . '</a></figcaption>' .
(false ? '<div style="display: none;">' .
'cached=' . ($cached ? 'true' : 'false') . ':' . $cache_time . PHP_EOL .
'timeout=' . $timeout . PHP_EOL .
esc_html(print_r($meta, true)) .
'</div>' : '') .
'</figure>';
}
?>