[html-formfu] new dists - major changes!

Octavian Rasnita orasnita at gmail.com
Fri Sep 24 18:37:23 GMT 2010


Hi Carl,

I attached the code of the inflator.

I put it in application's directory:

lib/DBIx/Class/InflateColumn/FileUpload.pm


The scope of this inflator is to be able to add/edit database records that =
contain file fields without manually doing the file upload/movement to the =
desired location and without manually checking if the previously uploaded f=
ile should be replaced with a new one, and without doing the file deletion.
It is not a finished module so it also requires adding 5 lines of code in t=
he edit action method as I explained below.

It was inspired by InflateColumn::File which is deprecated because I couldn=
't make one that subclasses InflateColumn::FS to work with HTML::FormFu, so=
 it has that limitation that it can't create more levels of directories for=
 storing the uploaded files.

For using it I need to do the following:

1. Create the following elements in the form's configuration file.
This is for an edit form. For an insert form is more simple because only th=
e File field is needed.
If the user doesn't check the checkbox "replace file", the existing file al=
ready uploaded won't be replaced.
If the user checks the checkbox and uploads a new file, the new file will r=
eplace the previously uploaded one.
If the user checks the checkbox but doesn't upload a new file, the previous=
ly uploaded file is replaced with nothing, so it is just deleted.
This field's name should be [File_field_name]_replace_validator where File_=
field_name here is "fil".

The second element is used just for showing the user a direct link to the p=
reviously uploaded file. Its content will be created in the programming cod=
e. (This has nothing to do with this inflator, but I also added it here).

These first 2 fields are not required in the edit form, but they are helpfu=
l.

<elements>
name fil_replace_validator
type Checkbox
label_loc Replace file
</elements>

<elements>
name existing_file
type Block
</elements>

<elements>
name fil
type File
label_loc File:
</elements>


2. If the file replace confirmation checkbox is defined, make an accessor f=
or a checkbox in the Result class, because there is no field in the databas=
e table for this field:

__PACKAGE__->mk_group_accessors(simple =3D> 'fil_replace_validator');

3. Load the column inflator in the Result class:

__PACKAGE__->load_components("InflateColumn::FileUpload");

4. Specify the directory where the uploaded files will be stored:

__PACKAGE__->add_columns(
"fil", {
data_type =3D> "varchar2",
default_value =3D> undef,
is_nullable =3D> 1,
size =3D> 255,
is_file_upload =3D> 1,
file_upload_path =3D> $ENV{uploaded_files_dir},
},
);


The method for creating a new record with the values from the submitted for=
m in the database is the known one, with nothing added, like:

