Login | Register For Free | Help
Search for: (Advanced)

Mailing List Archive: Catalyst: Users

Where is the form field lost?

 

 

Catalyst users RSS feed   Index | Next | Previous | View Threaded


orasnita at gmail

Jan 24, 2010, 7:03 AM

Post #1 of 15 (2194 views)
Permalink
Where is the form field lost?

Hi,

After sending a form with a file upload field, that field is lost if no file
was attached, just like when the form doesn't contain that file upload field
at all.

I have tried to check Catalyst, Catalyst::Request, Catalyst::Engine,
HTTP::Body and HTTP::Body::MultiPart in order to find where are the file
upload fields lost, but I
couldn't find it.

I need to know if the form didn't have a file upload field, or if it had it
but no file was uploaded.

I have printed Dumper $request->_body in Catalyst::Engine::prepare_uploads,
and when a file is uploaded, it looks like:

$VAR1 = bless( {
'content_length' => '1727',
'tmpdir' => 'C:\\DOCUME~1\\Octavian\\LOCALS~1\\Temp',
'part' => {},
'buffer' => '',
'state' => 'done',
'chunk_buffer' => '',
'body' => undef,
'content_type' => 'multipart/form-data;
boundary=---------------------------7da8c3070458',
'length' => 1727,
'boundary' => '---------------------------7da8c3070458',
'chunked' => '',
'upload' => {
'file' => {
'headers' => {
'Content-Type' =>
'text/plain',
'Content-Disposition'
=> 'form-data; name="file"; filename="E:\\zzzz_cool.txt"'
},
'tempname' =>
'C:\\DOCUME~1\\Octavian\\LOCALS~1\\Temp\\PrJ0ruNzzR',
'name' => 'file',
'size' => 44,
'filename' => 'E:\\zzzz_cool.txt'
}
},
'param' => {},
}, 'HTTP::Body::MultiPart' );


If no file was uploaded, it prints:

$VAR1 = bless( {
'content_length' => '1699',
'tmpdir' => 'C:\\DOCUME~1\\Octavian\\LOCALS~1\\Temp',
'part' => {},
'buffer' => '',
'state' => 'done',
'chunk_buffer' => '',
'body' => undef,
'content_type' => 'multipart/form-data;
boundary=---------------------------7da1573870458',
'length' => 1699,
'boundary' => '---------------------------7da1573870458',
'chunked' => '',
'upload' => {},
'param' => {},
}, 'HTTP::Body::MultiPart' );

So the 'upload' key doesn't contain anything, not even the name of the file
upload field.

Can you give me a hint where I should look for finding where the empty file
upload field is skipped if it is empty?

Thank you.

Octavian


_______________________________________________
List: Catalyst [at] lists
Listinfo: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst
Searchable archive: http://www.mail-archive.com/catalyst [at] lists/
Dev site: http://dev.catalyst.perl.org/


moseley at hank

Jan 24, 2010, 7:39 AM

Post #2 of 15 (2122 views)
Permalink
Re: Where is the form field lost? [In reply to]

On Sun, Jan 24, 2010 at 7:03 AM, Octavian Rasnita <orasnita [at] gmail>wrote:

I need to know if the form didn't have a file upload field, or if it had it

but no file was uploaded.


Give your upload field(s) a name like "upload_1" and then see if it exists
in uploads.


Can you give me a hint where I should look for finding where the empty file
> upload field is skipped if it is empty?
>

That's how HTTP::Body works. If there's a filename, which there is with
upload fields, but the file name is empty, then it's skipped.

if ( exists $part->{filename} ) {
if ( $part->{filename} ne "" ) {
$part->{fh}->close if defined $part->{fh};

delete @{$part}{qw[ data done fh ]};

$self->upload( $part->{name}, $part );
}
}

BTW -- I think that delete of "fh" should not happen (and the temp file
should be set to unlink on destroy). Otherwise you can end up with orphaned
temp files.

--
Bill Moseley
moseley [at] hank


stephen at enterity

Jan 24, 2010, 7:44 AM

Post #3 of 15 (2122 views)
Permalink
Re: Where is the form field lost? [In reply to]

I believe your problem lies in the browser itself. I know, for
example, that browsers do not send empty values for checkboxes that
remain unchecked - they simply eliminate that field from the form
submission altogether. Sounds like file fields might be the same way.
Your best bet is to use a bit of scripting on the browser side to mark
a hidden field to stand in for the empty file field.

