App-ZofCMS
view release on metacpan or search on metacpan
lib/App/ZofCMS/Plugin/CRUD.pm view on Meta::CPAN
$self->{T}{t}{crud_items} = $db_items;
}
}
sub _process_DELETE {
my $self = shift;
### Delete all the files, if we have any
my @file_items = grep $_->{el_file}, @{ $self->{ITEMS} || [] };
if ( @file_items ) {
my $item = ($self->_dbh->selectall_arrayref(
'SELECT * FROM `' . $self->{CONF}{table}. '` WHERE `crud_id` = ?',
{ Slice => {} },
$self->{Q}{crud_id},
) || [])->[0]
or return $self->_set_error(q|Couldn't find the item to delete|);
for ( map $_->{name}, @file_items ) {
unlink $item->{ $_ };
}
}
$self->_dbh->do(
'DELETE FROM `' . $self->{CONF}{table} . '` WHERE `crud_id` = ?',
undef,
$self->{Q}{crud_id},
);
$self->{T}{t}{crud_success_message}
= '<p class="success-message">Item was successfully deleted.</p>';
}
sub _set_error {
my $self = shift;
my $error = shift;
$self->{T}{t}{crud_error} = qq|<p class="error">$error</p>|;
return;
}
sub _process_CREATE {
my $self = shift;
my @errors;
for ( grep !$_->{el_auto_set}, @{ $self->{ITEMS} || [] } ) {
next if $_->{optional};
push @errors, +{ error => "Parameter '$_->{text}' must be specified" }
unless defined $_->{value} and length $_->{value};
}
if ( @errors ) {
$self->{FORM_ERRORS} = \@errors;
return;
}
for my $item (
grep $_->{el_file}
&& defined $self->{Q}{ $_->{name} }
&& length $self->{Q}{ $_->{name} }, @{ $self->{ITEMS} || [] }
) {
push @errors, grep defined, $self->_process_file_upload( $item );
}
if ( @errors ) {
$self->{FORM_ERRORS} = \@errors;
return;
}
$self->_insert_CREATE_into_db;
}
sub _process_file_upload {
my $self = shift;
my $item = shift;
my $cgi = $self->{CONFIG}{cgi};
my $fh = $cgi->upload( $item->{name} );
if ( not $fh and $cgi->cgi_error ) {
return +{ error => 'File upload error: ' . $cgi->cgi_error };
}
return +{ error => q|File upload error (no error message available)| }
unless $fh;
( my $filename = $item->{value} ) =~ s/[^\w.-]/_/g;
while ( -e File::Spec->catdir( $self->{CONF}{file_dir}, $filename ) ) {
$filename = "_$filename";
}
$filename = File::Spec->catdir( $self->{CONF}{file_dir}, $filename );
return +{ error => "Failed to open local file $filename [$!]" }
unless open my $fh_out, '>', $filename;
seek $fh, 0, 0;
binmode $fh;
binmode $fh_out;
{
local $/ = \1024;
while ( <$fh> ) {
print $fh_out $_;
}
}
close $fh;
close $fh_out;
$item->{value} = $filename;
return;
}
sub _insert_CREATE_into_db {
my $self = shift;
my %items = map +( @$_{qw/name value/} ), @{ $self->{ITEMS} };
$self->_dbh->do(
"INSERT INTO `$self->{CONF}{table}` (" .
join(',', map "`$_`", keys %items )
. ') VALUES (' .
join(', ', ('?') x (keys %items) )
. ')',
undef,
values %items,
);
$self->{CREATE_SUCCESS} = 1
}
sub _create_CU_form {
my $self = shift;
my $is_create = shift;
my $ht = HTML::Template->new_scalar_ref( \(_get_CU_form_template()),
die_on_bad_params => 0,
);
my @items = @{ $self->{ITEMS} || [] };
$ht->param(
lib/App/ZofCMS/Plugin/CRUD.pm view on Meta::CPAN
items => [
{ Time => sub { time(); } },
]
The key will function the same as described for C<A string> above. The
only difference is that this item will not be shown in the Create/Update
form. The sub will be executed and its value will be assigned to the item
as if it were specified by the user. On Update, this item will not be
editable and the sub B<will NOT be executed>. The C<@_> of the sub will
contain (in that order): ZofCMS Template hashref and query parameters
hashref where keys are params' names and values are their values.
=head3 C<list_sub>
list_sub => sub {
my ( $d, $t, $q ) = @_;
for ( @$d ) {
$_->{time} = localtime $_->{time};
$_->{is_good_employee}
= $t->{d}{records}{ $_->{employee_s_performance_record__} }
? 1 : 0;
$_->{sort} = $q->{sort};
}
},
B<Optional.> B<By default> is not specified.
B<Takes >a subref as a value. Allows you to make modifications
to the list of records in the List output. The C<@_> of the sub will
contain (in that order): the arrayref of hashrefs where each hashref
is a record in the database, ZofCMS Template hashref, and query parameters
hashref where keys are params' names and values are their values. The
hashref for each record will contain all the columns from the database
for that specific record, as well as:
=over 10
=item * C<< crud_can_ud => 1 >> if the user
can either update or delete records (see C<can> parameter below),
=item * C<< crud_can_u => 1 >> if the user can update records
=item * C<< crud_can_d => 1 >> if the user can delete records
=item * C<< crud_d_form >> containing HTML of the form used for deleting
this record
=item * C<< crud_u_form >> containing HTML of the form used for
updating this record
=back
=head3 C<file_dir>
file_dir => 'files',
B<Optional.> B<Defaults to> C<files>. B<Takes> a string as a value that
specifies the directory (relative to C<index.pl>) where the plugin
will store files uploaded by the user (that is for any records for which
C<< <input type="file"> >> was used in the Create form).
=head3 C<can>
can => 'CRUDL',
can => 'RL',
can => 'CUL',
B<Optional.> B<Defaults to> C<CRUDL>. Takes a string of letters
(in any order) as the value. Each letter specifies what the current
user is allowed to do: C<< C => Create >>, C<< R => Read >>,
C<< U => Update >>, C<< D => Delete >>, C<< L => List >>. B<Note:>
if C<L> is specified, plugin will automatically load B<all> records into
C<< {t}{crud_list} >>.
=head3 C<no_time_sort>
no_time_sort => 0,
B<Optional. Takes> true or false value. B<Defaults to> false. In 99%
of my CRUD pages, I've had a C<time> item in the record that stored
the time of
when the record was added, and when the records were listed they were
sorted by "most recent first." This is exactly what this plugin does
automatically
and it expects C<time> item to be present and set to a value of Unix time
(output of C<time()>). If you don't have such a column or don't want your
records sorted by time, set C<no_time_sort> to a true value.
=head1 HTML::Template TEMPLATE VARIABLES
<tmpl_var name='crud_success_message'>
<tmpl_var name='crud_error'>
<h3>Add New Item</h3>
<tmpl_var name='crud_form'>
<h3>Items In The Database</h3>
<tmpl_if name='crud_has_items'>
<table>
<thead>
<tr>
<td>File</td>
<td>Description</td>
<td>Add Time</td>
</tr>
</thead>
<tbody>
<tmpl_loop name='crud_items'>
<tr>
<td>
<tmpl_var name='crud_d_form'>
<tmpl_var name='crud_u_form'>
<a href="<tmpl_var escape='html' name='file'>"
><tmpl_var escape='html' name='item'></a></td>
<td><tmpl_var name='description'></td>
( run in 0.979 second using v1.01-cache-2.11-cpan-b16cb0d3907 )