diff --git a/conf/defaults.config b/conf/defaults.config index eb631e9790..d3335b276f 100644 --- a/conf/defaults.config +++ b/conf/defaults.config @@ -73,7 +73,7 @@ $mail{feedbackRecipients} = [ # %% = literal percent sign # -$mail{feedbackSubjectFormat} = "[WWfeedback] course:%c user:%u set:%s prob:%p sec:%x rec:%r"; +$mail{feedbackSubjectFormat} = '[WWfeedback] course:%c user:%u{ set:%s}{ prob:%p}{ sec:%x}{ rec:%r}'; # feedbackVerbosity: # 0: send only the feedback comment and context link diff --git a/lib/WeBWorK/ConfigValues.pm b/lib/WeBWorK/ConfigValues.pm index 27ccd65cbb..209cde6df8 100644 --- a/lib/WeBWorK/ConfigValues.pm +++ b/lib/WeBWorK/ConfigValues.pm @@ -829,13 +829,15 @@ sub getConfigValues ($ce) { x('E-Mail'), { var => 'mail{feedbackSubjectFormat}', - doc => x('Format for the subject line in feedback emails'), + doc => x('Format for the subject of feedback emails'), doc2 => x( - 'When students click the Email Instructor button to send feedback, WeBWorK fills in the ' - . 'subject line. Here you can set the subject line. In it, you can have various bits of ' - . 'information filled in with the following escape sequences.

If content is between ' + . "a brace pair, like '{ rec:%r}', then it will only be included in the subject line if all " + . 'substitutions within the double brace pair are defined and nonempty.' ), width => 45, type => 'text' diff --git a/lib/WeBWorK/ContentGenerator/Feedback.pm b/lib/WeBWorK/ContentGenerator/Feedback.pm index 336e5fc127..335caff765 100644 --- a/lib/WeBWorK/ContentGenerator/Feedback.pm +++ b/lib/WeBWorK/ContentGenerator/Feedback.pm @@ -12,7 +12,7 @@ use Email::Stuffer; use Try::Tiny; use WeBWorK::Upload; -use WeBWorK::Utils qw(createEmailSenderTransportSMTP fetchEmailRecipients); +use WeBWorK::Utils qw(createEmailSenderTransportSMTP fetchEmailRecipients formatEmailSubject); # request paramaters used # @@ -108,18 +108,15 @@ sub initialize ($c) { } } - my %subject_map = ( - 'c' => $courseID, - 'u' => $user ? $user->user_id : undef, - 's' => $set ? $set->set_id : undef, - 'p' => $problem ? $problem->problem_id : undef, - 'x' => $user ? $user->section : undef, - 'r' => $user ? $user->recitation : undef, - '%' => '%', + my $subject = formatEmailSubject( + $ce->{mail}{feedbackSubjectFormat}, + $courseID, + $user ? $user->user_id : '', + $set ? $set->set_id : '', + $problem ? $problem->problem_id : '', + $user ? $user->section : '', + $user ? $user->recitation : '' ); - my $chars = join('', keys %subject_map); - my $subject = $ce->{mail}{feedbackSubjectFormat} || 'WeBWorK question from %c: %u set %s/prob %p'; - $subject =~ s/%([$chars])/defined $subject_map{$1} ? $subject_map{$1} : ''/eg; my %data = ( user => $user, diff --git a/lib/WeBWorK/Utils.pm b/lib/WeBWorK/Utils.pm index 86a2e91a90..a7c9f8d54c 100644 --- a/lib/WeBWorK/Utils.pm +++ b/lib/WeBWorK/Utils.pm @@ -30,6 +30,7 @@ our @EXPORT_OK = qw( processEmailMessage createEmailSenderTransportSMTP generateURLs + formatEmailSubject getAssetURL x ); @@ -382,6 +383,35 @@ sub generateURLs ($c, %params) { } } +sub formatEmailSubject ($formatString, $courseID, $userID, $setID, $problemID, $section, $recitation) { + my %subject_map = ( + c => $courseID, + u => $userID, + s => $setID, + p => $problemID, + x => $section, + r => $recitation, + '%' => '%', + ); + my $chars = join('', keys %subject_map); + my $subject = $formatString; + # extract the brace pairs + my @braces = $formatString =~ /(\{(?:[^{}]*|(?0))*\})/xg; + if (@braces) { + # for each brace pair, do substitutions, but leave %c etc when variable is empty + my %braces = map { $_ => $_ =~ s/%([$chars])/$subject_map{$1} ne '' ? $subject_map{$1} : "%$1"/egr } @braces; + # if there is an instance of %c, etc, nullify the whole thing + %braces = map { $_ => $braces{$_} =~ /%[$chars]/ ? '' : $braces{$_} } keys %braces; + # remove outer braces + %braces = map { $_ => $braces{$_} =~ s/\{(.*)\}/$1/egr } keys %braces; + my $regex = join('|', keys %braces); + $regex = qr/$regex/; + $subject =~ s/($regex)/$braces{$1}/g; + } + $subject =~ s/%([$chars])/$subject_map{$1} ne '' ? $subject_map{$1} : ''/eg; + return $subject; +} + my $staticWWAssets; my $staticPGAssets; my $thirdPartyWWDependencies; diff --git a/lib/WeBWorK/Utils/ProblemProcessing.pm b/lib/WeBWorK/Utils/ProblemProcessing.pm index cb2af6bd38..cfe9ba8903 100644 --- a/lib/WeBWorK/Utils/ProblemProcessing.pm +++ b/lib/WeBWorK/Utils/ProblemProcessing.pm @@ -13,7 +13,7 @@ use Try::Tiny; use Mojo::JSON qw(encode_json decode_json); use WeBWorK::Debug; -use WeBWorK::Utils qw(encodeAnswers createEmailSenderTransportSMTP); +use WeBWorK::Utils qw(encodeAnswers createEmailSenderTransportSMTP formatEmailSubject); use WeBWorK::Utils::DateTime qw(before after); use WeBWorK::Utils::JITAR qw(jitar_id_to_seq jitar_problem_adjusted_status); use WeBWorK::Utils::Logs qw(writeLog writeCourseLog); @@ -383,19 +383,12 @@ sub jitar_send_warning_email ($c, $userProblem) { $problemID = join('.', jitar_id_to_seq($problemID)); - my %subject_map = ( - 'c' => $courseID, - 'u' => $userID, - 's' => $setID, - 'p' => $problemID, - 'x' => $user->section, - 'r' => $user->recitation, - '%' => '%', + my $subject = formatEmailSubject( + $ce->{mail}{feedbackSubjectFormat}, + $courseID, $userID, $setID, $problemID, + $user ? $user->section : '', + $user ? $user->recitation : '' ); - my $chars = join('', keys %subject_map); - my $subject = $ce->{mail}{feedbackSubjectFormat} - || 'WeBWorK question from %c: %u set %s/prob %p'; # default if not entered - $subject =~ s/%([$chars])/defined $subject_map{$1} ? $subject_map{$1} : ""/eg; my $full_name = $user->full_name; my $email_address = $user->email_address;