Index: glossify.module
===================================================================
--- glossify.module	(revision 3815)
+++ glossify.module	(working copy)
@@ -1,8 +1,8 @@
 <?php
 // $Id: glossify.module,v 1.1.2.23 2010/02/23 11:37:18 rsvelko Exp $
- 
 
 
+
 /**
  * Implementation of hook_menu().
  */
@@ -25,38 +25,35 @@
  */
 
 function _glossify_build_dictionary_of_link_to_terms() {
-  global $glossify_dict;
-  global $glossify_dict_titles;
+  static $glossify_dict;
+  static $glossify_dict_titles;
 
-  if (!empty($glossify_dict) ) { return; }
+  if (!empty($glossify_dict) ) { return array($glossify_dict, $glossify_dict_titles); }
 
   $content_types_that_give_terms = variable_get('glossify_glossary_content_type', NULL);
-  
+
   // return if no nodetypes that hold terms
   if (!isset($content_types_that_give_terms)) {
     return;
   }
 
-  
+
   // build WHERE clause
   foreach ($content_types_that_give_terms as $type) {
-    $clause_parts[] = "type='$type' ";
-    $clause_parts_with_name[] = "type_name='$type' ";
+    $clause_parts[] = "type='" . db_escape_string($type) ."' ";
+    $clause_parts_with_name[] = "type_name='" . db_escape_string($type) . "' ";
   }
-  
-  $where_clause = implode(' OR ', $clause_parts);
+
+  $where_clause = 'status > 0 AND ' . implode(' OR ', $clause_parts);
   $where_clause_with_name = implode(' OR ', $clause_parts_with_name);
   // WHERE clause ready
-  
-  
-  
-  
-  
+
+
   // for target cck field
   $field_name_for_the_target = variable_get('glossify_use_this_cck_field_for_target_url_override', 'none');
   $field_name_for_the_target_name_of_the_value_column = $field_name_for_the_target . "_value";
-  
-  
+
+
   if ($field_name_for_the_target != 'none' ) {
    $target_vals_table_name = __glossify_get_val_table_from_cck_field_name($field_name_for_the_target);
   }
@@ -66,7 +63,7 @@
   while ($obj_3 = db_fetch_object($result_3)) {
     $nid = $obj_3->nid;
 
-    
+
     if ( $field_name_for_the_target != 'none'  ) {
       $result_2 = db_query("
         SELECT vals_table.vid, vals_table.nid, vals_table.%s FROM {" . $target_vals_table_name . "} vals_table
@@ -75,7 +72,7 @@
         WHERE %s IS NOT NULL
           AND vals_table.nid = %d
       ", $field_name_for_the_target_name_of_the_value_column, $field_name_for_the_target_name_of_the_value_column, $nid);
-    
+
       if ($obj_2 = db_fetch_object($result_2) ) {
         $target = $obj_2->{$field_name_for_the_target_name_of_the_value_column};
       }
@@ -87,32 +84,27 @@
     else {
       $target = 'node/' . $nid;
     }
-    
-    
+
+
     $glossify_dict[$obj_3->title] = $target;
   }
 
   $synonyms_dict = glossify_get_synonyms();
-  
+
   if (!empty($synonyms_dict)) {
     foreach ($synonyms_dict as $title => $target_url ) {
       $glossify_dict[$title] = $target_url;
     }
   }
-  
 
-  
-  
-  
   // sort the array by string length - long strings first
   if (!empty($glossify_dict) ) {
     uksort($glossify_dict, "__glossify_sort_array_by_keys_string_length_cmp");
     $glossify_dict_titles = array_keys($glossify_dict);
   }
 
-  
   //print_r($glossify_dict);
-  
+  return array($glossify_dict, $glossify_dict_titles);
 }
 
 
@@ -122,31 +114,12 @@
   // otidi vyv f ins i vzemi vsi4ki gloss inst
   // ako e samo 1 - tyrsi gloss vals v node_ctype
   // ako sa pove4e - vyv content_field_gloss
-  $how_many_cck_instances_we_have =
-    db_result(db_query("SELECT COUNT(*) FROM {content_node_field_instance} WHERE field_name = '%s' ",
-    $field_name));
-  
-  $result = db_query("SELECT type_name FROM {content_node_field_instance} WHERE field_name = '%s' ",
-    $field_name);
-  while ( $obj = db_fetch_object($result) ) {
-    $cck_types_that_have_this_field[] = $obj->type_name;
-  }
-    
-    
-  if (    $how_many_cck_instances_we_have == "0") {
-    // some warning?
-  }
-  elseif ($how_many_cck_instances_we_have == "1") {
-    // look into the type table
-    $vals_table_name = "content_type_" . $cck_types_that_have_this_field[0];
-  }
-  // look into content_field_glossify_synonyms for example
-  else {
-    $vals_table_name = "content_" . $field_name;
-  }
 
-  return $vals_table_name;
-  
+  // omerida - use cck APi to figure this out, handles case where one
+  //           content type is using a multi-value field.
+  $field = content_fields($field_name);
+  $db_info = content_database_info($field);
+  return $db_info['table'];
 }
 
 
@@ -157,37 +130,36 @@
   //$glossify_dict['turpis'] = "5";
   // get synonyms from nodes
   $field_name_for_the_synonyms = variable_get('glossify_use_this_cck_field_for_keyword_synonyms', 'none');
-  
+
   if ( $field_name_for_the_synonyms == 'none' ) {return array(); }
-  
+
   $field_name_for_the_synonyms_name_of_the_value_column = $field_name_for_the_synonyms . "_value";
-  
+
   $syn_vals_table_name = __glossify_get_val_table_from_cck_field_name($field_name_for_the_synonyms);
 
   // for target cck field
   $field_name_for_the_target = variable_get('glossify_use_this_cck_field_for_target_url_override', '');
   $field_name_for_the_target_name_of_the_value_column = $field_name_for_the_target . "_value";
-  
+
   if ( $field_name_for_the_target != 'none'  ) {
     $target_vals_table_name = __glossify_get_val_table_from_cck_field_name($field_name_for_the_target);
   }
-  
-  
+
   $result = db_query("
     SELECT vals_table.vid, vals_table.nid, vals_table.%s FROM {" . $syn_vals_table_name . "} vals_table
     JOIN {node} node
-      ON vals_table.vid = node.vid
+      ON (node.status > 0 AND vals_table.vid = node.vid)
     WHERE %s IS NOT NULL
   ", $field_name_for_the_synonyms_name_of_the_value_column, $field_name_for_the_synonyms_name_of_the_value_column );
-  
+
   while ( $obj = db_fetch_object($result) ) {
     $cck_vals = explode(",", $obj->{$field_name_for_the_synonyms_name_of_the_value_column} );
     $nid = $obj->nid;
-    
+
     if (!empty($cck_vals) ) {
-      
+
       if ( $field_name_for_the_target != 'none' ) {
-      
+
         $result_2 = db_query("
           SELECT vals_table.vid, vals_table.nid, vals_table.%s FROM {" . $target_vals_table_name . "} vals_table
           JOIN {node} node
@@ -195,7 +167,7 @@
           WHERE %s IS NOT NULL
             AND vals_table.nid = %d
         ", $field_name_for_the_target_name_of_the_value_column, $field_name_for_the_target_name_of_the_value_column, $nid);
-  
+
         if ($obj_2 = db_fetch_object($result_2) ) {
           $target = $obj_2->{$field_name_for_the_target_name_of_the_value_column};
         }
@@ -203,12 +175,12 @@
         else {
           $target = 'node/' . $nid;
         }
-      
+
       }
       else {
         $target = 'node/' . $nid;
       }
-      
+
       foreach ($cck_vals as $val) {
         $val_trimmed = trim($val, " ");
         // now we have the keywords
@@ -218,7 +190,7 @@
     }
   }
   //drupal_set_message("<pre>" . print_r($syn_dict, true));
-  
+
   return $syn_dict;
 }
 
@@ -227,12 +199,9 @@
  */
 function glossify_init() {
 
-  _glossify_build_dictionary_of_link_to_terms();
+  //_glossify_build_dictionary_of_link_to_terms();
 
-  global $glossify_style;
-  $glossify_style = variable_get('glossify_style', 'links');
-
-  // add css only on pages that will be parsed
+// add css only on pages that will be parsed
 // TODO add it only if at least one reason (page/teaser)
 //  drupal_add_css(drupal_get_path('module', 'glossify') . '/glossify.css');
 }
@@ -262,21 +231,23 @@
   $node_nid    = $node->nid;
   $node_body   = $node->body;
   //$node_body   = $node->content['body']['#value'];
-  
+
   $node_teaser = $node->teaser;
   //$node_teaser = $node->content['teaser']['#value'];
-  
 
+
   switch ($op) {
 
     case 'alter':
-      if (variable_get('glossify_display_parsing_time_for_performance_debugging', FALSE) ) {$time = __glossify_timer_start(); }
+      if (variable_get('glossify_display_parsing_time_for_performance_debugging', FALSE) ) {
+        $time = __glossify_timer_start();
+      }
 
       // parse teaser
       if (variable_get('glossify_teaser', TRUE) && $a3 == 1 ) { // $a3 == 1 means it is a teaser we are parsing
-        global $glossify_style;
-        global $glossify_dict;
-        global $glossify_dict_titles;
+        $glossify_style = _get_glossify_style();
+        list($glossify_dict, $glossify_dict_titles) = _glossify_build_dictionary_of_link_to_terms();
+
         $replacements = __glossify_build_replacements($glossify_style, $glossify_dict, $node_nid);
 
         $node->teaser = __glossify_parse_html_text_and_replace_terms_safely($node_teaser, $glossify_dict_titles, $replacements);
@@ -284,30 +255,31 @@
       }
 
       if ( $a4 == 1 ) {      // render the page's body
-        global $glossify_style;
-        global $glossify_dict;
-        global $glossify_dict_titles;
+        $glossify_style = _get_glossify_style();
+        list($glossify_dict, $glossify_dict_titles) = _glossify_build_dictionary_of_link_to_terms();
         $replacements = __glossify_build_replacements($glossify_style, $glossify_dict, $node_nid);
 
         $node->body = __glossify_parse_html_text_and_replace_terms_safely($node_body, $glossify_dict_titles,  $replacements);
       }
-      if (variable_get('glossify_display_parsing_time_for_performance_debugging', FALSE) ) {__glossify_timer_stop($time); }
+      if (variable_get('glossify_display_parsing_time_for_performance_debugging', FALSE)) {
+        __glossify_timer_stop($time);
+      }
 
     break; // done with $op = 'alter'
 
     case 'view': // used for reference section display
 
-      global $glossify_style;
+      $glossify_style = _get_glossify_style();
 
       switch ($glossify_style) {
 
         case 'links':
           break;
-        
+
         case 'reference':
 
-          global $glossify_dict;
-  
+          list($glossify_dict, $glossify_dict_titles) = _glossify_build_dictionary_of_link_to_terms();
+
           foreach ($glossify_dict as $term_title => $term_nid) {
 
             //TODO: this is slow but right! make it fast by saving the found terms from the replacing func
@@ -316,14 +288,14 @@
               $term_definition_list .= theme('glossify_term', $term_nid, $glossify_style);
             } // endif found a term to glossify
           } // endforeach looping through terms
-        
+
         case 'hovertip':
         default:
 
-          global $glossify_dict;
+          list($glossify_dict, $glossify_dict_titles) = _glossify_build_dictionary_of_link_to_terms();
 
           foreach ($glossify_dict as $term_title => $term_nid) {
-      
+
             //TODO: this is slow but right! make it fast by saving the found terms from the replacing func
             //        if (__glossify_tell_whether_term_is_present_somewhere_in_the_html_plaintext($node_body, $term_title) ) {
             if (preg_match('/' . preg_quote($term_title, '/') . '/', $node_body)) {
@@ -336,10 +308,10 @@
           } // endforeach looping through terms
 
           break;
-            
+
       } // endswitch glossify style
-    
-    
+
+
       // make reference section under the node
       if ($glossify_style == 'reference') {
         $node->content['glossify'] = array(
@@ -347,9 +319,9 @@
           '#value'  => theme('glossify_reference_section', $term_definition_list),
           );
       } // endif make reference section
-    
+
       break; // break case view op
-    
+
   } // endswitch $op
 } // endfunction glossify_nodeapi
 
@@ -370,7 +342,7 @@
     // else
     $haystack = substr_replace($haystack, $replacements[$i], $pos, strlen($needle_el));
   }
-  
+
   return $haystack;
 }
 
