
package LedgerSMB::Template::DB;

=head1 NAME

LedgerSMB::Template::DB - Template administration functions for LedgerSMB

=head1 DESCRIPTION

Implements the routines to save, store and edit document templates to/from
"the" database.

=head1 SYNPOPSIS

To retrieve template data as a scalar ref (for TT):

   LedgerSMB::Template::DB->get_template($template_name, $language_code);

To retrieve for editing:

   LedgerSMB::Template::DB->get_by_id($id);

or

   LedgerSMB::Template::DB->get(
           template_name => $template_name, language_code => $language_code
   );

To save:

   my $template =  LedgerSMB::Template::DB->new(%$request);
   $template->save;

=cut

use Moose;
use namespace::autoclean;
with 'LedgerSMB::PGObject', 'LedgerSMB::I18N';

=head1 PROPERTIES

=head2 id int

=head2 template_name text (required)

=head2 language_code text

=head2 template text (required)

=head2 format text (required)


=cut

has id             => (is => 'ro', isa => 'Int', required => 0);
has template_name  => (is => 'ro', isa => 'Str', required => 1);
has language_code  => (is => 'ro', isa => 'Str', required => 0);
has format         => (is => 'ro', isa => 'Str', required => 1);
has template       => (is => 'ro', isa => 'Str', required => 1);


=head1 METHODS

=head2 get_template(template_name, language_code, format)

Returns a scalar ref to the template text so that Template Toolkit can run it.

=cut

sub get_template {
    my ($module, $template_name, $language_code, $format) = @_;
    my ($temp) = __PACKAGE__->call_procedure(
         funcname => 'template__get',
         args => [$template_name, $language_code, $format]
    );
    my $text = $temp->{template};
    die text('Could Not Load Template from DB') unless $text;
    $temp = __PACKAGE__->new($temp);
    return \$text;
}

=head2 get_by_id(id)

Gets the template by ID.  Returns a whole template object.

=cut

sub get_by_id {
    my ($module, $id) = @_;
    my ($temp) = __PACKAGE__->call_procedure(
         funcname => 'template__get_by_id',
         args => [$id]
    );
    return __PACKAGE__->new(%$temp);
}


=head2 get(hash args)

Gets the template by args (for editing or management).  Args are:

=over

=item template_name

=item language_code

=item format

=item dbh

=back

=cut

sub get {
    my $module = shift @_;
    my %args = @_;
    my @args =
        $args{id} ? ($args{id})
        : (@args{qw/template_name language_code format /});
    my ($temp) = __PACKAGE__->call_procedure(
        dbh        => $args{dbh},
        funcname   => ($args{id} ? 'template__get_by_id' : 'template__get'),
        funcschema => $args{dbh}->{private_LedgerSMB}->{schema},
        args       => \@args,
    );
    die text('Could Not Load Template from DB') unless $temp;
    for (keys (%$temp)){
        delete $temp->{$_} unless defined $temp->{$_};
    }
    $temp->{_dbh} = $args{dbh};
    return __PACKAGE__->new(%$temp);
}

=head2 get_from_file($path, $language_code)

Loads a template from a file path.  This should only be used during database
setup because it could be used to access any file on the system that the web
server or fcgi process could.  It is highly recommended that other web app code
does not call this without carefully whitelisting values.

=cut

sub get_from_file {
    my ($package, $path, $language_code) = @_;
    my $fname;
    if ($path =~ m|/.*:| ){
       die 'Cannot run on NTFS alternate data stream!';
    }
    if ( $path =~ m|(.*)/([^/]+)$| ) {
        $fname = $2;
    }

    my ($template_name, $format) = split /\./, $fname;
    my $content = '';
    open my $fh, '<', $path
        or die "Failed to open template file $path : $!";
    {
        local $/ = undef;
        $content =  <$fh>;
    }
    close $fh or die "Cannot close file $path";
    my %args = (
           template_name => $template_name,
           format => $format,
           template => $content,
    );
    $args{language_code} = $language_code if $language_code;
    my $self = LedgerSMB::Template::DB->new(%args);
    return $self;
}


=head2 save

Saves the current object

=cut

sub save {
    my ($self) = @_;
    return $self->call_dbmethod(funcname => 'template__save');
}

=head1 LICENSE AND COPYRIGHT

Copyright (C) 2014 The LedgerSMB Core Team

This file is licensed under the GNU General Public License version 2, or at your
option any later version.  A copy of the license should have been included with
your software.

=cut

__PACKAGE__->meta->make_immutable;

1;
