Hello,

I'm new to Perl, and Dancer, and I've been working on porting a plugin (Dancer::Plugin::Nitesi) to Dancer 2. Reading the documentation on Dancer2::Plugin, all I can see that is different in Dancer 2 plugins is the use of the $dsl variable.

So I added 'my $dsl = shift;' to every 'sub' or 'register ... => sub', and changed the necessary code to use the $dsl variable, but in one subroutine, it will only give this error:

Variable "$dsl" is not imported at <home>/perl5/perlbrew/perls/perl-5.16.3/lib/site_perl/5.16.3/Dancer2/Plugin/Nitesi.pm line 347.

This is the code for the subroutine:

sub _update_session {
    my $dsl = shift;
    my ($function, $acct) = @_;
    my ($key, $sref);

    my $settings = plugin_setting();

    # determine session key
    $key = $settings->{Account}->{Session}->{Key} || 'user';

    $function ||= '';

    if ($function eq 'init') {
        # initialize user related information
        $dsl->app->session{$key} = $acct;
    } elsif ($function eq 'update') {
# update user related information (retrieve current state first)
        $sref = $dsl->app->session{$key};

        for my $name (keys %$acct) {
            $sref->{$name} = $acct->{$name};
        }

        $dsl->app->session->{$key} = $sref;

        return $sref;
    }
    elsif ($function eq 'destroy') {
    # destroy user related information
    $dsl->app->session->{$key} = undef;
    }
    else {
    # return user related information
    return $dsl->app->session($key);
    }
};

I've tried changing the $dsl declaration to all of these:

my ($dsl, $function, $acct) = @_;
my ($function, $acct, $dsl) = @_;
my ($function, $dsl, $acct) = @_;
my $dsl = shift @_;

Nothing seems to work.

I've attached the whole file. I'm pretty sure it's the only file I've changed, and I've probably made a mess of it.

Any help would be much appreciated, again, I'm new to Perl and Dancer, so I don't really know what I'm doing.

Thanks.

--
Phin Jensen
End Point Corporation
[email protected]
404-692-4034
package Dancer2::Plugin::Interchange;

use strict;
use warnings;

use Interchange::Account::Manager;
use Interchange::Product;
use Interchange::Cart;
use Interchange::Class;
use Interchange::Query::DBI;

use Moo::Role;

use Dancer2 qw(!before !after);
use Dancer2::Plugin;
use Dancer2::Plugin::Database;

=head1 NAME

Dancer2::Plugin::Interchange - Interchange Shop Machine plugin for Dancer2

=head1 VERSION

Version 0.0060

=cut

our $VERSION = '0.0060';

=head1 SYNOPSIS

    use Dancer2::Plugin::Interchange;

    cart->add({sku => 'ABC', name => 'Foobar', quantity => 1, price => 42});
    cart->items();
    cart->clear();

    account->login(username => '[email protected]', password => 'nevairbe');
    account->acl(check => 'view_prices');
    account->logout();

=head1 DESCRIPTION

This dancer plugin gives you access to the account and cart functions of
the Interchange shop machine.

=head1 CARTS

The cart keyword returns a L<Interchange::Cart> object with the corresponding 
methods. 

You can use multiple carts like that:

    cart('wishlist')->add({sku => 'ABC', name => 'Foobar', quantity => 1, price 
=> 42});
    cart('wishlist')->total;

The DBI backend (L<Dancer2::Plugin::Interchange::Cart::DBI>) allows you to load 
carts
of arbitrary users.

    cart('', 123)->items;

=head1 ACCOUNTS

The account keyword returns a L<Interchange::Account::Manager> object with the
corresponding methods.

Login to an account:

    account->login(username => '[email protected]', password => 'nevairbe');

Logout:

    account->logout();

Check permissions:

    account->acl(check => 'view_prices');

Change password for current account:

    account->password('nevairbe');

Change password for other account:

    account->password(username => '[email protected]', password => 
'nevairbe');

Create account:

    account->create(email => '[email protected]');

=head1 HOOKS

This plugin installs the following hooks:

=head2 Add to cart

The functions registered for these hooks receive the cart object
and the item to be added as parameters.

=over 4

=item before_cart_add_validate

Triggered before item is validated for adding to the cart.

=item before_cart_add

Triggered before item is added to the cart.

=item after_cart_add

Triggered after item is added to the cart.
Used by DBI backend to save item to the database.

=back

=head2 Update cart

The functions registered for these hooks receive the cart object,
the current item in the cart and the updated item.

=over 4

=item before_cart_update

Triggered before cart item is updated (changing quantity).

=item after_cart_update