@@ -412,7 +384,7 @@
     }
 
       $haystack = preg_replace( __glossify_convert_string_array_to_array_of_escaped_regexps($needles), $replacements, $haystack, $number_of_replacements);
-  
+
   }
   else { // uses str_replace for performance
 
@@ -427,10 +399,10 @@
       // str replace with array args
       $haystack = str_replace($needles, $replacements, $haystack);
     }
-  
+
   }
-  
 
+
 // escape again the htmlentities - useful for non autolinked characters - so they are returned to their previous html-entities-state
 // (autolinked chars are whatever the link-to titles/strings are ...)
   $haystack = htmlentities($haystack, ENT_COMPAT, "UTF-8");
@@ -447,7 +419,7 @@
   // Load HTML from a string
   $html_obj->load($input_html);
 
-  
+
   // escape a tags - phase 1
   $i=-1;
   foreach ($html_obj->find('a') as $obj) {
@@ -459,9 +431,9 @@
     // the actual escaping happens
     $obj->outertext          = $a_marker;
   }
-  
 
-  
+
+
   // implode-explode all-in-one-go parsing
   // 1. stick together
   $glue = "[_p__p_]";
@@ -469,7 +441,7 @@
 
   // escape replacements - so that link-to-places that are substring of other ltp-s do not cause...
   // the a-tag into a-tag situation
