Bivio::Type::FileField
# Copyright (c) 1999-2010 bivio Software, Inc. All rights reserved. # $Id$ package Bivio::Type::FileField; use strict; use Bivio::Base 'Bivio.Type'; my($_T) = b_use('Type.Text'); my($_RF) = b_use('Model.RealmFile'); my($_TE) = b_use('Bivio.TypeError'); my($_FP) = b_use('Type.FilePath'); my($_F) = b_use('IO.File'); sub from_any { my($proto, @args) = @_; return $proto->from_literal(@args) if ref($args[0]) eq 'HASH'; return $proto->from_string_ref(@args) if ref($args[0]) eq 'SCALAR'; return $proto->from_disk(@args) if @args == 1 && !ref($args[0]) && $args[0] !~ /\n/; return $proto->from_string_ref(\(shift(@args)), @args) if @args >= 1 && !ref($args[0]) && defined($args[0]); b_die(\@args, ': unable to convert arguments'); # DOES NOT RETURN } sub from_string_ref { return shift->from_literal({ content => shift, filename => shift || '', content_type => shift || 'application/octet-stream', }); } sub from_disk { my($v, $e) = shift->unsafe_from_disk(@_); return $v if $v; my(undef, $file_name) = @_; b_die($file_name, ': invalid disk file: ' , $e || $_TE->NULL); # DOES NOT RETURN } sub from_literal { my($proto, $value) = @_; $proto->internal_from_literal_warning unless wantarray; return (undef, undef) unless defined($value); unless (ref($value) eq 'HASH') { return (undef, $_TE->FILE_FIELD) if length($value); return (undef, undef); } return $value if length(${$value->{content}}); return (undef, undef) unless $value->{filename}; return (undef, $_TE->NOT_FOUND) unless $value->{content_type}; return (undef, $_TE->EMPTY); } sub from_sql_column { die("can't convert a FileField from sql"); } sub get_width { return $_T->get_width; } #TODO: Make an object with hashlooks working in deprecated mode # sub new { # my($self) = shift->SUPER::new(@_); # $self->[$_IDI] = { # }; # return $self; # } sub to_literal { my(undef, $value) = @_; return ref($value) eq 'HASH' && defined($value->{filename}) ? $value->{filename} : ''; } sub to_query { die("can't convert a FileField to a query"); } sub to_uri { die("can't convert a FileField to a uri"); } sub unsafe_from_disk { my($proto, $value) = @_; return (undef, undef) unless defined($value) && length($value); return $proto->use('IO.Ref')->nested_copy($value) if ref($value) eq 'HASH' && grep(exists($value->{$_}), qw(filename content content_type)) == 3 && ref($value->{content}) eq 'SCALAR'; return (undef, $_TE->NOT_FOUND) unless -r $value && !(-d _); return { filename => $_FP->get_tail($value), content_type => $_RF->get_content_type_for_path($value), content => $_F->read($value), }; } 1;