From 3a9b7f356a4a7fb23b2d3010a593a9cb233637a6 Mon Sep 17 00:00:00 2001 From: markleeds Date: Sat, 23 Sep 2006 18:32:02 +0000 Subject: [PATCH] Improvements by Mike Brinson including features, bug fixes, and commenting. --- contrib/forms/formmaker/formscript.pl | 1218 ++++++++++++++++++--------------- 1 file changed, 656 insertions(+), 562 deletions(-) diff --git a/contrib/forms/formmaker/formscript.pl b/contrib/forms/formmaker/formscript.pl index 407810213..4ef30be9b 100644 --- a/contrib/forms/formmaker/formscript.pl +++ b/contrib/forms/formmaker/formscript.pl @@ -1,562 +1,656 @@ -#!/usr/bin/perl - -use strict; -use warnings; - -use CGI qw(:standard); - -#file templates here - -#documentation -my $documentation =<<'START'; - -******************************************* -* Form Generating Script 1.1.2 * -******************************************* - -new for 1.1.2 - -Added a 'do not save' link at the top and bottom of the form. -Fixed problem with using single and double quotes in input file. -Changed deprecated PHP function mysql_escape_string to -mysql_real_escape_string. - -bugs: There may still be a problem with reserved MySQL words not -being caught. There may be other bugs not discovered yet. - -future plans: I plan on improving the output format in report.php. -For now, users can alter this form as needed. Since formscript.pl -knows the fields to be used, it makes more sense to list them -explicitly than to print them in a foreach loop. I will get to -work on this soon. - -1.1 - -This is a complete rewrite of an earlier Perl script I wrote to generate -forms for OpenEMR. It is now all self contained within a single .pl file. -To run at the shell command line, type: - -Perl formscript.pl [filename] - -where filename is a text file with data relating to your form. If you run -without a filename argument, a sample data file will be created in the same -directory named 'sample.txt' that you can use to see how to create your own. - -Basically you enter one database field item per line like this: - -Social History::popup_menu::smoker::non-smoker - -or - -Social History::radio_group::smoker::non-smoker - - -where the first item is the field name. spaces within the name will convert to '_' -for the sql database field name. If you use a SQL reserved word, the form generation -will fail and this program will notify you of the word(s) you used. - -The '::' is the standard delimiter that I use between items. The second item on the line -is the form widget type. You can choose from: - -textfield -textarea -checkbox -checkbox_group -radio_group -popup_menu -scrolling_list -scrolling_list_multiples - -Putting a '+' at the beginning of the field name will let the form know that you want to -report negatives. This means the following: - -+cardiac_review::checkbox_group::chest pain::shortness of breath::palpitations - -creates a group of checkboxes where if the user chooses the first two boxes, the database will -have the following line entered: - -chest pain, shortness of breath. Negative for palpitations. - -The remaining items after the fieldname and the widget type are the names for -checkboxes or radio buttons or default text -for a textfield or text area. You can also start a line with a '#' as the first character and this -will be an ignored comment line. If you put html tags on their own lines, they will be integrated -into the form. It will be most helpful to look at 'sample.txt' to see how this works. - -This is 1.1 and is tested to the extent of installing the form and entering data within an encounter. -Please send feedback to mail@doc99.com. I will definitely -be fixing and improving it. - -Mark Leeds - - -START - -#info.txt -my $info_txt=<<'START'; -FORM_NAME -START - -my $do_not_save=<<'START'; -[do not save]"; -?> -START - -#new.php -my $new_php =<<'START'; - - - - - topmargin=0 rightmargin=0 leftmargin=2 bottommargin=0 marginwidth=2 marginheight=0> -
-
-

FORM_NAME

-
- -DATABASEFIELDS - -
- -START - -#print.php -my $print_php=<<'START'; - - - - - topmargin=0 rightmargin=0 leftmargin=2 bottommargin=0 marginwidth=2 marginheight=0> -
-

FORM_NAME