Triggered after cart item is updated (changing quantity).
Used by DBI backend to update item to the database.

=back

=head2 Remove from cart

The functions registered for these hooks receive the cart object
and the item to be added as parameters.

=over 4

=item before_cart_remove_validate

Triggered before item is validated for removal.
Receives cart object and item SKU.

=item before_cart_remove

Triggered before item is removed from the cart.
Receives cart object and item.

=item after_cart_remove

Triggered after item is removed from the cart.
Used by DBI backend to delete item from the database.
Receives cart object and item.

=back

=head2 Clear cart

=over 4

=item before_cart_clear

Triggered before cart is cleared.

=item after_cart_clear

Triggered after cart is cleared.

=back

=head2 Rename cart

The functions registered for these hooks receive the cart object,
the old name and the new name.

=over 4

=item before_cart_rename

Triggered before cart is renamed.

=item after_cart_rename

Triggered after cart is renamed.

=back

=head1 CONFIGURATION

The default configuration is as follows:

    plugins:
      Interchange:
        Account:
          Session:
            Key: account
          Provider: DBI
      Cart:
        Backend: Session
      Product:
        backend: DBI
        table: products
        key: sku

=head2 ACCOUNT

=head3 Connection

The connection used by L<Dancer2::Plugin::Database> can be set
as follows:

    plugins:
      Interchange:
        Account:
          Provider: DBI
          Connection: shop

=head3 Fields

Extra fields can be retrieved from the account provider and
put into the session after a successful login:

    plugins:
      Interchange:
        Account:
          Provider: DBI
          Fields: first_name,last_name,city

=cut

register_hook(qw/before_cart_add_validate
                 before_cart_add after_cart_add
                 before_cart_update after_cart_update
                 before_cart_remove_validate
                 before_cart_remove after_cart_remove
                 before_cart_rename after_cart_rename
                 before_cart_clear after_cart_clear
                /);

my $settings = undef;

my %acct_providers;
my %carts;


hook 'after' => sub {
    my $carts;
    my $dsl = shift;

    # save all carts
    $carts = $dsl->context->vars->{'interchange_carts'} || {};

    for (keys %$carts) {
        $carts->{$_}->save();
    }
};


register account => \&_account;

sub _account {
    my $acct;
    my $dsl = shift;

    unless ($dsl->context->vars->{'interchange_account'}) {
        # not yet used in this request
        $acct = Interchange::Account::Manager->new(provider_sub => 
\&_load_account_providers);
        $acct->init_from_session;

        var interchange_account => $acct;
    }

    return $dsl->context->vars->{'interchange_account'};
};

sub _api_object {
    my (%args) = @_;

    my $name = shift || 'main';
    my $id = shift;
    my $dsl = shift;

    for my $thing (%args) {
        print $thing;
    }

    if (defined $id) {
        $token = "$name\0$id";
    }
    else {
        $token = $name;
    }

    unless (exists $dsl->context->vars->{interchange_carts}->{$token}) {
        # instantiate cart
        $dsl->context->vars->{interchange_carts}->{$token} = 
_create_cart($name, $id);
    }

    return $dsl->context->vars->{'interchange_carts'}->{$token};
};

register query => sub {
    my ($name, $arg, $q, $dbh);
    my $dsl = shift;

    if (@_) {
        $name = shift;
        $arg = $name;
    }
    else {
        $name = '';
        $arg = undef;
    }
    
    unless (exists $dsl->context->vars->{'interchange_query'}->{$name}) {
        # not yet used in this request
        unless ($dbh = database($arg)) {
            die "No database handle for database '$name'";
        }

        $q = Interchange::Query::DBI->new(dbh => $dbh);
        $dsl->context->vars->{'interchange_query'}->{$name} = $q;
    }

    return $dsl->context->vars->{interchange_query}->{$name};
};

sub _update_session {
    my $dsl;
    my ($function, $acct) = @_;
    my ($key, $sref);

    my $settings = plugin_setting();

    # determine session key
    $key = $settings->{Account}->{Session}->{Key} || 'user';

    $function ||= '';

    if ($function eq 'init') {
        # initialize user related information
            $dsl->app->session{$key} = $acct;
    } elsif ($function eq 'update') {
        # update user related information (retrieve current state first)
        $sref = $dsl->app->session{$key};

        for my $name (keys %$acct) {
            $sref->{$name} = $acct->{$name};
        }

        $dsl->app->session->{$key} = $sref;

        return $sref;
    }
    elsif ($function eq 'destroy') {
        # destroy user related information
        $dsl->app->session->{$key} = undef;
    }
    else {
        # return user related information
        return $dsl->app->session($key);
    }
};

