sub matchUser {
# Find all db entries related to user
# while looking through all db items
# parsedbstring
# if user answer
# get linked question
# parse the question
# push question into final data structure: @matchQuestionsAndAnswers
# if user note
# add to array of notes @notes
# add notesto final data structure
while (($key, $val) = each %hash){
parseDatabaseString($val);
$hold = $val;
# if the data is an answer
if (($parsedinfo[1] eq '3') && ($call{'user'} eq $parsedinfo[2])){
# put existing answer info into a buffer
$tempid = $parsedinfo[0];
$tempdatatype = $parsedinfo[1];
$tempuser = $parsedinfo[2];
$templinkid = $parsedinfo[3];
$tempkeywords = $keywords;
$tempquestion = $parsedinfo[4];
# get linked question
# Hash access doesn't allow subscript.
# use a clean var with no subscript
$clean = $parsedinfo[3];
$val = $hash{$clean};
# parse the question
parseDatabaseString($val); # sets @parsedinfo to question data
# push question into final data structure:
push (@matchQuestionsAndAnswers, {
ID => $parsedinfo[0],
datatype => $parsedinfo[1],
user => $parsedinfo[2],
linkid => $parsedinfo[3],
keywords => $keywords,
question => $parsedinfo[4]
});
# push buffered answer into final data structure:
push (@matchQuestionsAndAnswers, {
ID => $tempid,
datatype => $tempdatatype,
user => $tempuser,
linkid => $templinkid,
keywords => $tempkeywords,
question => $tempquestion
});
}
elsif (($parsedinfo[1] eq '2') && ($call{'user'} eq $parsedinfo[2])){
# add to array of notes @notes
push (@notes, {
ID => $parsedinfo[0],
datatype => $parsedinfo[1],
user => $parsedinfo[2],
linkid => $parsedinfo[3],
keywords => $keywords,
question => $parsedinfo[4]
});
}
}
# add notes to final data structure
while ($i <= $#notes){
push (@matchQuestionsAndAnswers, {
ID => $notes[$i]{'ID'},
datatype => $notes[$i]{'datatype'},
user => $notes[$i]{'user'},
linkid => $notes[$i]{'linkid'},
keywords => $notes[$i]{'keywords'},
question => $notes[$i]{'question'}
});
$i++;
}
$i = 0;
}
sub fixQuestionOrder{
&defineKeywords;
while (($key, $val) = each %hash){
$count = 0;
#print "We are at: key: $key, val: $val
\n";
parseDatabaseString($val);
#print "We are at: parsedinfo[1]: $parsedinfo[1]
\n";
$i = 0;
# while looping through the array of keywords from the form
while ($i <= $#formkeys){
#print "We are at: i $i <= #formkeys $#formkeys
\n";
$j = 0;
# compare with each keyword in the database location
while ($j <= $#parsedstring){
#print "We are at: j $j <= #parsedstring $#parsedstring
\n";
if ($formkeys[$i] eq $parsedstring[$j]){
#print "We are at: formkeys[$i]: $formkeys[$i] eq parsedstring[$j]: $parsedstring[$j]
\n";
# this keyword matches. increment count
$count += 1;
$j = $#parsedstring;
}
$j++;
}
$i++;
}
# if there are the same number of matches
# as the size of the array parsedstring,
# we have a match
#print "Test: count: $count == #parsedstring: $#parsedstring
\n";
if ($count == ($#parsedstring + 1)){
# if daata type 1 or (if user matches & datatype is either 2 or 3)
# print "Debug: parsedinfo[1] eq $parsedinfo[1]
\n";
if ($parsedinfo[1] eq '1'){
# print "$call{'user'} eq $parsedinfo[2] && $parsedinfo[1] is either 2 or 3, or $parsedinfo[1] = 1
\n";
$buffer = $parsedinfo[3];
$fixQuestionOrder[$buff]{'ID'} = $parsedinfo[0];
$fixQuestionOrder[$buff]{'datatype'} = $parsedinfo[1];
$fixQuestionOrder[$buff]{'user'} = $parsedinfo[2];
$fixQuestionOrder[$buff]{'linkid'} = $parsedinfo[3];
$fixQuestionOrder[$buff]{'keywords'} = $keywords;
$fixQuestionOrder[$buff]{'question'} = $parsedinfo[4];
$fixQuestionOrderSize += 1;
print "Debug: Push matchKeywords: $parsedinfo[0] #: $#matchKeywords
\n";
}
}
}
#print "Hello: keywordsfound = $keywordsfound\n";
# clean up
$i = '';
$j = '';
# now, file through the array
# set linkid to new array index. Replace entry in Database
while ($i <= $fixQuestionOrderSize){
if ($fixQuestionOrder[$i]{'ID'}){
$j += 1;
$fixQuestionOrder[$i]{'linkid'} = $j;
$addstring =
$fixQuestionOrder[$i]{'ID'} . "|" .
$fixQuestionOrder[$i]{'datatype'} . "|" .
$fixQuestionOrder[$i]{'user'} . "|" .
$fixQuestionOrder[$i]{'linkid'} . "|" .
$fixQuestionOrder[$i]{'keywords'} . "|" .
$fixQuestionOrder[$i]{'question'};
$id = $fixQuestionOrder[$i]{'ID'};
print "fizing order!
\n";
&addEntryToDatabase;
}
$i++;
}
}
sub addAnswersAndNotes{
# addAnswersAndNotes's job is to add a answer to a question in the database
# is called by a form, who's required elements are: database, user,
# question id to link to, answer, keywords. Keywords must match the
# question to link to. There will be no finalize form because the
# student is likely to be adding a few answers, and can edit their
# answers later. Then addAnswersAndNotes calls search to display the question
# with the answer added. Assumes DB is already open
# add answers to questions and notes to database
# $call{'questioncount'}, $call{'user'},
# $call{'keywordsx'} x is 1 - $call{'keywordcount'},
# $call{'notes'},
#
#
# review form information, determine if info is to be added to db
# while looping $call{'questioncount'} times
$j = 0;
# while looking at each ? on the form,
while ($j < $call{'questioncount'}){
# print "while : $j < $call{'questioncount'}";
$j++;
$ans = 'ansid' . $j;
# if the user is admin, handle editing the question
if ($call{'user'} eq $hash{'1'}){
$quest = ('question' . $j);
if ($call{$quest}){
#if ($call{$quest} =~ m/delete/g){
# $qid = ("qid" . $j);
# $del = $call{$qid};
# print "Deleting: qid: $qid
\n";
# delete $hash{$del};
#}
#else {
# edit the question here
$datatype = '1';
$qlink = ("qlink" . $j);
$linkid = $call{$qlink};
#print "Setting linkid: $qlink: $call{$qlink}.
\n";
$formdata = $call{$quest};
$qid = ("qid" . $j);
#print "qid: $qid
\n";
$count = $call{$qid};
&assembleString; # parsedata.pl
&addEntryToDatabase;
#}
}
}
# so if the text in the textbox exists, we can add a new entry.
if ($call{$ans} eq 'new'){
# print "call{ans} eq 'new'
\n";
$loca = ("answer" . $j);
if ($call{$loca}){
# print "I am adding an Answer
\n";
$datatype = '3';
$lnkid = ("link" . $j);
#print "lnkid = $lnkid
\n";
$linkid = $call{$lnkid};
#print "Setting linkid: $linkid
\n";
$text = "answer" . $j;
$formdata = $call{$text};
#print "Debug: call{$ans}: $call{ans}
\n";
#$count = $call{$ans};
&incrementDBcount;
&assembleString; # parsedata.pl
&addEntryToDatabase;
}
}
# or, since the entry already exists, we update the db with new info
else {
$loca = ("answer" . $j);
# print "loca : $loca";
if ($call{$loca}){
# print "adding Answer
\n";
$datatype = '3';
$lnkid = ("link" . $j);
# print "lnkid = $lnkid
\n";
$linkid = $call{$lnkid};
# print "Setting linkid: $linkid
\n";
$text = "answer" . $j;
$formdata = $call{$text};
# print "Debug: call{$ans}: $call{ans}
\n";
$count = $call{$ans};
#&incrementDBcount;
&assembleString; # parsedata.pl
&addEntryToDatabase;
}
}
}
# Now we will edit the where to go next text.
if (($call{'next'}) && ($call{'user'} eq $hash{'1'})){
$datatype = '4';
$linkid = 'n'; # n = next (not used here, better than null)
$formdata = $call{'next'};
$count = $call{'nextid'};
&assembleString; # parsedata.pl
&addEntryToDatabase;
}
# Here is where we handle the wildcard data
# the form is set up with the following fields
# $call{'wildcardcount'}
# $call{'keywordsx'}
# These keywords exist only when the user is admin
# Conceptually, when you edit a wildcard question,
# it adds a new entry in the database. There is an
# issue I am debating, How to set these questions up
# to block the wildcard from appearing at this location?
# $call{'wildcardq1'}
# $call{'wildcardqlink1'} 4
# Anyways, the users can add answers that are relevant
# to the wildcard q's. A problem however is that the answer
# will appear in the normal array of questions because it
# is like any other question. I know: Set the linkId of the
# answer to this 'w45' where the w tells the program that
# it links to a wildcard and it should be treated differently.
# $call{'wildcard1'} The text for the answers
# $call{'wildcardlink1'} 48
# $call{'wildcardansid1'} new
# $call{'wildcardqid1'}
$i = 0;
$j = 0;
while ($j <= $call{'wildcardcount'}){
$wildqid = "wildcardqid$j";
$wild = "wildcard$j";
$wildlink = "wildcardlink$j";
$wildansid = "wildcardansid$j";
# print "That's Wild! $wildqid, $wild, $wildlink, $wildansid";
if ($call{$wild}){
if ($call{$wildansid} eq "new"){
# create a new db item
$datatype = '3';
$linkid = "w$call{$wildqid}";
$formdata = $call{$wild};
&incrementDBcount;
&assembleString; # parsedata.pl
&addEntryToDatabase;
}
else{
$datatype = '3';
$linkid = "w$call{$wildqid}";
$formdata = $call{$wild};
$count = $call{$wildansid};
&assembleString; # parsedata.pl
&addEntryToDatabase;
}
}
$j++;
}
# the following commented code calls the routine to fix the order
# of questions in the db, and it's pretty buggy.
#if ($call{'user'} eq $hash{'1'}){
# &fixQuestionOrder;
#}
if ($call{'note'} eq 'new'){
if ($call{'notes'}){
# print "Adding New Notes
\n";
# add notes to db
$datatype = '2';
$linkid = '-';
$formdata = $call{'notes'};
&incrementDBcount;
&assembleString; # parsedata.pl
&addEntryToDatabase;
}
}
else {
if ($call{'notes'}){
# print "Editing Existing Notes
\n";
# add notes to db
$datatype = '2';
$linkid = '-';
$formdata = $call{'notes'};
$count = $call{'note'};
#&incrementDBcount;
&assembleString; # parsedata.pl
&addEntryToDatabase;
}
}
}
sub matchKeywords{
# matchKeywords has to look for questions that match the
# keyword identifiers, then it must look for data at these
# locations that match the user and push the matching
# database lines into an array.
# the array that we are building's structure will be a list of hashes:
# @matchKeywords =
# [1]:
# 'ID' = '14', # $matchKeywords[1]{'ID'}
# 'datatype' = '1',
# 'user' = 'keny',
# 'linkid' = '2',
# 'keywords' = 'x=y,x=y,x=y', # there will be a sub that parses keys
# 'question' = 'the question?'
# [2]:
# 'ID' = '14',
# 'datatype' = '1',
# 'user' = 'keny',
# 'linkid' = '2',
# 'keywords' = 'x=y,x=y,x=y',
# 'question' = 'the question?'
# pseudo
# for each entry in db
# parseDatabaseString
# if keywords match
# if data type 1 add question to array
# or user match && data type is 2 or 3, add note or answer to array
# else ignore this db entry
&defineKeywords;
#$wildcards = 20;
while (($key, $val) = each %hash){
$count = 0;
#print "We are at: key: $key, val: $val
\n";
parseDatabaseString($val);
#print "Debug $parsedinfo[1] eq '4'? $parsedinfo[0]
\n";
# if the data is the right type
#if ($parsedinfo[1] eq '1')
#print "We are at: parsedinfo[1]: $parsedinfo[1]
\n";
$i = 0;
# while looping through the array of keywords from the form
while ($i <= $#formkeys){
#print "We are at: i $i <= #formkeys $#formkeys
\n";
$j = 0;
# compare with each keyword in the database location
while ($j <= $#parsedstring){
#print "We are at: j $j <= #parsedstring $#parsedstring
\n";
if ($formkeys[$i] eq $parsedstring[$j]){
#print "We are at: formkeys[$i]: $formkeys[$i] eq parsedstring[$j]: $parsedstring[$j]
\n";
# this keyword matches. increment count
$count += 1;
$j = $#parsedstring;
}
$j++;
}
$i++;
}
$i = 0;
# look for wildcards and increment count by number of
# wildcard keywords
while ($i <= $#parsedstring){
if ($parsedstring[$i] eq '*'){
$count += 1;
$j = $#parsedstring;
# print "want to play a game? $key $parsedstring[$j]
\n";
}
$i += 1;
}
$i = 0;
# if there are the same number of matches
# as the size of the array parsedstring,
# we have a match
# print "Test: count: $count == #parsedstring: $#parsedstring
\n";
if ($count == ($#parsedstring + 1)){
# if daata type 1 or (if user matches & datatype is either 2 or 3)
# print "Debug: parsedinfo[1] eq $parsedinfo[1]
\n";
if (($parsedinfo[1] eq '1') ||
($parsedinfo[1] eq '4')
|| (($call{'user'} eq $parsedinfo[2])
&& (($parsedinfo[1] eq '2')
|| ($parsedinfo[1] eq '3')))){
# print "$call{'user'} eq $parsedinfo[2] && $parsedinfo[1] is either 2 or 3, or $parsedinfo[1] = 1
\n";
if ($keywords =~ m/\*/){
push (@wildcards, {
ID => $parsedinfo[0], # $matchKeywords[1]{'ID'}
datatype => $parsedinfo[1],
user => $parsedinfo[2],
linkid => $parsedinfo[3],
keywords => $keywords, # there will be a sub that parses keys
question => $parsedinfo[4]
});
if ($parsedinfo[1] eq '1'){
$wildcardcount += 1;
}
}
elsif ($parsedinfo[1] eq '4'){
push (@gonext, {
ID => $parsedinfo[0], # $matchKeywords[1]{'ID'}
datatype => $parsedinfo[1],
user => $parsedinfo[2],
linkid => $parsedinfo[3],
keywords => $keywords, # there will be a sub that parses keys
question => $parsedinfo[4]
});
}
else{
if ($parsedinfo[3] !~ m/w/){
push (@matchKeywords, {
ID => $parsedinfo[0], # $matchKeywords[1]{'ID'}
datatype => $parsedinfo[1],
user => $parsedinfo[2],
linkid => $parsedinfo[3],
keywords => $keywords, # there will be a sub that parses keys
question => $parsedinfo[4]
});
}
else {
# handle the wildcard response
# print "Baa Baa Black Sheep
\n";
push (@wildcards, {
ID => $parsedinfo[0], # $matchKeywords[1]{'ID'}
datatype => $parsedinfo[1],
user => $parsedinfo[2],
linkid => $parsedinfo[3],
keywords => $keywords, # there will be a sub that parses keys
question => $parsedinfo[4]
});
}
}
# print "Debug: Push matchKeywords: $parsedinfo[0] #: $#matchKeywords
\n";
}
}
}
#print "Hello: keywordsfound = $keywordsfound\n";
# clean up
$i = '';
$j = '';
#print "lo, Match Keywords out!";
}
sub addEntryToDatabase{
# adds addstring to the database add string is an
# assembled entry to the database it will be added at $id
# Lesson: {$id} assigns the variable held in $id
# as the hash key. {'$id'} assigns $id to the hash key
# only use single quotes when there is a number or string,
# not a variable.
$hash{$id} = $addstring;
}
sub setOrderOfDisplayQuestions{
# assumes database is already open
# analyzes form parameters from printFinalizeAddForm
# and changes the appropriate link ids of the questions
# that match the current question location. It then
# creates $linkid which is the number for the current
# question being added to be used in assembleQuestionEntry
# $call{'numbermatched'} is the amount of questions found that match
# $call{'order1_numbermatched'} are the form elements that contain id's
# $call{'order_numbermatched+1'} is the question to be added. value = 0
# our job is to go through the form parameters and change the order to
# the value set in $call{'order1_numbermatched'}.
# while going through found form id's
while ($i <= ($call{'numbermatched'} + 1)){
$num = 'order' . $i; # generates form variabale
$id = $call{$num}; # points to form variable
if ($call{$num} eq '0'){
# this one is the new question
$linkid = $i;
}
else {
$val = $hash{$id}; # points to db string
&parseDatabaseString; # creates the next few var's
$addstring =
$parsedinfo[0] . "|" . $parsedinfo[1] . "|" .
$parsedinfo[2] . "|" . $i . "|" .
$keywords . "|" . $parsedinfo[4];
# if there is a legitimate string to add...
if ($addstring != "|||||"){
&addEntryToDatabase; # see previous subroutine
}
}
$i++; # go to next question
}
$i = 0;
# print "The new question is Question # $linkid";
}
sub searchForMatchQuestions{
# searchForMatchQuestions looks trough the database and
# finds out whether or not there are questions that exist
# for the keywords specified in @keywords. if it finds any
# matching questions it pushes them into @matches
@matches = '';
&openDBhash;
# set up form elements into an array for future improvements
# it would be nice to figure out a way to do this for as many
# keywords as possible, but it's hard wired for 6 now.
# a lesson learned: Parenthesis make this an array,
# Brackets make this a hash. Hmmm.
&defineKeywords;
while (($key, $val) = each %hash){
#print "We are at: key: $key, val: $val
\n";
parseDatabaseString($val);
# if the data is the right type
if ($parsedinfo[1] eq '1'){
#print "We are at: parsedinfo[1]: $parsedinfo[1]
\n";
$i = 0;
$count = 0;
# while looping through the array of keywords from the form
while ($i <= $#formkeys){
# print "We are at: i $i <= #formkeys $#formkeys
\n";
$j = 0;
# compare with each keyword in the database location
while ($j <= $#parsedstring){
#print "We are at: j $j <= #parsedstring $#parsedstring
\n";
if ($formkeys[$i] eq $parsedstring[$j]){
# print "We are at: formkeys[$i]: $formkeys[$i] eq parsedstring[$j]: $parsedstring[$j]
\n";
# this keyword matches. increment count
$count += 1;
$j = $#parsedstring;
}
$j++;
}
$i++;
}
# if there are the same number of matches
# as the size of the array parsedstring,
# we have a match
#print "Test: count: $count == #parsedstring: $#parsedstring
\n";
if ($count == ($#parsedstring + 1)){
push @matches, $parsedinfo[0];
$keywordsfound = '1'; # we found matching keyword sets in the db
}
}
}
#print "Hello: keywordsfound = $keywordsfound\n";
&closeDBhash;
# clean up
$i = '';
$j = '';
}
sub checkDatabase{
# checkdatabase is how we define which database to be used
# therefore it must be present at all calls to riverweb
# This element should be checked in the beginning of the
# script. This routine returns an error page if the
# database does not exist, exits the program.
if ($call{'database'}){
# check to see if the database exists
$buffer = 'database/' . $call{'database'};
if (!(-e $buffer)){
&printHtmlHeader;
print "