- Stephen

On Jan 24, 2010, at 7:03 AM, Octavian Rasnita wrote:

> Hi,
>
> After sending a form with a file upload field, that field is lost if
> no file
> was attached, just like when the form doesn't contain that file
> upload field
> at all.
>
> I have tried to check Catalyst, Catalyst::Request, Catalyst::Engine,
> HTTP::Body and HTTP::Body::MultiPart in order to find where are the
> file upload fields lost, but I
> couldn't find it.
>
> I need to know if the form didn't have a file upload field, or if it
> had it
> but no file was uploaded.
>
> I have printed Dumper $request->_body in
> Catalyst::Engine::prepare_uploads,
> and when a file is uploaded, it looks like:
>
> $VAR1 = bless( {
> 'content_length' => '1727',
> 'tmpdir' => 'C:\\DOCUME~1\\Octavian\\LOCALS~1\\Temp',
> 'part' => {},
> 'buffer' => '',
> 'state' => 'done',
> 'chunk_buffer' => '',
> 'body' => undef,
> 'content_type' => 'multipart/form-data;
> boundary=---------------------------7da8c3070458',
> 'length' => 1727,
> 'boundary' =>
> '---------------------------7da8c3070458',
> 'chunked' => '',
> 'upload' => {
> 'file' => {
> 'headers' => {
> 'Content-
> Type' =>
> 'text/plain',
> 'Content-
> Disposition'
> => 'form-data; name="file"; filename="E:\\zzzz_cool.txt"'
> },
> 'tempname' =>
> 'C:\\DOCUME~1\\Octavian\\LOCALS~1\\Temp\\PrJ0ruNzzR',
> 'name' => 'file',
> 'size' => 44,
> 'filename' => 'E:\
> \zzzz_cool.txt'
> }
> },
> 'param' => {},
> }, 'HTTP::Body::MultiPart' );
>
>
> If no file was uploaded, it prints:
>
> $VAR1 = bless( {
> 'content_length' => '1699',
> 'tmpdir' => 'C:\\DOCUME~1\\Octavian\\LOCALS~1\\Temp',
> 'part' => {},
> 'buffer' => '',
> 'state' => 'done',
> 'chunk_buffer' => '',
> 'body' => undef,
> 'content_type' => 'multipart/form-data;
> boundary=---------------------------7da1573870458',
> 'length' => 1699,
> 'boundary' =>
> '---------------------------7da1573870458',
> 'chunked' => '',
> 'upload' => {},
> 'param' => {},
> }, 'HTTP::Body::MultiPart' );
>
> So the 'upload' key doesn't contain anything, not even the name of
> the file
> upload field.
>
> Can you give me a hint where I should look for finding where the
> empty file
> upload field is skipped if it is empty?
>
> Thank you.
>
> Octavian
>
>
> _______________________________________________
> List: Catalyst [at] lists
> Listinfo: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst
> Searchable archive: http://www.mail-archive.com/catalyst [at] lists/
> Dev site: http://dev.catalyst.perl.org/


_______________________________________________
List: Catalyst [at] lists
Listinfo: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst
Searchable archive: http://www.mail-archive.com/catalyst [at] lists/
Dev site: http://dev.catalyst.perl.org/


orasnita at gmail

Jan 24, 2010, 8:31 AM

Post #4 of 15 (2117 views)
Permalink
Re: Where is the form field lost? [In reply to]

Hi Bill,

From: "Bill Moseley" <moseley [at] hank>
> On Sun, Jan 24, 2010 at 7:03 AM, Octavian Rasnita
> <orasnita [at] gmail>wrote:
>
> I need to know if the form didn't have a file upload field, or if it had
> it
>
> but no file was uploaded.
>
>
> Give your upload field(s) a name like "upload_1" and then see if it
> exists
> in uploads.

I gave it the name "file", but if the file is not uploaded, it doesn't
appear in uploads(). (I hope "file" is OK as a name, no?)

> Can you give me a hint where I should look for finding where the empty
> file
>> upload field is skipped if it is empty?
>>
>
> That's how HTTP::Body works. If there's a filename, which there is with
> upload fields, but the file name is empty, then it's skipped.

Aha, so I should look better in HTTP::Body.
Is there a reason it does that? (Leaves alone all other empty form fields
but deletes the empty file upload fields?)