-
-DATABASEFIELDS -
- -START - -#report.php -my $report_php=<<'START'; -"; -foreach($data as $key => $value) { -if ($key == "id" || $key == "pid" || $key == "user" || $key == "groupname" || $key == "authorized" || $key == "activity" || $key == "date" || $value == "" || $value == "0000-00-00 00:00:00") { - continue; -} -if ($value == "on") { -$value = "yes"; -} -$key=ucwords(str_replace("_"," ",$key)); -$output = stripslashes($value); -print "$key: $output"; -$count++; -if ($count == $cols) { -$count = 0; -print "\n"; -} -} -} -print ""; -} -?> -START - -#save.php -my $save_php=<<'START'; -$val) -{ - if ($val == "checkbox") - { - if ($_POST[$key]) {$field_names[$key] = "positve";} - else {$field_names[$key] = "negative";} - } - elseif (($val == "checkbox_group")||($val == "scrolling_list_multiples")) - { - $neg = ''; - if (array_key_exists($key,$negatives)) #a field requests reporting of negatives - { - foreach($_POST[$key] as $pos) #check positives against list - { - if (array_key_exists($pos, $negatives[$key])) - { #remove positives from list, leaving negatives - unset($negatives[$key][$pos]); - } - } - $neg = ". Negative for ".implode(', ',$negatives[$key]); - } - $field_names[$key] = implode(', ',$_POST[$key]).$neg; - } - else - { - $field_names[$key] = $_POST[$key]; - } -} - -//end special processing - -foreach ($field_names as $k => $var) { -$field_names[$k] = mysql_real_escape_string($var); -echo "$var\n"; -} -if ($encounter == "") -$encounter = date("Ymd"); -if ($_GET["mode"] == "new"){ -$newid = formSubmit("form_FORM_NAME", $field_names, $_GET["id"], $userauthorized); -addForm($encounter, "FORM_NAME", $newid, "FORM_NAME", $pid, $userauthorized); -}elseif ($_GET["mode"] == "update") { - - -sqlInsert("update form_FORM_NAME set pid = {$_SESSION["pid"]},groupname='".$_SESSION["authProvider"]."',user='".$_SESSION["authUser"]."',authorized=$userauthorized,activity=1, date = NOW(), FIELDS where id=$id"); -} -$_SESSION["encounter"] = $encounter; -formHeader("Redirecting...."); -formJump(); -formFooter(); -?> -START - -#table.sql -my $table_sql=<<'START'; -CREATE TABLE IF NOT EXISTS `form_FORM_NAME` ( -id bigint(20) NOT NULL auto_increment, -date datetime default NULL, -pid bigint(20) default NULL, -user varchar(255) default NULL, -groupname varchar(255) default NULL, -authorized tinyint(4) default NULL, -activity tinyint(4) default NULL, -DATABASEFIELDS -PRIMARY KEY (id) -) TYPE=MyISAM; -START - -#view.php -my $view_php =<<'START'; - - - - - - topmargin=0 rightmargin=0 leftmargin=2 bottommargin=0 marginwidth=2 marginheight=0> -
" name="my_form"> -

FORM_NAME

-
-DATABASEFIELDS - -
- -START - -#preview.html -my $preview_html =<<'START'; - - - -
-
-

FORM_NAME

-
-DATABASEFIELDS -
- - -START - -#sample.txt -my $sample_txt =<<'START'; -a1_preop_physical - -chief_complaints::textarea - -

past surgical history

-+surgical history::checkbox_group::cholecystectomy::tonsillectomy::apendectomy -

other

-surgical history other::textfield - -

past surgical history

-+medical history::scrolling_list_multiples::asthma::diabetes::hypertension -

other

-medical history other::textfield - -

Allergies

-+allergies::checkbox_group::penicillin::sulfa::iodine -

other

-allergies other::textfield - -

Social History

-

smoking

-smoke history::radio_group::non-smoker::smoker -

alcohol