-  
+
    // escape replacements
   $i=-1;
   foreach ($replacements as $replacement) {
@@ -480,23 +452,23 @@
     $repl_unescaped[$i] = $replacement;
     // the actual escaping happens just below
   }
-  
+
   // do string or preg replace - only 1st OR all occurencies - all depends on the settings of the module
   $plain_text_string = __glossify_replace($glossary_terms_search_for, $repl_markers, $plain_text_string);
-  
+
   //unescape replacements
   $plain_text_string = str_replace($repl_markers, $repl_unescaped, $plain_text_string);
-  
+
   $plain_text_objects_array = explode($glue, $plain_text_string);
-  
+
   $i = -1;
   foreach ($html_obj->find('text') as $plain_text_obj ) {
     $i++;
     $plain_text_obj->outertext = $plain_text_objects_array[$i] ;
-  
+
   } // end foreach plaintext chunk
 
-  
+
   // convert obj to string
   $html_obj_string = $html_obj->save();
 
@@ -519,12 +491,12 @@
 
   // look only in plaintext html parts - ommit inside html tags - like in <a here> </here>
   foreach ($html_obj->find('text') as $plain_text_obj ) {
-      if (strstr($plain_text_obj->outertext, $term_title) !== FALSE ) {
-        $html_obj->clear();
-        return TRUE;
-      }
+    if (strstr($plain_text_obj->outertext, $term_title) !== FALSE ) {
+      $html_obj->clear();
+      return TRUE;
+    }
   } // end foreach plaintext chunk