> if ( exists $part->{filename} ) {
> if ( $part->{filename} ne "" ) {
> $part->{fh}->close if defined $part->{fh};
>
> delete @{$part}{qw[ data done fh ]};
>
> $self->upload( $part->{name}, $part );
> }
> }
>
> BTW -- I think that delete of "fh" should not happen (and the temp file
> should be set to unlink on destroy). Otherwise you can end up with
> orphaned
> temp files.

And I think it should also returned the empty file upload field as an empty
upload field, and not delete it at all.
I think this change cannot cause errors in other places.

Octavian


_______________________________________________
List: Catalyst [at] lists
Listinfo: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst
Searchable archive: http://www.mail-archive.com/catalyst [at] lists/
Dev site: http://dev.catalyst.perl.org/


orasnita at gmail

Jan 24, 2010, 8:37 AM

Post #5 of 15 (2117 views)
Permalink
Re: Where is the form field lost? [In reply to]

Hi Stephen,

From: "Stephen Howard" <stephen [at] enterity>
>I believe your problem lies in the browser itself. I know, for example,
>that browsers do not send empty values for checkboxes that remain
>unchecked - they simply eliminate that field from the form submission
>altogether. Sounds like file fields might be the same way. Your best bet
>is to use a bit of scripting on the browser side to mark a hidden field to
>stand in for the empty file field.
>
> - Stephen

I have verified that, and the browser sends the empty upload field, with no
content, like:

-----------------------------7da3d8a106ce

Content-Disposition: form-data; name="file"; filename=""

Content-Type: application/octet-stream



-----------------------------7da3d8a106ce



So after the MIME header there is no content, but the header with the name
of the field ("file") is sent to the server.



Octavian



_______________________________________________
List: Catalyst [at] lists
Listinfo: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst
Searchable archive: http://www.mail-archive.com/catalyst [at] lists/
Dev site: http://dev.catalyst.perl.org/


moseley at hank

Jan 24, 2010, 11:56 AM

Post #6 of 15 (2116 views)
Permalink
Re: Where is the form field lost? [In reply to]

On Sun, Jan 24, 2010 at 8:31 AM, Octavian Rasnita <orasnita [at] gmail>wrote:
>
>
>> Give your upload field(s) a name like "upload_1" and then see if it
>> exists
>> in uploads.
>>
>
> I gave it the name "file", but if the file is not uploaded, it doesn't
> appear in uploads(). (I hope "file" is OK as a name, no?)


Why do you need to know that a field existed on the form but was submitted
empty? Checkboxes don't submit if not checked. You get what's included in
the post and have to work from that. Either you have an upload or not,
right?




Aha, so I should look better in HTTP::Body.

Is there a reason it does that? (Leaves alone all other empty form fields
> but deletes the empty file upload fields?)


Without commends in the code or documentation can't really know the author's
reasoning. I guess it assume uploads go to temp files and no need to do
that if there's no content.

(IIRC, I thought "filename" was optional, but maybe I'm mistaken.)

I'm kind of curious why it does this:


if ( $part->{fh} && ( my $length = length( $part->{data} ) ) ) {
$part->{fh}->write( substr( $part->{data}, 0, $length, '' ), $length
);
}

instead of:

print $part->{fh} $part->{data} if $part->{fh};

Maybe for fear of line ending conversion??




--
Bill Moseley
moseley [at] hank


orasnita at gmail

Jan 24, 2010, 12:47 PM

Post #7 of 15 (2112 views)
Permalink
Re: Where is the form field lost? [In reply to]

From: "Bill Moseley" <moseley [at] hank>
> On Sun, Jan 24, 2010 at 8:31 AM, Octavian Rasnita
> <orasnita [at] gmail>wrote:
>>
>>
>>> Give your upload field(s) a name like "upload_1" and then see if it
>>> exists
>>> in uploads.
>>>
>>
>> I gave it the name "file", but if the file is not uploaded, it doesn't
>> appear in uploads(). (I hope "file" is OK as a name, no?)
>
>
> Why do you need to know that a field existed on the form but was submitted
> empty? Checkboxes don't submit if not checked. You get what's included
> in
> the post and have to work from that. Either you have an upload or not,
> right?

I made a InflateColumn::FileUpload inflator similar to InflateColumn::File,
which also works with HTML::FormFu and it has an additional feature.

The files can be uploaded by just using:

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

my $form = $c->stash->{form};

if ($form->submitted_and_valid) {
$form->model->create;
#Print the success message and redirect here
}
}

And the existing record that contains file uploads can be also modified by
using:

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

