View source
<?php
define("GLOSSIFY_USE_FILTER", 0);
define("GLOSSIFY_WITHOUT_FILTER", 1);
define("GLOSSIFY_WITHOUT_FILTER_OMIT_COMMENTS", 2);
function glossify_perm() {
return array(
'administer glossify',
);
}
function glossify_menu() {
$items['admin/settings/glossify'] = array(
'title' => 'Glossify',
'description' => 'Manipulate glossify behaviour',
'page callback' => 'drupal_get_form',
'page arguments' => array(
'glossify_admin_settings',
),
'access arguments' => array(
'administer glossify',
),
'file' => 'glossify.admin.inc',
);
$weight = 1;
$items['admin/settings/glossify/global'] = array(
'type' => MENU_DEFAULT_LOCAL_TASK,
'title' => t('Global'),
'weight' => $weight,
);
$configurations = variable_get('glossify_configurations', array());
foreach ($configurations as $configuration => $values) {
if ($configuration !== 'global') {
$weight++;
$items["admin/settings/glossify/{$configuration}"] = array(
'type' => MENU_LOCAL_TASK,
'title' => $configuration,
'page arguments' => array(
'glossify_admin_settings',
),
'access arguments' => array(
'administer glossify',
),
'file' => 'glossify.admin.inc',
'weight' => $weight,
);
}
}
$items['admin/settings/glossify/add'] = array(
'type' => MENU_LOCAL_TASK,
'title' => t('Add a new configuration'),
'page arguments' => array(
'glossify_admin_settings',
),
'access arguments' => array(
'administer glossify',
),
'file' => 'glossify.admin.inc',
'weight' => 99,
);
return $items;
}
function glossify_theme() {
return array(
'glossify_term' => array(
'arguments' => array(
'nid' => NULL,
'glossify_style' => NULL,
),
),
'glossify_reference_section' => array(
'arguments' => array(
'term_definition_list' => NULL,
),
),
);
}
function theme_glossify_term($target, $glossify_style) {
if (is_numeric($target)) {
$term = node_load($target);
}
elseif (drupal_lookup_path('source', $target)) {
$exploded_path = explode('/', drupal_lookup_path('source', $target));
$term = node_load($exploded_path[count($exploded_path) - 1]);
}
switch ($glossify_style) {
case 'reference':
$output = '<dt>' . check_plain($term->title) . '</dt>';
$output .= '<dd>' . check_markup($term->body) . '</dd>';
break;
case 'hovertip':
default:
$output = '<div id="' . check_plain($term->title) . '" class="hovertip" style="display: none;">';
$output .= '<h1>' . check_plain($term->title) . '</h1>';
$glossify_mode = variable_get('glossify_process_mode', GLOSSIFY_USE_FILTER);
if ($glossify_mode != GLOSSIFY_USE_FILTER) {
$term->body = glossify_filter('process', 0, $term->format, $term->body);
}
$output .= '<p>' . check_markup($term->body) . '</p>';
$output .= '</div>';
break;
}
return $output;
}
function theme_glossify_reference_section($term_definition_list) {
$output = '<div id="glossify-reference">';
$output .= '<h3>Terms referenced:</h3>';
$output .= '<dl>';
$output .= $term_definition_list;
$output .= '</dl>';
$output .= '</div>';
return $output;
}
function glossify_form_alter(&$form, $form_state, $form_id) {
if (isset($form['type']) && isset($form['#node']) && $form['type']['#value'] . '_node_form' == $form_id) {
$configurations = variable_get('glossify_configurations', array());
$use_internal = FALSE;
foreach ($configurations as $configuration) {
if ($configuration['methods']['use_internal'] && in_array($form['type']['#value'], $configuration['to'])) {
$use_internal = TRUE;
}
}
if ($use_internal) {
$node = $form['#node'];
$form['glossify'] = array(
'#type' => 'fieldset',
'#title' => t('Glossify'),
'#collapsible' => TRUE,
'#collapsed' => isset($node->glossify_keywords) && !empty($node->glossify_keywords) || isset($node->glossify_override) && !empty($node->glossify_override) ? FALSE : TRUE,
'#weight' => 0,
);
$form['glossify']['glossify_keywords'] = array(
'#type' => 'textfield',
'#title' => t('Glossify Keywords'),
'#default_value' => isset($node->glossify_keywords) ? $node->glossify_keywords : '',
'#description' => t('You can add more than one keyword by seperating them with commas.'),
'#weight' => 0,
);
$form['glossify']['glossify_override'] = array(
'#type' => 'textfield',
'#title' => t('Glossify Override'),
'#default_value' => isset($node->glossify_override) ? $node->glossify_override : '',
'#weight' => 1,
);
}
}
}
function glossify_theme_registry_alter(&$theme_registry) {
if (!empty($theme_registry['comment_view'])) {
$theme_registry['comment_view']['function'] = 'glossify_theme_comment_view';
}
}
function glossify_nodeapi(&$node, $op, $a3 = NULL, $a4 = NULL) {
switch ($op) {
case 'delete':
$configurations = variable_get('glossify_configurations', array());
foreach ($configurations as $config_name => $configuration) {
if (isset($configuration['to'][$node->type])) {
$enabled_styles = array_filter($configuration['style']);
$methods = $configuration['methods'];
if (isset($methods['use_title'])) {
_keyword_table('delete', $node->nid, 'title', $config_name, $node->language);
}
if (isset($methods['use_internal'])) {
_keyword_table('delete', $node->nid, 'internal', $config_name, $node->language);
}
if (isset($methods['use_cck'])) {
_keyword_table('delete', $node->nid, 'cck', $config_name, $node->language);
}
if (isset($methods['use_taxonomy'])) {
_keyword_table('delete', $node->nid, 'taxonomy', $config_name, $node->language);
}
}
}
break;
case 'load':
$glossify_keywords = implode(', ', _fetch_keywords($node->nid, 'internal'));
$glossify_override = db_result(db_query('SELECT alternate FROM {glossify} WHERE nid = %d', $node->nid));
return array(
'glossify_keywords' => $glossify_keywords,
'glossify_override' => $glossify_override,
);
break;
case 'presave':
$configurations = variable_get('glossify_configurations', array());
$clear_filter_cache = array();
foreach ($configurations as $config_name => $configuration) {
$clear_filter_cache = in_array($node->type, array_merge($configuration['to'], $configuration['from']));
}
if ($clear_filter_cache) {
cache_clear_all('*', 'cache_filter', TRUE);
}
break;
case 'insert':
$configurations = variable_get('glossify_configurations', array());
$keywords = array();
$affected_content_types = array();
$html_body = str_get_html($node->body);
$html_teaser = str_get_html($node->teaser);
foreach ($configurations as $config_name => $configuration) {
if (in_array($node->type, $configuration['to'])) {
if ($configuration['methods']['use_title']) {
_keyword_table('insert', $node->nid, 'title', $config_name, $node->language, $node->title);
$keywords[$node->title] = $node->title;
}
if ($configuration['methods']['use_internal'] && !empty($node->glossify_keywords)) {
foreach (array_map('trim', explode(',', $node->glossify_keywords)) as $keyword) {
_keyword_table('insert', $node->nid, 'internal', $config_name, $node->language, $keyword, $node->glossify_override);
$keywords[$keyword] = $keyword;
}
}
if ($configuration['methods']['use_cck']) {
$fieldname = $configuration['methods']['keyword_field'];
$override = $configuration['methods']['override_field'];
foreach (array_map('trim', explode(',', $node->{$fieldname}[0]['value'])) as $keyword) {
_keyword_table('insert', $node->nid, 'cck', $config_name, $node->language, $keyword, $node->{$override}[0]['value']);
$keywords[$keyword] = $keyword;
}
}
if ($configuration['methods']['use_taxonomy']) {
foreach (array_map('trim', explode(',', $node->taxonomy['tags'][$configuration['methods']['vocabulary']])) as $keyword) {
_keyword_table('insert', $node->nid, 'taxonomy', $config_name, $node->language, $keyword);
$keywords[$keyword] = $keyword;
}
}
$affected_content_types = array_merge($affected_content_types, $configuration['from']);
}
}
break;
case 'update':
$configurations = variable_get('glossify_configurations', array());
$keywords = array();
$affected_content_types = array();
$html_body = str_get_html($node->body);
$html_teaser = str_get_html($node->teaser);
foreach ($configurations as $config_name => $configuration) {
if (in_array($node->type, $configuration['to'])) {
if ($configuration['methods']['use_title']) {
if (!db_result(db_query("SELECT gtid FROM {glossify} WHERE nid = %d AND method = '%s' AND configuration = '%s'", $node->nid, 'title', $config_name))) {
_keyword_table('insert', $node->nid, 'title', $config_name, $node->language, $node->title);
$keywords[$node->title] = $node->title;
}
elseif (!db_result(db_query("SELECT gtid FROM {glossify} WHERE nid = %d AND method = '%s' AND term = '%s' AND configuration = '%s'", $node->nid, 'title', $node->title, $config_name))) {
$keywords = array_merge($keywords, _keyword_table('update', $node->nid, 'title', $config_name, $node->language, $node->title));
$keywords[$node->title] = $node->title;
}
}
if ($configuration['methods']['use_internal']) {
$keywords = array_merge($keywords, _fetch_affected_keywords($node, 'internal', $config_name));
}
if ($configuration['methods']['use_cck']) {
$keywords = array_merge($keywords, _fetch_affected_keywords($node, 'cck', $config_name, $configuration['methods']['keyword_field'], $configuration['methods']['override_field']));
}
if ($configuration['methods']['use_taxonomy']) {
$keywords = array_merge($keywords, _fetch_affected_keywords($node, 'taxonomy', $config_name, $configuration['methods']['vocabulary']));
}
$affected_content_types[$config_name] = array_merge($affected_content_types, $configuration['from']);
}
}
break;
case 'view':
$configurations = variable_get('glossify_configurations', array());
$term_definition_list = '';
$referenced_terms = array();
foreach ($configurations as $config_name => $configuration) {
if (in_array($node->type, $configuration['from'])) {
$enabled_styles = array_filter($configuration['style']);
$possible_keywords = _fetch_possible_keywords($config_name, $configuration, $node->nid);
if (in_array('reference', $enabled_styles)) {
foreach ($possible_keywords as $kwd) {
list($term_title, $path) = $kwd;
if (preg_match(_glossify_regex($configuration, $term_title), $node->body)) {
if (!in_array($path, $referenced_terms)) {
$term_definition_list .= theme('glossify_term', $path, 'reference');
$referenced_terms[] = $path;
}
}
}
}
if (in_array('hovertip', $enabled_styles)) {
foreach ($possible_keywords as $kwd) {
list($term_title, $path) = $kwd;
if (preg_match(_glossify_regex($configuration, $term_title), $node->body)) {
$node->content['glossify_hovertip'][$term_title] = array(
'#value' => theme('glossify_term', $path, 'hovertip'),
'#weight' => 10,
);
$node->content['glossify_hovertip']['#weight'] = 10;
$node->content['glossify_all_hovertips']['#value'] .= $node->content['glossify_hovertip'][$term_title]['#value'];
}
}
}
}
}
if ($term_definition_list !== '') {
$node->content['glossify_reference'] = array(
'#weight' => '10',
'#value' => theme('glossify_reference_section', $term_definition_list),
);
}
$glossify_mode = variable_get('glossify_process_mode', GLOSSIFY_USE_FILTER);
if ($glossify_mode != GLOSSIFY_USE_FILTER) {
$node->content['body']['#value'] = glossify_filter('process', 0, $node->format, $node->content['body']['#value']);
}
break;
}
}
function glossify_comment(&$a1, $op) {
if ($op == 'view') {
$glossify_mode = variable_get('glossify_process_mode', GLOSSIFY_USE_FILTER);
if ($glossify_mode == GLOSSIFY_WITHOUT_FILTER) {
$a1->comment = glossify_filter('process', 0, $a1->format, $a1->comment);
}
}
}
function glossify_filter($op, $delta = 0, $format = -1, $text = '', $cache_id = 0) {
static $configurations;
switch ($op) {
case 'list':
if (variable_get('glossify_process_mode', GLOSSIFY_USE_FILTER) == GLOSSIFY_USE_FILTER) {
return array(
0 => t('Glossify filter'),
);
}
else {
return array();
}
case 'description':
return t('Glossify the entered content.');
case 'prepare':
return $text;
case 'process':
if (empty($text)) {
return $text;
}
if (($node = menu_get_object()) == NULL) {
$q = db_query("SELECT nid FROM {node_revisions} WHERE '%s'=CONCAT(format, ':', MD5(body))", $cache_id);
$r = db_fetch_object($q);
if ($r->nid) {
$node = node_load($r->nid);
}
else {
return $text;
}
}
if (!isset($configurations)) {
$configurations = variable_get('glossify_configurations', array());
foreach ($configurations as $key => &$config) {
if (isset($config['excl_tags']) && !empty($config['excl_tags'])) {
$html_tags = preg_split("/\r\n|\r|\n|,/", $config['excl_tags']);
$config['excl_tags'] = array_combine($html_tags, $html_tags);
}
}
}
if (class_exists('DOMDocument', false)) {
$newtext = _glossify_replace_terms_phpdom($text, $configurations, $node);
}
else {
$newtext = _glossify_replace_terms_simplehtmldom($text, $configurations, $node);
}
return $newtext;
default:
return $text;
}
}
function _glossify_replace_terms_simplehtmldom($text, $configurations, $node) {
$html_body = str_get_html($text);
foreach ($configurations as $config_name => $configuration) {
if (isset($configuration['from'][$node->type])) {
$enabled_styles = array_filter($configuration['style']);
$compare_function = $configuration['case_insensitivity'] ? 'stripos' : 'strpos';
foreach (_fetch_possible_keywords($config_name, $configuration, $node->nid) as $kwd) {
list($term_title, $target_url) = $kwd;
$replaced = 0;
foreach ($enabled_styles as $style => $enabled) {
if ($enabled && !empty($term_title) && false !== $compare_function($html_body->innertext, $term_title)) {
$replacement = _fetch_replacement($style, $term_title, $target_url);
_glossify_replace($configuration, $html_body, $term_title, $replacement, $replaced);
if (0 < $replaced) {
$html_body = str_get_html($html_body->innertext);
}
}
}
}
}
}
return $html_body->innertext;
}
function _glossify_replace_terms_phpdom($text, $configurations, $node) {
$original = $text;
$text = '<meta http-equiv="content-type" content="text/html; charset=utf-8">' . $text;
$dom = new DOMDocument();
$dom->formatOutput = true;
@$dom
->loadHTML($text);
if (!$dom
->hasChildNodes()) {
return $original;
}
$xpath = new DOMXpath($dom);
$xpath_query = "//text()";
$text_nodes = $xpath
->query($xpath_query);
if (0 == $text_nodes->length) {
return $original;
}
$has_replacements = false;
foreach ($configurations as $config_name => $configuration) {
if (isset($configuration['from'][$node->type])) {
$enabled_styles = array_filter($configuration['style']);
$exclude_tags = is_array($configuration['excl_tags']) ? $configuration['excl_tags'] : array();
$keywords = _fetch_possible_keywords($config_name, $configuration, $node->nid);
foreach ($keywords as $kwd) {
list($term_title, $target_url) = $kwd;
if (empty($term_title)) {
continue;
}
$rx = _glossify_regex($configuration, $term_title);
if (!preg_match($rx, $original)) {
continue;
}
foreach ($enabled_styles as $style => $enabled) {
$replacement = _fetch_replacement($style, $term_title, $target_url);
$child = $dom->firstChild;
while ($child) {
if (_glossify_process_domnode($child, $dom, $rx, $replacement, $configuration['excl_mode'], $exclude_tags, $configuration['only_first'])) {
$has_replacements = true;
if ($configuration['only_first']) {
break;
}
}
$child = $child->nextSibling;
}
}
}
}
}
if (false == $has_replacements) {
return $original;
}
$body = $dom
->GetElementsByTagName('body')
->item(0);
if ($body instanceof DOMNode) {
$return = new DOMDocument();
$root = $return
->createElement('body');
$root = $return
->appendChild($root);
$result_node = $return
->importNode($body, true);
$return->documentElement
->appendChild($result_node);
$out = $return
->saveHTML();
$out = str_replace(array(
'<body>',
'</body>',
), '', $out);
return $out;
}
else {
return $original;
}
}
function _glossify_process_domnode($domnode, $dom, $rx, $replacement, $excl_mode, $exclude_tags, $only_first = FALSE, &$next_node = NULL, $level = 0) {
$result = false;
switch ($domnode->nodeType) {
case XML_TEXT_NODE:
$exclude_this = false;
if (!empty($exclude_tags)) {
$tmpnode = $domnode;
$real_parent = '';
while ($tmpnode->parentNode) {
if ($tmpnode->parentNode
->hasAttributes()) {
$parent_class = $tmpnode->parentNode->attributes
->getNamedItem('class');
if (is_object($parent_class)) {
if (preg_match('/glossify_term/', $parent_class->nodeValue) !== 0) {
$tmpnode = $tmpnode->parentNode;
continue;
}
}
}
$real_parent = $tmpnode->parentNode->nodeName;
break;
}
if ($excl_mode == 0 && isset($exclude_tags[$real_parent]) || $excl_mode == 1 && !isset($exclude_tags[$real_parent])) {
$exclude_this = true;
}
}
$next_sibling = $domnode->nextSibling;
if (!$exclude_this) {
$replaced = preg_replace($rx, $replacement, $domnode->wholeText, $only_first ? 1 : -1, $replace_done);
if ($replace_done) {
$new_node = $dom
->createDocumentFragment();
$replaced = preg_replace('/&(?!amp;)/', '&', $replaced);
if (@$new_node
->appendXML($replaced)) {
$domnode->parentNode
->replaceChild($new_node, $domnode);
$result = true;
$next_node = $next_sibling;
}
}
}
break;
default:
if ($domnode
->hasChildNodes()) {
$child = $domnode->firstChild;
while ($child) {
if ($child->nodeType != XML_TEXT_NODE && ($child->nodeName == 'iframe' || $child->nodeName == 'object')) {
continue;
}
else {
$nxtnode = NULL;
$result = _glossify_process_domnode($child, $dom, $rx, $replacement, $excl_mode, $exclude_tags, $only_first, $nxtnode, $level + 1) || $result;
if ($result && $only_first) {
break;
}
}
if (is_object($nxtnode)) {
$child = $nxtnode;
}
else {
$child = $child->nextSibling;
}
}
}
break;
}
return $result;
}
function _glossify_node_load(&$node, $module) {
$fn = $module . '_nodeapi';
$result = $fn($node, 'load');
if ($result) {
foreach ($result as $key => $value) {
$node->{$key} = $value;
}
}
}
function _glossify_replace($configuration, &$html, $term_title, $replacement, &$replaced) {
$text_nodes = $html
->find('text');
$exclude_tags = array_merge(is_array($configuration['excl_tags']) ? $configuration['excl_tags'] : array(), array(
'iframe' => 'iframe',
'object' => 'object',
));
foreach ($text_nodes as $text_node) {
if (!isset($text_node->parent->tag) || $configuration['excl_mode'] == 0 && !isset($exclude_tags[$text_node->parent->tag]) || $configuration['excl_mode'] == 1 && isset($exclude_tags[$text_node->parent->tag])) {
$text_node->innertext = preg_replace(_glossify_regex($configuration, $term_title), $replacement, $text_node->innertext, $configuration['only_first'] ? 1 : -1, $result);
if ($result) {
$replaced += $result;
if ($configuration['only_first']) {
break;
}
}
}
}
}
function _fetch_replacement($style, $term_title, $target_url) {
switch ($style) {
case 'links':
return $replacement = l('$1', $target_url, array(
'attributes' => array(
'title' => $term_title,
'class' => 'glossify_term',
),
));
case 'hovertip':
return $replacement = '<span class="glossify_term hovertip_target" hovertip="' . $term_title . '">$1</span>';
case 'reference':
return $replacement = '<span class="glossify_term">' . $term_title . '</span>';
}
}
function _fetch_keywords($nid, $method = FALSE, $configuration = NULL) {
if (!$configuration) {
$q = db_query("SELECT term, method FROM {glossify} WHERE nid = %d ORDER BY term", $nid);
}
else {
$q = db_query("SELECT term, method FROM {glossify} WHERE nid = %d AND configuration = '%s' ORDER BY term", $nid, $configuration);
}
$glossary = array();
while ($r = db_fetch_array($q)) {
if ($method) {
if ($method == $r['method']) {
$glossary[] = $r['term'];
}
}
else {
$glossary[$r['method']][] = $r['term'];
}
}
return $glossary;
}
function _keyword_table($operation, $nid, $method, $configuration = 'global', $language = '', $term = '', $alternate = '') {
switch ($operation) {
case 'insert':
$gnid = db_result(db_query("SELECT nid FROM {glossify} WHERE term = '%s' AND language = '%s' AND method = '%s' AND configuration = '%s'", $term, $language, $method, $configuration));
$new_terms = array();
if (!$gnid) {
db_query("INSERT INTO {glossify} (nid, term, language, method, alternate, configuration) VALUES (%d, '%s', '%s', '%s', '%s', '%s')", $nid, $term, $language, $method, $alternate, $configuration);
$new_terms[$term] = $term;
}
else {
$node = node_load($gnid);
drupal_set_message(t("The keyword: '%term' for the %method-method under configuration %config was already assigned to point to <a href=\"/node/{$node->nid}\">%title</a>", array(
'%term' => $term,
'%title' => $node->title,
'%method' => $method,
'%config' => $configuration,
)), 'warning');
}
return $new_terms;
break;
case 'update':
$old_term = db_result(db_query("SELECT term FROM {glossify} WHERE nid = %d AND method = '%s'", $nid, 'title'));
db_query("UPDATE {glossify} SET term = '%s', language = '%s', method = '%s' WHERE nid = %d AND method = '%s' AND configuration = '%s'", $term, $language, $method, $nid, 'title', $configuration);
return array(
$old_term => $old_term,
);
break;
case 'delete':
$old_terms = array();
if (!empty($term)) {
$old_terms[$term] = $term;
db_query("DELETE FROM {glossify} WHERE nid = %d AND method = '%s' AND language = '%s' AND term = '%s' AND configuration = '%s'", $nid, $method, $language, $term, $configuration);
}
else {
$q = db_query("SELECT term FROM {glossify} WHERE nid = %d AND method = '%s' AND configuration = '%s' ORDER BY term", $nid, $method, $configuration);
while ($r = db_fetch_array($q)) {
$old_terms[$r['term']] = $r['term'];
}
db_query("DELETE FROM {glossify} WHERE nid = %d AND method = '%s' AND configuration = '%s'", $nid, $method, $configuration);
}
return $old_terms;
break;
}
return TRUE;
}
function _fetch_affected_keywords($node, $method, $configuration = 'global', $keywordsource = NULL, $override = '') {
$keywords = array();
$existing_keywords = _fetch_keywords($node->nid, $method, $configuration);
switch ($method) {
case 'internal':
$form_keywords = !empty($node->glossify_keywords) ? array_map('trim', explode(',', $node->glossify_keywords)) : array();
$form_override = $node->glossify_override;
break;
case 'cck':
$keyword = $node->{$keywordsource};
$override = $node->{$override};
if (isset($keyword[0]['value'])) {
$form_keywords = !empty($keyword[0]['value']) ? array_map('trim', explode(',', $keyword[0]['value'])) : array();
}
if (isset($override[0]['value'])) {
$form_override = $override[0]['value'];
}
else {
$form_override = '';
}
break;
case 'taxonomy':
if (isset($node->taxonomy)) {
$form_keywords = array();
foreach ($node->taxonomy['tags'] as $vid => $tag) {
if (in_array($vid, $keywordsource)) {
$form_keywords = array_merge($form_keywords, array_map('trim', explode(',', $tag)));
}
}
$form_override = $override;
}
break;
}
if (count($form_keywords) > 0) {
if (count($existing_keywords)) {
$ikwds1 = array_diff($existing_keywords, $form_keywords);
$ikwds2 = array_diff($form_keywords, $existing_keywords);
if (count($ikwds1) !== count($ikwds2) || count($ikwds1) !== 0 && count($ikwds2) !== 0) {
$ikwds3 = array_intersect($ikwds1, $ikwds2);
if (count($ikwds3) == 0) {
foreach ($ikwds1 as $keyword) {
$keywords = array_merge($keywords, _keyword_table('delete', $node->nid, $method, $configuration, $node->language, $keyword));
}
foreach ($ikwds2 as $keyword) {
$keywords = array_merge($keywords, _keyword_table('insert', $node->nid, $method, $configuration, $node->language, $keyword, $form_override));
}
}
}
}
else {
foreach ($form_keywords as $keyword) {
$keywords = array_merge($keywords, _keyword_table('insert', $node->nid, $method, $configuration, $node->language, $keyword, $form_override));
}
}
}
else {
if (count($existing_keywords) > 0) {
$keywords = array_merge($keywords, _keyword_table('delete', $node->nid, $method, $configuration));
}
}
return $keywords;
}
function _fetch_affected_nodes($keywords, $content_types) {
$nodes = array();
foreach ($keywords as $keyword) {
$q = db_query("SELECT n.nid FROM {node} n INNER JOIN {node_revisions} r ON r.nid = n.nid WHERE n.type IN (" . db_placeholders($content_types, 'varchar') . ") AND r.body LIKE '%%%s%%'", $content_types, $keyword);
while ($r = db_fetch_array($q)) {
$nodes[] = $r['nid'];
}
}
return $nodes;
}
function _fetch_possible_keywords($config_name, $configuration, $nid) {
$glossify_dict = array();
static $keyword_lists = array();
if (isset($keyword_lists[$config_name][$nid])) {
return $keyword_lists[$config_name][$nid];
}
$methods = array();
if ($configuration['methods']['use_title']) {
$methods[] = 'title';
}
if ($configuration['methods']['use_internal']) {
$methods[] = 'internal';
}
if ($configuration['methods']['use_cck']) {
$methods[] = 'cck';
}
if ($configuration['methods']['use_taxonomy']) {
$methods[] = 'taxonomy';
}
$query = "SELECT g.term, g.nid, g.alternate, g.language, g.method FROM {node} n INNER JOIN {glossify} g ON g.nid = n.nid WHERE n.type IN (" . db_placeholders($configuration['to'], 'varchar') . ") AND g.method IN (" . db_placeholders($methods, 'varchar') . ") AND g.configuration = '%s' AND n.status = 1";
if ($configuration['language']) {
$query .= " AND g.language = n.language";
}
if (!$configuration['link_self']) {
$query .= " AND g.nid != %d";
$q = db_query($query, array_merge($configuration['to'], $methods, (array) $config_name, (array) $nid));
}
else {
$q = db_query($query, array_merge($configuration['to'], $methods, (array) $config_name));
}
while ($r = db_fetch_array($q)) {
if ($configuration['methods']['link_term'] && $r['method'] == 'taxonomy') {
$term = db_fetch_array(db_query("SELECT tid FROM {term_data} WHERE name = '%s'", $r['term']));
$glossify_dict[] = array(
$r['term'],
drupal_lookup_path('alias', 'taxonomy/term/' . $term['tid'], $r['language']),
);
}
else {
if (!empty($r['alternate'])) {
if (is_numeric($r['alternate'])) {
$glossify_dict[] = array(
$r['term'],
drupal_lookup_path('alias', 'node/' . $r['alternate'], $r['language']),
);
}
elseif ($path = drupal_lookup_path('alias', $r['alternate'], $r['language'])) {
$glossify_dict[] = array(
$r['term'],
$path,
);
}
else {
$glossify_dict[] = array(
$r['term'],
$r['alternate'],
);
}
}
else {
$glossify_dict[] = array(
$r['term'],
drupal_lookup_path('alias', 'node/' . $r['nid'], $r['language']),
);
}
}
}
$keyword_lists[$config_name][$nid] = $glossify_dict;
return $glossify_dict;
}
function _update_keywords_for_methods($content_types, $methods, $configuration) {
$q = db_query("SELECT nid, vid, type, title, language FROM {node} WHERE status=1 AND type IN (" . db_placeholders($content_types, 'varchar') . ")", $content_types);
while ($node = db_fetch_object($q)) {
if (isset($methods['title'])) {
if ($methods['title']) {
_keyword_table('insert', $node->nid, 'title', $configuration, $node->language, $node->title);
}
else {
_keyword_table('delete', $node->nid, 'title', $configuration, $node->language);
}
}
if (isset($methods['internal'])) {
_glossify_node_load($node, 'glossify');
if ($methods['internal']['use_internal']) {
_fetch_affected_keywords($node, 'internal', $configuration);
}
else {
_keyword_table('delete', $node->nid, 'internal', $configuration, $node->language);
}
}
if (isset($methods['cck'])) {
_glossify_node_load($node, 'content');
if ($methods['cck']['use_cck']) {
_fetch_affected_keywords($node, 'cck', $configuration, $methods['cck']['keyword_field'], $methods['cck']['override_field']);
}
else {
_keyword_table('delete', $node->nid, 'cck', $configuration, $node->language);
}
}
if (isset($methods['taxonomy'])) {
_glossify_node_load($node, 'taxonomy');
if ($methods['taxonomy']['use_taxonomy']) {
_fetch_affected_keywords($node, 'taxonomy', $configuration, $methods['taxonomy']['vocabulary']);
}
else {
_keyword_table('delete', $node->nid, 'taxonomy', $configuration, $node->language);
}
}
}
}
function _fetch_modifiers($configuration) {
$modifiers = '';
if ($configuration['unicode']) {
$modifiers .= 'u';
}
if ($configuration['case_insensitivity']) {
$modifiers .= 'i';
}
return $modifiers;
}
function _check_for_configuration_conflicts($configurations, $content_types, $method) {
foreach ($configurations as $configuration) {
if (count(array_intersect($content_types, $configuration['to'])) > 0) {
if ($configuration['methods'][$method]) {
return FALSE;
}
}
}
return TRUE;
}
function _backwards_compatibility() {
$keyword_field = variable_get('glossify_use_this_cck_field_for_keyword_synonyms', FALSE);
$override_field = variable_get('glossify_use_this_cck_field_for_target_url_override', '');
if ($keyword_field) {
$content_types = variable_get('glossify_glossary_content_type', array());
if (count($content_types > 0)) {
$methods = array(
'title',
'cck' => array(
'keyword_field' => $keyword_field,
'override_field' => $override_field,
),
);
_update_keywords_for_methods($content_types, $methods);
}
}
variable_del('glossify_glossary_content_type');
variable_del('glossify_content_types_to_search');
variable_del('glossify_link_first_only');
variable_del('glossify_do_we_need_unicode_compatibility');
variable_del('glossify_teaser');
variable_del('glossify_style');
variable_del('glossify_dont_break_words');
variable_del('glossify_display_parsing_time_for_performance_debugging');
variable_del('glossify_use_this_cck_field_for_keyword_synonyms');
variable_del('glossify_use_this_cck_field_for_target_url_override');
}
function glossify_theme_comment_view($comment, $node, $links = array(), $visible = TRUE) {
static $first_new = TRUE;
$output = '';
$comment->new = node_mark($comment->nid, $comment->timestamp);
if ($first_new && $comment->new != MARK_READ) {
$first_new = FALSE;
$output .= "<a id=\"new\"></a>\n";
}
$output .= "<a id=\"comment-{$comment->cid}\"></a>\n";
$glossify_mode = variable_get('glossify_process_mode', GLOSSIFY_USE_FILTER);
if ($visible) {
$comment->comment = check_markup($comment->comment, $comment->format, FALSE);
comment_invoke_comment($comment, 'view');
if ($glossify_mode != GLOSSIFY_WITHOUT_FILTER_OMIT_COMMENTS) {
_glossify_comment_hovertips($comment, $node);
}
$output .= theme('comment', $comment, $node, $links);
}
else {
$output .= theme('comment_folded', $comment);
}
return $output;
}
function _glossify_comment_hovertips(&$comment, $node) {
$configurations = variable_get('glossify_configurations', array());
$referenced_terms = array();
foreach ($configurations as $config_name => $configuration) {
if (in_array($node->type, $configuration['from'])) {
$enabled_styles = array_filter($configuration['style']);
$possible_keywords = _fetch_possible_keywords($config_name, $configuration, $node->nid);
if (in_array('hovertip', $configuration['style']) && $configuration['style']['hovertip']) {
foreach ($possible_keywords as $kwd) {
list($term_title, $path) = $kwd;
if (in_array($term_title, $referenced_terms)) {
continue;
}
if (preg_match(_glossify_regex($configuration, $term_title), $comment->comment)) {
$referenced_terms[] = $term_title;
if (!isset($node->content['glossify_hovertip'][$term_title])) {
$comment->comment .= theme('glossify_term', $path, 'hovertip');
}
}
}
}
}
}
}
function _glossify_regex($configuration, $term_title) {
$modifiers = _fetch_modifiers($configuration);
if ($configuration['break'] && $configuration['unicode']) {
$rx = '/(?<![\\pL\\pN_])(' . preg_quote($term_title, '/') . ')(?![\\pL\\pN_])/' . $modifiers;
}
else {
$rx = '/' . ($configuration['break'] ? '\\b(' . preg_quote($term_title, '/') . ')\\b' : '(' . preg_quote($term_title) . ')') . '/' . $modifiers;
}
return $rx;
}