From dc36351d8ba7eb55a64ebd3cecd304555e94dd6a Mon Sep 17 00:00:00 2001 From: willcast Date: Thu, 16 Oct 2003 22:05:00 +0000 Subject: [PATCH] Case sensitive match Whole words match No match at all (a bit rude (you have to get down to the HTML code), no GUI so far either) Categories are now linked too (I forced to be a case sensitive match) You can automatically link one or several glossaries at once no matter if it is a main one or not. --- lang/en/glossary.php | 4 + lang/en/help/glossary/casesensitive.html | 5 + lang/en/help/glossary/fullmatch.html | 5 + lang/en/help/glossary/usedynalink.html | 6 + mod/glossary/db/mysql.php | 13 ++ mod/glossary/db/mysql.sql | 4 + mod/glossary/db/postgres7.sql | 4 + mod/glossary/dynalink.php | 161 +++++++++++++---------- mod/glossary/edit.html | 61 ++++++++- mod/glossary/edit.php | 14 +- mod/glossary/lib.php | 19 +-- mod/glossary/mod.html | 19 +++ mod/glossary/showentry.php | 21 ++- mod/glossary/version.php | 2 +- 14 files changed, 242 insertions(+), 96 deletions(-) create mode 100644 lang/en/help/glossary/casesensitive.html create mode 100644 lang/en/help/glossary/fullmatch.html create mode 100644 lang/en/help/glossary/usedynalink.html diff --git a/lang/en/glossary.php b/lang/en/glossary.php index d43001b9e1..d97b5f8694 100644 --- a/lang/en/glossary.php +++ b/lang/en/glossary.php @@ -12,6 +12,7 @@ $string['areyousuredelete'] = "Are you sure you want to delete this entry?"; $string['areyousuredeletecomment'] = "Are you sure you want to delete this comment?"; $string['attachment'] = "Attachment"; $string['back'] = "Back"; +$string['casesensitive'] = "This entry is
case sensitive"; $string['categories'] = "Categories"; $string['categoryview'] = "Browse by category"; $string['category'] = "Category"; @@ -41,12 +42,14 @@ $string['entrieswithoutcategory'] = "Entries without category"; $string['entry'] = "Entry"; $string['entryalreadyexist'] = "Entry already exists"; $string['entrydeleted'] = "Entry deleted"; +$string['entryusedynalink'] = "This entry should be
automatically linked"; $string['entryexported'] = "Entry succesfully exported"; $string['explainspecial'] = "Shows entries that do not begin with a letter"; $string['explainalphabet'] = "Browse the glossary using this index"; $string['explainall'] = "Shows ALL entries on one page"; $string['exportedentry'] = "Exported entry"; $string['exporttomainglossary'] = "Export to main glossary"; +$string['fullmatch'] = "Match whole words only
(when automatically linked)"; $string['glossarytype'] = "Glossary Type"; $string['mainglossary'] = "Main glossary"; $string['modulename'] = "Glossary"; @@ -66,6 +69,7 @@ $string['showall'] = "Show 'ALL' link"; $string['special'] = "Special"; $string['standardview'] = "Browse by alphabet"; $string['studentcanpost'] = "Students can add entries"; +$string['usedynalink'] = "Link this glossary with other modules automatically"; $string['warningstudentcapost'] = "(Applies only if the glossary is not the main one)"; $string['writtenby'] = "by"; $string['youarenottheauthor'] = "You are not the author of this comment, therefore, you are not allowed to edit it."; diff --git a/lang/en/help/glossary/casesensitive.html b/lang/en/help/glossary/casesensitive.html new file mode 100644 index 0000000000..003a43e160 --- /dev/null +++ b/lang/en/help/glossary/casesensitive.html @@ -0,0 +1,5 @@ +

Case sensitive matching

+ +

This setting specify if an entry should be found with the exact case as it is in order to be automatically linked. +

Note that this flag does not limit that a concept could be contained insidee another: Use the Whole Words Matching flag instead. + diff --git a/lang/en/help/glossary/fullmatch.html b/lang/en/help/glossary/fullmatch.html new file mode 100644 index 0000000000..621c390215 --- /dev/null +++ b/lang/en/help/glossary/fullmatch.html @@ -0,0 +1,5 @@ +

Whole words matching

+ +

If you stablish that an entry could be automatically linked from other resources, then, +if you set this flag also, only those concepts which words match completelly with this entry, will be linked. +

Note that this flag does not force the match of the case. Use the Case Sensitive flag instead. \ No newline at end of file diff --git a/lang/en/help/glossary/usedynalink.html b/lang/en/help/glossary/usedynalink.html new file mode 100644 index 0000000000..a34161f3cf --- /dev/null +++ b/lang/en/help/glossary/usedynalink.html @@ -0,0 +1,6 @@ +

