Updated helper for Root class
[catagits/Catalyst-Runtime.git] / lib / Catalyst.pm
index 8fedc9c..981b20f 100644 (file)
@@ -21,7 +21,6 @@ use Scalar::Util qw/weaken/;
 use Tree::Simple qw/use_weak_refs/;
 use Tree::Simple::Visitor::FindByUID;
 use attributes;
-use YAML ();
 
 __PACKAGE__->mk_accessors(
     qw/counter request response state action stack namespace/
@@ -48,7 +47,7 @@ our $DETACH    = "catalyst_detach\n";
 require Module::Pluggable::Fast;
 
 # Helper script generation
-our $CATALYST_SCRIPT_GEN = 26;
+our $CATALYST_SCRIPT_GEN = 27;
 
 __PACKAGE__->mk_classdata($_)
   for qw/components arguments dispatcher engine log dispatcher_class
@@ -59,7 +58,7 @@ __PACKAGE__->engine_class('Catalyst::Engine::CGI');
 __PACKAGE__->request_class('Catalyst::Request');
 __PACKAGE__->response_class('Catalyst::Response');
 
-our $VERSION = '5.64';
+our $VERSION = '5.66';
 
 sub import {
     my ( $class, @arguments ) = @_;
@@ -179,6 +178,14 @@ C<My::Module>.
 
     use Catalyst qw/My::Module/;
 
+If your plugin starts with a name other than C<Catalyst::Plugin::>, you can
+fully qualify the name by using a unary plus:
+
+    use Catalyst qw/
+        My::Module
+        +Fully::Qualified::Plugin::Name
+    /;
+
 Special flags like C<-Debug> and C<-Engine> can also be specified as
 arguments when Catalyst is loaded:
 
@@ -535,12 +542,7 @@ loads and instantiates the given class.
 
 sub plugin {
     my ( $class, $name, $plugin, @args ) = @_;
-    $plugin->require;
-
-    if ( my $error = $UNIVERSAL::require::ERROR ) {
-        Catalyst::Exception->throw(
-            message => qq/Couldn't load instant plugin "$plugin", "$error"/ );
-    }
+    $class->_register_plugin( $plugin, 1 );
 
     eval { $plugin->import };
     $class->mk_classdata($name);
@@ -601,15 +603,6 @@ sub setup {
 
     $class->setup_home( delete $flags->{home} );
 
-    # YAML config support
-    my $confpath = $class->config->{file}
-      || $class->path_to(
-        ( Catalyst::Utils::appprefix( ref $class || $class ) . '.yml' ) );
-    my $conf = {};
-    $conf = YAML::LoadFile($confpath) if -f $confpath;
-    my $oldconf = $class->config;
-    $class->config( { %$oldconf, %$conf } );
-
     $class->setup_log( delete $flags->{log} );
     $class->setup_plugins( delete $flags->{plugins} );
     $class->setup_dispatcher( delete $flags->{dispatcher} );
@@ -708,7 +701,9 @@ EOF
 Merges path with C<$c-E<gt>request-E<gt>base> for absolute uri's and
 with C<$c-E<gt>namespace> for relative uri's, then returns a
 normalized L<URI> object. If any args are passed, they are added at the
-end of the path.
+end of the path.  If the last argument to uri_for is a hash reference,
+it is assumed to contain GET parameter key/value pairs, which will be
+appended to the URI in standard fashion.
 
 =cut
 
@@ -727,12 +722,16 @@ sub uri_for {
     $namespace = '' if $path =~ /^\//;
     $path =~ s/^\///;
 
+    my $params =
+      ( scalar @args && ref $args[$#args] eq 'HASH' ? pop @args : {} );
+
     # join args with '/', or a blank string
     my $args = ( scalar @args ? '/' . join( '/', @args ) : '' );
     $args =~ s/^\/// unless $path;
     my $res =
       URI->new_abs( URI->new_abs( "$path$args", "$basepath$namespace" ), $base )
       ->canonical;
+    $res->query_form(%$params);
     $res;
 }
 
@@ -1848,25 +1847,64 @@ Sets up plugins.
 
 =cut
 
-sub setup_plugins {
-    my ( $class, $plugins ) = @_;
+=head2 $c->registered_plugins 
+
+Returns a sorted list of the plugins which have either been stated in the
+import list or which have been added via C<< MyApp->plugin(@args); >>.
+
+If passed a given plugin name, it will report a boolean value indicating
+whether or not that plugin is loaded.  A fully qualified name is required if
+the plugin name does not begin with C<Catalyst::Plugin::>.
 
-    $plugins ||= [];
-    for my $plugin ( reverse @$plugins ) {
+ if ($c->registered_plugins('Some::Plugin')) {
+     ...
+ }
 
-        $plugin = "Catalyst::Plugin::$plugin";
+=cut
+
+{
+    my %PLUGINS;
+
+    sub registered_plugins {
+        my $proto = shift;
+        return sort keys %PLUGINS unless @_;
+        my $plugin = shift;
+        return 1 if exists $PLUGINS{$plugin};
+        return exists $PLUGINS{"Catalyst::Plugin::$plugin"};
+    }
+
+    sub _register_plugin {
+        my ( $proto, $plugin, $instant ) = @_;
+        my $class = ref $proto || $proto;
 
         $plugin->require;
 
-        if ($@) {
+        if ( my $error = $@ ) {
+            my $type = $instant ? "instant " : '';
             Catalyst::Exception->throw(
-                message => qq/Couldn't load plugin "$plugin", "$@"/ );
+                message => qq/Couldn't load ${type}plugin "$plugin", $error/ );
         }
 
-        {
+        $PLUGINS{$plugin} = 1;
+        unless ($instant) {
             no strict 'refs';
             unshift @{"$class\::ISA"}, $plugin;
         }
+        return $class;
+    }
+
+    sub setup_plugins {
+        my ( $class, $plugins ) = @_;
+
+        $plugins ||= [];
+        for my $plugin ( reverse @$plugins ) {
+
+            unless ( $plugin =~ s/\A\+// ) {
+                $plugin = "Catalyst::Plugin::$plugin";
+            }
+
+            $class->_register_plugin($plugin);
+        }
     }
 }