Mercurial > pub > Impl
diff lib/IMPL/Web/DOM/FileNode.pm @ 407:c6e90e02dd17 ref20150831
renamed Lib->lib
author | cin |
---|---|
date | Fri, 04 Sep 2015 19:40:23 +0300 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/lib/IMPL/Web/DOM/FileNode.pm Fri Sep 04 19:40:23 2015 +0300 @@ -0,0 +1,193 @@ +package IMPL::Web::DOM::FileNode; +use parent qw(IMPL::DOM::Node); + +__PACKAGE__->PassThroughArgs; + +use IMPL::Class::Property; +use File::Temp qw(tempfile); + +BEGIN { + public property parameterName => { + get => sub { + my ($this) = @_; + $this->_parameterName() or + $this->_parameterName( + join '/', ( map { + (defined $_->nodeProperty('instanceId')) ? + $_->nodeName . '['.$_->nodeProperty('instanceId').']': + $_->nodeName + } $this->_selectParents, $this ) + ); + } + }; + private property _parameterName => prop_all; + public property fileName => { + get => sub { + my ($this) = @_; + return $this->document->query->param($this->parameterName); + } + }; + public property fileHandle => { + get => sub { + my ($this) = @_; + return $this->document->query->upload($this->parameterName); + } + }; +} + +sub invokeTempFile { + my ($this,$sub,$target) = @_; + + die new IMPL::InvalidArgumentException("A reference to a function should be specified") unless $sub && ref $sub eq 'CODE'; + + $target ||= $this; + + my $query = $this->document->nodeProperty('query') or die new IMPL::InvalidOperationException("Failed to get a CGI query from the document"); + my $hFile = $query->upload($this->parameterName) or die new IMPL::IOException("Failed to open the uploaded file",$query->cgi_error,$this->parameterName,$this->nodeProperty('instanceId')); + + my ($hTemp,$tempFileName) = tempfile(); + binmode($hTemp); + + print $hTemp $_ while <$hFile>; + + $hTemp->flush(); + seek $hTemp, 0,0; + { + local $_ = $tempFileName; + $sub->($this,$tempFileName,$hTemp); + } +} + +sub _selectParents { + my ($node) = @_; + + my @result; + + unshift @result, $node while $node = $node->parentNode; + + return @result; +} + +1; + +__END__ + +=pod + +=head1 NAME + +C<IMPL::Web::DOM::FileNode> - узел, использующийся для представления параметра запроса в котором передан файл. + +=head1 SINOPSYS + +=begin code xml + +<!-- input.schema.xml --> +<schema> + <SimpleType type="file" nativeType="IMPL::Web::DOM::FileNode"/> + <ComplexNode name="user"> + <Node type="file" name="avatar"/> + </ComplexNode> +</schema> + +=end code xml + +=begin code + +# handle.pl +use IMPL::DOM::Transform::PostToDOM (); +use IMPL::DOM::Schema; +use CGI; +use File::Copy qw(copy); + +my $t = new IMPL::DOM::Transform::PostToDOM( + undef, + IMPL::DOM::Schema->LoadSchema('input.schema.xml'), + 'user' +); + +my $doc = $t->Transform(CGI->new()); + +if ($t->Errors->Count) { + # handle errors +} + +$doc->selectSingleNode('avatar')->invokeTempFile( + sub { + my($node,$fname,$fhandle) = @_; + + # do smth with file + copy($_,'avatar.jpg'); + + # same thing + # copy($fname,'avatar.jpg'); + } +); + +=end code + +=head1 DESCRIPTION + +Данный класс используется для представлении параметров C<CGI> запросов при преобзаовании +запроса в ДОМ документ преобразованием C<IMPL::DOM::Transform::PostToDOM>. + +Узлы данного типа расширяют стандатрный C<IMPL::DOM::Node> несколькими свойствами и +методами для доступа к файлу, переданному в виде параметра запроса. + +=head1 MEMBERS + +=head2 PROPERTIES + +=over + +=item C<[get] parameterName> + +Имя параметра C<CGI> запроса соответствующего данному узлу. + +=item C<[get] fileName> + +Имя файла из параметра запроса + +=item C<[get] fileHandle> + +Указатель на файл из параметра запроса + +=back + +=head2 METHODS + +=over + +=item C<invokeTempFile($callback,$target)> + +Сохраняет файл, переданный в запросе во временный, вызывает C<$callback> для обработки временного файла. + +=over + +=item C<$callback> + +Ссылка на функцию которая будет вызвана для обработки временного файла. C<callback($target,$fname,$fhandle)> + +=over + +=item C<$fname> + +Имя временного файла + +=item C<$fhandle> + +Указатель на временный файл + +=back + +Также пременная C<$_> содержит имя временного файла. + +=item C<$target> + +Значение этого параметра будет передано первым параметром функции C<$callback>. + +=back + +=back + +=cut