Handel

 view release on metacpan or  search on metacpan

lib/Handel/Checkout.pm  view on Meta::CPAN

        $self->stash(
            $self->stash_class->new($stash)
        );
    } else {
        $self->stash(
            $self->stash_class->new
        );
    };

    foreach ($self->load_plugins($opts)) {
        if (blessed($_) && $_->isa('Handel::Checkout::Plugin')) {
            push @{$self->{'plugins'}}, $_;
            $_->register($self);
        };
    };

    if ($opts->{'cart'}) {
        $self->cart($opts->{'cart'});
    };
    if ($opts->{'order'}) {
        $self->order($opts->{'order'});
    };
    if ($opts->{'phases'}) {
        $self->phases($opts->{'phases'});
    };

    return $self;
};

sub plugins {
    my $self = shift;

    return wantarray ? sort @{$self->{'plugins'}} : $self->{'plugins'};
};

sub add_handler {
    my ($self, $phase, $ref, $preference) = @_;
    my ($package) = caller;

    if ($phase !~ /\D+/i) {
        throw Handel::Exception::Argument( -details =>
            translate('PARAM1_NOT_CHECKOUT_PHASE')
        ) unless constraint_checkout_phase($phase); ## no critic
    };

    throw Handel::Exception::Argument( -details =>
        translate('PARAM1_NOT_CODEREF')
    ) unless ref($ref) eq 'CODE'; ## no critic

    foreach (@{$self->{'plugins'}}) {
        if (ref $_ eq $package) {
            if ($preference) {
                if (exists $self->{'handlers'}->{$phase}->{$preference}) {
                    my $plugin = $self->{'handlers'}->{$phase}->{$preference}->[0];

                    throw Handel::Exception::Checkout( -details =>
                        translate('HANDLER_EXISTS_IN_PHASE', $phase, $preference, $plugin)
                    );
                };
            } else {
                my @prefs = sort {$a <=> $b} keys %{$self->{'handlers'}->{$phase}};
                $preference = scalar @prefs ? $#prefs++ : 101;
            };
            $self->{'handlers'}->{$phase}->{$preference} = [$_, $ref];
            last;
        };
    };

    return;
};

sub add_message {
    my ($self, $message) = @_;
    my ($package, $filename, $line) = caller;

    if (blessed($message) && $message->isa('Handel::Checkout::Message')) {
        $message->package($package) unless $message->package;       ## no critic
        $message->filename($filename) unless $message->filename;    ## no critic
        $message->line($line) unless $message->line;                ## no critic

        push @{$self->{'messages'}}, $message;
    } elsif (!ref $message || ref $message eq 'Apache::AxKit::Exception::Error') {
        push @{$self->{'messages'}}, Handel::Checkout::Message->new(
            text => $message, source => $package, filename => $filename, line => $line);
    } else {
        throw Handel::Exception::Argument( -details =>
            translate('PARAM1_NOT_CHECKOUT_MESSAGE')
        );
    };

    return;
};

sub add_phase {
    my ($self, $name, $value, $import) = @_;
    my $caller = (caller);

    carp 'add_phase is deprecated and will be removed in a future release';

    if (Handel::Constants->can($name)) {
        throw Handel::Exception::Constraint(
            -text => translate('CONSTANT_NAME_ALREADY_EXISTS', $name)
        );
    } elsif (constraint_checkout_phase($value)) {
        throw Handel::Exception::Constraint(
            -text => translate('CONSTANT_VALUE_ALREADY_EXISTS', $value)
        );
    } elsif ($import && main->can($name)) {
        throw Handel::Exception::Constraint(
            -text => translate('CONSTANT_EXISTS_IN_CALLER', $name, $caller)
        );
    } else {
        my $sub = sub {return $value};
        no strict 'refs';

        *{"Handel::Constants::$name"} = $sub;

        if ($import) {
            *{"${caller}::$name"} = $sub;
        };

        push @Handel::Constants::CHECKOUT_ALL_PHASES, $value;

lib/Handel/Checkout.pm  view on Meta::CPAN

        };
    };

    return $self->{'order'};
};

sub phases {
    my ($self, $phases) = @_;

    if ($phases) {
        throw Handel::Exception::Argument( -details =>
            translate('PARAM1_NOT_ARRAYREF_STRING')
        ) unless (ref($phases) eq 'ARRAY' || !ref($phases)); ## no critic

        if (! ref $phases) {
            # holy crap, that actually worked!
            $phases = [map(eval "$_" || $_, _path_to_array($phases))];
        };

        $self->{'phases'} = [map {eval "$_" || $_} @{$phases}];
    } else {
        if (wantarray) {
            return (scalar @{$self->{'phases'}}) ? @{$self->{'phases'}} : @{&CHECKOUT_DEFAULT_PHASES}; ## no critic
        } else {
            return (scalar @{$self->{'phases'}}) ? $self->{'phases'} : CHECKOUT_DEFAULT_PHASES;
        };
    };

    return;
};

sub process {
    my $self = shift;
    my $phases = shift;

    if ($phases) {
        throw Handel::Exception::Argument( -details =>
            translate('PARAM1_NOT_ARRAYREF_STRING')
        ) unless (ref($phases) eq 'ARRAY' || ! ref($phases)); ## no critic

        if (! ref $phases) {
            # holy crap, that actually worked!
            $phases = [map(eval "$_", _path_to_array($phases))];
        };
    } else {
        $phases = scalar @{$self->{'phases'}} ? $self->{'phases'} : CHECKOUT_DEFAULT_PHASES;
    };

    throw Handel::Exception::Checkout( -details =>
        translate('NO_ORDER_LOADED')
    ) unless $self->order; ## no critic

    $self->_setup;

    {
        $self->order->result->txn_begin;

        foreach my $phase (@{$phases}) {
            next unless $phase;

            my @handlerprefs = sort {$a <=> $b} keys %{$self->{'handlers'}->{$phase}};
            foreach my $handlerpref (@handlerprefs) {
                my $handler = $self->{'handlers'}->{$phase}->{$handlerpref};
                my $status = $handler->[1]->($handler->[0], $self);

                if ($status != CHECKOUT_HANDLER_OK && $status != CHECKOUT_HANDLER_DECLINE) {
                    $self->_teardown($self);

                    try {
                        $self->order->result->txn_rollback;
                        $self->order->result->discard_changes;
                        foreach my $item ($self->order->items->all) {
                            $item->result->discard_changes;
                        };
                    } otherwise {
                        throw Handel::Exception::Checkout(-details => translate('ROLLBACK_FAILED', shift));
                    };

                    return CHECKOUT_STATUS_ERROR;
                };
            };
        };

        $self->order->result->txn_commit;
    };

    $self->_teardown;

    return CHECKOUT_STATUS_OK;
};

sub _setup {
    my $self = shift;

    foreach (@{$self->{'plugins'}}) {
        try {
            $_->setup($self);
        };
    };

    return;
};

sub _teardown {
    my $self = shift;

    foreach (@{$self->{'plugins'}}) {
        try {
            $_->teardown($self);
        };
    };

    return;
};

sub load_plugins {
    my ($self, $opts) = @_;
    my ($package, $file) = caller;
    my $config = Handel->config;
    my $search_path;

    my $pluginpaths = ref $opts->{'pluginpaths'} eq 'ARRAY' ?



( run in 0.576 second using v1.01-cache-2.11-cpan-0bb4e1dffa6 )