my $form = $c->stash->{form};
my $record = $c->model("DB::TableName")->find($id);

if ($form->submitted_and_valid) {
$form->model->update($record);
# Here print the success message and redirect
}
else {
$form->model->default_values($record);
}
}

In the Result::TableName there should be:

# If the user might need to replace the existing uploaded file with another
one:
__PACKAGE__->mk_group_accessors(simple => 'file_replace_validator');

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

__PACKAGE__->add_columns(
"file", {
data_type => "VARCHAR",
default_value => undef,
is_nullable => 1,
size => 255,
is_file_upload => 1,
file_upload_path => $ENV{the_directory_where_the_files_will_be_stored},
});

The form used to add new records will contain a common HTML::FormFu File
element (and other elements needed).

The form used for editing can contain a checkbox with the name
"file_replace_validator", or if the name of the file upload field would be
"foo", that checkbox will be named "foo_replace_validator". I created an
accessor for it because there should be no column with this name in the db
table (although I may find a solution to not need it at all).

When the user will use the form for creating a new record, it will upload
the file if a file is loaded in the form, or it will send the form without
that field so here there is no problem.

When the user will use the editing form, he or she will have the option of
choosing if she wants to replace the existing file.
If she doesn't check that checkbox, it doesn't matter if she uploads a file
in that field, because the original file won't be changed.
If she checks it, it means that she wants to replace the existing file with
the new file uploaded. If she checks it but she doesn't upload any file, it
means that she wants to replace the existing file with nothing, so she just
wants to delete the existing file.

So with this inflator one can upload a new file, delete an existing file,
and replace an existing file with another one by using just 2 forms which
are the same, but the editing form may have that aditional checkbox for
confirming the replacement.

If the user will delete the record, the file attached will be also deleted
from the disk.
If the user will access the record, it will get a hashref with 2 elements -
the filename, and the IO::File handle to that file so she will be able to
use the same syntax as the InflateColumns::File does it:

<a href="[% c.uri_for('/static/path_to_dir', row.id, row.file.filename).path
%]">[% row.file.filename | html %]</a>

The problem is that if DBIC doesn't find any file upload field, the inflator
is not used at all, so it doesn't do anything, although it should see that
there is an empty file upload field that has the is_upload_file attribute,
see that the user has chosen to replace the existing file with it,
so it should delete the existing file.

For making it work, I need to add the following ugly code in the edit
action:

if ($form->submitted_and_valid) {
#Set a hashref for the empty file field because otherwise FileUpload
inflator ignores it
unless ($form->param('file')) {
$c->req->params->{file} = {};
$form->process;
}
$form->model->update($anunt);
#...
}

I didn't want to load this inflator to CPAN until I solve this issue, but if
you or somebody else wants, I can send you the source code.

> Without commends in the code or documentation can't really know the
> author's
> reasoning. I guess it assume uploads go to temp files and no need to do
> that if there's no content.

If the file is an empty one, I guess there shouldn't be a big issue if the
file would go to the temp directory. I think it could get deleted as the
other non-empty files which are uploaded there.
Octavian


_______________________________________________
List: Catalyst [at] lists
Listinfo: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst
Searchable archive: http://www.mail-archive.com/catalyst [at] lists/
Dev site: http://dev.catalyst.perl.org/


garrison at zeta

Jan 24, 2010, 3:41 PM

Post #8 of 15 (2111 views)
Permalink
Re: Where is the form field lost? [In reply to]

Good morning,

On 24/01/10 at 10:47 PM +0200, Octavian Rasnita
<orasnita [at] gmail> wrote:

>I made a InflateColumn::FileUpload inflator similar to
>InflateColumn::File, which also works with HTML::FormFu and it
>has an additional feature.

I had some problems with InflateColumn::File a few weeks ago
which were going to be hard for me to work around. I asked about
it on IRC and was told *not* to use the broken
InflateColumn::File and use InflateColumn::FS instead.

Not only did InflateColumn::FS resolve my main issue; it also
fixed a couple of frustrating niggles. I found InflateColumn::FS
to be more robust all around.

>I didn't want to load this inflator to CPAN until I solve this issue, but if you or somebody else wants, I can send you the source code.

If you're going to upload an HTML::FF inflator module tp CPAN, I
suggest making it work with InflateColumn::FS instead (or at
least in addition to InflateColumn::File).


Charlie

--
Ꮚ Charlie Garrison ♊ <garrison [at] zeta>
〠 PO Box 141, Windsor, NSW 2756, Australia

