407
+ − 1 package IMPL::Web::DOM::FileNode;
+ − 2 use parent qw(IMPL::DOM::Node);
+ − 3
+ − 4 __PACKAGE__->PassThroughArgs;
+ − 5
+ − 6 use IMPL::Class::Property;
+ − 7 use File::Temp qw(tempfile);
+ − 8
+ − 9 BEGIN {
+ − 10 public property parameterName => {
+ − 11 get => sub {
+ − 12 my ($this) = @_;
+ − 13 $this->_parameterName() or
+ − 14 $this->_parameterName(
+ − 15 join '/', ( map {
+ − 16 (defined $_->nodeProperty('instanceId')) ?
+ − 17 $_->nodeName . '['.$_->nodeProperty('instanceId').']':
+ − 18 $_->nodeName
+ − 19 } $this->_selectParents, $this )
+ − 20 );
+ − 21 }
+ − 22 };
+ − 23 private property _parameterName => prop_all;
+ − 24 public property fileName => {
+ − 25 get => sub {
+ − 26 my ($this) = @_;
+ − 27 return $this->document->query->param($this->parameterName);
+ − 28 }
+ − 29 };
+ − 30 public property fileHandle => {
+ − 31 get => sub {
+ − 32 my ($this) = @_;
+ − 33 return $this->document->query->upload($this->parameterName);
+ − 34 }
+ − 35 };
+ − 36 }
+ − 37
+ − 38 sub invokeTempFile {
+ − 39 my ($this,$sub,$target) = @_;
+ − 40
+ − 41 die new IMPL::InvalidArgumentException("A reference to a function should be specified") unless $sub && ref $sub eq 'CODE';
+ − 42
+ − 43 $target ||= $this;
+ − 44
+ − 45 my $query = $this->document->nodeProperty('query') or die new IMPL::InvalidOperationException("Failed to get a CGI query from the document");
+ − 46 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'));
+ − 47
+ − 48 my ($hTemp,$tempFileName) = tempfile();
+ − 49 binmode($hTemp);
+ − 50
+ − 51 print $hTemp $_ while <$hFile>;
+ − 52
+ − 53 $hTemp->flush();
+ − 54 seek $hTemp, 0,0;
+ − 55 {
+ − 56 local $_ = $tempFileName;
+ − 57 $sub->($this,$tempFileName,$hTemp);
+ − 58 }
+ − 59 }
+ − 60
+ − 61 sub _selectParents {
+ − 62 my ($node) = @_;
+ − 63
+ − 64 my @result;
+ − 65
+ − 66 unshift @result, $node while $node = $node->parentNode;
+ − 67
+ − 68 return @result;
+ − 69 }
+ − 70
+ − 71 1;
+ − 72
+ − 73 __END__
+ − 74
+ − 75 =pod
+ − 76
+ − 77 =head1 NAME
+ − 78
+ − 79 C<IMPL::Web::DOM::FileNode> - узел, использующийся для представления параметра запроса в котором передан файл.
+ − 80
+ − 81 =head1 SINOPSYS
+ − 82
+ − 83 =begin code xml
+ − 84
+ − 85 <!-- input.schema.xml -->
+ − 86 <schema>
+ − 87 <SimpleType type="file" nativeType="IMPL::Web::DOM::FileNode"/>
+ − 88 <ComplexNode name="user">
+ − 89 <Node type="file" name="avatar"/>
+ − 90 </ComplexNode>
+ − 91 </schema>
+ − 92
+ − 93 =end code xml
+ − 94
+ − 95 =begin code
+ − 96
+ − 97 # handle.pl
+ − 98 use IMPL::DOM::Transform::PostToDOM ();
+ − 99 use IMPL::DOM::Schema;
+ − 100 use CGI;
+ − 101 use File::Copy qw(copy);
+ − 102
+ − 103 my $t = new IMPL::DOM::Transform::PostToDOM(
+ − 104 undef,
+ − 105 IMPL::DOM::Schema->LoadSchema('input.schema.xml'),
+ − 106 'user'
+ − 107 );
+ − 108
+ − 109 my $doc = $t->Transform(CGI->new());
+ − 110
+ − 111 if ($t->Errors->Count) {
+ − 112 # handle errors
+ − 113 }
+ − 114
+ − 115 $doc->selectSingleNode('avatar')->invokeTempFile(
+ − 116 sub {
+ − 117 my($node,$fname,$fhandle) = @_;
+ − 118
+ − 119 # do smth with file
+ − 120 copy($_,'avatar.jpg');
+ − 121
+ − 122 # same thing
+ − 123 # copy($fname,'avatar.jpg');
+ − 124 }
+ − 125 );
+ − 126
+ − 127 =end code
+ − 128
+ − 129 =head1 DESCRIPTION
+ − 130
+ − 131 Данный класс используется для представлении параметров C<CGI> запросов при преобзаовании
+ − 132 запроса в ДОМ документ преобразованием C<IMPL::DOM::Transform::PostToDOM>.
+ − 133
+ − 134 Узлы данного типа расширяют стандатрный C<IMPL::DOM::Node> несколькими свойствами и
+ − 135 методами для доступа к файлу, переданному в виде параметра запроса.
+ − 136
+ − 137 =head1 MEMBERS
+ − 138
+ − 139 =head2 PROPERTIES
+ − 140
+ − 141 =over
+ − 142
+ − 143 =item C<[get] parameterName>
+ − 144
+ − 145 Имя параметра C<CGI> запроса соответствующего данному узлу.
+ − 146
+ − 147 =item C<[get] fileName>
+ − 148
+ − 149 Имя файла из параметра запроса
+ − 150
+ − 151 =item C<[get] fileHandle>
+ − 152
+ − 153 Указатель на файл из параметра запроса
+ − 154
+ − 155 =back
+ − 156
+ − 157 =head2 METHODS
+ − 158
+ − 159 =over
+ − 160
+ − 161 =item C<invokeTempFile($callback,$target)>
+ − 162
+ − 163 Сохраняет файл, переданный в запросе во временный, вызывает C<$callback> для обработки временного файла.
+ − 164
+ − 165 =over
+ − 166
+ − 167 =item C<$callback>
+ − 168
+ − 169 Ссылка на функцию которая будет вызвана для обработки временного файла. C<callback($target,$fname,$fhandle)>
+ − 170
+ − 171 =over
+ − 172
+ − 173 =item C<$fname>
+ − 174
+ − 175 Имя временного файла
+ − 176
+ − 177 =item C<$fhandle>
+ − 178
+ − 179 Указатель на временный файл
+ − 180
+ − 181 =back
+ − 182
+ − 183 Также пременная C<$_> содержит имя временного файла.
+ − 184
+ − 185 =item C<$target>
+ − 186
+ − 187 Значение этого параметра будет передано первым параметром функции C<$callback>.
+ − 188
+ − 189 =back
+ − 190
+ − 191 =back
+ − 192
+ − 193 =cut