Data-MuForm

 view release on metacpan or  search on metacpan

lib/Data/MuForm/Field.pm  view on Meta::CPAN

package Data::MuForm::Field;
# ABSTRACT: Base field package
use Moo;
use Types::Standard -types;
use Try::Tiny;
use Scalar::Util ('blessed', 'weaken');
use Data::Clone ('data_clone');
use Data::MuForm::Localizer;
use Data::MuForm::Merge ('merge');
with 'Data::MuForm::Common';

has 'name' => ( is => 'rw', required => 1 );
has 'id' => ( is => 'rw', lazy => 1, builder => 'build_id' );
sub build_id {
   my $self = shift;
   if ( my $meth = $self->get_method('build_id') ) {
       return $meth->($self, @_);
   }
   elsif ( $self->form && $self->form->can('build_field_id') ) {
       return $self->form->build_field_id($self);
   }
   return $self->prefixed_name;
}
has 'prefixed_name' => ( is => 'rw', lazy => 1, builder => 'build_prefixed_name');
sub build_prefixed_name {
    my $self = shift;
    my $prefix = ( $self->form && $self->form->field_prefix ) ? $self->field_prefix. "." : '';
    return $prefix . $self->full_name;
}
has 'form' => ( is => 'rw', weak_ref => 1, predicate => 'has_form' );
has 'type' => ( is => 'ro', required => 1, default => 'Text' );
has 'default' => ( is => 'rw' );
has 'input' => ( is => 'rw', predicate => 'has_input', clearer => 'clear_input' );
has 'input_without_param' => ( is => 'rw', predicate => 'has_input_without_param' );
has 'value' => ( is => 'rw', predicate => 'has_value', clearer => 'clear_value' );
has 'init_value' => ( is => 'rw', predicate => 'has_init_value', clearer => 'clear_init_value' );
has 'no_value_if_empty' => ( is => 'rw' );
has 'input_param' => ( is => 'rw' );
has 'filled_from' => ( is => 'rw', clearer => 'clear_filled_from' );
has 'password' => ( is => 'rw', default => 0 );
has 'accessor' => ( is => 'rw', lazy => 1, builder => 'build_accessor' );
sub build_accessor {
    my $self     = shift;
    my $accessor = $self->name;
    $accessor =~ s/^(.*)\.//g if ( $accessor =~ /\./ );
    return $accessor;
}
has 'custom' => ( is => 'rw' );
has 'parent' => ( is  => 'rw',   predicate => 'has_parent', weak_ref => 1 );
has 'source' => ( is => 'rw' );
has 'errors' => ( is => 'rw', isa => ArrayRef, default => sub {[]} );
sub has_errors { my $self = shift; return scalar @{$self->errors}; }
sub all_errors { my $self = shift; return @{$self->errors}; }
sub clear_errors { $_[0]->{errors} = [] }
sub clear_error_fields { }

# this is a permanent setting of active
has 'active' => ( is => 'rw', default => 1 );
# this is a temporary active set on the process call, cleared on clear_data
has '_active' => ( is => 'rw', predicate => '_has_active', clearer => '_clear_active' );
sub clear_inactive { $_[0]->active(1) }
sub inactive { return ( shift->active ? 0 : 1 ) }
sub is_active {
    my $self = shift;
    return $self->_active if $self->_has_active;
    return $self->active;
}
sub multiple { }
sub is_inactive { ! $_[0]->is_active }
has 'disabled' => ( is => 'rw', default => 0 );
has 'no_update' => ( is => 'rw', default => 0 );
has 'writeonly' => ( is => 'rw', default => 0 );
has 'is_contains' => ( is => 'rw' );
has 'apply' => ( is => 'rw', default => sub {[]} ); # for field defnitions
sub has_apply { return scalar @{$_[0]->{apply}} }
has 'base_apply' => ( is => 'rw', builder => 'build_base_apply' ); # for field classes
sub build_base_apply {[]}
sub has_base_apply { return scalar @{$_[0]->{base_apply}} }
has 'trim' => ( is => 'rw', default => sub { *default_trim } );
sub default_trim {
    my $value = shift;
    return unless defined $value;
    my @values = ref $value eq 'ARRAY' ? @$value : ($value);
    for (@values) {
        next if ref $_ or !defined;
        s/^\s+//;
        s/\s+$//;
    }
    return ref $value eq 'ARRAY' ? \@values : $values[0];
}
sub has_fields { } # compound fields will override
has 'methods' => ( is => 'rw', isa => HashRef, builder => 'build_methods', trigger => 1 );
sub build_methods {{}}
sub _trigger_methods {
    my ( $self, $new_methods ) = @_;
    my $base_methods = $self->build_methods;
    my $methods = merge($new_methods, $base_methods);
    $self->{methods} = $methods;

}
sub get_method {
   my ( $self, $meth_name ) = @_;
   return  $self->{methods}->{$meth_name};
}

has 'validate_when_empty' => ( is => 'rw' );
has 'not_nullable' => ( is => 'rw' );
sub is_repeatable {}
sub is_compound {}
sub is_form {0}
sub no_fif {0}

around BUILDARGS => sub {
  my ( $orig, $class, %field_attr ) = @_;

  munge_field_attr(\%field_attr);

  return $class->$orig(%field_attr);
};


sub BUILD {
    my $self = shift;

    if ( $self->form ) {
        # To avoid memory cycles it needs to be weakened when
        # it's set through a form.
        weaken($self->{localizer});
        weaken($self->{renderer});
    }
    else {
        # Vivify. This would generally only happen in a standalone field, in tests.
        $self->localizer;
        $self->renderer;
    }

    $self->_install_methods;
}

sub _install_methods {
    my $self = shift;

    if ( $self->form ) {
        my $suffix = $self->convert_full_name($self->full_name);
        foreach my $prefix ( 'validate', 'default' ) {
            next if exists $self->methods->{$prefix};
            my $meth_name = "${prefix}_$suffix";
            if ( my $meth = $self->form->can($meth_name) ) {
                my $wrap_sub = sub {
                    my $self = shift;
                    return $self->form->$meth($self);
                };
                $self->{methods}->{$prefix} = $wrap_sub;
            }
        }
    }
}


sub fif {
    my $self = shift;
    return unless $self->is_active;
    return '' if $self->password;
    return $self->input if $self->has_input;
    if ( $self->has_value ) {
      my $value = $self->value;
      $value = $self->transform_value_to_fif->($self, $value) if $self->has_transform_value_to_fif;
      return $value;
    }
    return '';
}


sub full_name {
    my $field = shift;

    my $name = $field->name;
    my $parent_name;
    # field should always have a parent unless it's a standalone field test
    if ( $field->parent ) {
        $parent_name = $field->parent->full_name;
    }
    return $name unless defined $parent_name && length $parent_name;
    return $parent_name . '.' . $name;
}

sub full_accessor {
    my $field = shift;



( run in 1.450 second using v1.01-cache-2.11-cpan-39bf76dae61 )