O< ascii ribbon campaign - stop html mail - www.asciiribbon.org
http://www.ietf.org/rfc/rfc1855.txt

_______________________________________________
List: Catalyst [at] lists
Listinfo: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst
Searchable archive: http://www.mail-archive.com/catalyst [at] lists/
Dev site: http://dev.catalyst.perl.org/


orasnita at gmail

Jan 24, 2010, 10:08 PM

Post #9 of 15 (2090 views)
Permalink
Re: Where is the form field lost? [In reply to]

From: "Charlie Garrison" <garrison [at] zeta>
On 24/01/10 at 10:47 PM +0200, Octavian Rasnita
<orasnita [at] gmail> wrote:

>I made a InflateColumn::FileUpload inflator similar to InflateColumn::File,
>which also works with HTML::FormFu and it has an additional feature.

> I had some problems with InflateColumn::File a few weeks ago which were
> going to be hard for me to work around. I asked about it on IRC and was
> told *not* to use the broken InflateColumn::File and use InflateColumn::FS
> instead.

Can you tell about those problems? I hope I won't create them in the
inflator I want to create.

> Not only did InflateColumn::FS resolve my main issue; it also fixed a
> couple of frustrating niggles. I found InflateColumn::FS to be more robust
> all around.

I have also tried InflateColumn::FS but the thing I don't like is that it
creates random directories and this is good from a security point of view,
but for ease of use I like the way InflateColumn::File create the target
dirs.

With InflateColumn::File the original file name is also used when it is
stored on the disk, and I just need to put a link to that static file,
without needing to create a column for storing the MIME type of the file and
without needing to use code for getting the file and giving it to those that
request it.
If it is possible to do that with InflateColumn::FS, please tell me.

> If you're going to upload an HTML::FF inflator module tp CPAN, I suggest
> making it work with InflateColumn::FS instead (or at least in addition to
> InflateColumn::File).

I have tried that with InflateColumn::File, but without success, but in any
case, the most important changes were to make it work with HTML::FormFu and
to be able to do all the operations to the file (add/modify/delete), and for
beeing able to also do the delete, I need to be able to get the file upload
field even if it is empty.

Octavian


_______________________________________________
List: Catalyst [at] lists
Listinfo: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst
Searchable archive: http://www.mail-archive.com/catalyst [at] lists/
Dev site: http://dev.catalyst.perl.org/


garrison at zeta

Jan 25, 2010, 12:28 AM

Post #10 of 15 (2089 views)
Permalink
Re: Where is the form field lost? [In reply to]

Good evening,

On 25/01/10 at 8:08 AM +0200, orasnita [at] gmail wrote:

>From: "Charlie Garrison" <garrison [at] zeta>
>On 24/01/10 at 10:47 PM +0200, Octavian Rasnita <orasnita [at] gmail> wrote:
>
>>I had some problems with InflateColumn::File a few weeks ago which
>>were going to be hard for me to work around. I asked about it on IRC
>>and was told *not* to use the broken InflateColumn::File and use
>>InflateColumn::FS instead.
>
>Can you tell about those problems? I hope I won't create them in the inflator I want to create.

I don't recall exactly, but IC::File had problems with multiple
'file' columns. I remember, the delete part was completely
broken if all files were not in the same directory. I was trying
to patch IC::File so that deleting would work; I was advised to
use IC::FS rather than trying to fix IC::File. (I don't recall
who said that, sorry.)

>>Not only did InflateColumn::FS resolve my main issue; it also fixed a
>>couple of frustrating niggles. I found InflateColumn::FS to be more
>>robust all around.
>
>I have also tried InflateColumn::FS but the thing I don't like is that
>it creates random directories and this is good from a security point of
>view, but for ease of use I like the way InflateColumn::File create the
>target dirs.

One of the reasons I found IC::FS so much better, was the extra
control for things like how files are named/stored on disk. From
the POD:

fs_file_name
Provides the file naming algorithm. Override this method to
change it.
This method is called with two parameters: The name of the
column and the column_info object.

_fs_column_dirs
Returns the sub-directory components for a given file name.
Override it to provide a deeper directory tree or change the algorithm.

Eg (example from myApp; I used a different naming scheme in the
end, but this shows the flexibility of IC::FS):

