View source
<?php
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>';
$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']) {
$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_nodeapi(&$node, $op, $a3 = NULL, $a4 = NULL) {
switch ($op) {
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 $configuration) {
if (in_array($node->type, $configuration['to'])) {
if ($configuration['methods']['use_title']) {
_keyword_table('insert', $node->nid, 'title', $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', $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, 'internal', $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, 'internal', $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'", $node->nid, 'title'))) {
_keyword_table('insert', $node->nid, 'title', $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'", $node->nid, 'title', $node->title))) {
$keywords = array_merge($keywords, _keyword_table('update', $node->nid, 'title', $node->language, $node->title));
$keywords[$node->title] = $node->title;
}
}
if ($configuration['methods']['use_internal']) {
$keywords = array_merge($keywords, _fetch_affected_keywords($node, 'internal'));
}
if ($configuration['methods']['use_cck']) {
$keywords = array_merge($keywords, _fetch_affected_keywords($node, 'cck', $configuration['methods']['keyword_field'], $configuration['methods']['override_field']));
}
if ($configuration['methods']['use_taxonomy']) {
foreach ($configuration['methods']['vocabulary'] as $vocabulary) {
$keywords = array_merge($keywords, _fetch_affected_keywords($node, 'taxonomy', $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'])) {
$possible_keywords = _fetch_possible_keywords($configuration, $node->nid);
if (in_array('reference', $configuration['style'])) {
foreach ($possible_keywords as $term_title => $path) {
if ($configuration['break']) {
if (preg_match('/\\b' . $term_title . '\\b/', $node->body)) {
if (!in_array($path, $referenced_terms)) {
$term_definition_list .= theme('glossify_term', $path, 'reference');
$referenced_terms[] = $path;
}
}
}
else {
if (preg_match('/' . $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', $configuration['style'])) {
foreach ($possible_keywords as $term_title => $path) {
if ($configuration['break']) {
if (preg_match('/\\b' . $term_title . '\\b/', $node->body)) {
$node->content['glossify_hovertip'][$term_title] = array(
'#value' => theme('glossify_term', $path, 'hovertip'),
'#weight' => 10,
);
$node->content['glossify_hovertip']['#weight'] = 10;
}
}
else {
if (preg_match('/' . $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;
}
}
}
}
}
}
if ($term_definition_list !== '') {
$node->content['glossify_reference'] = array(
'#weight' => '10',
'#value' => theme('glossify_reference_section', $term_definition_list),
);
}
break;
}
}
function glossify_filter($op, $delta = 0, $format = -1, $text = '', $cache_id = 0) {
switch ($op) {
case 'list':
return array(
0 => t('Glossify filter'),
);
case 'description':
return t('Glossify the entered content.');
case 'prepare':
return $text;
case 'process':
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);
$node = node_load($r->nid);
}
$configurations = variable_get('glossify_configurations', array());
$html_body = str_get_html($text);
foreach ($configurations as $config_name => $configuration) {
if (in_array($node->type, $configuration['from'])) {
foreach (_fetch_possible_keywords($configuration, $node->nid) as $term_title => $target_url) {
foreach ($configuration['style'] as $style => $enabled) {
if ($enabled) {
if (isset($old_body) && $old_body !== $html_body->innertext) {
$html_body = str_get_html($html_body->innertext);
}
$replacement = _fetch_replacement($style, $term_title, $target_url);
$old_body = $html_body->innertext;
$replaced = 0;
_glossify_replace($configuration, $html_body, $term_title, $replacement, $replaced);
}
}
}
}
}
return $html_body->innertext;
default:
return $text;
}
}
function _glossify_replace($configuration, &$html, $term_title, $replacement, &$replaced) {
if (count($html
->childNodes()) > 0) {
foreach ($html
->childNodes() as $child_node) {
_glossify_replace($configuration, $child_node, $term_title, $replacement, $replaced);
}
}
else {
if (isset($html->tag) && $html->tag !== 'root') {
if ($configuration['only_first'] && $replaced == 0) {
if ($configuration['break']) {
$html->innertext = preg_replace('/\\b' . $term_title . '\\b/', $replacement, $html->innertext, $configuration['only_first'] ? 1 : -1, $temp_replaced);
}
else {
$html->innertext = preg_replace('/' . $term_title . '/', $replacement, $html->innertext, $configuration['only_first'] ? 1 : -1, $temp_replaced);
}
$replaced = $temp_replaced;
}
}
}
}
function _fetch_replacement($style, $term_title, $target_url) {
switch ($style) {
case 'links':
return $replacement = l($term_title, $target_url, array(
'attributes' => array(
'title' => $term_title,
'class' => 'glossify_term',
),
));
case 'hovertip':
return $replacement = '<span class="glossify_term hovertip_target" hovertip="' . $term_title . '">' . $term_title . '</span>';
case 'reference':
return $replacement = '<span class="glossify_term">' . $term_title . '</span>';
}
}
function _fetch_keywords($nid, $method = FALSE) {
$q = db_query("SELECT term, method FROM {glossify} WHERE nid = %d ORDER BY term", $nid);
$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, $language = '', $term = '', $alternate = '') {
switch ($operation) {
case 'insert':
$gnid = db_result(db_query("SELECT nid FROM {glossify} WHERE term = '%s' AND language = '%s'", $term, $language));
$new_terms = array();
if (!$gnid) {
db_query("INSERT INTO {glossify} (nid, term, language, method, alternate) VALUES (%d, '%s', '%s', '%s', '%s')", $nid, $term, $language, $method, $alternate);
$new_terms[$term] = $term;
}
else {
$node = node_load($gnid);
drupal_set_message(t("Keyword: '%term' already exists for <a href=\"/node/{$node->nid}\">%title</a>", array(
'%term' => $term,
'%title' => $node->title,
)), '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'", $term, $language, $method, $nid, 'title');
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'", $nid, $method, $language, $term);
}
else {
$q = db_query("SELECT term FROM {glossify} WHERE nid = %d AND method = '%s' ORDER BY term", $nid, $method);
while ($r = db_fetch_array($q)) {
$old_terms[$r['term']] = $r['term'];
}
db_query("DELETE FROM {glossify} WHERE nid = %d AND method = '%s'", $nid, $method);
}
return $old_terms;
break;
}
return TRUE;
}
function _fetch_affected_keywords($node, $method, $keywordsource = NULL, $override = '') {
$keywords = array();
$existing_keywords = _fetch_keywords($node->nid, $method);
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':
if (isset($node->{$keywordsource}[0]['value']) && isset($node->{$override}[0]['value'])) {
$form_keywords = !empty($node->{$keywordsource}[0]['value']) ? array_map('trim', explode(',', $node->{$keywordsource}[0]['value'])) : array();
$form_override = $node->{$override}[0]['value'];
}
else {
drupal_set_message(t("This content type does not have the selected CCK Fields attached to it!<br />You need to either change the configuration or attach the selected CCK Fields to this content type."), 'warning');
return array();
}
break;
case 'taxonomy':
if (isset($node->taxonomy['tags'][$keywordsource])) {
$form_keywords = !empty($node->taxonomy['tags'][$keywordsource]) ? array_map('trim', explode(',', $node->taxonomy['tags'][$keywordsource])) : array();
$form_override = $override;
}
else {
drupal_set_message(t("This content type does not have the selected Vocabulary attached to it!<br />You need to either change the configuration or attach the selected Vocabulary to this content type."), 'warning');
return array();
}
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, $node->language, $keyword));
}
foreach ($ikwds2 as $keyword) {
$keywords = array_merge($keywords, _keyword_table('insert', $node->nid, $method, $node->language, $keyword, $form_override));
}
}
}
}
else {
foreach ($form_keywords as $keyword) {
$keywords = array_merge($keywords, _keyword_table('insert', $node->nid, $method, $node->language, $keyword, $form_override));
}
}
}
else {
if (count($existing_keywords) > 0) {
$keywords = array_merge($keywords, _keyword_table('delete', $node->nid, $method));
}
}
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($configuration, $nid) {
$glossify_dict = array();
$methods = array(
"'title'",
);
if ($configuration['methods']['use_internal']) {
$methods[] = "'internal'";
}
if ($configuration['methods']['use_cck']) {
$methods[] = "'cck'";
}
if ($configuration['methods']['use_taxonomy']) {
$methods[] = "'taxonomy'";
}
if ($configuration['language']) {
$q = db_query("SELECT g.term, g.nid, g.alternate, g.language FROM {node} n INNER JOIN {glossify} g ON g.nid = n.nid WHERE g.language = n.language AND n.type IN (" . db_placeholders($configuration['to'], 'varchar') . ") AND g.nid != %d AND g.method IN (" . implode(', ', $methods) . ")", $configuration['to'], $nid);
}
else {
$q = db_query("SELECT g.term, g.nid, g.alternate, g.language FROM {node} n INNER JOIN {glossify} g ON g.nid = n.nid WHERE n.type IN (" . db_placeholders($configuration['to'], 'varchar') . ") AND g.nid != %d AND g.method IN (" . implode(', ', $methods) . ")", $configuration['to'], $nid);
}
while ($r = db_fetch_array($q)) {
if (!empty($r['alternate'])) {
if (is_numeric($r['alternate'])) {
$glossify_dict[$r['term']] = drupal_lookup_path('alias', 'node/' . $r['alternate'], $r['language']);
}
elseif ($path = drupal_lookup_path('alias', $r['alternate'], $r['language'])) {
$glossify_dict[$r['term']] = $path;
}
else {
$glossify_dict[$r['term']] = $r['alternate'];
}
}
else {
$glossify_dict[$r['term']] = drupal_lookup_path('alias', 'node/' . $r['nid'], $r['language']);
}
}
return $glossify_dict;
}
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', FALSE);
if ($keyword_field) {
$content_types = variable_get('glossify_glossary_content_type', array());
foreach ($content_types as $content_type) {
$table = 'content_type_' . $content_type;
$q = db_query("SELECT nid FROM {$table} WHERE 1");
while ($r = db_fetch_array($q)) {
$node = node_load($r['nid'], NULL, TRUE);
$keyword = $node->{$keyword_field};
if ($override_field == 'none') {
_keyword_table('insert', $node->nid, 'cck', $node->language, $keyword[0]['value'], '');
}
else {
$override = $node->{$override_field};
_keyword_table('insert', $node->nid, 'cck', $node->language, $keyword[0]['value'], $override[0]['value']);
}
_keyword_table('insert', $node->nid, 'title', $node->language, $node->title, '');
}
}
}
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');
}