-etoh history::scrolling_list::none::occasional::daily::heavy use -START - -my @reserved = ('ADD','ALL','ALTER','ANALYZE','AND','AS','ASC','ASENSITIVE','BEFORE','BETWEEN','BIGINT','BINARY','BLOB','BOTH','BY','CALL','CASCADE','CASE','CHANGE','CHAR','CHARACTER','CHECK','COLLATE','COLUMN','CONDITION','CONNECTION','CONSTRAINT','CONTINUE','CONVERT','CREATE','CROSS','CURRENT_DATE','CURRENT_TIME','CURRENT_TIMESTAMP','CURRENT_USER','CURSOR','DATABASE','DATABASES','DAY_HOUR','DAY_MICROSECOND','DAY_MINUTE','DAY_SECOND','DEC','DECIMAL','DECLARE','DEFAULT','DELAYED','DELETE','DESC','DESCRIBE','DETERMINISTIC','DISTINCT','DISTINCTROW','DIV','DOUBLE','DROP','DUAL','EACH','ELSE','ELSEIF','ENCLOSED','ESCAPED','EXISTS','EXIT','EXPLAIN','FALSE','FETCH','FLOAT','FOR','FORCE','FOREIGN','FROM','FULLTEXT','GOTO','GRANT','GROUP','HAVING','HIGH_PRIORITY','HOUR_MICROSECOND','HOUR_MINUTE','HOUR_SECOND','IF','IGNORE','IN','INDEX','INFILE','INNER','INOUT','INSENSITIVE','INSERT','INT','INTEGER','INTERVAL','INTO','IS','ITERATE','JOIN','KEY','KEYS','KILL','LEADING','LEAVE','LEFT','LIKE','LIMIT','LINES','LOAD','LOCALTIME','LOCALTIMESTAMP','LOCK','LONG','LONGBLOB','LONGTEXT','LOOP','LOW_PRIORITY','MATCH','MEDIUMBLOB','MEDIUMINT','MEDIUMTEXT','MIDDLEINT','MINUTE_MICROSECOND','MINUTE_SECOND','MOD','MODIFIES','NATURAL','NOT','NO_WRITE_TO_BINLOG','NULL','NUMERIC','ON','OPTIMIZE','OPTION','OPTIONALLY','OR','ORDER','OUT','OUTER','OUTFILE','PRECISION','PRIMARY','PROCEDURE','PURGE','READ','READS','REAL','REFERENCES','REGEXP','RENAME','REPEAT','REPLACE','REQUIRE','RESTRICT','RETURN','REVOKE','RIGHT','RLIKE','SCHEMA','SCHEMAS','SECOND_MICROSECOND','SELECT','SENSITIVE','SEPARATOR','SET','SHOW','SMALLINT','SONAME','SPATIAL','SPECIFIC','SQL','SQLEXCEPTION','SQLSTATE','SQLWARNING','SQL_BIG_RESULT','SQL_CALC_FOUND_ROWS','SQL_SMALL_RESULT','SSL','STARTING','STRAIGHT_JOIN','TABLE','TERMINATED','THEN','TINYBLOB','TINYINT','TINYTEXT','TO','TRAILING','TRIGGER','TRUE','UNDO','UNION','UNIQUE','UNLOCK','UNSIGNED','UPDATE','USAGE','USE','USING','UTC_DATE','UTC_TIME','UTC_TIMESTAMP','VALUES','VARBINARY','VARCHAR','VARCHARACTER','VARYING','WHEN','WHERE','WHILE','WITH','WRITE','XOR','YEAR_MONTH','ZEROFILL','ACTION','BIT','DATE','ENUM','NO','TEXT','TIME','TIMESTAMP'); -my %reserved; -$reserved{uc $_}++ for @reserved; - -#main program - -if (@ARGV == 0) -{ - to_file('sample.txt',$sample_txt) if not -f 'sample.txt'; - print $documentation."\n"; - exit 0; -} - -my $form_name = <>; -chomp($form_name); -my $check_reserved = uc $form_name; -if ($reserved{uc $check_reserved}) -{ - print "You have chosen an SQL reserved word for your form name: $check_reserved. Please try again.\n"; - exit 1; -} -$form_name =~ s/^\s+(\S)\s+$/$1/; -$form_name =~ s/\s+/_/g; -if (not -d $form_name) -{ - mkdir "$form_name" or die "Could not create directory $form_name: $!"; -} -my @field_data; #the very important array of field data -chomp, push @field_data, [ split /::/ ] while <>; -my %negatives; #key=field name: these are the fields that require reporting of pertinant - #negatives. will only apply to checkbox_group and scrolling_list_multiples types -my @reserved_used; -#strip outer spaces from field names and field types and change inner spaces to underscores -#and check field names for SQL reserved words now -for (@field_data) -{ - if ($_->[0] and $_->[1]) - { - $_->[0] =~ s/^\s+(\S)\s+$/$1/; - $_->[0] =~ s/\s+/_/g; - $check_reserved = $_->[0] =~ m/(\w+)/ ? uc $1 : q{}; - push @reserved_used, $check_reserved if $reserved{$check_reserved}; - $_->[1] =~ s/^\s+(\S)\s+$/$1/; - if ($_->[0] =~ /^\+/) #a leading '+' indicates to print negatives - { # or not checked values in a checkbox_group or scrolling_list_multiples - $_->[0] =~ s/^\+(.*)/$1/; - $negatives{$_->[0]}++; - } - } -} -if (@reserved_used) -{ - print "You have chosen the following reserved words as field names. Please try again.\n"; - print "$_\n" for @reserved_used; - exit 1; -} - -my $text = make_form(@field_data); -my $out; - -#info.txt -$out = replace($info_txt, 'FORM_NAME', $form_name); -to_file("$form_name/info.txt",$out); - -#new.php -$out = replace($new_php, 'FORM_NAME', $form_name); -$out = replace($out, 'DATABASEFIELDS', $text); -to_file("$form_name/new.php",$out); - -#print.php -$out = replace($print_php, 'FORM_NAME', $form_name); -$out = replace($out, 'DATABASEFIELDS', $text); -to_file("$form_name/print.php",$out); - -#report.php -$out = replace($report_php, 'FORM_NAME', $form_name); -$out = replace($out, 'DATABASEFIELDS', $text); -to_file("$form_name/report.php",$out); - -#save.php -$out = replace($save_php, 'FORM_NAME', $form_name); -$out = replace_save_php($out, @field_data); -to_file("$form_name/save.php",$out); - -#view.php -$out = replace($view_php, 'FORM_NAME', $form_name); -$out = replace($out, 'DATABASEFIELDS', $text); -to_file("$form_name/view.php",$out); - -#table.sql -$out = replace($table_sql, 'FORM_NAME', $form_name); -$out = replace_sql($out, @field_data); -to_file("$form_name/table.sql",$out); - -#preview.html -$out = replace($preview_html, 'FORM_NAME', $form_name); -$out = replace($out, 'DATABASEFIELDS', $text); -to_file("$form_name/preview.html",$out); - -# subs - -sub replace -{ - my $text = shift; - my %words = @_; - $text =~ s/$_/$words{$_}/g for keys %words; - return $text; -} - - -sub replace_save_php #a special case -{ - my $text = shift; - my @fields = map {$_->[0]} grep{$_->[0] and $_->[1]} @_; - for (@fields) - { - $_ = "$_='\".\$field_names[\"$_\"].\"'"; - } - my $fields = join ',',@fields; - $text =~ s/FIELDS/$fields/; - @fields = (); - my @negatives; - for (@_) - { - if ($_->[0] and $_->[1]) - { - push @fields, "'$_->[0]' => '$_->[1]'"; - if ($negatives{$_->[0]}) - { - my @temp; - my $count = 2; - while ($count < scalar(@$_)) - { - push @temp, "'$_->[$count]' => '$_->[$count]'"; - $count++; - } - push @negatives, "'$_->[0]' => array(".join(', ', @temp).")"; - } - } - } - $fields = join ', ', @fields; - $text =~ s/FIELDNAMES/$fields/; - my $negatives = join ', ', @negatives; - $text =~ s/NEGATIVES/$negatives/; - return $text; -} - -sub replace_sql #a special case -{ - my $text = shift; - my @fields = map {$_->[0]} grep{$_->[0] and $_->[1]} @_; - my $replace = ''; - $replace .= "$_ TEXT,\n" for @fields; - $text =~ s/DATABASEFIELDS/$replace/; - return $text; -} - -sub make_form -{ - my @data = @_; - my $return = submit(-name=>'submit form') . $do_not_save; - $return .= ""; - for (@data) - { - next if not $_->[0]; - next if $_->[0] =~ /^#/; #ignore perl type comments - if ($_->[0] =~ /^\w/ and $_->[1]) - { - for (@$_) - { - s/'/\'/g; - s/"/\"/g; - } - my $field_name = shift @$_; - my $field_type = shift @$_; - my $label = $field_name; - $label =~ s/_/ /g; - if ($field_type =~ /^textfield$/) - { - $return .= Tr(td($label),td(textfield(-name=>$field_name, -value=> join @$_)))."\n"; - } - elsif ($field_type =~ /^textarea$/) - { - $return .= Tr(td($label),td(textarea(-name=>$field_name, -rows=>4, -columns=>40, -value=> join @$_)))."\n"; - } - elsif ($field_type =~ /^radio_group$/) - { - $return .= Tr(td($label),td(radio_group(-name=>$field_name, -values=>$_)))."\n";; - } - elsif ($field_type =~ /^checkbox$/) - { - $return .= Tr(td($label),td(checkbox(-name=>$field_name, -value=>'yes', -label=> join @$_)))."\n"; - } - elsif ($field_type =~ /^checkbox_group$/) - { - $return .= Tr(td($label),td(checkbox_group(-name=>$field_name.'[]', -values=>$_)))."\n"; - } - elsif ($field_type =~ /^popup_menu/) - { - $return .= Tr(td($label),td(popup_menu(-name=>$field_name, -values=>$_)))."\n"; - } - elsif ($field_type =~ /^scrolling_list/) - { - my $mult = 'false'; - my $mult2 = ''; - $mult = 'true' if $field_type =~ /multiples$/; - $mult2 = '[]' if $field_type =~ /multiples$/; - $return .= Tr(td($label),td(scrolling_list(-name=>$field_name.$mult2, -values=>$_, -size=>scalar(@$_), -multiple=>$mult)))."\n"; - } - unshift @$_, $field_type; - unshift @$_, $field_name; - } - else #probably an html tag or something - { - $return .= "
"; - $return .= $_->[0]."\n"; - $return .= ""; - } - } - $return .= "
"; - $return .= submit(-name=>'submit form') . $do_not_save; - return $return; -} - -sub to_file -{ - my $filename = shift; - my $string = shift; - my $file; - open $file, '>', $filename or die "cannot open $filename: $!"; - print $file $string; - close $file or die "cannot close $filename: $!"; -} +#!/usr/bin/perl + +use strict; +use warnings; + +use CGI qw(:standard); + +#file templates here + +#documentation +my $documentation =<<'START'; + +************************************* +* Form Generating Script 2.0 * +************************************* + +This is a complete rewrite of an earlier Perl script I wrote to generate +forms for OpenEMR. It is now all self contained within a single .pl file. +To run at the shell command line, type: + +Perl formscript.pl [filename] + +where filename is a text file with data relating to your form. If you run +without a filename argument, a sample data file will be created in the same +directory named 'sample.txt' that you can use to see how to create your own. + +The first line you enter in your textfile is the name of the form. +In the example this is "a1_preop_physical" + +Basically you enter one database field item per line like this: + +Social History::popup_menu::smoker::non-smoker + +or + +Social History::radio_group::smoker::non-smoker + + +where the first item is the field name, the second item is the widget type, and Nth items are values. +spaces within the name will convert to '_' +for the sql database field name. If you use a SQL reserved word, the form generation +will fail and this program will notify you of the word(s) you used. + +The '::' is the standard delimiter that I use between items. The second item on the line +is the form widget type. You can choose from: + +textfield +textarea +checkbox +checkbox_group +radio_group +popup_menu +scrolling_list +scrolling_list_multiples + +Putting a '+' at the beginning of the field name will let the form know that you want to +report negatives. This means the following: + ++cardiac_review::checkbox_group::chest pain::shortness of breath::palpitations + +creates a group of checkboxes where if the user chooses the first two boxes, the database will +have the following line entered: + +chest pain, shortness of breath. Negative for palpitations. + +The remaining items after the fieldname and the widget type are the names for +checkboxes or radio buttons or default text +for a textfield or text area. You can also start a line with a '#' as the first character and this +will be an ignored comment line. If you put html tags on their own lines, they will be integrated +into the form. It will be most helpful to look at 'sample.txt' to see how this works. + +This is 1.1 and is tested to the extent of installing the form and entering data within an encounter. +Please send feedback to mail@doc99.com. I will definitely +be fixing and improving it. + +Mark Leeds + + +START + +#info.txt +my $info_txt=<<'START'; +FORM_NAME +START + +#new.php +my $new_php =<<'START'; + + + + + topmargin=0 rightmargin=0 leftmargin=2 bottommargin=0 marginwidth=2 marginheight=0> +
+
+