sub fs_file_name {
my ($self, $column, $column_info) = @_;
my MIME::Type $img_mimetype =
MIME::Types->new->type($self->mime_type); #'image/jpeg'
my $size = $column eq 'media_full_file' ?
'full' :
$column eq 'media_thumb_file' ?
'thumb' :
$column eq 'media_orig_file' ?
'orig' :
'';
return sprintf("%05d-%s_%s.%s",
$self->user->id,
$self->name,
$size,
$img_mimetype->subType)
}

I ended up using something very close to the original method, I
just wanted to add the file extension:

sub fs_file_name {
my ($self, $column, $column_info) = @_;
my MIME::Type $img_mimetype =
MIME::Types->new->type($self->mime_type); #'image/jpeg'
return sprintf("%s.%s", DBIx::Class::UUIDColumns->get_uuid, $img_mimetype->subType)
}

I'm sure it's possible to use the original file name (from
upload param), but I didn't want to use that anyway. So again,
IC:FS was an easy win for me.

Note, I find the sub-dirs created with IC::FS much more
desirable than putting them all in one directory (for scaling
reasons). I was looking at ways of patching IC:File to do that
since I wasn't looking forward to many thousands of directory
entries in my media dir. And if I find that two-letter sub dirs
isn't enough (I hope we get that big), I can easily change that
by overriding _fs_column_dirs.

>With InflateColumn::File the original file name is also used when it is
>stored on the disk, and I just need to put a link to that static file,
>without needing to create a column for storing the MIME type of the
>file and without needing to use code for getting the file and giving it
>to those that request it. If it is possible to do that with
>InflateColumn::FS, please tell me.

Create a method that returns the file path and call that when
you need to create URL pointing to the file:

sub fs_file_path {
my ($self, $column) = @_;
my $fh = $self->$column;
return $fh->relative(
$self->result_source->column_info($column)->{fs_column_path} )->stringify;
}

And I created some wrapper methods for each column:

sub media_full_file_path {
shift->fs_file_path('media_full_file'); }
sub media_thumb_file_path {
shift->fs_file_path('media_thumb_file'); }
sub media_orig_file_path {
shift->fs_file_path('media_orig_file'); }

In my template:

[% img_full_src =
c.uri_for("/static/media/${user_image.media_full_file_path}" );
img_thumb_src = c.uri_for("/static/media/${user_image.media_thumb_file_path}");
-%]

Note, fs_file_path return a two-part path, so the value needs to
be passed as part of first arg to uri_for. Otherwise, if passed
as second arg, the slash will get encoded and things may not
work as expected.


>>If you're going to upload an HTML::FF inflator module tp CPAN, I
>>suggest making it work with InflateColumn::FS instead (or at least in
>>addition to InflateColumn::File).
>
>I have tried that with InflateColumn::File, but without success, but in
>any case, the most important changes were to make it work with
>HTML::FormFu and to be able to do all the operations to the file
>(add/modify/delete), and for beeing able to also do the delete, I need
>to be able to get the file upload field even if it is empty.

Watch out for the delete method in IC::File; it's broken. At
least it was broken for my usage. And that was pretty much a
deal breaker for me; that's what got me started on this journey.


Hmm, sounds like I may have just volunteered for Cookbook doc
patch, or at least an entry on my blog so others can benefit
from my pain. Does this sound like something that should go in
the DBIC cookbook?


Charlie

--
Ꮚ Charlie Garrison ♊ <garrison [at] zeta>
〠 PO Box 141, Windsor, NSW 2756, Australia

O< ascii ribbon campaign - stop html mail - www.asciiribbon.org
http://www.ietf.org/rfc/rfc1855.txt

_______________________________________________
List: Catalyst [at] lists
Listinfo: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst
Searchable archive: http://www.mail-archive.com/catalyst [at] lists/
Dev site: http://dev.catalyst.perl.org/


orasnita at gmail

Jan 25, 2010, 1:30 AM

Post #11 of 15 (2087 views)
Permalink
Re: Where is the form field lost? [In reply to]

From: "Charlie Garrison" <garrison [at] zeta>
>Can you tell about those problems? I hope I won't create them in the
>inflator I want to create.

I don't recall exactly, but IC::File had problems with multiple
'file' columns. I remember, the delete part was completely
broken if all files were not in the same directory. I was trying
to patch IC::File so that deleting would work; I was advised to
use IC::FS rather than trying to fix IC::File. (I don't recall
who said that, sorry.)