-  
+
   return FALSE;
 }
 
@@ -532,7 +504,7 @@
 function __glossify_sort_array_by_keys_string_length_cmp($str1, $str2) {
   $strlen_1 = strlen($str1);
   $strlen_2 = strlen($str2);
-  
+
   if ($strlen_1 == $strlen_2 ) {
     return 0;
   }
@@ -547,7 +519,7 @@
   $node_title = $node->title;
 
   foreach ($glossary_terms as $term_title => $target_url) {
-  
+
     // TODO self-linking improve it for synonyms too
     // don't link to myself - just replace the term with itself (without a link - just string)
     if ( $term_title == $node_title ) {
@@ -555,13 +527,13 @@
     } // next loop
 
     switch ($glossify_style) {
-      
+
       case 'links':
         // TODO a title custom
         $replacements[] = l($term_title, $target_url,
           array('attributes' => array('title' => $term_title, 'class' => 'glossify_term')));
       break;
-    
+
       case 'reference':
         $replacements[] = '<span class="glossify_term">' . $term_title . '</span>';
       break;
@@ -573,7 +545,7 @@
       break;
     } // endswitch glossify style
   }// end foreach term
-  
+
   return $replacements;
 
 } // end func __glossify_build_replacements
@@ -596,17 +568,17 @@
  * Form builder for administrative settings.
  */
 function glossify_admin_settings() {
-  
+
   if (!module_exists("content")) {
     $form['glossify_enable_cck_please'] = array(
       '#type' => 'checkbox',
       '#title' => t('(Dummy checkbox) Please download and enable the module "content" which is the core <a href="http://drupal.org/project/cck">CCK</a> module.'),
       '#default_value' => "",
     );
-    
+
   }
   else {
-    
+
     $form['glossify_content_types_to_search'] = array(
       '#type' => 'select',
       '#title' => t('"Link-FROM" content types - We look for keywords into their text and replace them with links'),
@@ -614,7 +586,7 @@
       '#options' => node_get_types('names'),
       '#default_value' => variable_get('glossify_content_types_to_search', ''),
     );
-    
+
     $form['glossify_glossary_content_type'] = array(
       '#type' => 'select',
       '#title' => t('"Link-TO" content types. (node-title = keyword)'),
@@ -622,20 +594,20 @@
       '#options' => node_get_types('names'),
       '#default_value' => variable_get('glossify_glossary_content_type', ''),
       );
-      
+
     $form['glossify_link_first_only'] = array(
       '#type' => 'checkbox',
       '#title' => t('Only link first occurance of term. On by default. If unchecked all occurences are replaced.'),
       '#default_value' => variable_get('glossify_link_first_only', TRUE),
     );
-  
+
     $form['glossify_do_we_need_unicode_compatibility'] = array(
       '#type' => 'checkbox',
       '#title' => t('Do we need Unicode compatibility?. Check this if you need Unicode support. If not checked, non-latin words would not get autolinked.<br>
                      If you get php warnings with this setting=On - then please update/fix your PCRE PHP-library.'),
       '#default_value' => variable_get('glossify_do_we_need_unicode_compatibility', TRUE),
     );
-  
+
     $form['glossify_teaser'] = array(
       '#type' => 'checkbox',
       '#title' => t('Link content in teaser'),
@@ -652,28 +624,28 @@
       '#default_value' => variable_get('glossify_style', 'hovertip'),
       '#description' => t('How the glossary should be styled. Note: "hovertip" style requires hovertip.module. If you choose anything other than links - it should work but for now it is untested territory - feedback welcome.'),
     );
-  
-    
+
+
     $form['glossify_dont_break_words'] = array(
       '#type' => 'checkbox',
       '#title' => t('Check this to NOT break words. This means that the keyword "bla" will not linkify the bla-part of "blade". We use this regexp to make this work: "/\b$keyword_term\b/".'),
       '#default_value' => variable_get('glossify_dont_break_words', TRUE),
     );
-  
-  
+
+
     $form['glossify_display_parsing_time_for_performance_debugging'] = array(
       '#type' => 'checkbox',
       '#title' => t('Show a small debug timer at top of glossify-parsed pages. Off by default.'),
       '#default_value' => variable_get('glossify_display_parsing_time_for_performance_debugging', FALSE),
     );
-  
+
     //
-    
+
     foreach (array_keys(content_fields()) as $key ) {
       $all_cck_field_names[$key] = $key;
     }
     $all_cck_field_names['none'] = 'none';
-    
+
     $form['glossify_use_this_cck_field_for_keyword_synonyms'] = array(
       '#type' => 'select',
       '#title' => t("CCK field to look into for synonyms of the node's title. For more than 1 content type - use the same cck field please."),
@@ -681,7 +653,7 @@
       '#default_value' => variable_get('glossify_use_this_cck_field_for_keyword_synonyms', 'none'),
       '#description' => t('Select a CCK field for synonyms.'),
     );
-  
+
     $form['glossify_use_this_cck_field_for_target_url_override'] = array(
       '#type' => 'select',
       '#title' => t("CCK field to look into for a 'target url override'. For more than 1 content type - use the same cck field please."),
@@ -690,7 +662,7 @@
       '#description' => t("Select a CCK field for target override.  After you create the cck field and then put something into it
         Example: 'node/34', 'url_alias', 'http://example.com/path' this will make the target url point to your override path."),
     );
-    
+
   }
   // system_settings_form: Add default buttons to a form and set its prefix.
   // then return it to the page callback of the menu (drupal_get_form)
@@ -759,3 +731,13 @@
   return $output;
 }
 
+function _get_glossify_style() {
+  static $glossify_style;
+
+  if (!isset($glossify_style)) {
+    $glossify_style = variable_get('glossify_style', 'links');
+  }
+
+  return $glossify_style;
+}
+
