oembed.module in oEmbed 7
Same filename and directory in other branches
Core functionality for oEmbed
File
oembed.moduleView source
<?php
/**
* @file
* Core functionality for oEmbed
*/
// Load all Field module hooks for oEmbed.
require_once dirname(__FILE__) . '/oembed.field.inc';
require_once dirname(__FILE__) . '/oembed.filter.inc';
/**
* Implements hook_hook_info().
*/
function oembed_hook_info() {
$hooks = array(
'oembed_request_alter',
'oembed_response_alter',
);
return array_fill_keys($hooks, array(
'group' => 'oembed',
));
}
/**
* Implements hook_help().
*/
function oembed_help($path, $arg) {
switch ($path) {
case 'admin/help#oembed':
$output = '<p>' . t('oEmbed module will allow your Drupal site to embed content from <a href="@oembed">oEmbed</a>-providers as well as for the site to become an oEmbed-provider itself so that other oEmbed-enabled websites can easily embed your content.', array(
'@oembed' => 'http://www.oembed.com/',
)) . '</p>';
$output .= '<p>' . t('Add or enable <a href="@provider">providers</a> to embed content from other sites.', array(
'@provider' => url('admin/build/oembed/provider'),
)) . '</p>';
$output .= '<p>' . t('Adds an input filter for replacing oEmbed enabled URLs with embedded content') . '</p>';
return $output;
case 'admin/config/media/oembed':
case 'admin/config/media/oembed/consumer':
$output = '<p>' . t('These settings affect how your site behaves when it makes requests as an oEmbed consumer.') . '</p>';
return $output;
case 'admin/config/media/oembed/provider':
$output = '<p>' . t('Providers are other web sites with oEmbed endpoints whose content you can embed on your site.') . '</p>';
return $output;
case 'admin/config/media/oembed/test':
$output = '<p>' . t('Use this form to test your configuration of provider plugins and endpoints.') . '</p>';
return $output;
}
}
/**
* Implements hook_permission().
*/
function oembed_permission() {
return array(
'administer oembed' => array(
'title' => t('Administer oEmbed'),
'description' => t('Define providers for oEmbed.'),
),
);
}
/**
* Implements hook_flush_caches().
*/
function oembed_flush_caches() {
// Because some oEmbed providers (e.g., http://embed.ly) charge per request,
// allow cache_oembed to opt out of drupal_flush_all_caches() clearing.
if (variable_get('oembed_cache_flush', TRUE)) {
return array(
'cache_oembed',
);
}
}
/**
* Implements hook_cron().
*/
function oembed_cron() {
// If cache_oembed opts out of oembed_flush_caches(), then system_cron()
// doesn't clear its expired records, so do so here.
if (!variable_get('oembed_cache_flush', TRUE)) {
cache_clear_all(NULL, 'cache_oembed');
}
}
/**
* Implements hook_menu().
*/
function oembed_menu() {
$items = array();
$items['admin/config/media/oembed'] = array(
'title' => 'oEmbed',
'description' => 'Settings for oEmbed',
'page callback' => 'drupal_get_form',
'page arguments' => array(
'oembed_settings',
),
'file' => 'oembed.admin.inc',
'access arguments' => array(
'administer site configuration',
),
);
$items['admin/config/media/oembed/consumer'] = array(
'title' => 'Consumer settings',
'type' => MENU_DEFAULT_LOCAL_TASK,
);
$items['admin/config/media/oembed/provider'] = array(
'title' => 'Provider plugins',
'description' => 'Settings for oEmbed provider plugins',
'type' => MENU_LOCAL_TASK,
);
$items['admin/config/media/oembed/test'] = array(
'title' => 'Test',
'description' => 'Test URLs for oEmbed',
'page callback' => 'drupal_get_form',
'page arguments' => array(
'oembed_test',
),
'file' => 'oembed.admin.inc',
'type' => MENU_LOCAL_TASK,
'access arguments' => array(
'administer site configuration',
),
);
return $items;
}
/**
* Implements hook_menu_alter().
*
* Instead of rewriting ctools export UI's hook_menu implementations, alter
* the callback items to have a common menu item.
*/
function oembed_menu_alter(&$items) {
// Create a new menu item where all oembed export UIs will be local tasks by
// copying the export UI's menu item that will become the default local task.
if (!empty($items['admin/config/media/oembed/provider/default'])) {
$items['admin/config/media/oembed/provider'] += $items['admin/config/media/oembed/provider/default'];
$items['admin/config/media/oembed/provider']['type'] = MENU_LOCAL_TASK;
$items['admin/config/media/oembed/provider/default']['type'] = MENU_DEFAULT_LOCAL_TASK;
}
}
/**
* Implements of hook_theme().
*/
function oembed_theme($existing, $type, $theme, $path) {
return array(
'oembed' => array(
'file' => 'oembed.theme.inc',
'path' => $path . '/theme',
'variables' => array(
'embed' => NULL,
),
),
'oembed__photo' => array(
'variables' => array(
'embed' => NULL,
),
'base hook' => 'oembed',
),
'oembed__rich' => array(
'variables' => array(
'embed' => NULL,
),
'base hook' => 'oembed',
),
'oembed__video' => array(
'variables' => array(
'embed' => NULL,
),
'base hook' => 'oembed',
),
);
}
/**
* Returns the provider for a url.
*
* @param string $url
* The url to get the provider for.
* @param array $matches
* Array reference for providers that capture arguments from URL.
* @param string $role
*
* @return mixed
* A valid callback or FALSE
*/
function oembed_get_provider($url, &$matches, $role = 'consumer') {
ctools_include('plugins');
$plugins = ctools_get_plugins('oembed', 'providers');
uasort($plugins, 'ctools_plugin_sort');
// This function may need check twice if a provider matches the URL. The first
// check is to determine if the plugin's callback can handle the URL.
// The second check returns the name of the child plugin that can fulfill
// the request.
foreach ($plugins as $plugin) {
// A plugin with no schemes is effectively disabled.
if ($plugin[$role] && !empty($plugin['scheme'])) {
// Remove '#' and '#i' from the begining and end.
$scheme = substr($plugin['scheme'], 1, -2);
$sub_schemes = explode('|', $scheme);
foreach ($sub_schemes as $pattern) {
// Plugins will only be checked if they are enabled for the role.
if (preg_match("#{$pattern}#i", $url, $matches)) {
// A scheme map is used to match a URL to a specific child plugin.
if (!empty($plugin['scheme map'])) {
foreach ($plugin['scheme map'] as $id => $scheme) {
if (preg_match($scheme, $url, $matches)) {
// This forces the 'get child' callback to the loaded.
ctools_plugin_get_function($plugin, 'get child');
$plugin = ctools_get_plugins('oembed', 'providers', $id);
break;
}
}
}
return $plugin;
}
}
}
}
return FALSE;
}
/**
* Reset the registered provider caches.
*/
function oembed_providers_reset() {
ctools_include('plugins');
ctools_get_plugins_reset();
$info = ctools_plugin_get_info('oembed', 'providers');
cache_clear_all('plugins:oembed:providers', $info['cache table']);
}
/**
* Fetch data for an embeddable URL.
*
* @param string $url
* An external URL for the content to embed.
* @param array $parameters
* An associative array of request parameters, with the following keys:
* - 'maxwidth'
* The maximum width of the embed, in pixels.
* - 'maxheight'
* The maximum height of the embed, in pixels.
* Other keys may be supported by some providers (twitter, youtube, wordpress).
* @return bool|array
* False or an array representing the embeddable data of the URL.
*/
function oembed_get_data($url, $parameters = array()) {
$matches = array();
$parameters = array_filter($parameters);
if ($plugin = oembed_get_provider($url, $matches)) {
return oembed_oembed_fetch($plugin, $url, $matches, $parameters);
}
return FALSE;
}
/**
* Helper function generates a cache key based on url and request parameters.
*
* @param $url
* @param array $parameters
* @return string
*/
function oembed_cache_key($url, $parameters = array()) {
$cache_keys = array();
// Remove trailing slash to normalize URLs.
$cache_keys[] = hash('sha256', substr($url, -1) == '/' ? substr($url, 0, -1) : $url);
// Hash and serialize request parameters and display options.
if (!empty($parameters)) {
// Normalize the parameters and attributes for better cache performance.
ksort($parameters);
$parameters = array_filter($parameters);
$cache_keys[] = hash('sha256', serialize($parameters));
}
$cache_key = implode(':', $cache_keys);
return $cache_key;
}
/**
* Helper function to calculate expire based on lifetime and cache age.
*
* @param $embed
* @return mixed|null
*/
function oembed_cache_expire($embed) {
// If expire is not set, use default value and adjust for request time.
$lifetime = variable_get('oembed_cache_lifetime', 3600);
// Recalculate cache expire time based on response.
if ($lifetime != CACHE_PERMANENT && isset($embed['cache_age'])) {
$lifetime = max($lifetime, intval($embed['cache_age']));
}
if ($lifetime == CACHE_PERMANENT) {
$expire = $lifetime;
}
else {
// Twitter returns an unreasonably high cache_age of 31536000000 seconds,
// which is longer than the expire column in Drupal cache table supports.
$expire = min($lifetime + REQUEST_TIME, pow(2, 31));
}
return $expire;
}
/**
* oEmbed fetcher and parser.
*
* This handles fetching from remote providers and local registered callbacks.
* It does not cache the responses because they are cached when rendered.
*/
function oembed_oembed_fetch($plugin, $url, $matches, $parameters = array()) {
if ($plugin['cache']) {
$cache_key = oembed_cache_key($url, $parameters);
$cache = cache_get($cache_key, 'cache_oembed');
// Cache hit.
if ($cache) {
return isset($cache->data) ? $cache->data : FALSE;
}
}
// Cache miss.
drupal_alter('oembed_request', $parameters, $plugin, $url);
// Drupal oEmbed provider uses function callbacks for internal requests.
$function = ctools_plugin_get_function($plugin, 'callback');
if (!$function) {
return FALSE;
}
try {
$embed = call_user_func($function, $plugin, $url, $matches, $parameters);
// Decorate the oEmbed response object with additional properties that are
// handy when theming the output.
$embed['original_url'] = $url;
$embed['provider'] = $plugin['name'];
drupal_alter('oembed_response', $embed);
if ($plugin['cache']) {
$expire = oembed_cache_expire($embed);
cache_set($cache_key, $embed, 'cache_oembed', $expire);
}
return $embed;
} catch (RuntimeException $e) {
if ($plugin['cache'] && ($e
->getCode() === 404 || $e
->getCode() === 501 || $e
->getCode() === 401)) {
// If expire is not set, use default value and adjust for request time.
$lifetime = variable_get('oembed_cache_lifetime', 3600);
if ($lifetime == CACHE_PERMANENT) {
$lifetime = 3600;
}
cache_set($cache_key, NULL, 'cache_oembed', $lifetime + REQUEST_TIME);
}
}
return FALSE;
}
/**
* Implements hook_element_info().
*/
function oembed_element_info() {
$types = array();
// Standard oEmbed that changes its theme based on response.
$types['oembed'] = array(
'#theme' => 'oembed',
'#embed' => NULL,
'#parameters' => array(),
'#attributes' => array(),
'#pre_render' => array(
'oembed_pre_render_fetch',
'oembed_pre_render_retheme',
),
);
// Retrieves an image (photo or thumbnail) or nothing.
$types['oembed_thumbnail'] = array(
'#theme' => 'image',
'#path' => NULL,
'#width' => NULL,
'#height' => NULL,
'#alt' => '',
'#title' => NULL,
'#attributes' => array(),
'#embed' => NULL,
'#parameters' => array(),
'#pre_render' => array(
'oembed_pre_render_fetch',
'oembed_pre_render_thumbnail',
),
);
return $types;
}
/**
* Change oEmbed request into a thumbnail.
*/
function oembed_pre_render_thumbnail($element) {
// Only act when the oEmbed response is true.
if (!empty($element['#printed'])) {
return $element;
}
$embed = $element['#embed'];
// Check if the oEmbed response provides a thumbnail image.
if (empty($embed['thumbnail_url'])) {
$element['#printed'] = TRUE;
return $element;
}
oembed_pre_render_image_helper($element, 'thumbnail_');
return $element;
}
/**
* Set the properties for a themed image.
*
* This function takes the element by reference because it should never be called as a
* pre render function despite appearances.
*/
function oembed_pre_render_image_helper(&$element, $prefix = '') {
$embed = $element['#embed'];
$element['#path'] = $embed[$prefix . 'url'];
$element['#alt'] = oembed_alt_attr($embed);
$element['#title'] = $embed['title'];
$element['#height'] = isset($embed[$prefix . 'height']) ? $embed[$prefix . 'height'] : NULL;
$element['#width'] = isset($embed[$prefix . 'width']) ? $embed[$prefix . 'width'] : NULL;
// theme_image() prefers width, height, alt and title element properties over
// attributes so we manually override them if an associated attribute is set.
foreach (array(
'width',
'height',
'alt',
'title',
) as $key) {
if (isset($element['#attributes'][$key])) {
$element['#' . $key] = $element['#attributes'][$key];
}
}
}
/**
* Rewrite the theme parameter based on the response.
*/
function oembed_pre_render_retheme($element) {
// Only act when the oEmbed response is true.
if (!empty($element['#printed'])) {
return $element;
}
$embed = $element['#embed'];
$element['#theme'] = 'oembed__' . $embed['type'] . '__' . implode('__', explode(':', $embed['provider'], 2));
return $element;
}
/**
* Pre render fetches the oEmbed data.
*/
function oembed_pre_render_fetch($element) {
$embed = oembed_get_data($element['#url'], $element['#parameters']);
// Prevent rendering if the response is bad.
if (!$embed) {
$element['#printed'] = TRUE;
return $element;
}
$element['#embed'] = $embed;
return $element;
}
/**
* Prepare an element based on a oEmbed request.
*
* @param $type
* Element type.
* @param $url
* URL to embed.
* @param $parameters
* oEmbed request parameters.
*
* @return array
* A renderable array with the following keys and values:
* - #type: The passed-in element $type.
* - #url: The passed-in $url.
* - #parameters: The passed-in $parameters.
*/
function oembed_render_element($type, $url, $parameters = array()) {
return array(
'#type' => $type,
'#url' => $url,
'#parameters' => $parameters,
);
}
/**
* Generate a string for use as ALT attribute.
*/
function oembed_alt_attr($embed) {
$options = array(
'@type' => $embed['type'],
);
// alt attribute using hopefully available title and provider name.
if (isset($embed['title'])) {
$string = '@title';
$options['@title'] = $embed['title'];
}
else {
$string = 'Embedded @type';
}
if (isset($embed['provider_name'])) {
$string .= ' on @provider_name';
$options['@provider_name'] = $embed['provider_name'];
}
return t($string, $options);
}
/**
* Implement hook_ctools_plugin_directory().
*/
function oembed_ctools_plugin_directory($module, $plugin) {
if ($module == 'ctools' && $plugin == 'export_ui') {
return 'plugins/' . $plugin;
}
if ($module == 'oembed' && $plugin == 'providers') {
return 'plugins/' . $plugin;
}
}
/**
* Implements hook_ctools_plugin_api().
*/
function oembed_ctools_plugin_api($module, $api) {
if ($module == 'oembed' && $api == 'oembed_provider') {
return array(
'version' => 1,
);
}
if ($module == 'file_entity' && $api == 'file_type') {
return array(
'version' => 1,
);
}
if ($module == 'file_entity' && $api == 'file_default_displays') {
return array(
'version' => 1,
);
}
}
/**
* Implements hook_ctools_plugin_type().
*/
function oembed_ctools_plugin_type() {
$plugins = array();
$plugins['providers'] = array(
'cache' => TRUE,
'child plugins' => TRUE,
'process' => array(
'file' => 'oembed.oembed.inc',
'path' => drupal_get_path('module', 'oembed'),
'function' => 'oembed_provider_process',
),
'defaults' => array(
'capture subpatterns' => FALSE,
'cache' => TRUE,
'consumer' => FALSE,
'provider' => FALSE,
),
);
return $plugins;
}
/**
* Implement hook_preprocess_file_entity().
*/
function oembed_preprocess_file_entity(&$vars, $hook) {
if (isset($vars['file']->metadata['oembed'])) {
$vars['oembed_response'] = $embed = $vars['file']->metadata['oembed'];
$vars['classes_array'][] = 'oembed-' . $embed['type'];
if (strpos($embed['provider'], ':')) {
list($parent, $child) = explode(':', $embed['provider'], 2);
$vars['classes_array'][] = 'oembed-' . $parent;
$vars['classes_array'][] = 'oembed-' . $child;
}
else {
$vars['classes_array'][] = 'oembed-' . $embed['provider'];
}
$vars['title_attributes_array']['class'][] = 'oembed-title';
// This conflicts with default file_entity.tpl.php which hardcodes a class attribute.
$vars['content_attributes_array']['class'][] = 'oembed-content';
}
}
/**
* Create stream wrapper for oEmbed videos.
*/
function oembed_stream_wrappers() {
return array(
'oembed' => array(
'name' => t('oEmbed resources'),
'class' => 'OEmbedStreamWrapper',
'description' => t('Resources provided by oEmbed.'),
'type' => STREAM_WRAPPERS_READ_VISIBLE,
),
);
}
/**
* Implements hook_file_formatter_FORMATTER_view().
*/
function oembed_file_formatter_view($file, $display, $langcode) {
$scheme = file_uri_scheme($file->uri);
if ($scheme == 'oembed') {
/** @var \DrupalStreamWrapperInterface $wrapper */
$wrapper = file_stream_wrapper_get_instance_by_uri($file->uri);
// Build render attributes array. Prefer file-specific overrides to display settings.
$attributes = (isset($file->override) ? $file->override : array()) + $display['settings'];
unset($attributes['attributes']);
unset($attributes['wmode']);
$parameters = array();
if (!empty($display['settings']['wmode'])) {
$parameters['mode'] = $display['settings']['wmode'];
}
// The oEmbed spec defines `maxwidth` and `maxheight` parameters, but some providers
// support `width` and `height`. Precise dimensions supercede maximums.
if ($file->type != 'image' && $display['type'] != 'oembed_thumbnail') {
if (isset($attributes['width'])) {
$parameters['maxwidth'] = $parameters['width'] = $attributes['width'];
}
if (isset($attributes['height'])) {
$parameters['maxheight'] = $parameters['height'] = $attributes['height'];
}
}
$element = oembed_render_element($display['type'], $wrapper
->getExternalUrl(), $parameters);
$element['#attributes'] = $attributes;
// Unfortunately, it's necessary to validate the oEmbed response before rendering
// so that file_view_file() can continue to the next formatter.
$output = drupal_render($element);
if ($output) {
return show($element);
}
}
}
/**
* Implements hook_file_formatter_FORMATTER_view().
*/
function oembed_remote_file_formatter_view($file, $display, $langcode) {
$scheme = file_uri_scheme($file->uri);
if ($scheme == 'oembed') {
// URI of local copy of remote file must be stored because it may be
// different from the oEmbed URLs. If the URL does not have a valid
// extension, it will redirect to a URL that does.
if (!isset($file->metadata['oembed_remote_file_image']) || !file_exists($file->metadata['oembed_remote_file_image'])) {
$embed = $file->metadata['oembed'];
if ($embed['type'] == 'photo' && !empty($embed['url'])) {
$url = $embed['url'];
}
else {
if (isset($embed['thumbnail_url'])) {
$url = $embed['thumbnail_url'];
}
}
if (isset($url)) {
$result = drupal_http_request($url);
// Using the redirect URL's basename might guarantee a path with an
// appropriate file extension.
if (isset($result->redirect_url)) {
// If the redirect and original basenames are identical, do nothing.
if (drupal_basename($result->redirect_url) != drupal_basename($url)) {
$url .= '/' . drupal_basename($result->redirect_url);
}
}
$parsed_url = parse_url($url);
// Store local copies of images using hostname, path and filename of source.
$path = $parsed_url['host'];
$path .= drupal_dirname($parsed_url['path']);
if (substr($path, -1) != '/') {
$path .= '/';
}
$filename = drupal_basename($parsed_url['path']);
if (strpos($filename, '.') !== FALSE) {
$filename = file_munge_filename($filename, 'jpg jpeg gif png', FALSE);
}
$path .= $filename;
$local_uri = file_stream_wrapper_uri_normalize(file_default_scheme() . '://oembed/' . $path);
if (!file_exists($local_uri)) {
// Drupal dislikes protocol relative URL schemes. Everything should
// be accessible without HTTPS.
if (strpos($url, '//') === 0) {
$url = 'http:' . $url;
}
/// Ensure filesystem has directories for new file.
$dirname = drupal_dirname($local_uri);
file_prepare_directory($dirname, FILE_CREATE_DIRECTORY | FILE_MODIFY_PERMISSIONS);
// Save the file data to the local directory.
$files = entity_load('file', FALSE, array(
'uri' => $local_uri,
));
if (!empty($files)) {
file_unmanaged_save_data($result->data, $local_uri);
}
else {
file_save_data($result->data, $local_uri);
}
}
$file->metadata['oembed_remote_file_image'] = $local_uri;
// Redundantish. See file_entity_file_insert and related hooks.
foreach (array(
'oembed_remote_file_image',
) as $name) {
if (!empty($file->metadata[$name])) {
$value = $file->metadata[$name];
db_merge('file_metadata')
->fields(array(
'value' => serialize($value),
))
->key(array(
'fid' => $file->fid,
'name' => $name,
))
->execute();
}
}
}
}
if (isset($file->metadata['oembed_remote_file_image'])) {
$local_uri = $file->metadata['oembed_remote_file_image'];
$image_file = file_uri_to_object($local_uri);
$image_file->metadata = array();
// Forcing the image file's type is perhaps no longer necessary.
if (!isset($image_file->type) || $image_file->type === FILE_TYPE_NONE) {
$image_file->type = 'image';
}
if ($image_file->filesize) {
$image_file->metadata = image_get_info($image_file->uri);
$image_file->filemime = $image_file->metadata['mime_type'];
return file_entity_file_formatter_file_image_view($image_file, $display, $langcode);
}
}
}
}
/**
* Implements hook_file_formatter_FORMATTER_settings().
*/
function oembed_file_formatter_oembed_settings($form, &$form_state, $settings) {
$element = array();
$element['width'] = array(
'#title' => t('Width'),
'#type' => 'textfield',
'#default_value' => $settings['width'],
);
$element['height'] = array(
'#title' => t('Height'),
'#type' => 'textfield',
'#default_value' => $settings['height'],
);
$element['wmode'] = array(
'#title' => t('Flash window mode (wmode)'),
'#type' => 'select',
'#empty_option' => t('None (do not request a specific wmode from the provider)'),
'#options' => drupal_map_assoc(array(
'window',
'transparent',
'opaque',
'direct',
'gpu',
)),
'#description' => t('Controls layering, transparency, and playback performance of content rendered by the Flash player. For more information, view <a href="http://kb2.adobe.com/cps/127/tn_12701.html#main_Using_Window_Mode__wmode__values_">Adobe\'s documentation</a>.'),
'#default_value' => $settings['wmode'],
);
return $element;
}
/**
* Implements hook_file_formatter_FORMATTER_settings().
*/
function oembed_file_formatter_oembed_thumbnail_settings($form, &$form_state, $settings) {
$element = array();
$element['width'] = array(
'#title' => t('Width'),
'#type' => 'textfield',
'#default_value' => $settings['width'],
);
$element['height'] = array(
'#title' => t('Height'),
'#type' => 'textfield',
'#default_value' => $settings['height'],
);
return $element;
}
/**
* Clear the cached oEmbed content for the selected files.
*/
function oembed_cache_clear($fids) {
$fids = array_keys($fids);
$query = new EntityFieldQuery();
$results = $query
->entityCondition('entity_type', 'file')
->propertyCondition('uri', 'oembed:', 'STARTS_WITH')
->propertyCondition('fid', $fids)
->execute();
$files = file_load_multiple(array_keys($results['file']));
foreach ($files as $file) {
$wrapper = file_stream_wrapper_get_instance_by_uri($file->uri);
$url = $wrapper
->getExternalUrl();
$cid = hash('sha256', $url);
cache_clear_all($cid, 'cache_oembed', TRUE);
}
}
/**
* Checks that the oEmbed response has required standard properties for its type.
*
* @param \stdClass $file
* A Drupal file object.
*
* @return array
* If the oEmbed response is invalid, the array will contain at least one error message.
*/
function oembed_file_validator_type(stdClass $file) {
return oembed_validate_response($file->metadata['oembed']);
}
/**
* Validates oEmbed responses.
*/
function oembed_validate_response($embed) {
$errors = array();
if (!$embed) {
$errors[] = t('Unable to fetch oEmbed data or it is not a valid URL.');
}
else {
if (empty($embed['version']) || empty($embed['type']) || intval($embed['version']) != 1) {
$errors[] = t('oEmbed data for is invalid.');
}
}
// Validate that response has required properties for its type.
$message = t('oEmbed response is missing required properties for @type.', array(
'@type' => $embed['type'],
));
// Video, rich and photo all must have width and height.
// This validation causes lots of legitimate responses to be rejected. To retain access
// to Twitter, Scribd and others, we allow responses that do not have height and width.
if (in_array($embed['type'], array(
'video',
'rich',
'photo',
))) {
if (!isset($embed['width']) || empty($embed['width']) || (!isset($embed['height']) || empty($embed['height']))) {
//$errors[] = $message;
}
}
// Video and rich type must have html content.
if (in_array($embed['type'], array(
'video',
'rich',
))) {
if (!isset($embed['html']) || empty($embed['html'])) {
$errors[] = $message;
}
}
// Image type must have a URL.
if ($embed['type'] == 'photo') {
if (!isset($embed['url']) || empty($embed['url'])) {
$errors[] = $message;
}
}
return $errors;
}
/**
* Return a file entity for a URL. Create the file if necessary.
*
* @param string $url
* URL of oEmbed request.
* @param boolean $create
* Flag to create the file entity if it does not already exist.
*
* @return \stdClass
*/
function oembed_url_to_file($url, $create = FALSE) {
$uri = 'oembed://' . drupal_encode_path($url);
$file = file_uri_to_object($uri);
$file->metadata = array();
if (!isset($file->metadata['oembed'])) {
$file->metadata['oembed'] = oembed_get_data($url);
}
// New URLs need to be validated before being saved.
if ($create && !isset($file->fid)) {
// Save the new file.
file_save($file);
}
return $file;
}
/**
* Implements hook_system_info_alter().
*
* Media and File entity are not dependencies, but if they are available, they must
* be version 2.
*/
function oembed_system_info_alter(&$info, $file, $type) {
if ($type == 'module' && $file->name == 'oembed') {
if (module_exists('file_entity')) {
$info['dependencies'][] = 'file_entity (>1.99)';
}
if (module_exists('media')) {
$info['dependencies'][] = 'media (>1.99)';
}
}
}
Functions
Name | Description |
---|---|
oembed_alt_attr | Generate a string for use as ALT attribute. |
oembed_cache_clear | Clear the cached oEmbed content for the selected files. |
oembed_cache_expire | Helper function to calculate expire based on lifetime and cache age. |
oembed_cache_key | Helper function generates a cache key based on url and request parameters. |
oembed_cron | Implements hook_cron(). |
oembed_ctools_plugin_api | Implements hook_ctools_plugin_api(). |
oembed_ctools_plugin_directory | Implement hook_ctools_plugin_directory(). |
oembed_ctools_plugin_type | Implements hook_ctools_plugin_type(). |
oembed_element_info | Implements hook_element_info(). |
oembed_file_formatter_oembed_settings | Implements hook_file_formatter_FORMATTER_settings(). |
oembed_file_formatter_oembed_thumbnail_settings | Implements hook_file_formatter_FORMATTER_settings(). |
oembed_file_formatter_view | Implements hook_file_formatter_FORMATTER_view(). |
oembed_file_validator_type | Checks that the oEmbed response has required standard properties for its type. |
oembed_flush_caches | Implements hook_flush_caches(). |
oembed_get_data | Fetch data for an embeddable URL. |
oembed_get_provider | Returns the provider for a url. |
oembed_help | Implements hook_help(). |
oembed_hook_info | Implements hook_hook_info(). |
oembed_menu | Implements hook_menu(). |
oembed_menu_alter | Implements hook_menu_alter(). |
oembed_oembed_fetch | oEmbed fetcher and parser. |
oembed_permission | Implements hook_permission(). |
oembed_preprocess_file_entity | Implement hook_preprocess_file_entity(). |
oembed_pre_render_fetch | Pre render fetches the oEmbed data. |
oembed_pre_render_image_helper | Set the properties for a themed image. |
oembed_pre_render_retheme | Rewrite the theme parameter based on the response. |
oembed_pre_render_thumbnail | Change oEmbed request into a thumbnail. |
oembed_providers_reset | Reset the registered provider caches. |
oembed_remote_file_formatter_view | Implements hook_file_formatter_FORMATTER_view(). |
oembed_render_element | Prepare an element based on a oEmbed request. |
oembed_stream_wrappers | Create stream wrapper for oEmbed videos. |
oembed_system_info_alter | Implements hook_system_info_alter(). |
oembed_theme | Implements of hook_theme(). |
oembed_url_to_file | Return a file entity for a URL. Create the file if necessary. |
oembed_validate_response | Validates oEmbed responses. |