FORM_NAME

+
+DATABASEFIELDS +
+ +START + +#print.php +my $print_php=<<'START'; + + + + + topmargin=0 rightmargin=0 leftmargin=2 bottommargin=0 marginwidth=2 marginheight=0> +
+

FORM_NAME

+
+DATABASEFIELDS +
+ +START + +#report.php +my $report_php=<<'START'; +"; +foreach($data as $key => $value) { +if ($key == "id" || $key == "pid" || $key == "user" || $key == "groupname" || $key == "authorized" || $key == "activity" || $key == "date" || $value == "" || $value == "0000-00-00 00:00:00") { + continue; +} +if ($value == "on") { +$value = "yes"; +} +$key=ucwords(str_replace("_"," ",$key)); +print "$key: ".stripslashes($value).""; +$count++; +if ($count == $cols) { +$count = 0; +print "\n"; +} +} +} +print ""; +} +?> +START + +#save.php +my $save_php=<<'START'; +$val) +{ + if ($val == "checkbox") + { + if ($_POST[$key]) {$field_names[$key] = "yes";} + else {$field_names[$key] = "negative";} + } + elseif (($val == "checkbox_group")||($val == "scrolling_list_multiples")) + { + $neg = ''; + if (array_key_exists($key,$negatives)) #a field requests reporting of negatives + { + foreach($_POST[$key] as $pos) #check positives against list + { + if (array_key_exists($pos, $negatives[$key])) + { #remove positives from list, leaving negatives + unset($negatives[$key][$pos]); + } + } + $neg = ". Negative for ".implode(',',$negatives[$key]); + } + $field_names[$key] = implode(',',$_POST[$key]).$neg; + } + else + { + $field_names[$key] = $_POST[$key]; + } +} + +//end special processing + +foreach ($field_names as $k => $var) { +$field_names[$k] = mysql_escape_string($var); +echo "$var\n"; +} +if ($encounter == "") +$encounter = date("Ymd"); +if ($_GET["mode"] == "new"){ +$newid = formSubmit("form_FORM_NAME", $field_names, $_GET["id"], $userauthorized); +addForm($encounter, "FORM_NAME", $newid, "FORM_NAME", $pid, $userauthorized); +}elseif ($_GET["mode"] == "update") { + + +sqlInsert("update form_FORM_NAME set pid = {$_SESSION["pid"]},groupname='".$_SESSION["authProvider"]."',user='".$_SESSION["authUser"]."',authorized=$userauthorized,activity=1, date = NOW(), FIELDS where id=$id"); +} +$_SESSION["encounter"] = $encounter; +formHeader("Redirecting...."); +formJump(); +formFooter(); +?> +START + +#table.sql +my $table_sql=<<'START'; +CREATE TABLE IF NOT EXISTS `form_FORM_NAME` ( +id bigint(20) NOT NULL auto_increment, +date datetime default NULL, +pid bigint(20) default NULL, +user varchar(255) default NULL, +groupname varchar(255) default NULL, +authorized tinyint(4) default NULL, +activity tinyint(4) default NULL, +DATABASEFIELDS +PRIMARY KEY (id) +) TYPE=MyISAM; +START + +#view.php +my $view_php =<<'START'; + + + + + + topmargin=0 rightmargin=0 leftmargin=2 bottommargin=0 marginwidth=2 marginheight=0> +
" name="my_form"> +