If I remember well, the algorithm for deletion made a single deletion and
then did a last() thinking that if one file was deleted, all the files were
deleted. I think there was a little comment there that tells that.
Although I didn't need to store the files in different dirs, I've noticed
that that piece of code won't work in case of more directories used, however
I don't think it is so hard to patch it for solving that issue.

Thank you for the code you sent. I will analyse it better to see if I can
use another way, but what I would like to avoid is exactly to need writing
too much code like this in order to use the module, so I don't want to need
writing those wrappers for each file column nor a separate subroutine that
provides the file name. But maybe I will be able to create one in the
inflator...

However I am not sure the way InflateColumn::FS works is compatible with
HTML::FormFu. I think a better way would be the style used by
InflateColumn::File eventually with a more flexible storage, or
InflateColumn::FS should be changed so it should get the ID of the row after
it is stored in the DB.
But in the second case, I don't know how I could store the real file name
and the random path to the file without using more fields in the table.

Anyway, back to the main issue, the biggest problem is HTTP::Body steals the
file upload fields if no files were attached.

Octavian


_______________________________________________
List: Catalyst [at] lists
Listinfo: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst
Searchable archive: http://www.mail-archive.com/catalyst [at] lists/
Dev site: http://dev.catalyst.perl.org/


garrison at zeta

Jan 25, 2010, 4:31 AM

Post #12 of 15 (2069 views)
Permalink
Re: Where is the form field lost? [In reply to]

Good evening,

On 25/01/10 at 11:30 AM +0200, orasnita [at] gmail wrote:

>If I remember well, the algorithm for deletion made a single deletion
>and then did a last() thinking that if one file was deleted, all the
>files were deleted. I think there was a little comment there that tells
>that. Although I didn't need to store the files in different dirs, I've
>noticed that that piece of code won't work in case of more directories
>used, however I don't think it is so hard to patch it for solving that
>issue.

That's the issue and that's what I was going to patch. But
IC::FS was a better solution (at least in my case).

>Thank you for the code you sent. I will analyse it better to see if I
>can use another way, but what I would like to avoid is exactly to need
>writing too much code like this in order to use the module, so I don't
>want to need writing those wrappers for each file column nor a separate
>subroutine that provides the file name. But maybe I will be able to
>create one in the inflator...

Those wrappers aren't needed; it was just a convenience to make
usage from TT easier.

>However I am not sure the way InflateColumn::FS works is compatible
>with HTML::FormFu. I think a better way would be the style used by
>InflateColumn::File eventually with a more flexible storage, or
>InflateColumn::FS should be changed so it should get the ID of the row
>after it is stored in the DB.

I use HTML::FF, but not for any file uploads, so I have no idea
what sort of compatibility is needed (or available). I don't
recall any difference between IC::File and IC::FS in relation to
how files are assigned to columns. Hmm, there is a vague memory
that with IC::File I had to create a hashref and store that
instead, so again IC::FS is a win for simplicity.

>But in the second case, I don't know how I could store the real file
>name and the random path to the file without using more fields in the
>table.

Create a fs_file_name method and have it assign the name? Maybe
HTML::FF upload element doesn't allow any flexibility there. I
know that I was able to use the supplied file name, but I was
also passing around the $req->upload object so it was easy for
me to grab the file name. In the end I decided I didn't want
that anyway.

>Anyway, back to the main issue, the biggest problem is HTTP::Body
>steals the file upload fields if no files were attached.

Sorry, can't help with that. I'm not sure I understand the issue
either; if there is no upload field then just assign undef to
the file column. Ahh, cause HTML::FF is doing it all for you.
While I find HTML::FF is a great solution for many cases, there
are also many cases where it needs manual intervention; this may
be one of them.

I just had a look at HTML::FormFu::Element::File and I don't see
how it's doing anything to assist with creating the hashref
required by IC::File. Is HTML::FormFu::Model::DBIC handling that?


Charlie

--
Ꮚ Charlie Garrison ♊ <garrison [at] zeta>
〠 PO Box 141, Windsor, NSW 2756, Australia

O< ascii ribbon campaign - stop html mail - www.asciiribbon.org
http://www.ietf.org/rfc/rfc1855.txt

_______________________________________________
List: Catalyst [at] lists
Listinfo: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst
Searchable archive: http://www.mail-archive.com/catalyst [at] lists/
Dev site: http://dev.catalyst.perl.org/


orasnita at gmail

Jan 26, 2010, 9:56 AM

Post #13 of 15 (1975 views)
Permalink
Re: Where is the form field lost? [In reply to]

> From: "Charlie Garrison" <
garrison [at] zeta>

