class OpenGraphMeta in Open Graph meta tags 7
Same name and namespace in other branches
- 6 opengraph_meta.common.inc \OpenGraphMeta
- 7.2 opengraph_meta.common.inc \OpenGraphMeta
Hierarchy
- class \OpenGraphMeta
Expanded class hierarchy of OpenGraphMeta
File
- ./
opengraph_meta.common.inc, line 17
View source
class OpenGraphMeta {
const TITLE = 'title';
const DESCRIPTION = 'description';
const IMAGE = 'image';
const SITE_NAME = 'site_name';
const TYPE = 'type';
const URL = 'url';
// Location tags
const LATITUDE = 'latitude';
const LONGITUDE = 'longitude';
const STREET_ADDRESS = 'street-address';
const LOCALITY = 'locality';
const REGION = 'region';
const POST_CODE = 'postal-code';
const COUNTRY_NAME = 'country-name';
// Contact tags
const EMAIL = 'email';
const PHONE_NUMBER = 'phone_number';
const FAX_NUMBER = 'fax_number';
/** Db field name for optional tags (not to be used by external code) */
const __OPTIONAL_DB_FIELD = 'optional';
/** Singleton instance. */
private static $instance = NULL;
private $settings_obj = NULL;
private $render_obj = NULL;
private $data_obj = NULL;
/**
* @var array Keep track of which meta tags have already been written to output so that we don't write them again.
* This is handy when we're outputting multiples nodes to a single page view.
*/
private $tags_already_output = array();
/**
* Constructor
*/
private function __construct() {
$this->settings_obj = new OGMDrupalSettings();
$this->render_obj = new OGMDrupalRender();
$this->data_obj = new OGMDrupalData();
}
/** Get singleton instance. */
public static function instance() {
if (empty(self::$instance)) {
self::$instance = new OpenGraphMeta();
}
return self::$instance;
}
/**
* Get default values for all meta tags (including optional ones).
* @param $node a node object. If provided then defaults will be tailored to this node.
*/
public function get_og_optional_tag_defaults($node = NULL) {
static $defaults = array();
if (empty($defaults)) {
$defaults = array(
self::LATITUDE => '',
self::LONGITUDE => '',
self::STREET_ADDRESS => '',
self::LOCALITY => '',
self::REGION => '',
self::POST_CODE => '',
self::COUNTRY_NAME => '',
self::EMAIL => '',
self::PHONE_NUMBER => '',
self::FAX_NUMBER => '',
);
}
if (!empty($node)) {
$optionals = variable_get(OPENGRAPH_META_VAR_OPTIONAL_TAGS, array());
foreach ($defaults as $f => &$i) {
$i = !empty($optionals[$f]) ? $optionals[$f] : $i;
}
}
return $defaults;
}
/**
* Get default values for all meta tags (including optional ones).
* @param $node a node object. If provided then defaults will be tailored to this node.
* @param $full_view whether the node is being viewed on its own in full view.
*/
private function get_og_tag_defaults($node = NULL, $full_view = FALSE) {
// defaults
static $defaults = array();
if (empty($defaults)) {
$defaults = array(
self::TITLE => '',
self::DESCRIPTION => '',
self::IMAGE => '',
self::TYPE => '',
self::URL => '',
);
}
$ret = array_merge($defaults, $this
->get_og_optional_tag_defaults($node));
$ret[self::SITE_NAME] = $this->settings_obj
->get(OPENGRAPH_META_VAR_SITE_NAME, $this->settings_obj
->get('site_name', 'Drupal'));
if (!empty($node)) {
// if node given then override defaults
$ret[self::TITLE] = $full_view ? drupal_get_title() : $node->title;
$body = OpenGraphMetaDrupalLayer::get_node_body($node);
$ret[self::DESCRIPTION] = !empty($body) ? drupal_substr(strip_tags($body), 0, 200) : $node->title;
$ret[self::TYPE] = $this->settings_obj
->get(OPENGRAPH_META_VAR_CONTENT_TYPE_ . $node->type, '');
$ret[self::IMAGE] = $this->settings_obj
->get(OPENGRAPH_META_VAR_FALLBACK_IMG, '');
$images = $this
->harvest_images_from_node($node);
if (!empty($images)) {
$i = array_shift($images);
$ret[self::IMAGE] = $i['url'];
}
$ret[self::URL] = url(drupal_get_path_alias('node/' . $node->nid), array(
'absolute' => TRUE,
));
}
return $ret;
}
/**
* Get all possible values for the og:type meta tags, grouped by category, ready for use as #options for a
* SELECT form item.
*/
public function get_all_og_types_for_select_field() {
static $ret = array();
if (empty($ret)) {
// Taken from http://opengraphprotocol.org/ on 18/Nov/2010
$ogtypes = array(
t('Activities') => array(
'activity',
'sport',
),
t('Businesses') => array(
'bar',
'company',
'cafe',
'hotel',
'restaurant',
),
t('Groups') => array(
'cause',
'sports_league',
'sports_team',
),
t('Organizations') => array(
'band',
'government',
'non_profit',
'school',
'university',
),
t('People') => array(
'actor',
'athlete',
'author',
'director',
'musician',
'politician',
'public_figure',
),
t('Places') => array(
'city',
'country',
'landmark',
'state_province',
),
t('Products and Entertainment') => array(
'album',
'book',
'drink',
'food',
'game',
'movie',
'product',
'song',
'tv_show',
),
t('Websites') => array(
'article',
'blog',
'website',
),
);
$ret = array(
'' => '',
);
foreach ($ogtypes as $cat => $t) {
$ret[$cat] = array_combine($t, $t);
}
}
return $ret;
}
/**
* Get whether meta tags are enabled for the given content type.
* @return TRUE if so; FALSE otherwise.
*/
public function tags_are_enabled_for_content_type($type) {
$content_types = $this->settings_obj
->get(OPENGRAPH_META_VAR_CONTENT_TYPES_ENABLED, array());
$content_types = array_filter($content_types);
// if no content types specifically set OR if this content type is set then tags are enabled
return empty($content_types) || !empty($content_types[$type]);
}
/** Delete FB meta tag data for the given node. */
public function delete_node_data($nid) {
$this->data_obj
->delete_tags($nid);
}
/**
* Save FB meta tag data for the given node.
*
* @param $data key-value pairs
*/
public function save_node_data($nid, $data) {
$ret = $this->data_obj
->load_tags($nid);
if (FALSE === $ret) {
$row = new stdClass();
$row->nid = $nid;
}
else {
$row = $ret;
}
// collapse data tree into 1-D array
$collapsed_data = new stdClass();
// needed to work around pass-by-reference deprecation warning for array_walk_recursive
$collapsed_data->keys = array();
$collapsed_data->values = array();
array_walk_recursive($data, create_function('$val, $key, $obj', 'array_push($obj->keys, $key); array_push($obj->values, $val);'), $collapsed_data);
$collapsed_data = array_combine($collapsed_data->keys, $collapsed_data->values);
foreach ($this
->get_og_tag_defaults() as $field => $_d) {
$row->{$field} = isset($collapsed_data[$field]) ? $collapsed_data[$field] : '';
}
$this->data_obj
->update_tags($row, FALSE !== $ret ? 'nid' : array());
}
/**
* Load FB meta tag data for the given node.
*
* @return array('title' => ..., 'summary' => ...)
*/
public function load_node_data($node) {
$fields = $this
->get_og_tag_defaults();
$row = $this->data_obj
->load_tags($node->nid);
if (FALSE !== $row) {
foreach ($fields as $field => &$val) {
if (isset($row->{$field})) {
$val = $row->{$field};
}
}
}
return $fields;
}
/** Render the meta tag data for the given node. */
public function render_data(&$node, $opengraph_data) {
// fallback values in case no values set.
$allfields = $this
->get_og_tag_defaults($node, TRUE);
foreach ($allfields as $field => $_d) {
// already written this meta tag to output?
if (array_key_exists($field, $this->tags_already_output)) {
$this
->warn(t("Already output og:%s", array(
'%s' => $field,
)));
continue;
}
$v = !empty($opengraph_data[$field]) ? $opengraph_data[$field] : $_d;
if (!empty($v)) {
switch ($field) {
case self::IMAGE:
$v = url(ltrim($v, '/'), array(
'absolute' => TRUE,
));
break;
case self::TITLE:
case self::DESCRIPTION:
case self::STREET_ADDRESS:
case self::LOCALITY:
case self::REGION:
case self::COUNTRY_NAME:
$v = htmlspecialchars(htmlspecialchars_decode($v));
break;
case self::LATITUDE:
case self::LONGITUDE:
$v = floatval($v);
break;
}
// allow other people to alter this value
$v = OpenGraphMetaDrupalLayer::invoke_filter('og_tag_render_alter', $v, array(
$node,
$field,
));
$this->render_obj
->add_meta('og:' . $field, $v);
$this->tags_already_output[$field] = true;
}
// if value available for field
}
// for each field
}
/**
* Harvest all images from the given node.
*
* @return array(array('title' => , 'alt' => , 'url' =>))
*/
public function harvest_images_from_node($node) {
// extract image fields
$ret = array();
OpenGraphMetaDrupalLayer::extract_image_fields((array) $node, $ret);
// extract all images from body content
$body = OpenGraphMetaDrupalLayer::get_node_body($node);
if (!empty($body)) {
libxml_use_internal_errors(TRUE);
// turn off libxml errors for now
$doc = new DOMDocument();
$doc
->loadHTML($body);
$list = $doc
->getElementsByTagName('img');
for ($i = 0; $list->length > $i; ++$i) {
$item = $list
->item($i);
if ($item
->hasAttribute('src')) {
$url = $item
->getAttribute('src');
if (!empty($url)) {
$ret[$url] = array(
'title' => $url,
'alt' => $url,
'url' => $url,
);
}
}
}
libxml_use_internal_errors(FALSE);
// turn libxml errors back on
}
return $ret;
}
/**
* Log a warning message.
* @param $msg the message.
*/
public function warn($msg) {
watchdog('opengraph_meta', $msg, array(), WATCHDOG_WARNING);
}
/**
* FOR TESTING PURPOSES ONLY!
* Replace the internally used data and config instances with the given ones.
*/
public function __set_objects($data_obj, $settings_obj, $render_obj) {
$this->data_obj = $data_obj;
$this->settings_obj = $settings_obj;
$this->render_obj = $render_obj;
}
/**
* FOR TESTING PURPOSES ONLY!
* Get the internally used data and config instances with the given ones.
*/
public function __get_objects() {
return array(
$this->data_obj,
$this->settings_obj,
$this->render_obj,
);
}
/**
* FOR TESTING PURPOSES ONLY!
* Reset array which keeps track of which tags have already been output.
*/
public function __reset_tags_already_output() {
$this->tags_already_output = array();
}
}
Members
Name | Modifiers | Type | Description | Overrides |
---|---|---|---|---|
OpenGraphMeta:: |
private | property | ||
OpenGraphMeta:: |
private static | property | Singleton instance. | |
OpenGraphMeta:: |
private | property | ||
OpenGraphMeta:: |
private | property | ||
OpenGraphMeta:: |
private | property | This is handy when we're outputting multiples nodes to a single page view. | |
OpenGraphMeta:: |
constant | |||
OpenGraphMeta:: |
public | function | Delete FB meta tag data for the given node. | |
OpenGraphMeta:: |
constant | |||
OpenGraphMeta:: |
constant | |||
OpenGraphMeta:: |
constant | |||
OpenGraphMeta:: |
public | function | Get all possible values for the og:type meta tags, grouped by category, ready for use as #options for a SELECT form item. | |
OpenGraphMeta:: |
public | function | Get default values for all meta tags (including optional ones). | |
OpenGraphMeta:: |
private | function | Get default values for all meta tags (including optional ones). | |
OpenGraphMeta:: |
public | function | Harvest all images from the given node. | |
OpenGraphMeta:: |
constant | |||
OpenGraphMeta:: |
public static | function | Get singleton instance. | |
OpenGraphMeta:: |
constant | |||
OpenGraphMeta:: |
public | function | Load FB meta tag data for the given node. | |
OpenGraphMeta:: |
constant | |||
OpenGraphMeta:: |
constant | |||
OpenGraphMeta:: |
constant | |||
OpenGraphMeta:: |
constant | |||
OpenGraphMeta:: |
constant | |||
OpenGraphMeta:: |
public | function | Render the meta tag data for the given node. | |
OpenGraphMeta:: |
public | function | Save FB meta tag data for the given node. | |
OpenGraphMeta:: |
constant | |||
OpenGraphMeta:: |
constant | |||
OpenGraphMeta:: |
public | function | Get whether meta tags are enabled for the given content type. | |
OpenGraphMeta:: |
constant | |||
OpenGraphMeta:: |
constant | |||
OpenGraphMeta:: |
constant | |||
OpenGraphMeta:: |
public | function | Log a warning message. | |
OpenGraphMeta:: |
private | function | Constructor | |
OpenGraphMeta:: |
public | function | FOR TESTING PURPOSES ONLY! Get the internally used data and config instances with the given ones. | |
OpenGraphMeta:: |
constant | Db field name for optional tags (not to be used by external code) | ||
OpenGraphMeta:: |
public | function | FOR TESTING PURPOSES ONLY! Reset array which keeps track of which tags have already been output. | |
OpenGraphMeta:: |
public | function | FOR TESTING PURPOSES ONLY! Replace the internally used data and config instances with the given ones. |