diff Lib/IMPL/Web/DOM/FileNode.pm @ 148:e6447ad85cb4

DOM objects now have a schema and schemaSource properties RegExp now can launder data Improved post to DOM transformation (multiple values a now supported) Added new axes to navigation queries: ancestor and descendant minor changes and bug fixes
author wizard
date Mon, 16 Aug 2010 08:26:44 +0400
parents
children e36ffd8c29db
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Lib/IMPL/Web/DOM/FileNode.pm	Mon Aug 16 08:26:44 2010 +0400
@@ -0,0 +1,193 @@
+package IMPL::Web::DOM::FileNode;
+use IMPL::base 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 {
+					$_->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 $query->cgi_error ? die new IMPL::IOException("Failed to open the uploaded file",$query->cgi_error) : return;
+			
+	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
\ No newline at end of file