package Smolder::Control::Developer::Prefs;
use base 'Smolder::Control';
use strict;
use warnings;
use Smolder::Constraints qw(enum_value length_between unsigned_int existing_field_value bool);
=head1 NAME
Smolder::Control::Developer::Prefs
=head1 DESCRIPTION
Controller module for dealing with developer preferences
=cut
sub setup {
my $self = shift;
$self->start_mode('show');
$self->run_modes(
[
qw(
show
update_pref
change_pw
process_change_pw
get_pref_details
)
]
);
}
sub require_group { 'developer' }
=head1 RUN MODES
=head2 change_pw
Show the form to allow a developer to change their password. Uses the
F<Developer/Prefs/change_pw.tmpl> template.
=cut
sub change_pw {
my ($self, $tt_params) = @_;
$tt_params ||= {};
return $self->tt_process($tt_params);
}
=head2 process_change_pw
Handled the incoming data from the C<change_pw> run mode. If
it passes validation then it updates the database and then returns
to the C<change_pw> mode.
=cut
sub process_change_pw {
my $self = shift;
my $dev = $self->developer;
# validate the incoming info
my $form = {
required => [qw(current_pw new_pw new_pw_retyped)],
constraint_methods => {
# make sure it's the right encrypted pw
current_pw => sub {
my ($dfv, $val) = @_;
if (crypt($val, $dev->password) eq $dev->password) {
return $val;
} else {
return;
}
},
# make sure it's long enough (but not too long)
new_pw => length_between(4, 255),
# make sure it's the same as 'new_pw'
new_pw_retyped => sub {
my ($dfv, $val) = @_;
# get the value of 'new_pw'
my $data = $dfv->get_input_data(as_hashref => 1);
if ($data->{new_pw} eq $val) {
return $val;
} else {
return;
}
},
},
};
my $results = $self->check_rm('change_pw', $form)
|| return $self->check_rm_error_page();
my $valid = $results->valid();
$dev->password($valid->{new_pw});
$dev->update();
$self->add_message(msg => "Password successfully changed.");
return $self->change_pw();
}
=head2 show
Show all of the preferences for each project that this developer is assigned to.
Uses the F<Developer/Prefs/show.tmpl> template.
=cut
sub show {
my ($self, $tt_params, $pref) = @_;
$tt_params ||= {};
my $html = $self->tt_process($tt_params);
# if this wasn't an update form submission
# and we don't have a preference, then make it the default
if (!$self->query->param('update_pref') && !$pref) {
$pref = $self->developer->preference;
}
# if we have a preference use it to fill in the form
if ($pref) {
my %fill_data =
map { $_ => $pref->$_ } qw(id email_type email_freq email_limit show_passing);
return HTML::FillInForm->new()->fill(
scalarref => $html,
fdat => \%fill_data,
);
} else {
return $html;
}
}
=head2 get_pref_details
This run mode will return a JSON header which contains the name-value
pairs for this preferences data.
=cut
sub get_pref_details {
my $self = shift;
my $pref = Smolder::DB::Preference->retrieve($self->query->param('id'));
my %data;
if ($pref) {
%data = map { $_ => $pref->$_ } qw(email_type email_freq email_limit show_passing);
}
return $self->add_json_header(%data);
}
=head2 update_pref
Update the information coming from the C<show> run mode.
If validation passes, the database is updated and the C<show>
run mode is returned.
=cut
sub update_pref {
my $self = shift;
# validate the data
my $form = {
required => [qw(id email_type email_freq email_limit show_passing)],
constraint_methods => {
id => existing_field_value('preference', 'id'),
email_type => enum_value('preference', 'email_type'),
email_freq => enum_value('preference', 'email_freq'),
email_limit => unsigned_int(),
show_passing => bool(),
}
};
my $results = $self->check_rm('show', $form)
|| return $self->check_rm_error_page();
my $valid = $results->valid();
my $pref = Smolder::DB::Preference->retrieve($valid->{id});
if ($pref) {
delete $valid->{id};
$pref->set(%$valid);
$pref->update();
# is this the default pref?
if ($pref->id eq $self->developer->preference) {
$self->add_message(msg => "Default preferences successfully updated.");
} else {
$self->add_message(msg => "Preference for project '"
. $pref->project->name
. "' has been successfully updated'");
}
}
# if we are updating the default pref and they want to sync them
if ($self->query->param('sync') && ($pref->id eq $self->developer->preference)) {
my @projs = $self->developer->project_developers;
foreach my $proj (@projs) {
$proj->preference->set(%$valid);
$proj->preference->update();
}
$self->add_message(msg => "Preferences have been successfully synced with all Projects.");
}
return $self->show({}, $pref);
}
1;