#! /usr/bin/perl # Copyright 2001-2021 Leslie Richardson # This file is part of Open Admin for Schools. # Open Admin for Schools is free software; you can redistribute it # and/or modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 of # the License, or (at your option) any later version. my %lex = ('Main' => 'Main', 'No Student(s) Found' => 'No Student(s) Found', 'View/Download' => 'View/Download', 'Custom Classlist' => 'Custom Classlist', 'Main' => 'Main', 'View Log File' => 'View Log File', 'Continue' => 'Continue', 'Homeroom' => 'Homeroom', 'Grade' => 'Grade', 'Cell Width' => 'Cell Width', 'Maximum' => 'Maximum', 'Page' => 'Page', 'Students' => 'Students', 'Select by' => 'Select by', 'Repeat Entry Elements' => 'Repeat Entry Elements', 'Classlist' => 'Classlist', 'Rm' => 'Rm', 'Students' => 'Students', 'Paper Size' => 'Paper Size', 'Letter' => 'Letter', 'Legal' => 'Legal', 'A4' => 'A4', 'Font Size' => 'Font Size', 'Gray Shade' => 'Gray Shade', 'Smaller=Darker' => 'Smaller=Darker', 'Include' => 'Include', 'Student Number' => 'Student Number', 'Additional Field' => 'Additional Field', 'Error' => 'Error', 'Y' => 'Y', 'Width' => 'Width', 'Sort by' => 'Sort by', 'Name' => 'Name', 'Single Value Only' => 'Single Value Only', 'Not Found' => 'Not Found', ); my $self = 'rptcustomclasslist.pl'; use DBI; use CGI; use Cwd; # Configurable settings my $maxstudents = 28; # maximum students per page. my $width = 8; # default width of columns, 8 mm; my $defaultgrayshade = '0.90'; # shading for alternate rows my $entrylimit = 18; # Max entries allowed for rotated text. my $maxentrysize = 14; # Maximum number of characters for the entry my $namewidth = 50; # Width of the first 'Name' column in mm. my $studnumwidth = 15; # Width of local student number. my $extrafieldsize = 20; # default extra field in mm; overridden on start page (possible) eval require "../etc/admin.conf"; if ( $@ ) { print $lex{Error}. " $@
\n"; die $lex{Error}. " $@\n"; } eval require "../lib/liblatex.pl"; if ( $@ ) { print $lex{Error}. " $@
\n"; die $lex{Error}. " $@\n"; } my $q = new CGI; print $q->header( -charset, $charset ); my %arr = $q->Vars; my ($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $iddst) = localtime(time); $year = $year + 1900; $wday++; $mon++; my $currdate = "$dow[$wday], $month[$mon] $mday, $year"; my $dsn = "DBI:$dbtype:dbname=$dbase"; my $dbh = DBI->connect($dsn,$user,$password); $dbh->{mysql_enable_utf8} = 1; # Get current dir so know what CSS to display; if ( getcwd() =~ /tcgi/ ){ # we are in tcgi $css = $tchcss; $homepage = $tchpage; } my $title = qq{$lex{'Custom Classlist'}}; print qq{$doctype\n$title\n}; print qq{\n}; print qq{$chartype\n\n}; print qq{
[ $lex{Main} ]
\n}; print qq{

$title

\n}; # Get values for Customization, then exit; # Values passed are width, maxstudents, repeat, entry1 to entry8 if ( not $arr{page} ) { showStartPage(); } else { delete $arr{page}; } # foreach my $key ( sort keys %arr ) { print qq{K:$key V:$arr{$key}
\n}; } if ( $arr{fieldwidth} ) { $extrafieldsize = $arr{fieldwidth}; } delete $arr{fieldwidth}; # Setup Extra fields my ( $studnumfield, $extrafield, $extrafieldName ); if ( $arr{studnumfield} ) { $studnumfield = 1; delete $arr{studnumfield}; } my ($extrafieldName, %defaultvalues); # default values only for selecthash form type if ( $arr{extrafield} ) { $extrafield = $arr{extrafield}; my $sth = $dbh->prepare("select fieldname, defaultvalue, formtype from meta where tableid = 'student' and fieldid = ?"); $sth->execute( $extrafield ); if ($DBI::errstr) { print $DBI::errstr; die $DBI::errstr; } my ($defaultvalue, $formtype); # these 2 are local ($extrafieldName, $defaultvalue, $formtype) = $sth->fetchrow; if ( $formtype eq 'selecthash' ) { # we want to display their text equivalent values from meta my @temp = split(/\s+/, $defaultvalue); #split based on spaces foreach my $val ( @temp ) { $val =~ s/_/ /g; # strip underscores used as separators } %defaultvalues = @temp; } ( $extrafieldName ) = latex_filter( $extrafieldName ); delete $arr{extrafield}; } # Set Sizes # Letter paper size is 279mm x 216mm # 200mm wide - 50mm name, 20mm extra fld, leaves 130mm for columns. # a4 paper is 297mm x 210mm; legal is 356mm x 216mm # The tabcolsep of 1mm leaves 128 mm where each col is $width + 1mm wide. my $fontsize = $arr{fontsize}. 'pt'; my ( $papersize, $textwidth, $textheight ); if ( $arr{papersize} eq 'letter' ) { $papersize = 'letterpaper'; $textwidth = $g_letterpaper_textwidth; $textheight = $g_letterpaper_textheight; } elsif ( $arr{papersize} eq 'legal' ) { $papersize = 'legalpaper'; $textwidth = $g_legalpaper_textwidth; $textheight = $g_legalpaper_textheight; } elsif ( $arr{papersize} eq 'a4' ) { $papersize = 'a4paper'; $textwidth = $g_a4paper_textwidth; $textheight = $g_a4paper_textheight; } # Restrict Gray Shading values if ( $arr{grayshade} > 1 ) { $arr{grayshade} = 1; } if ( $arr{grayshade} < 0.5 ) { $arr{grayshade} = 0.5; } my $wi = $arr{width} - 1; # width of each col desired (in mm) # take away 1 for 1mm tabcolsep. my $availablesize = $textwidth - $namewidth; # Set column count after shrinking available size if ( $studnumfield ) { $availablesize -= $studnumwidth; } if ( $extrafield ) { $availablesize -= $extrafieldsize; } my $colcount = $availablesize / ($arr{width} + 1); $colcount = int $colcount; # truncate # Filter for Passed values that might crash LaTeX foreach my $key ( keys %arr ) { ( $arr{$key} ) = latex_filter( $arr{$key} ); } if ( $arr{maxstudents} ) { $maxlines = $arr{maxstudents}; } else { $maxlines = $maxstudents; } # push entry text into array. for (1..$entrylimit){ my $entryname = 'entry'.$_; if ($arr{$entryname}){ # if it exists...push into array push @entry,$arr{$entryname}; } } my $entrysize = $#entry + 1; #print qq{Entry size: $entrysize\n}; if ($arr{repeat} and $entrysize){ $repeatcount = $colcount / $entrysize; $repeatcount = int $repeatcount; } elsif ($entrysize){ $repeatcount = 1; # only do it once if not repeat. } else { $repeatcount = 0;} #print qq{Repeat Count: $repeatcount\n}; my $shortname = "cclasslist$$"; my $filename = "$shortname.tex"; open(TEX,">$filename") || die "Can't open tex file"; print TEX "\\documentclass[$fontsize,$papersize ]{article} \\usepackage{array,newcent,rotating,colortbl,inputenc} $a_latex_header \\pagestyle{empty} \\setlength{\\textwidth}{$textwidth} \\setlength{\\textheight}{$textheight} \\setlength{\\hoffset}{-36mm} \\setlength{\\voffset}{-36mm} \\addtolength{\\evensidemargin}{0mm} \\addtolength{\\oddsidemargin}{0mm} \\setlength{\\tabcolsep}{1mm} \\setlength{\\extrarowheight}{2mm} \\newcolumntype{G}{>{\\columncolor[gray]{1.00}}p{$namewidth mm}}\n"; # Note above... a columncolor of 1.00 means white, smaller number is darker. print TEX "\\begin{document}\n"; my ($select, $grouptype, @group); if ( $arr{homeroom} ) { if ( $arr{homeroom} eq 'all' ) { my @homerooms; my $sth = $dbh->prepare("select distinct homeroom from student where homeroom is not NULL and homeroom != '';"); $sth->execute; if ($DBI::errstr) { print $DBI::errstr; die $DBI::errstr; } while ( my $hr = $sth->fetchrow ) { push @homerooms, $hr; } @group = sort {$a <=> $b} @homerooms; } else { # one homeroom # my $grpvalue = $dbh->quote( $arr{homeroom} ); push @group, $arr{homeroom}; } $grouptype = 'homeroom'; } elsif ( $arr{grade} ) { if ( $arr{grade} eq 'all' ) { my @grades; my $sth = $dbh->prepare("select distinct grade from student where grade is not NULL and grade != '';"); $sth->execute; if ($DBI::errstr) { print $DBI::errstr; die $DBI::errstr; } while ( my $grade = $sth->fetchrow ) { push @grades, $grade; } @group = sort {$a <=> $b} @grades; } else { # one grade only # my $grpvalue = $dbh->quote( $arr{grade} ); # $select = "where grade = $grpvalue"; push @group, $arr{grade} } $grouptype = 'grade'; } else { # Error; no selection print qq{No Homeroom or Grade selected.\n}; print qq{\n}; exit; } # Set sorting order my $sortorder = 'order by lastname, firstname'; my $teachername; #for my $i ( 1..$rows ) { foreach my $graderoom ( @group ) { # grade or homeroom my $sth = $dbh->prepare("select lastname, firstname, grade, homeroom, studnum from student where $grouptype = ? order by lastname, firstname"); $sth->execute( $graderoom ); # grade or homeroom if ($DBI::errstr) { print $DBI::errstr; die $DBI::errstr; } # Get Teacher name, if any my $sth1 = $dbh->prepare("select sal, lastname from staff as s, staff_multi as sm where s.userid = sm.userid and field_name = 'homeroom' and field_value = ?"); $sth1->execute( $graderoom ); if ($DBI::errstr) { print "Teacher Error: $DBI::errstr"; die $DBI::errstr; } $teachrows = $sth1->rows; $teachername = ''; for ( 1..$teachrows ){ my ($sal, $lastname) = $sth1->fetchrow; $teachername .= " $sal~$lastname"; } # end of teacher name my $first = 1; my $linecount = $studcount = 0; while ( my ( $lastname, $firstname, $grade, $homeroom, $studnum ) = $sth->fetchrow ) { if ( $first ) { # print header to start prHeader($teachername, $graderoom ); $first = 0; } $linecount++; $studcount++; if ( $linecount > $maxlines ) { # We'll print a new page header here # New Page Header $linecount = 0; if ( $i != 1 ) { print TEX "\\end{tabular}\\\\ \\newpage\n"; } prHeader($teachername, $graderoom ); } # Print Normal Record. prRecord($lastname, $firstname, $studnum); } # now do bottom of page prStudCount(); print TEX "\n\\end{tabular} \n\n \\newpage \n"; } # End of Loop for all groups #$studcount++; #prStudCount(); # print TEX "\\end{tabular}\\\\ \n\\end{document}"; print TEX "\n\\end{document}"; close TEX; # Solve download location issues with cgi vs tcgi.. # Get current dir so know what CSS to display; if (getcwd() =~ /tcgi/){ # we are in tcgi $downloaddir = $tchdownloaddir; $webdownloaddir = $tchwebdownloaddir; } system("$pdflatex $filename >pdflog$$.txt"); system("mv $shortname.pdf $downloaddir"); system("mv pdflog$$.txt $downloaddir"); system("rm -f $shortname.*"); print qq{

}; print qq{$lex{'View/Download'} $lex{'Custom Classlist'}

\n}; print qq{

[ $lex{Main} |\n }; print qq{$lex{'View Log File'}\n ]

}; print qq{\n}; #---------------- sub showStartPage { # Entry Values for Custom Script #---------------- # Read student fields, and defaults into a @fields and %fieldname hash. my $sth = $dbh->prepare("select fieldid, fieldname from meta where tableid = 'student' order by fieldname"); $sth->execute; if ($DBI::errstr) { print $DBI::errstr; die $DBI::errstr; } my @fields; my %fieldnames; while ( ( my $fieldid, $fieldname ) = $sth->fetchrow ) { # $fieldname =~ s/\(//g; # $fieldname =~ s/\)//g; # strip parenthese. (sp?) push @fields, $fieldid; $fieldname{ $fieldid } = $fieldname; } # Get Grades my @grades; my $sth = $dbh->prepare("select distinct grade from student where grade is not NULL and grade != '';"); $sth->execute; if ($DBI::errstr) { print $DBI::errstr; die $DBI::errstr; } while ( my $grade = $sth->fetchrow ) { push @grades, $grade; } @grades = sort {$a <=> $b} @grades; # Get Homerooms my @homerooms; my $sth = $dbh->prepare("select distinct homeroom from student where homeroom is not NULL and homeroom != '';"); $sth->execute; if ($DBI::errstr) { print $DBI::errstr; die $DBI::errstr; } while ( my $hr = $sth->fetchrow ) { push @homerooms, $hr; } @homerooms = sort {$a <=> $b} @homerooms; print qq{
\n}; print qq{\n}; print qq{\n}; print qq{\n}; # Student By Grade print qq{}; print qq{\n}; # OR print qq{\n}; # Student by Homeroom my $sth = $dbh->prepare("select lastname, firstname from staff s, staff_multi sm where s.userid = sm.userid and field_name = 'homeroom' and field_value = ?"); print qq{\n}; # Sort Order # print qq{}; # print qq{}; # print qq{\n}; # Use Legal Name, if present print qq{}; print qq{\n}; # Cell Width print qq{\n\n}; # Font size print qq{\n}; # Gray Shade print qq{\n}; # Paper print qq{\n}; # Include Student Number print qq{}; print qq{\n}; # Additional Field print qq{\n}; print qq{\n}; # Additional Field Width print qq{\n}; print qq{\n}; # $extrafieldsize is set at top of script as a default value. # Max Student print qq{\n\n}; print qq{\n}; print qq{\n}; for ( 1..$entrylimit ) { my $entrytxt = "entry$_"; print qq{\n}; print qq{}; print qq{\n}; } print qq{\n}; print qq{
$lex{'Select by'} $lex{Grade}
OR
Homeroom}; print qq{
$lex{'Sort by'}
Use Legal Name (if present)
$lex{'Cell Width'}}; print qq{ mm
$lex{'Font Size'}\n}; print qq{
$lex{'Gray Shade'}\n}; print qq{}; print qq{ (0-1) $lex{'Smaller=Darker'}
$lex{'Paper Size'}}; print qq{
$lex{Include} $lex{'Student Number'}
$lex{'Additional Field'}
$lex{'Additional Field'} $lex{Width} mm
$lex{Maximum} $lex{Students}/$lex{Page}}; print qq{}; print qq{
$lex{'Repeat Entry Elements'}?
Entry $_
\n}; exit; } #----------- sub prHeader { #----------- my ($teachername,$group) = @_; # Done at the start of a new page. print TEX "\\begin{tabular}{G|"; if ( $studnumfield ) { print TEX "p{ $studnumwidth mm}|"; } if ( $extrafield ) { print TEX "p{ $extrafieldsize mm}|"; } for (1..$colcount){ print TEX "p{$wi mm}|"; } print TEX "}\n"; print TEX "\\raggedright\\bf $schoolname ". $lex{Classlist}; if ( $studnumfield ) { print TEX "& "; } if ( $extrafield ) { print TEX "& "; } for ( 1..$colcount ){ print TEX "& ";} print TEX "\\\\ \n"; print TEX "\\small\\raggedright $currdate\n\\bigskip "; if ( $studnumfield ) { print TEX "& "; } if ( $extrafield ) { print TEX "& "; } for ( 1..$colcount ){ print TEX "& ";} print TEX "\\\\ \n"; # Print Grade or Homeroom, if not sorting by name # if ( not $group ) { $group = $lex{'Not Found'}; } if ( $grouptype eq 'grade' ){ print TEX "\\Large\\raggedright $lex{Grade} $group "; } else { # homeroom print TEX "\\bf\\raggedright $teachername "; print TEX $lex{Rm}. " $group "; } if ( $studnumfield ) { print TEX "& "; } if ( $extrafield ) { print TEX "&\\hfil\\rule{6pt}{0pt}\\begin{rotate}{90}$extrafieldName"; print TEX "\\end{rotate}\\hfil"; #print TEX "& "; } my $remainder = $colcount - ($repeatcount * $entrysize); if ( $repeatcount ){ for (1..$repeatcount){ # times to loop to print rotated text. foreach my $txt ( @entry ) { print TEX "&\\hfil\\rule{6pt}{0pt}\\begin{rotate}{90}$txt"; print TEX "\\end{rotate}\\hfil"; } } } for (1..$remainder){ print TEX "& ";} print TEX "\\\\ \\hline\n"; } # End of prHeader #----------- sub prRecord { # print normal record (ie. line) #----------- my ( $lastname, $firstname, $studnum ) = @_; my ($youngest, $sex, $efield); my $fields = 'youngest, sex, legal_lastname, legal_firstname '; if ( $extrafield ) { $fields .= ", $extrafield"; } my $sth1 = $dbh->prepare("select $fields from student where studnum = ?"); $sth1->execute( $studnum ); if ($DBI::errstr) { print $DBI::errstr; die $DBI::errstr; } ( $youngest, $sex, $legal_lastname,$legal_firstname, $efield ) = $sth1->fetchrow; ( $efield ) = latex_filter( $efield ); if ( $youngest ) { $youngest = $lex{Y}; } if ( $arr{uselegal} ) { my $fi = substr($firstname, 0, 1); my $li = substr($lastname, 0, 1); if ( $legal_lastname ) { $lastname = "$li$fi ". $legal_lastname. "{\\bf\\tiny{a}}"; } if ( $legal_firstname ) { $firstname = $legal_firstname. "{\\bf\\tiny{a}}"; } } if ( $alternatingcolor == 0 ) { print TEX "\\rowcolor[gray]{". $arr{grayshade}. "}"; $alternatingcolor = 1; } else { $alternatingcolor = 0;} print TEX "\\raggedright $lastname, $firstname"; if ( $studnumfield ) { my $snfld = $studnum. $youngest. $sex; print TEX "&\\footnotesize{$snfld}"; } if ( $extrafield ) { if ( %defaultvalues and $efield ) { my $tmp = $efield; # store original value $efield = $defaultvalues{$efield}; # display text equivalent $efield .= qq{ ($tmp)}; } print TEX "&\\hfil\\footnotesize{$efield}\\hfil"; } for (1..$colcount){ print TEX "& ";} print TEX "\\\\\\hline\n"; } #-------------- sub prStudCount { #-------------- #if ($alternatingcolor == 0){ # continue color from above... my $grayval = $arr{grayshade} - 0.08; # make it darker, slightly print TEX "\\rowcolor[gray]{$grayval}"; #} print TEX $lex{Students}. ": $studcount"; if ( $studnumfield ) { print TEX "& "; } for (1..$colcount){ print TEX "& ";} print TEX "\\\\\\hline\n"; }