> One of the reasons I found IC::FS so much better, was the extra
> control for things like how files are named/stored on disk. From
> the POD:
>
> fs_file_name
> Provides the file naming algorithm. Override this method to
> change it.
> This method is called with two parameters: The name of the
> column and the column_info object.
>
> _fs_column_dirs
> Returns the sub-directory components for a given file name.
> Override it to provide a deeper directory tree or change the algorithm.

That's true, but I still don't know how can I store the path to the file.

If in the file field I store just the file name, I need to create a second
column just for storing the random path for each file upload field.

If I will store the random path and the file name in the same column like
/e3/e3434ae1b/The original file name.pdf

then each time I would need to create a subroutine that takes this file name
and gets only the original file name for printing it on the page, but I
think this is the most simple way though.

Octavian


_______________________________________________
List: Catalyst [at] lists
Listinfo: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst
Searchable archive: http://www.mail-archive.com/catalyst [at] lists/
Dev site: http://dev.catalyst.perl.org/


garrison at zeta

Jan 26, 2010, 4:51 PM

Post #14 of 15 (1945 views)
Permalink
Re: Where is the form field lost? [In reply to]

Good morning,

On 26/01/10 at 7:56 PM +0200, Octavian Rasnita
<orasnita [at] gmail> wrote:

>>From: "Charlie Garrison" <garrison [at] zeta>
>
>>_fs_column_dirs
>> Returns the sub-directory components for a given file name.
>>Override it to provide a deeper directory tree or change the algorithm.
>
>That's true, but I still don't know how can I store the path to the file.

Don't store it, retrieve it via the file field combined with the
config (column_info) for the file field; add a method like this:

sub fs_file_path {
my ($self, $column) = @_;
my $fh = $self->$column;
return $fh->relative(
$self->result_source->column_info($column)->{fs_column_path} )->stringify;
}

And if you only have one file field, then create a second method
and call it instead (eg, for field named 'image'):

sub image_path { shift->fs_file_path('image'); }


>If in the file field I store just the file name, I need to create a second
>column just for storing the random path for each file upload field.

Nope, use a method, no need to store the value in the db.

>If I will store the random path and the file name in the same column like
>/e3/e3434ae1b/The original file name.pdf

You don't need to store a random path either; Override the
_fs_column_dirs & fs_file_name methods to name the file the way
you want (& store it in the sub-directory you want).

>then each time I would need to create a subroutine that takes this file name
>and gets only the original file name for printing it on the
>page, but I think this is the most simple way though.

I'm not following that, you would only create the subroutine
once. If you are writing lots of apps and need to the same
functionality then either create a base class or role and put
the sub there.


Charlie

--
Ꮚ Charlie Garrison ♊ <garrison [at] zeta>
〠 PO Box 141, Windsor, NSW 2756, Australia

O< ascii ribbon campaign - stop html mail - www.asciiribbon.org
http://www.ietf.org/rfc/rfc1855.txt

_______________________________________________
List: Catalyst [at] lists
Listinfo: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst
Searchable archive: http://www.mail-archive.com/catalyst [at] lists/
Dev site: http://dev.catalyst.perl.org/


garrison at zeta

Jan 30, 2010, 6:44 AM

Post #15 of 15 (1637 views)
Permalink
Re: Where is the form field lost? [In reply to]

Good morning,

On 25/01/10 at 7:28 PM +1100, Charlie Garrison <garrison [at] zeta> wrote:

>Hmm, sounds like I may have just volunteered for Cookbook doc patch, or
>at least an entry on my blog

I've done a write-up of my experiences (and views) of using DBIx::Class::InflateColumn::FS:

<http://www.riverviews.com.au/perl/dbic-ic-fs.html>


Charlie

--
Ꮚ Charlie Garrison ♊ <garrison [at] zeta>
〠 PO Box 141, Windsor, NSW 2756, Australia

O< ascii ribbon campaign - stop html mail - www.asciiribbon.org
http://www.ietf.org/rfc/rfc1855.txt

_______________________________________________
List: Catalyst [at] lists
Listinfo: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst
Searchable archive: http://www.mail-archive.com/catalyst [at] lists/
Dev site: http://dev.catalyst.perl.org/

Catalyst users RSS feed   Index | Next | Previous | View Threaded
 
 


Interested in having your list archived? Contact Gossamer Threads
 
  Web Applications & Managed Hosting Powered by Gossamer Threads Inc.