view Lib/CDBI/Transform.pm @ 35:f25d021780b3

DOM::Navigator::Builder working version
author Sergey
date Tue, 17 Nov 2009 17:46:24 +0300
parents 03e58a454b20
children 16ada169ca75
line wrap: on
line source

package CDBI::Transform::FormToObject;
use strict;
use warnings;

use base qw(IMPL::Object::Autofill Form::Transform );
use IMPL::Class::Property;
require IMPL::Exception;

BEGIN {
    public property Class => prop_all;
    public property Namespace => prop_all;
}

sub CTOR {
    my $this = shift;
    $this->superCTOR(@_);
    
    die new IMPL::InvalidArgumentException('Class is required') unless $this->Class;
}

sub TransformContainer {
    my ($this,$container) = @_;
    
    my $class;
    if ($container->Name eq 'Form') {
        $class = $this->Class;
    } else {
        $class = $this->_mk_class($container->Attributes->{'cdbi.class'}) or die new IMPL::Exception('cdbi.class isn\'t specified',$container->Id->Canonical);
    }
    
    my %data;
    
    #my %columns = map {$_,1} $class->columns();
    
    no strict 'refs';
    my @accessors = map $_->accessor, $class->columns();# grep $columns{lc $_}, keys %{"${class}::"};
    
    # формируем из контейнера формы данные для объекта
    foreach my $column ( @accessors, 'id' ) {
        my ($val) = $container->GetChild($column);
        $data{$column} = $this->Transform($val) if $val;
    }
    
    my $obj;
    if ($data{id}) {
        # edit value
        
        
        $obj = $class->validateId($data{id});
        my %filter = map { $_, $obj->$_()} @accessors;
        $filter{$_} = $data{$_} foreach keys %data;
        my ($newObj) = $class->lookup(\%data);
        die new IMPL::DuplicateException('The object already exists', $class) if ($newObj and $newObj->id != $data{id});
        
        $obj->$_($data{$_}) foreach keys %data;
        $obj->update();
    } else {
        # new instance
        die new IMPL::DuplicateException('The object already exists', $class) if $class->lookup(\%data);
        $obj = $class->insert(\%data);
    }
    return $obj;
}

sub _mk_class {
    my ($this,$name) = @_;
    
    return unless $name;
    return $name if $name =~ /::/;
    return $this->Namespace ? $this->Namespace."::$name" : $name;
}

package CDBI::Transform::ObjectToForm;
use base qw(IMPL::Transform);

use IMPL::Class::Property;

sub CTOR {
    my $this = shift;
    
    $this->superCTOR(
        Default => \&TransformObject,
        Plain => sub { my ($this,$val) = @_; return $val; }
    );
}

sub TransformObject {
    my ($this,$object) = @_;
    
    return $object if not ref $object;
    
    my %data;
    foreach my $column ( (map $_->accessor,$object->columns()),'id') {
        my $value = $object->$column();
        
        if (ref $value eq 'HASH') {
            $data{"$column/$_"} = $value->{$_} foreach keys %$value;
        } else {
            $data{$column} = $value;
        }
    }
    
    return \%data;
}
1;