register_plugin for_versions => [2];

sub _load_settings {
    $settings ||= plugin_setting;
}

sub _load_account_providers {
    _load_settings();

    # setup account providers
    if (exists $settings->{Account}->{Provider}) {
        if ($settings->{Account}->{Provider} eq 'DBI') {
            return [['Interchange::Account::Provider::DBI',
                     dbh => database($settings->{Account}->{Connection}),
                     fields => _config_to_array($settings->{Account}->{Fields}),
                     inactive => $settings->{Account}->{inactive},
                    ]];
        }
        else {
            my $provider_class = $settings->{Account}->{Provider};

            unless ($provider_class =~ /::/) {
                $provider_class = 
"Interchange::Account::Provider::$provider_class";
            }

            my %account_init = %{$settings->{Account}};

            delete $account_init{Provider};

            return [[$provider_class, %account_init]];
        }
    }

    # DBI provider is the default
    return [['Interchange::Account::Provider::DBI',
             dbh => database]];
}

sub _config_to_array {
    my $config = shift;
    my @values;

    if (defined $config) {
        @values = split(/\s*,\s*/, $config);
        return \@values;
    }

    return [];
}

sub _create_cart {
    my ($name, $id) = @_;
    my ($backend, $backend_class, $cart, $cart_settings);

    _load_settings();

    if (exists $settings->{Cart}->{Backend}) {
        $backend = $settings->{Cart}->{Backend};
    }
    else {
        $backend = 'Session';
    }

    # check for specific settings for this cart name
    if (exists $settings->{Cart}->{Carts}) {
        my $sref = $settings->{Cart}->{Carts};

        if (ref($sref) eq 'ARRAY') {
            # walk through settings
            for my $try (@$sref) {
                if (exists $try->{name}
                    && $name eq $try->{name}) {
                    $cart_settings = $try;
                    last;
                }
                if (exists $try->{match}) {
                    my $match = qr/$try->{match}/;

                    if ($name =~ /$match/) {
                        $cart_settings = $try;
                        last;
                    }
                }
            }
        }
        elsif (ref($sref) eq 'HASH') {
            if (exists $settings->{Cart}->{Carts}->{$name}) {
                $cart_settings = $settings->{Cart}->{Carts}->{$name};
            }
        }
        else {
            die "Invalid cart settings.";
        }
    }

    # determine backend class name
    if ($backend =~ /::/) {
        $backend_class = $backend;
    }
    else {
        $backend_class = __PACKAGE__ . "::Cart::$backend";
    }

    $cart = Interchange::Class->instantiate($backend_class,
                                       name => $name,
                                       settings => $cart_settings,
                                       run_hooks => sub {execute_hook(@_)});

    $cart->load(uid => $id || _account()->uid);

    return $cart;
}



=head1 CAVEATS

Please anticipate API changes in this early state of development.

=head1 AUTHOR

Stefan Hornburg (Racke), C<[email protected]>

=head1 BUGS

Please report any bugs or feature requests to C<bug-interchange at 
rt.cpan.org>, or through
the web interface at 
L<http://rt.cpan.org/NoAuth/ReportBug.html?Queue=Dancer2-Plugin-Interchange>.  
I will be notified, and then you'll
automatically be notified of progress on your bug as I make changes.

=head1 SUPPORT

You can find documentation for this module with the perldoc command.

    perldoc Dancer2-Plugin-Interchange

You can also look for information at:

=over 4

=item * RT: CPAN's request tracker (report bugs here)

L<http://rt.cpan.org/NoAuth/Bugs.html?Dist=Dancer2-Plugin-Interchange>

=item * AnnoCPAN: Annotated CPAN documentation

L<http://annocpan.org/dist/Dancer2-Plugin-Interchange>

=item * CPAN Ratings

L<http://cpanratings.perl.org/d/Dancer2-Plugin-Interchange>

=item * Search CPAN

L<http://search.cpan.org/dist/Dancer2-Plugin-Interchange/>

=back


=head1 ACKNOWLEDGEMENTS

The L<Dancer2> developers and community for their great application framework
and for their quick and competent support.

=head1 LICENSE AND COPYRIGHT

Copyright 2010-2012 Stefan Hornburg (Racke).

This program is free software; you can redistribute it and/or modify it
under the terms of either: the GNU General Public License as published
by the Free Software Foundation; or the Artistic License.

See http://dev.perl.org/licenses/ for more information.

=head1 SEE ALSO

L<Interchange>

=cut

1;
_______________________________________________
dancer-users mailing list
[email protected]
http://lists.preshweb.co.uk/mailman/listinfo/dancer-users

Reply via email to