FORM_NAME

+
+DATABASEFIELDS + +
+ +START + +#preview.html +my $preview_html =<<'START'; + + + +
+
+

FORM_NAME

+
+DATABASEFIELDS +
+ + +START + +#sample.txt +my $sample_txt =<<'START'; +a1_preop_physical + +chief_complaints::textarea + +

past surgical history

++surgical history::checkbox_group::cholecystectomy::tonsillectomy::apendectomy +

other

+surgical history other::textfield + +

past surgical history

++medical history::scrolling_list_multiples::asthma::diabetes::hypertension +

other

+medical history other::textfield + +

Allergies

++allergies::checkbox_group::penicillin::sulfa::iodine +

other

+allergies other::textfield + +

Social History

+

smoking

+smoke history::radio_group::non-smoker::smoker +

alcohol

+etoh history::scrolling_list::none::occasional::daily::heavy use +START + +my @reserved = ('ADD','ALL','ALTER','ANALYZE','AND','AS','ASC','ASENSITIVE','BEFORE','BETWEEN','BIGINT','BINARY','BLOB','BOTH','BY','CALL','CASCADE','CASE','CHANGE','CHAR','CHARACTER','CHECK','COLLATE','COLUMN','CONDITION','CONNECTION','CONSTRAINT','CONTINUE','CONVERT','CREATE','CROSS','CURRENT_DATE','CURRENT_TIME','CURRENT_TIMESTAMP','CURRENT_USER','CURSOR','DATABASE','DATABASES','DAY_HOUR','DAY_MICROSECOND','DAY_MINUTE','DAY_SECOND','DEC','DECIMAL','DECLARE','DEFAULT','DELAYED','DELETE','DESC','DESCRIBE','DETERMINISTIC','DISTINCT','DISTINCTROW','DIV','DOUBLE','DROP','DUAL','EACH','ELSE','ELSEIF','ENCLOSED','ESCAPED','EXISTS','EXIT','EXPLAIN','FALSE','FETCH','FLOAT','FOR','FORCE','FOREIGN','FROM','FULLTEXT','GOTO','GRANT','GROUP','HAVING','HIGH_PRIORITY','HOUR_MICROSECOND','HOUR_MINUTE','HOUR_SECOND','IF','IGNORE','IN','INDEX','INFILE','INNER','INOUT','INSENSITIVE','INSERT','INT','INTEGER','INTERVAL','INTO','IS','ITERATE','JOIN','KEY','KEYS','KILL','LEADING','LEAVE','LEFT','LIKE','LIMIT','LINES','LOAD','LOCALTIME','LOCALTIMESTAMP','LOCK','LONG','LONGBLOB','LONGTEXT','LOOP','LOW_PRIORITY','MATCH','MEDIUMBLOB','MEDIUMINT','MEDIUMTEXT','MIDDLEINT','MINUTE_MICROSECOND','MINUTE_SECOND','MOD','MODIFIES','NATURAL','NOT','NO_WRITE_TO_BINLOG','NULL','NUMERIC','ON','OPTIMIZE','OPTION','OPTIONALLY','OR','ORDER','OUT','OUTER','OUTFILE','PRECISION','PRIMARY','PROCEDURE','PURGE','READ','READS','REAL','REFERENCES','REGEXP','RENAME','REPEAT','REPLACE','REQUIRE','RESTRICT','RETURN','REVOKE','RIGHT','RLIKE','SCHEMA','SCHEMAS','SECOND_MICROSECOND','SELECT','SENSITIVE','SEPARATOR','SET','SHOW','SMALLINT','SONAME','SPATIAL','SPECIFIC','SQL','SQLEXCEPTION','SQLSTATE','SQLWARNING','SQL_BIG_RESULT','SQL_CALC_FOUND_ROWS','SQL_SMALL_RESULT','SSL','STARTING','STRAIGHT_JOIN','TABLE','TERMINATED','THEN','TINYBLOB','TINYINT','TINYTEXT','TO','TRAILING','TRIGGER','TRUE','UNDO','UNION','UNIQUE','UNLOCK','UNSIGNED','UPDATE','USAGE','USE','USING','UTC_DATE','UTC_TIME','UTC_TIMESTAMP','VALUES','VARBINARY','VARCHAR','VARCHARACTER','VARYING','WHEN','WHERE','WHILE','WITH','WRITE','XOR','YEAR_MONTH','ZEROFILL','ACTION','BIT','DATE','ENUM','NO','TEXT','TIME','TIMESTAMP'); +my %reserved; +$reserved{$_}++ for @reserved; # Shortened syntax for assigning value of 1 to each associative element in array. + # IE: UNLOCK = 1, WRITE = 1, ETC... Associative array. + + + + +#********************************************************************************* +#******************************** MAIN PROGRAM *********************************** +#********************************************************************************* + +if (@ARGV == 0) +{ + to_file('sample.txt',$sample_txt) if not -f 'sample.txt'; + print $documentation."\n"; + exit 0; +} + +my $form_name = <>; +chomp($form_name); +my $compare = $form_name; +$compare =~ tr/[a-z]/[A-Z]/; +if ($reserved{$compare}) +{ + print "You have chosen an SQL reserved word for your form name: $form_name. Please try again.\n"; + exit 1; +} +$form_name =~ s/^\s+(\S)\s+$/$1/; #Remove spaces from beginning and end of form name and save $1 which is a backreference to subexpression ("\S" MEANS Any non-whitespace character)) to $form_name. +$form_name =~ s/\s+/_/g; #Substitute all blank spaces with _ globally --> g means globally. +if (! -e $form_name) +{ + mkdir "$form_name" or die "Could not create directory $form_name: $!"; +} +my @field_data; #the very important array of field data +chomp, push @field_data, [ split /::/ ] while <>; #while <> continues through currently open file (parameter from command line invoking perl ie: "subjective.txt"), chomping return characters, splitting on :: or more (::::) and putting into field_data array. +my %negatives; #key=field name: these are the fields that require reporting of pertinant + #negatives. will only apply to checkbox_group and scrolling_list_multiples types +my @reserved_used; +#strip outer spaces from field names and field types and change inner spaces to underscores +#and check field names for SQL reserved words now +for (@field_data) +{ + if ($_->[0] and $_->[1]) #$_->[0] is field name and $_->[1] is field type. IE: @field_data[4]->[0] and @field_data[4]->[1] + { + $_->[0] =~ s/^\s+(\S)\s+$/$1/; #\s means spaces, \S means non spaces. (\S) creates backreference pointed to by $1 at end. ***FIELD NAME*** + $_->[0] = lc $_->[0]; #MAKE SURE FIELNAMES ARE ALL LOWERCASE (to avoid problems later) + $_->[0] =~ s/\s+|-+/_/g; # So now @field_data[1]->[0] contains the field name without spaces at beginning or end and this replaces spaces with _ ie: "field type" becomes "field_type" + push @reserved_used, $_->[0] if $reserved{$_->[0]}; + $_->[1] =~ s/^\s+(\S)\s+$/$1/; + if ($_->[0] =~ /^\+/) #a leading '+' indicates to print negatives + { # or not checked values in a checkbox_group or scrolling_list_multiples + $_->[0] =~ s/^\+(.*)/$1/; + $negatives{$_->[0]}++; #Shortened syntax for putting $field_name, 1 into "negatives" associative array. + #Same as %negatives = (%negatives, $_->[0], 1) + } + } +} +if (@reserved_used) +{ + print "You have chosen the following reserved words as field names. Please try again.\n"; + print "$_\n" for @reserved_used; + exit 1; +} + + + +#**************************************************************************** +#**Send field data to the Make_form subroutine and receive it back as $text** +#**************************************************************************** + +my $make_form_results = make_form(@field_data); +my $out; + + + +#*************************************************************************** +#**************************REPLACEMENT SECTION****************************** +#*************************************************************************** +#***This section replaces the 'PLACE_HOLDERS' in the $whatever.php above.*** +#***$text holds the results from the "make_form" subroutine below. *** +#*************************************************************************** + + +#info.txt +$out = replace($info_txt, 'FORM_NAME', $form_name); #Custom delcared sub 3 parameters +to_file("$form_name/info.txt",$out); + +#new.php +$out = replace($new_php, 'FORM_NAME', $form_name); +$out = replace($out, 'DATABASEFIELDS', $make_form_results); +to_file("$form_name/new.php",$out); + +#print.php +$out = replace($print_php, 'FORM_NAME', $form_name); +$out = replace($out, 'DATABASEFIELDS', $make_form_results); +to_file("$form_name/print.php",$out); + +#report.php +$out = replace($report_php, 'FORM_NAME', $form_name); #Here's where we set $out = to it's corresponding input (whatever_php) and replace the place holder 'FORM_NAME' with the correct $form_name +$out = replace($out, 'DATABASEFIELDS', $make_form_results); #Then replace 'DATABASEFIELDS' in 'whatever_php' with $make_form_results, generated from make_form subroutine. +to_file("$form_name/report.php",$out); + +#save.php +$out = replace($save_php, 'FORM_NAME', $form_name); +$out = replace_save_php($out, @field_data); #Or send it to a special case where extra things can be added to the output. ("replace_save_php" is down below under "sub-routines") +to_file("$form_name/save.php",$out); + +#view.php +$out = replace($view_php, 'FORM_NAME', $form_name); +$out = replace($out, 'DATABASEFIELDS', $make_form_results); +$out = replace_view_php($out); +to_file("$form_name/view.php",$out); + +#table.sql +$out = replace($table_sql, 'FORM_NAME', $form_name); +$out = replace_sql($out, @field_data); +to_file("$form_name/table.sql",$out); + +#preview.html +$out = replace($preview_html, 'FORM_NAME', $form_name); +$out = replace($out, 'DATABASEFIELDS', $make_form_results); +to_file("$form_name/preview.html",$out); + + + + +#****************************************************************** +#************************* SUB-ROUTINES *************************** +#****************************************************************** + +sub replace +{ + my $text = shift; #This shifts through the supplied arguments ($whatever_php, 'FORM_NAME', and $form_name) + #This $text is a LOCAL variable. Does not overwrite other $make_form_results + #Shift starts with the first value. If variable (as in $whatever_php) expands and goes through line by line + my %words = @_; + $text =~ s/$_/$words{$_}/g for keys %words; + return $text; +} + + +sub replace_save_php #a special case +{ + my $text = shift; + my @fields = map {$_->[0]} grep{$_->[0] and $_->[1]} @_; #Checks to see that Field_name and Field_type exist --Grep statement and map to @array. + for (@fields) + { + $_ = "$_='\".\$field_names[\"$_\"].\"'"; + } + my $fields = join ',',@fields; + $text =~ s/FIELDS/$fields/; + @fields = (); + my @negatives; + for (@_) + { + if ($_->[0] and $_->[1]) + { + push @fields, "'$_->[0]' => '$_->[1]'"; + if ($negatives{$_->[0]}) + { + my @temp; + my $count = 2; + while ($count < scalar(@$_)) + { + push @temp, "'$_->[$count]' => '$_->[$count]'"; + $count++; + } + push @negatives, "'$_->[0]' => array(".join(',', @temp).")"; + } + } + } + $fields = join ',', @fields; + $text =~ s/FIELDNAMES/$fields/; + my $negatives = join ',', @negatives; + $text =~ s/NEGATIVES/$negatives/; + return $text; +} + +sub replace_sql #a special case +{ + my $text = shift; + my @fields = map {$_->[0]} grep{$_->[0] and $_->[1]} @_; + my $replace = ''; + $replace .= "$_ TEXT,\n" for @fields; + $text =~ s/DATABASEFIELDS/$replace/; + return $text; +} + +sub replace_view_php #a special case (They're all special cases aren't they? ;^ ) ) +{ + my $text = shift; + $text =~ s/(<\/label>)\s?(