Apache2-Controller

 view release on metacpan or  search on metacpan

lib/Apache2/Controller/Dispatch/Simple.pm  view on Meta::CPAN

        ];

        DEBUG(sub{"search_uris:".Dump(\%search_uris)});
        DEBUG(sub{"uri_lengths:".Dump(\%uri_lengths)});
    }
    return ($dispatch_map, $uri_length_map, $search_uri_list);
}

=head2 find_controller

Find the controller and method for a given URI from the data
set in the dispatch class module.

=cut

sub find_controller {
    my ($self) = @_;

    my $class = $self->{class};

    my ($dispatch_map, $uri_length_map, $search_uri_list) 
        = $self->_get_class_info();

    # figure out what most-specific path matches this URI.
    my $r = $self->{r};

    my $location = $r->location();

    my $uri = $r->uri();
    DEBUG(sub{Dump({
        uri             => $uri,
        location        => $location,
    })});

    $uri = substr $uri, length $location;

    DEBUG("uri becomes '$uri'");

    if ($uri) {
        # trim duplicate /'s
        $uri =~ s{ /{2,} }{/}mxsg;

        # chop leading /
        $uri = substr($uri, 1) if substr($uri, 0, 1) eq '/';
    }
    else {
        # 'default' is the default URI for top-level requests
        $uri = 'default';
    }
    my $uri_len = length $uri;
    my $uri_lc  = lc $uri;

    my ($controller, $method, $relative_uri) = ();
    my @path_args = ();

    SEARCH_URI:
    for my $search_uri (
        grep $uri_length_map->{$_} <= $uri_len, @{$search_uri_list} 
        ) {
        my $len = $uri_length_map->{$search_uri};
        my $fragment = substr $uri_lc, 0, $len;
        DEBUG("search_uri '$search_uri', len $len, fragment '$fragment'");
        if ($fragment eq $search_uri) {

            DEBUG("fragment match found: '$fragment'");

            # if next character in URI is not / or end of string, this is not it,
            # only a partial (/foo/barrybonds/stats should not match /foo/bar)
            my $next_char = substr $uri, $len, 1;
            if ($next_char && $next_char ne '/') {
                DEBUG("only partial match.  next SEARCH_URI...");
                next SEARCH_URI;
            }

            $controller = $dispatch_map->{$search_uri} 
                || a2cx
                  "No controller assigned in $class dispatch map for $search_uri.";
            
            # extract the method and the rest of the path args from the uri
            if ($next_char) {
                my $rest_of_uri = substr $uri, $len + 1;
                my $first_arg;
                ($first_arg, @path_args) = split '/', $rest_of_uri;

                DEBUG sub { Dump({
                    rest_of_uri     => $rest_of_uri,
                    first_arg       => defined $first_arg 
                                    ?   "'$first_arg'" 
                                    :   '[undef]'
                                    ,
                    path_args       => \@path_args,
                }) };

                # if the first field in the rest of the uri is a valid method,
                # assume that is the thing to use.
                if  (   defined $first_arg 
                    &&  controller_allows_method($controller, $first_arg)
                    ) {
                    $method = $first_arg;
                }
                # else use the 'default' method
                else {
                    $method = 'default';
                    unshift @path_args, $first_arg if defined $first_arg;
                }
                $relative_uri = $search_uri;
            }
            last SEARCH_URI;
        }
    }

    DEBUG($controller ? "Found controller '$controller'" : "no controller found");
    DEBUG($method     ? "Found method '$method'"         : "no method found");

    if (!$controller) {
        DEBUG("No controller found.  Using default module from dispatch map.");

        $controller = $dispatch_map->{default} 
            || a2cx "No 'default' controller assigned in $class dispatch map.";

        my $first_arg;
        ($first_arg, @path_args) = split '/', $uri;
        if (controller_allows_method($controller => $first_arg)) {
            $method = $first_arg;
        }



( run in 2.285 seconds using v1.01-cache-2.11-cpan-b16cb0d3907 )