Linking glossaries' entries with other modules automatically

+ +

If you stablish that a glossary or an entry should be automatically linked, the entries affected will be automatically linked whenever they are found in other resources (forums, comments, etc). +

If you do not want a specific entry to be linked, you should insert it between the <nolink> and </nolink> tags in the source of the HTML. +

Also, if a category is found, it will also be linked. Note that category linking is case sensitive. + diff --git a/mod/glossary/db/mysql.php b/mod/glossary/db/mysql.php index ac24cb0a97..9711921670 100644 --- a/mod/glossary/db/mysql.php +++ b/mod/glossary/db/mysql.php @@ -91,6 +91,19 @@ function glossary_upgrade($oldversion) { execute_sql(" INSERT INTO {$CFG->prefix}log_display VALUES ('glossary', 'delete comment', 'glossary', 'name') "); } + if ( $oldversion < 2003101600 ) { + execute_sql( "ALTER TABLE `{$CFG->prefix}glossary` " . + "ADD `usedynalink` TINYINT(2) UNSIGNED NOT NULL DEFAULT '1' AFTER `allowcomments` " ); + + execute_sql( "ALTER TABLE `{$CFG->prefix}glossary_entries` " . + "ADD `usedynalink` TINYINT(2) UNSIGNED NOT NULL DEFAULT '1' AFTER `sourceglossaryid`, ". + "ADD `casesensitive` TINYINT(2) UNSIGNED NOT NULL DEFAULT '0' AFTER `usedynalink` "); + } + + if ( $oldversion < 2003101601 ) { + execute_sql( "ALTER TABLE `{$CFG->prefix}glossary_entries` " . + "ADD `fullmatch` TINYINT(2) UNSIGNED NOT NULL DEFAULT '1' AFTER `casesensitive` "); + } return true; } diff --git a/mod/glossary/db/mysql.sql b/mod/glossary/db/mysql.sql index e7d3696045..8f58e8ae4d 100644 --- a/mod/glossary/db/mysql.sql +++ b/mod/glossary/db/mysql.sql @@ -21,6 +21,7 @@ CREATE TABLE prefix_glossary ( showalphabet tinyint(2) unsigned NOT NULL default '1', showall tinyint(2) unsigned NOT NULL default '1', allowcomments tinyint(2) unsigned NOT NULL default '0', + usedynalink tinyint(2) unsigned NOT NULL default '1', timecreated int(10) unsigned NOT NULL default '0', timemodified int(10) unsigned NOT NULL default '0', PRIMARY KEY (id) @@ -42,6 +43,9 @@ CREATE TABLE prefix_glossary_entries ( timemodified int(10) unsigned NOT NULL default '0', teacherentry tinyint(2) unsigned NOT NULL default '0', sourceglossaryid int(10) unsigned NOT NULL default '0', + usedynalink tinyint(2) unsigned NOT NULL default '1', + casesensitive tinyint(2) unsigned NOT NULL default '0', + fullmatch tinyint(2) unsigned NOT NULL default '1', PRIMARY KEY (id) ) TYPE=MyISAM COMMENT='all glossary entries'; diff --git a/mod/glossary/db/postgres7.sql b/mod/glossary/db/postgres7.sql index 310a4ca3d5..0f45bdd21c 100644 --- a/mod/glossary/db/postgres7.sql +++ b/mod/glossary/db/postgres7.sql @@ -21,6 +21,7 @@ CREATE TABLE prefix_glossary ( showalphabet int2 NOT NULL default '1', showall int2 NOT NULL default '1', allowcomments int2 NOT NULL default '0', + usedynalink int2 NOT NULL default '1', timecreated int4 NOT NULL default '0', timemodified int4 NOT NULL default '0', PRIMARY KEY (id) @@ -42,6 +43,9 @@ CREATE TABLE prefix_glossary_entries ( timemodified int4 NOT NULL default '0', teacherentry int2 NOT NULL default '0', sourceglossaryid int4 NOT NULL default '0', + usedynalink int2 NOT NULL default '1', + casesensitive int2 NOT NULL default '0', + fullmatch tinyint(2) NOT NULL default '1', PRIMARY KEY(id) ); diff --git a/mod/glossary/dynalink.php b/mod/glossary/dynalink.php index 388608a21d..65f8656a46 100644 --- a/mod/glossary/dynalink.php +++ b/mod/glossary/dynalink.php @@ -1,92 +1,114 @@ id != $glossaryid ) { // ...and the specified glossary is different from the previous call - $permissiongranted = 1; - } - } else { - $permissiongranted = 1; // if it is the first call and a glossary was specify + + $glossarieslist = get_records_select("glossary", "usedynalink = 1 and course = $courseid","id"); + if ( $glossarieslist ) { + $glossaries = ""; + foreach ( $glossarieslist as $glossary ) { + $glossaries .= "$glossary->id,"; } - } - if ( $permissiongranted ) { - if ( !$glossaryid ) { // If no glossary was specify, fetch the main glossary of the course - $glossary = get_record("glossary","course",$courseid,"mainglossary",1); - } else { // if a glossary as specify, fetch this one - $glossary = get_record("glossary","course",$courseid,"id",$glossaryid); + $glossaries=substr($glossaries,0,-1); + + $entries = get_records_select("glossary_entries", "glossaryid IN ($glossaries) AND usedynalink = 1","glossaryid","id,glossaryid,concept,casesensitive,".GLOSSARY_CONCEPT_IS_ENTRY." category,fullmatch"); + $categories = get_records_select("glossary_categories", "glossaryid IN ($glossaries)", "glossaryid,id","id,glossaryid,name concept, 1 casesensitive,".GLOSSARY_CONCEPT_IS_CATEGORY." category, 1 fullmatch"); + if ( $entries and $categories ) { + $concepts = array_merge($entries, $categories); + } elseif ( $categories ) { + $concepts = $categories; + } elseif ( $entries ) { + $concepts = $entries; } - } - if ( $glossary ) { - if ( !$entries ) { - // char_lenght is compatible with PostgreSQL and MySQL. Other DBMS must be implemented - - /* I'm ordering the cursor by the lenght of the concept trying to avoid the bug that occurs - when a concept in contained in other entry's concept (i.e. HOUSE is in DOLL HOUSE). - However, I haven't find a solution yet. - Will (Sept. 30, 2003) - */ - if ($CFG->dbtype == "postgres7" or $CFG->dbtype == "mysql") { - $ORDER_BY = "CHAR_LENGTH(concept) DESC"; - } else { - $ORDER_BY = "concept ASC"; - } - $ownentries = get_records("glossary_entries", "glossaryid", $glossary->id,$ORDER_BY); - $importedentries = get_records("glossary_entries", "sourceglossaryid", $glossary->id,$ORDER_BY); + if ( $concepts ) { + $lastglossary = 0; + $lastcategory = 0; + foreach ( $concepts as $concept ) { + if ( $lastglossary != $concept->glossaryid ) { + $glossary = get_record("glossary","id",$concept->glossaryid); + $lastglossary = $glossary->id; + } - if ( $ownentries and $importedentries ) { - $entries = array_merge($ownentries, $importedentries); - usort($entries, glossary_sort_entries_by_lenght); - } elseif ( $importedentries ) { - $entries = $importedentries; - } elseif ( $ownentries ) { - $entries = $ownentries; - } - } - if ( $entries ) { - foreach ( $entries as $entry ) { - $title = strip_tags("$glossary->name: $entry->concept"); - $href_tag_begin = "wwwroot/mod/glossary/showentry.php?courseid=$courseid&concept=$entry->concept\" ". - "onClick=\"return openpopup('/mod/glossary/showentry.php?courseid=$courseid\&concept=$entry->concept', 'entry', 'menubar=0,location=0,scrollbars,resizable,width=600,height=450', 0);\">"; + if ( $concept->category ) { + if ( $lastcategory != $concept->id ) { + $category = get_record("glossary_categories","id",$concept->id); + $lastcategory = $concept->id; + } - $concept = trim(strip_tags($entry->concept)); + $title = strip_tags("$glossary->name: " . get_string("category","glossary"). " $category->name"); + $href_tag_begin = "wwwroot/mod/glossary/view.php?id=182¤tview=categories&cat=$concept->id\">"; + } else { + $title = strip_tags("$glossary->name: $concept->concept"); + $href_tag_begin = "wwwroot/mod/glossary/showentry.php?courseid=$courseid&concept=$concept->concept\" ". + "onClick=\"return openpopup('/mod/glossary/showentry.php?courseid=$courseid\&concept=$concept->concept', 'entry', 'menubar=0,location=0,scrollbars,resizable,width=600,height=450', 0);\">"; + } - $text = glossary_link_concepts($text,$concept,$href_tag_begin, ""); + $currentconcept = trim(strip_tags($concept->concept)); + $text = glossary_link_concepts($text,$currentconcept,$href_tag_begin, "",$concept->casesensitive,$concept->fullmatch); } } } - return $text; } - function glossary_link_concepts($text,$concept,$href_tag_begin,$href_tag_end = "") { + function glossary_link_concepts($text,$concept,$href_tag_begin,$href_tag_end = "",$casesensitive,$fullmatch) { $list_of_words_cp = $concept; - // getting ride of "A" tags - $final = array(); + if ($list_of_words_cp{0}=="|") { + $list_of_words_cp{0} = ""; + } + if ($list_of_words_cp{strlen($list_of_words_cp)-1}=="|") { + $list_of_words_cp{strlen($list_of_words_cp)-1}=""; + } + $list_of_words_cp = trim($list_of_words_cp); + if ($fullmatch) { + $invalidprefixs = "([a-zA-Z0-9])"; + $invalidsufixs = "([a-zA-Z0-9])"; + // getting ride of words or phrases that containg the pivot concept on it + $words = array(); + $regexp = '/' . $invalidprefixs . "(" . $list_of_words_cp . ")" . "|" . "(" . $list_of_words_cp . ")". $invalidsufixs . '/is'; + preg_match_all($regexp,$text,$list_of_words); + + foreach (array_unique($list_of_words[0]) as $key=>$value) { + $words['<*'.$key.'*>'] = $value; + } + if ( $words ) { + $text = str_replace($words,array_keys($words),$text); + } + } + + // getting ride of "nolink" tags + $excludes = array(); + preg_match_all('/(.+?)<\/nolink>/is',$text,$list_of_excludes); + foreach (array_unique($list_of_excludes[0]) as $key=>$value) { + $excludes['<+'.$key.'+>'] = $value; + } + if ( $excludes ) { + $text = str_replace($excludes,array_keys($excludes),$text); + } + + // getting ride of "A" tags + $links = array(); preg_match_all('/(.+?)<\/A>/is',$text,$list_of_links); foreach (array_unique($list_of_links[0]) as $key=>$value) { - $links['<|*'.$key.'*|>'] = $value; + $links['<@'.$key.'@>'] = $value; } - if ( $links ) { + if ( $links ) { $text = str_replace($links,array_keys($links),$text); } - // getting ride of all other tahs + // getting ride of all other tags $final = array(); preg_match_all('/<(.+?)>/is',$text,$list_of_words); @@ -96,19 +118,22 @@ $text = str_replace($final,array_keys($final),$text); - if ($list_of_words_cp{0}=="|") { - $list_of_words_cp{0} = ""; - } - if ($list_of_words_cp{strlen($list_of_words_cp)-1}=="|") { - $list_of_words_cp{strlen($list_of_words_cp)-1}=""; + $list_of_words_cp = "(".$list_of_words_cp."$nocharsend)"; + if ( $casesensitive ) { + $text = ereg_replace("$list_of_words_cp", "$href_tag_begin"."\\1"."$href_tag_end", $text); + } else { + $text = eregi_replace("$list_of_words_cp", "$href_tag_begin"."\\1"."$href_tag_end", $text); } - $list_of_words_cp = "(".trim($list_of_words_cp).")"; - - $text = eregi_replace("$list_of_words_cp", "$href_tag_begin"."\\1"."$href_tag_end", $text); $text = str_replace(array_keys($final),$final,$text); - if ( $links ) { + if ( $links ) { $text = str_replace(array_keys($links),$links,$text); } + if ( $excludes ) { + $text = str_replace(array_keys($excludes),$excludes,$text); + } + if ( $words and $fullmatch ) { + $text = str_replace(array_keys($words),$words,$text); + } return stripslashes($text); } diff --git a/mod/glossary/edit.html b/mod/glossary/edit.html index 1324a230fe..111e3f13c7 100644 --- a/mod/glossary/edit.html +++ b/mod/glossary/edit.html @@ -17,7 +17,7 @@ id); echo " + +

:

+ + + + + +

:

+ + + + + +

:

+ + + +

:

@@ -99,7 +156,7 @@ diff --git a/mod/glossary/edit.php b/mod/glossary/edit.php index e2a936f473..cb4b690663 100644 --- a/mod/glossary/edit.php +++ b/mod/glossary/edit.php @@ -54,13 +54,16 @@ if ($e) { $newentry->concept = $form->concept; $newentry->definition = $form->text; $newentry->format = $form->format; + $newentry->usedynalink = $form->usedynalink; + $newentry->casesensitive = $form->casesensitive; + $newentry->fullmatch = $form->fullmatch; $newentry->timemodified = time(); $newentry->teacherentry = isteacher($course->id,$USER->id); $permissiongranted = 1; if ( !$glossary->allowduplicatedentries ) { - $dupentries = get_records("glossary_entries","UCASE(concept)", strtoupper($newentry->concept)); - if ($dupentries) { + $dupentries = get_records("glossary_entries","UCASE(concept)", strtoupper($newentry->concept)); + if ($dupentries) { foreach ($dupentries as $curentry) { if ( $glossary->id == $curentry->glossaryid ) { if ( $curentry->id != $entry ) { @@ -68,7 +71,7 @@ if ($e) { } } } - } + } } if ( $permissiongranted ) { $newentry->attachment = $_FILES["attachment"]; @@ -93,6 +96,9 @@ if ($e) { $newentry->definition = $form->text; $newentry->format = $form->format; $newentry->timecreated = time(); + $newentry->usedynalink = $form->usedynalink; + $newentry->casesensitive = $form->casesensitive; + $newentry->fullmatch = $form->fullmatch; $newentry->timemodified = time(); $newentry->teacherentry = isteacher($course->id,$USER->id); $newentry->sourceglossaryid = 0; @@ -159,7 +165,7 @@ if (empty($entry)) { $entry->format = $defaultformat; } -print_header("$course->shortname: $glossary->name", "$course->fullname", +print_header(strip_tags("$course->shortname: $glossary->name"), "$course->fullname", "
wwwroot/course/view.php?id=$course->id\">$course->shortname -> id\">$strglossaries -> id\">$glossary->name -> $stredit", "theform.text", diff --git a/mod/glossary/lib.php b/mod/glossary/lib.php index c810c8dcab..a947486343 100644 --- a/mod/glossary/lib.php +++ b/mod/glossary/lib.php @@ -235,18 +235,19 @@ function glossary_print_entry_icons($course, $cm, $glossary, $entry,$currentview $isteacher = isteacher($course->id); $ismainglossary = $glossary->mainglossary; - echo ""; - - if ( $glossary->allowcomments ) { - echo "
"; - $count = count_records("glossary_comments","entryid",$entry->id); + echo ""; + echo " + + + + diff --git a/mod/glossary/showentry.php b/mod/glossary/showentry.php index 112717f386..0b36d94f25 100644 --- a/mod/glossary/showentry.php +++ b/mod/glossary/showentry.php @@ -22,21 +22,18 @@ echo ""; diff --git a/mod/glossary/version.php b/mod/glossary/version.php index 1f92564c72..61eaf7cd92 100644 --- a/mod/glossary/version.php +++ b/mod/glossary/version.php @@ -5,7 +5,7 @@ /// This fragment is called by moodle_needs_upgrading() and /admin/index.php ///////////////////////////////////////////////////////////////////////////////// -$module->version = 2003101501; // The current module version (Date: YYYYMMDDXX) +$module->version = 2003101601; // The current module version (Date: YYYYMMDDXX) $module->cron = 0; // Period for cron to check this module (secs) $release = "0.5 development"; // User-friendly version number -- 2.39.5
"; + $count = count_records("glossary_comments","entryid",$entry->id); + if ( $count ) { echo "id&eid=$entry->id\">$count " . get_string("comments","glossary") . ""; - echo ""; + } + echo ""; + + echo ""; + if ( $glossary->allowcomments ) { echo "id&eid=$entry->id\">\"" "; - } else { - echo ""; } - + if ($isteacher or $glossary->studentcanpost and $entry->userid == $USER->id) { // only teachers can export entries so check it out diff --git a/mod/glossary/mod.html b/mod/glossary/mod.html index 3da3f7ab59..f9edca29d3 100644 --- a/mod/glossary/mod.html +++ b/mod/glossary/mod.html @@ -112,6 +112,25 @@ if (!$mainglossary or $mainglossary->id == $form->instance ) {

:

+ +

"; if ( $entries ) { foreach ( $entries as $entry ) { - if( $ConceptIsPrinted ) { - echo "
"; + + if (! $glossary = get_record("glossary", "id", $entry->glossaryid)) { + error("Glossary ID was incorrect or no longer exists"); } - if ( !$ConceptIsPrinted ) { - echo "" . $entry->concept . ":
"; - $ConceptIsPrinted = 1; + if (! $course = get_record("course", "id", $glossary->course)) { + error("Glossary is misconfigured - don't know what course it's from"); } - - if ($entry->attachment) { - $entry->course = $courseid; - echo "
"; - echo glossary_print_attachments($entry,"html"); - echo "
"; + if (!$cm = get_coursemodule_from_instance("glossary", $entry->glossaryid, $courseid) ) { + error("Glossary is misconfigured - don't know what course module it is "); } - echo format_text($entry->definition, $entry->format); + + glossary_print_entry($course, $cm, $glossary, $entry); } } echo "