sub add : Local : FormConfig {
  my ($self, $c) =3D @_;

  my $form =3D $c->stash->{form};
  $form->default_values({date_time =3D> DateTime->now(time_zone =3D> 'Europ=
e/Bucharest')});

  if ($form->submitted_and_valid) {
    $form->model->create;
    $c->flash(message =3D> "The data was saved successfully.");
    $c->res->redirect($c->uri_for_action("/admin/anunturi/list"));
  }
}


The method used for editing an existing record in the database is a little =
more complex because my column inflator is not fully developed, but ideally=
 it should be as a simple standard method for handling forms without File f=
ields:

sub edit : Local : FormConfig {
  my ($self, $c, $id) =3D @_;

  my $anunt =3D $c->model("DB::Anunturi")->find($id);
  my $form =3D $c->stash->{form};

  if ($form->submitted_and_valid) {
    #Set a hashref for the empty file field because otherwise FileUpload in=
flator ignores it
    #Ideally, the next 4 lines should disappear:
    unless ($form->param('file')) {
      $c->req->params->{file} =3D {};
      $form->process;
    }

    $form->model->update($anunt);
    $c->flash(message =3D> "The data was updated successfully.");
    $c->res->redirect($c->uri_for_action("/admin/anunturi/list"));
  }
  else {
    $form->model->default_values($anunt);

    #The following 8 lines are used for creating the content of the existin=
g_file field (the link to the previously uploaded file)
    # and it could be nice if I could find a cleaner and shorter method of =
doing this:
    my ($filename, $filename_label, $anunt_id);
    if ($anunt->file) {
      $anunt_id =3D $anunt->id;
      $filename =3D $anunt->file->{filename};
      $filename_label =3D encode_entities($filename);
    }

    $form->get_element({name =3D> 'existing_file'})->content_xml(qq~<a href=
=3D"~ . $c->uri_for($c->config->{uploaded_files_url}, $anunt_id, $filename)=
->path . qq~">$filename_label</a>~);

    #Close the file handle because $anunt->file->{handle} doesn't get out o=
f scope
    #This is because of the line: $form->model->default_values($anunt);
    #This is the second piece of code I need to add for using this column i=
nflator because somewhere probably a variable needs to be weakened
    #But this line should also disappear
    undef $anunt->file->{handle} if ref($anunt->file) eq 'HASH';
  }
}


You've seen in the Result class file field definition the following line:

file_upload_path =3D> $ENV{uploaded_files_dir},

This environment variable contains __path_to(root,static,uploaded_files)__

It was taken from the configuration file of the app which contains somethin=
g like:

my $config =3D {
uploaded_files_dir =3D> '__path_to(root,static,uploaded_files)__',
uploaded_files_url =3D> '/static/uploaded_files',
};

$ENV{uploaded_files_dir} =3D $config->{uploaded_files_dir};

$config;

After the module Catalyst::Plugin::ConfigLoader reads this config file, it =
replaces __path_to(...)__ with the generated path in the $c->config but it =
doesn't do it in the environment variable.

Until this last version of HTML::FormFu, I don't know how and where (maybe =
by mistake :) this column inflator was working fine, but now that macro __p=
ath_to()__ is not expanded anymore.

Thanks for reading this long post.

Octavian

----- Original Message ----- =

From: "Carl Franks" <fireartist at gmail.com>
To: "HTML Form Creation,Rendering and Validation Framework" <html-formfu at li=
sts.scsys.co.uk>
Sent: Friday, September 24, 2010 2:42 PM
Subject: Re: [html-formfu] new dists - major changes!


> On 24 September 2010 09:39, Octavian Rasnita <orasnita at gmail.com> wrote:
>> Hi Carl,
>>
>> Thank you for this new release.
>>
>> I found a thing that doesn't work as before and I don't know what was
>> changed.
>>
>> I use HTML::FormFu with a DBIx::Class column inflator for uploading files
>> from the File fields, similar to DBIx::Class::InflateColumn::File and for
>> specifying the directory that will get the uploaded files, I used a
>> configuration like the one below in the DBIC Result classes:
>>
>> file_upload_path =3D> '__path_to(root,static,anunturi)__',
>>
>> Actually, I have this path defined with __path_to()__ in the main
>> configuration file of the application and then I use that configuration =
in
>> the DBIC Result classes.
>> Until this last version of H::F it has been working fine and that string=
 was
>> expanded to the right path by Catalyst::Plugin::ConfigLoader, but now it=
 is
>> used literally and it creates a directory like __path_to(.....)__ so it
>> doesn't work anymore.
>>
>> Do you have any idea where could be the change that make it not work?
> =

> Hi,
> Could you send me the code for the inflator?
> (off-list is fine, if you prefer)
> =

> Cheers,
> Carl
> =

> _______________________________________________
> HTML-FormFu mailing list
> HTML-FormFu at lists.scsys.co.uk
> http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/html-formfu
-------------- next part --------------
A non-text attachment was scrubbed...
Name: FileUpload.pm
Type: application/octet-stream
Size: 4089 bytes
Desc: not available
Url : http://lists.scsys.co.uk/pipermail/html-formfu/attachments/20100924/f=
f67c3a1/FileUpload.obj


More information about the HTML-FormFu mailing list