type);
}
}
}
/**
* Implements hook_nodeapi().
*/
function nodewords_nodeapi(&$node, $op, $teaser = NULL, $page = NULL) {
switch ($op) {
case 'load':
$output['nodewords']['metatags'] = nodewords_load_tags(array(
'type' => NODEWORDS_TYPE_NODE,
'id' => $node->nid,
));
return $output;
case 'insert':
case 'update':
if (isset($node->nodewords['metatags'])) {
nodewords_save_tags($node->nodewords['metatags'], array(
'type' => NODEWORDS_TYPE_NODE,
'id' => $node->nid,
));
}
break;
case 'delete':
nodewords_delete_tags(array(
'type' => NODEWORDS_TYPE_NODE,
'id' => $node->nid,
));
break;
}
}
/**
* Implements hook_perm().
*/
function nodewords_perm() {
return array('administer meta tags', 'edit meta tags');
}
/**
* Implements hook_preprocess_page().
*/
function nodewords_preprocess_page(&$variables) {
$output_tags = array();
$head_tags = variable_get('nodewords_head', array());
$options = nodewords_detect_type_id();
if ($options['type'] != NODEWORDS_TYPE_NONE && $options['type'] != NODEWORDS_TYPE_OFFLINE) {
$options['output'] = 'head';
if ($options['type'] == NODEWORDS_TYPE_PAGER) {
nodewords_load_all_includes('nodewords.tags.inc');
foreach (nodewords_get_possible_tags() as $name => $info) {
if (empty($head_tags[$name])) {
continue;
}
$bool = (
!empty($info['context']['allowed']) &&
in_array(NODEWORDS_TYPE_PAGER, $info['context']['allowed']) &&
function_exists($function = $info['callback'] . '_prepare')
);
if ($bool) {
$options['parameters'] = !empty($info['callback arguments']) ? $info['callback arguments'] : array();
$function($output_tags, array(), $options);
}
}
}
else {
// Load the values from the database
if ($options['type'] != NODEWORDS_TYPE_NODE || node_access('view', node_load($options['id']))) {
$tags = nodewords_load_tags($options);
}
else {
$tags = array();
}
nodewords_load_all_includes('nodewords.tags.inc');
// Prepare the tags.
foreach (nodewords_get_possible_tags() as $name => $info) {
if (empty($head_tags[$name])) {
continue;
}
if (function_exists($function = $info['callback'] . '_prepare')) {
$options['parameters'] = !empty($info['callback arguments']) ? $info['callback arguments'] : array();
$function(
$output_tags,
_nodewords_tag_value($name, isset($tags[$name]) ? $tags[$name] : array(), $options + array('admin' => FALSE)),
$options
);
}
}
}
nodewords_load_all_includes('nodewords.hooks.inc');
drupal_alter('nodewords_tags', $output_tags, $options);
$output = _nodewords_output_tags($output_tags);
drupal_alter('nodewords_tags_output', $output, $options);
// Output the tags to the header.
drupal_set_html_head($output);
$variables['head'] = drupal_get_html_head();
}
}
/**
* Implements hook_taxonomy().
*/
function nodewords_taxonomy($op, $type, $array = NULL) {
switch ($type) {
case 'term':
$id = $array['tid'];
$type = NODEWORDS_TYPE_TERM;
break;
case 'vocabulary':
$id = $array['vid'];
$type = NODEWORDS_TYPE_VOCABULARY;
break;
default:
return;
}
switch ($op) {
case 'insert':
case 'update':
if (isset($array['nodewords']['metatags'])) {
nodewords_save_tags($array['nodewords']['metatags'], array('type' => $type, 'id' => $id));
unset($array['nodewords']);
}
break;
case 'delete':
nodewords_delete_tags(array('type' => $type, 'id' => $id));
break;
}
}
/**
* Implements hook_user().
*/
function nodewords_user($op, &$edit, &$account, $category = NULL) {
switch ($op) {
case 'load':
$account->nodewords['metatags'] = nodewords_load_tags(array(
'type' => NODEWORDS_TYPE_USER,
'id' => $account->uid,
));
break;
case 'insert':
case 'update':
if (isset($edit['nodewords']['metatags'])) {
nodewords_save_tags($edit['nodewords']['metatags'], array(
'type' => NODEWORDS_TYPE_USER,
'id' => $account->uid,
));
}
unset($edit['nodewords']);
break;
case 'delete':
nodewords_delete_tags(array(
'type' => NODEWORDS_TYPE_USER,
'id' => $account->uid,
));
break;
}
}
/**
* Add the tokens help to the form.
*
* Add the tokens help to the form passed as argument.
* It is responsability of the calling function to verify that token.module is
* enabled.
*
* @param &$form
* The form to which the help text will be added.
* @param $type
* An array containing information about the object for which the meta tags
* are being edited.
*/
function nodewords_add_tokens_help(&$form, $type) {
// Always include the global context.
$token_types[] = 'global';
switch ($type['type']) {
case NODEWORDS_TYPE_DEFAULT:
case NODEWORDS_TYPE_PAGE:
$token_types[] = 'node';
$token_types[] = 'taxonomy';
$token_types[] = 'vocabulary';
$token_types[] = 'user';
break;
case NODEWORDS_TYPE_CONTENT_TYPE:
case NODEWORDS_TYPE_NODE:
$token_types[] = 'node';
break;
case NODEWORDS_TYPE_TERM:
$token_types[] = 'taxonomy';
break;
case NODEWORDS_TYPE_VOCABULARY:
$token_types[] = 'vocabulary';
break;
case NODEWORDS_TYPE_USER:
$token_types[] = 'user';
break;
}
$form['token_help'] = array(
'#title' => t('Replacement patterns'),
'#type' => 'fieldset',
'#collapsible' => TRUE,
'#collapsed' => TRUE,
'#description' => t('Use the raw versions of tokens to avoid problems with HTML entities.'),
);
$form['token_help']['help'] = array(
'#value' => theme('token_tree', $token_types),
);
}
/**
* Verify the API version is one currently supported by Nodewords.
*
* @param $version
* The version string as accepted by version_compare().
*
* @return
* TRUE, if the API version is currently supported by Nodewords.
*/
function nodewords_check_api_version($version) {
return (
version_compare($version, NODEWORDS_MINIMUM_API_VERSION, '>=') &&
version_compare($version, NODEWORDS_API_VERSION, '<=')
);
}
/**
* Delete tags from table.
*/
function nodewords_delete_tags($options = array()) {
$options += _nodewords_get_default_metatags_type();
db_query("DELETE FROM {nodewords} WHERE type = %d AND id = %d", $options['type'], $options['id']);
nodewords_load_all_includes('nodewords.hooks.inc');
module_invoke_all('nodewords_delete_tags', $options);
}
/**
* Try to guess the type and the ID associated with the viewed page.
*
* @param $options
* An array of parameters that describe the page to check. If the array is
* is not passed, the function will return the type of the currently viewed
* page.
*
* @return
* An array containing information about the type of the page.
*/
function nodewords_detect_type_id($options = array()) {
$options += array(
'page' => isset($_REQUEST['page']) ? $_REQUEST['page'] : -1,
'headers' => drupal_get_headers(),
'q' => $_GET['q'],
);
$arg = explode('/', $options['q']) + array_fill(0, MENU_MAX_PARTS, NULL);
// Start out with the default type.
$result = array('type' => NODEWORDS_TYPE_DEFAULT, 'id' => 0);
if (variable_get('site_offline', 0) && !user_access('administer site configuration')) {
// Offline page always has the highest weight.
$result['type'] = NODEWORDS_TYPE_OFFLINE;
}
elseif (preg_match('@HTTP/1\.[01]\x20+(403|404)[^a-zA-Z0-9]@', $options['headers'], $matches)) {
// Error pages (403 or 404s)
$result['type'] = NODEWORDS_TYPE_ERRORPAGE;
$result['id'] = (int) $matches[1];
}
elseif (!variable_get('nodewords_list_repeat', FALSE) && intval($options['page']) > 0) {
$result['type'] = NODEWORDS_TYPE_PAGER;
}
elseif (!isset($arg[0])) {
// @todo WTF is this doing?
$result['type'] = NODEWORDS_TYPE_NONE;
}
else {
// Allow other modules to alter the current page context.
_nodewords_load_hook_files();
foreach (module_implements('nodewords_type_id') as $module) {
$function = $module . '_nodewords_type_id';
$function($result, $arg);
if ($result['type'] != NODEWORDS_TYPE_DEFAULT) {
break;
}
}
}
return $result;
}
/**
* Query all the modules implementing meta tags and return the list of meta tags.
*
* @return
* An array containing the list of meta tags definitions.
*/
function nodewords_get_possible_tags() {
static $tags_info = array();
nodewords_load_all_includes('nodewords.hooks.inc');
if (empty($tags_info)) {
// Allow third-party modules to alter the meta tags list, or to add new
// meta tags.
foreach (module_implements('nodewords_tags_info') as $module) {
$result = module_invoke($module, 'nodewords_tags_info');
if (isset($result) && is_array($result)) {
$tags_info = array_merge($tags_info, $result);
}
}
}
drupal_alter('nodewords_tags_info', $tags_info);
return $tags_info;
}
/**
* Return the term object matching a term ID. This is a modified version of
* taxonomy_get_term() which uses db_rewrite_sql().
*
* @param $tid
* A term's ID.
* @param $uid
* The user ID; if not passed, the function will use the global user ID.
*
* @return
* A term object, or FALSE. Results are statically cached.
*/
function nodewords_get_term($tid, $uid = NULL) {
global $user;
static $terms = array();
if (!isset($uid)) {
$uid = $user->uid;
}
if (!isset($terms[$uid][$tid])) {
$query = db_query(db_rewrite_sql('SELECT * FROM {term_data} t WHERE t.tid = %d', 't', 'tid'), $tid);
$terms[$uid][$tid] = db_fetch_object($query);
}
return !empty($terms[$uid][$tid]) ? $terms[$uid][$tid] : FALSE;
}
/**
* Load an include file for each of the modules that have support for Nodewords.
*
* @param $file
* The file to load; the name of the module will be preappended to the file
* name passed. By default the file name is 'nodewords.inc'.
*/
function nodewords_load_all_includes($file = 'nodewords.inc') {
foreach (module_implements('nodewords_api') as $module) {
$info = module_invoke($module, 'nodewords_api');
if (isset($info['version']) && nodewords_check_api_version($info['version'])) {
if (isset($info['path']) && $info['path'] == '') {
// Special case: if the path is an empty string, the directory used will be
// the directory include in the module directory.
$include_path = drupal_get_path('module', $module) . '/includes/';
}
elseif (isset($info['path'])) {
$include_path = $info['path'] . '/';
}
else {
$include_path = drupal_get_path('module', $module) . '/';
}
$include_file = $include_path . $module . '.' . $file;
if (is_file($include_file)) {
require_once $include_file;
}
elseif ($file != 'nodewords.inc' && is_file($include_file = $include_path . $module . '.' . 'nodewords.inc')) {
require_once $include_file;
}
}
}
}
/**
* Load an include file.
*
* @param $module
* The module for which the file is loaded.
*
* @param $file
* The file to load; the name of the module will be preappended to the file
* name passed. By default the file name is 'nodewords.inc'.
*
*/
function nodewords_load_include($module, $file = 'nodewords.inc') {
$info = module_invoke($module, 'nodewords_api');
if (isset($info['path']) && $info['path'] == '') {
// Special case: if the path is an empty string, the directory used will be
// the directory include in the module directory.
$include_path = drupal_get_path('module', $module) . '/includes/';
}
elseif (isset($info['path'])) {
$include_path = $info['path'] . '/';
}
else {
$include_path = drupal_get_path('module', $module) . '/';
}
$include_file = $include_path . $module . '.' . $file;
if (is_file($include_file)) {
require_once $include_file;
}
elseif ($file != 'nodewords.inc' && is_file($include_file = $include_path . $module . '.' . 'nodewords.inc')) {
require_once $include_file;
}
else {
return FALSE;
}
}
/**
* Load tags from table.
*
* @param $options
* An array of options.
*
* @return
* An array of meta tags data as saved in the database table.
*/
function nodewords_load_tags($options = array()) {
$tags = array();
$options += _nodewords_get_default_metatags_type();
$tags_info = nodewords_get_possible_tags();
$result = db_query("SELECT * FROM {nodewords} WHERE type = %d AND id = %d", $options['type'], $options['id']);
while ($row = db_fetch_object($result)) {
if (isset($tags_info[$row->name])) {
$tags[$row->name] = unserialize($row->content);
}
}
if (empty($tags) && $options['type'] == NODEWORDS_TYPE_TERM) {
$id = db_result(db_query_range('SELECT vid FROM {term_data} WHERE tid = %d', $options['id'], 0, 1));
if ($id !== FALSE) {
$options['type'] = NODEWORDS_TYPE_VOCABULARY;
$options['id'] = $id;
return nodewords_load_tags($options);
}
}
return $tags;
}
function nodewords_replace_tokens($content, $options = array()) {
if (empty($content) || !variable_get('nodewords_enable_tokens', TRUE) || !module_exists('token')) {
return $content;
}
// Always include the global context.
$token_objects['global'] = NULL;
$options += _nodewords_get_default_metatags_type();
// Allow other modules to alter the context used for tokens below if the
// current context is not yet specific.
switch ($options['type']) {
case NODEWORDS_TYPE_DEFAULT:
case NODEWORDS_TYPE_FRONTPAGE:
case NODEWORDS_TYPE_PAGE:
case NODEWORDS_TYPE_PAGER:
$original_type = $options['type'];
$arg = arg() + array_fill(0, MENU_MAX_PARTS, NULL);
foreach (module_implements('nodewords_type_id') as $module) {
$function = $module . '_nodewords_type_id';
$function($options, $arg);
if ($options['type'] != $original_type) {
break;
}
}
break;
}
switch ($options['type']) {
case NODEWORDS_TYPE_NODE:
$token_objects['node'] = node_load($options['id']);
break;
case NODEWORDS_TYPE_TERM:
$token_objects['taxonomy'] = taxonomy_get_term($options['id']);
break;
case NODEWORDS_TYPE_VOCABULARY:
$token_objects['vocabulary'] = taxonomy_vocabulary_load($options['id']);
break;
case NODEWORDS_TYPE_USER:
$token_objects['user'] = user_load($options['id']);
break;
}
// Perform token replacement, making sure all tokens are replaced even if
// there is no replacement value for a token.
$content = token_replace_multiple($content, $token_objects, TOKEN_PREFIX, TOKEN_SUFFIX, array('clear' => TRUE));
return $content;
}
/**
* Update or insert tags in the table.
*/
function nodewords_save_tags($tags, $options = array()) {
$done = FALSE;
$options += (_nodewords_get_default_metatags_type() + array('log_message' => TRUE));
$tags_info = nodewords_get_possible_tags();
$types_str = _nodewords_get_type_strings();
foreach ($tags as $name => $content) {
if (isset($tags_info[$name])) {
$content = serialize($content);
$result = _nodewords_get_tags_data($name, $options);
if ($result === FALSE) {
$row = _nodewords_init_tags_data($name, $options);
}
else {
$row = $result;
}
$row->content = $content;
$ret = drupal_write_record('nodewords', $row, isset($row->mtid) ? 'mtid' : array());
if (!$done && $options['log_message'] && $ret) {
watchdog('meta tags', 'Meta tags changed for type @type @id.', array(
'@type' => isset($types_str[$options['type']]) ? $types_str[$options['type']] : t('unknown'),
'@id' => $options['id'],
));
$done = TRUE;
}
}
}
}
/**
* Return the form used to set the meta tags values.
*
* @param $type
* An array containing the type of the object, and its ID.
*
* @param $tags
* The meta tags array as returned by nodewords_load_tags().
*
* @return
* An array as requested by the form API.
*/
function nodewords_tags_edit_fields($type, $tags, $options = array()) {
$form = array();
$tokens_support = FALSE;
$tokens_type = array();
$options += array(
'admin' => FALSE,
'collapsed' => TRUE,
'collapsible' => TRUE,
'description' => '',
'fieldset' => FALSE,
'title' => t('Meta tags'),
'weight' => 20,
);
$edit_tags = variable_get(!empty($options['admin']) ? 'nodewords_admin_edit' : 'nodewords_ui_edit', array());
$head_output = variable_get('nodewords_head', array());
$tokens_enabled = module_exists('token') && variable_get('nodewords_enable_tokens', TRUE);
$type += _nodewords_get_default_metatags_type();
if (isset($options['tag options']) && is_array($options['tag options'])) {
$tag_options = $options['tag options'] + $type;
}
else {
$tag_options = $type;
}
nodewords_load_all_includes('nodewords.tags.inc');
nodewords_load_all_includes('nodewords.hooks.inc');
$filter_metatags = ($type['type'] != NODEWORDS_TYPE_DEFAULT);
foreach (nodewords_get_possible_tags() as $name => $info) {
$description = array();
$permission = TRUE;
drupal_alter('nodewords_tags_permission', $permission, $type, $name, $info);
if ($permission) {
$bool = (
(
(
!empty($info['context']['allowed']) &&
is_array($info['context']['allowed']) &&
!in_array($type['type'], $info['context']['allowed'])
) ||
(
!empty($info['context']['denied']) &&
is_array($info['context']['denied']) &&
in_array($type['type'], $info['context']['denied'])
)
)
);
if ($bool || ($filter_metatags && empty($edit_tags[$name]))) {
continue;
}
if (!empty($info['tokens'])) {
$description[] = ' ' . t('This meta tag supports tokens.') . '';
$tokens_support = TRUE;
}
if (empty($head_output[$name]) && user_access('administer meta tags')) {
$description[] = ' ' . t('This meta tag has not been selected to be output in HTML.');
}
if (function_exists($function = $info['callback'] . '_form')) {
if (!empty($description)) {
$tag_options['description'] = implode('', $description);
}
else {
$tag_options['description'] = '';
}
$tag_options['parameters'] = !empty($info['callback arguments']) ? $info['callback arguments'] : array();
$function($form_metatags, _nodewords_tag_value($name, isset($tags[$name]) ? $tags[$name] : array(), $type + array('admin' => $options['admin'])), $tag_options);
}
}
}
if (!empty($form_metatags) && $options['fieldset']) {
$form['#tree'] = TRUE;
$form['#type'] = 'fieldset';
$form['#title'] = $options['title'];
$form['#description'] = $options['description'];
$form['#collapsible'] = $options['collapsible'];
$form['#collapsed'] = $options['collapsed'];
$form['#weight'] = $options['weight'];
$form['#group'] = 'additional_settings';
}
if (!empty($options['first fields'])) {
$form = $options['first fields'] + $form;
}
if (!empty($form_metatags)) {
$form['metatags'] = $form_metatags;
}
if ($tokens_enabled && $tokens_support) {
nodewords_add_tokens_help($form, $type);
}
if (!empty($options['last fields'])) {
$form += $options['last fields'];
}
return $form;
}
/**
* Remove the duplicates from a list of items separated from the separator,
* preserving the order in which they appear.
* @param $text
* The string containing the list of items concatenated using $separator.
* @param $separator
* The string used to split the string into an array. A space will be appended
* to the string before it is used to create the string from the array of
* unique items found in the string passed as argument.
* @param $max_items
* The maximum number of items accepted in the returned array; the default
* value is -1, which means no limit.
*
* @return
* A string containing only unique items present in the string of concatenated
* items.
*/
function nodewords_unique_values($text, $separator = ',', $max_items = -1) {
$lc_values = array();
$unique_values = array();
if (empty($text)) {
return '';
}
foreach (array_filter(array_map('trim', explode($separator, $text))) as $item) {
$lowercase = drupal_strtolower($item);
if (!in_array($lowercase, $lc_values)) {
$lc_values[] = $lowercase;
$unique_values[] = $item;
}
}
if ($max_items > 0) {
$unique_values = array_slice($uniq_values, 0, $max_items);
}
return implode($separator, $unique_values);
}
/**
* Return the absolute URL of a path.
*
* Return the absolute URL of a path built using the base URL saved in the
* Drupal variable nodewords_base_url.
*
* @param $path
* The path for which the absolute must be built.
* @param $options
* An array of options as used by url().
*/
function nodewords_url($path, $options = array()) {
$options += array(
'alias' => TRUE,
'absolute' => TRUE,
'base_url' => rtrim(variable_get('nodewords_base_url', ''), '/'),
'fragment' => '',
'query' => '',
'prefix' => ''
);
if (empty($options['base_url'])) {
$options['base_url'] = NULL;
}
return url($path, $options);
}
/**
* Return the default values that identify the object associated with the meta tags.
*
* @return
* An array containing the indexes 'type', and 'id'.
*/
function _nodewords_get_default_metatags_type() {
return array('type' => NODEWORDS_TYPE_DEFAULT, 'id' => 0);
}
function _nodewords_get_tags_data($name, $options) {
return db_fetch_object(db_query_range("SELECT * FROM {nodewords} WHERE type = %d AND id = %d AND name = '%s'", $options['type'], $options['id'], $name, 0, 1));
}
function _nodewords_get_type_strings() {
return array(
NODEWORDS_TYPE_DEFAULT => t('default'),
NODEWORDS_TYPE_ERRORPAGE => t('HTTP error page'),
NODEWORDS_TYPE_NODE => t('node'),
NODEWORDS_TYPE_PAGE => t('custom page'),
NODEWORDS_TYPE_TERM => t('taxonomy term'),
NODEWORDS_TYPE_USER => t('user profile'),
NODEWORDS_TYPE_VOCABULARY => t('vocabulary'),
);
}
function _nodewords_init_tags_data($name, $options) {
$row = new stdClass();
$row->type = $options['type'];
$row->id = $options['id'];
$row->name = $name;
return $row;
}
/**
* Load the files in the directory "includes" basing on the enabled modules.
*
*/
function _nodewords_load_hook_files() {
$dir = drupal_get_path('module', 'nodewords') . '/includes';
foreach (file_scan_directory($dir, '.*\.inc', array('.', '..', 'CVS'), 0, FALSE) as $filename => $info) {
if (module_exists($info->name) && !module_hook($info->name, 'nodewords_type_id')) {
module_load_include('inc', 'nodewords', 'includes/' . $info->name);
}
}
nodewords_load_all_includes('nodewords.hooks.inc');
}
/**
* Render the meta tag values as HTML.
*
* @param $tags
* An array of tags.
*
* @param $output_type
* The type of output, 'head' (default), or 'update index'.
*
* @return
* A string containing the HTML output for the META tag.
*/
function _nodewords_output_tags($tags, $output_type = 'head') {
$output = array();
$tags_info = nodewords_get_possible_tags();
$weights = array();
foreach ($tags as $name => $content) {
if (empty($content)) {
continue;
}
$parts = explode(':', $name);
$template = '';
if (!isset($parts[1])) {
$parts[1] = $parts[0];
}
$bool = (
isset($tags_info[$parts[0]]['templates']['head'][$parts[1]]) &&
($meta_name = check_plain(decode_entities(strip_tags($parts[1])))) &&
($meta_content = trim(check_plain(decode_entities(strip_tags(preg_replace('/(\s)\s+/', '$1', $content))))))
);
if ($bool) {
$replace = array(
'%name' => $meta_name,
'%content' => $meta_content,
'%attributes' => empty($tags_info[$parts[0]]['attributes'][$parts[1]]) ? '' : drupal_attributes($tags_info[$parts[0]]['attributes'][$parts[1]]),
);
$template = $tags_info[$parts[0]]['templates']['head'][$parts[1]];
$weight = isset($tags_info[$parts[0]]['weight'][$parts[1]]) ? $tags_info[$parts[0]]['weight'][$parts[1]] : 0;
switch ($template) {
case NODEWORDS_META:
$template = '';
break;
case NODEWORDS_HTTP_EQUIV:
$template = '';
break;
case NODEWORDS_LINK_REL:
$template = '';
break;
case NODEWORDS_LINK_REV:
$template = '';
break;
default:
if (!is_string($template)) {
$template = '';
}
break;
}
}
if (!empty($template)) {
$output[] = strtr($template, $replace);
$weights[] = $weight;
}
}
if (count($output)) {
array_multisort($weights, $output);
return implode("\n", $output);
}
else {
return '';
}
}
function _nodewords_tag_value($tag, $value, $options = array()) {
static $default = NULL;
$options += _nodewords_get_default_metatags_type();
$id = $options['id'];
$type = $options['type'];
if (!isset($default[$type][$id])) {
$default_values = array();
nodewords_load_all_includes('nodewords.hooks.inc');
drupal_alter('nodewords_default_value', $default_values, $options + array('phase' => 'pre_load'));
if (!empty($default_values)) {
$default[$type][$id] = $default_values;
}
else {
$default[$type][$id] = nodewords_load_tags();
drupal_alter('nodewords_default_value', $default[$type][$id], $options + array('phase' => 'post_load'));
}
}
if ($type == NODEWORDS_TYPE_DEFAULT) {
$value = isset($default[$type][$id][$tag]) ? $default[$type][$id][$tag] : array();
}
else {
$tags_info = nodewords_get_possible_tags();
$variable = empty($options['admin']) ? 'nodewords_ui_use_default_value_' . $tag : 'nodewords_admin_use_default_value_' . $tag;
switch (variable_get($variable, 'empty')) {
case 'empty':
$bool = (
isset($tags_info[$tag]['callback']) &&
function_exists($function = $tags_info[$tag]['callback'] . '_is_empty')
);
if ($bool && $function($value)) {
$value = isset($default[$type][$id][$tag]) ? $default[$type][$id][$tag] : array();
}
elseif (!$bool && empty($value['value'])) {
$value = isset($default[$type][$id][$tag]) ? $default[$type][$id][$tag] : array();
}
break;
case 'always':
$value = isset($default[$type][$id][$tag]) ? $default[$type][$id][$tag] : array();
break;
}
}
return $value;
}