Catalyst-Runtime

 view release on metacpan or  search on metacpan

lib/Catalyst/Utils.pm  view on Meta::CPAN

          return $ns->new(@init_args);
        } elsif(Class::Load::try_load_class("Plack::Middleware::$namespace")) { ## Act like Plack::Builder
          return "Plack::Middleware::$namespace"->new(@init_args);
        } else {
          die "Can't load middleware via '$namespace'.  It's not ".$class."::Middleware::".$namespace." or Plack::Middleware::$namespace";
        }
    }

    return; ## be sure we can count on a proper return when valid
}

=head2 apply_registered_middleware ($psgi)

Given a $psgi reference, wrap all the L<Catalyst/registered_middlewares>
around it and return the wrapped version.

This exists to deal with the fact Catalyst registered middleware can be
either an object with a wrap method or a coderef.

=cut

sub apply_registered_middleware {
    my ($class, $psgi) = @_;
    my $new_psgi = $psgi;
    foreach my $middleware ($class->registered_middlewares) {
        $new_psgi = Scalar::Util::blessed $middleware ?
          $middleware->wrap($new_psgi) :
            $middleware->($new_psgi);
    }
    return $new_psgi;
}

=head2 inject_component

Used to add components at runtime:

    into        The Catalyst package to inject into (e.g. My::App)
    component   The component package to inject
    traits      (Optional) ArrayRef of L<Moose::Role>s that the component should consume.
    as          An optional moniker to use as the package name for the derived component

For example:

    Catalyst::Utils::inject_component( into => My::App, component => Other::App::Controller::Apple )

        The above will create 'My::App::Controller::Other::App::Controller::Apple'

    Catalyst::Utils::inject_component( into => My::App, component => Other::App::Controller::Apple, as => Apple )

        The above will create 'My::App::Controller::Apple'

    Catalyst::Utils::inject_component( into => $myapp, component => 'MyRootV', as => 'Controller::Root' );

Will inject Controller, Model, and View components into your Catalyst application
at setup (run)time. It does this by creating a new package on-the-fly, having that
package extend the given component, and then having Catalyst setup the new component
(via $app->setup_component).

B<NOTE:> This is basically a core version of L<CatalystX::InjectComponent>.  If you were using that
you can now use this safely instead.  Going forward changes required to make this work will be
synchronized with the core method.

B<NOTE:> The 'traits' option is unique to the L<Catalyst::Utils> version of this feature.

B<NOTE:> These injected components really need to be a L<Catalyst::Component> and a L<Moose>
based class.

=cut

sub inject_component {
    my %given = @_;
    my ($into, $component, $as) = @given{qw/into component as/};

    croak "No Catalyst (package) given" unless $into;
    croak "No component (package) given" unless $component;

    Class::Load::load_class($component);

    $as ||= $component;
    unless ( $as =~ m/^(?:Controller|Model|View)::/ || $given{skip_mvc_renaming} ) {
        my $category;
        for (qw/ Controller Model View /) {
            if ( $component->isa( "Catalyst::$_" ) ) {
                $category = $_;
                last;
            }
        }
        croak "Don't know what kind of component \"$component\" is" unless $category;
        $as = "${category}::$as";
    }
    my $component_package = join '::', $into, $as;

    unless ( Class::Load::is_class_loaded $component_package ) {
        eval "package $component_package; use base qw/$component/; 1;" or
            croak "Unable to build component package for \"$component_package\": $@";
        Moose::Util::apply_all_roles($component_package, @{$given{traits}}) if $given{traits};
        (my $file = "$component_package.pm") =~ s{::}{/}g;
        $INC{$file} ||= 1;
    }

    my $_setup_component = sub {
      my $into = shift;
      my $component_package = shift;
      $into->components->{$component_package} = $into->delayed_setup_component( $component_package );
    };

    $_setup_component->( $into, $component_package );
}

=head1 PSGI Helpers

Utility functions to make it easier to work with PSGI applications under Catalyst

=head2 env_at_path_prefix

Localize C<$env> under the current controller path prefix:

    package MyApp::Controller::User;

    use Catalyst::Utils;



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