Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Accessing package controllers in Laravel 4

I have created a package following the "Creating a Package" instructions in the Laravel 4 documentation. After creating the package I have created a "controllers" folder and a routes file. The new file structure is:

/src
    /Vendor
        /Package
            PackageServiceProvider.php
    /config
    /controllers
    /lang
    /migrations
    /views
    routes.php
/tests
/public

I added the routes file to the boot portion of the package service provider:

public function boot()
{
    $this->package('vendor/package');
    include __DIR__ . '/../../routes.php';
}

Then added a basic route to the routes file:

Route::get('/package', function() {
    return "Package route test";
});

Visiting my application at the specified route (app.dev/package) returns the expected:

Package route test

Then adding a basic controller call to the route (using the default Laravel controller, "HomeController") works:

Route::get('/package', 'HomeController@showWelcome');

I then followed this SO answer for setting up the controller for the package. I added the src/controllers folder to the composer classmap, then I dumped the autoloader and checked vendor/composer/autoload_classmap.php and found the class is successfully loaded by composer:

<?php

// autoload_classmap.php generated by Composer

$vendorDir = dirname(__DIR__);
$baseDir = dirname($vendorDir);

return array(
    'HomeController' => $baseDir . '/src/controllers/HomeController.php',
);

Now I added the new package controller to the route using the namespace:

Route::get('/package', 'Vendor\Package\Controllers\HomeController@showWelcome');

but this produces an error about not finding the class:

ReflectionException: Class Vendor\Package\Controllers\HomeController does not exist

I've also tried calling it using the package name:

Route::get('/package', 'Package::HomeController@showWelcome');

which produces the same error:

ReflectionException: Class Vendor\Package\Controllers\HomeController does not exist

No matter what I try the package cannot access its own controller, which composer confirms is loaded (by viewing vendor/package/autoload_classmap.php).

Any ideas? I'm not sure if the issue is composer not loading the class, I'm not sure where to start with debugging the problem. I've created another package and repeated the steps here and get the same problem.

I can access the package views from both the package and the app, eg:

View::make('package::view');

The problem seems to be between composer loading the controller and Laravel being able to access it.

like image 805
sam Avatar asked Feb 19 '13 01:02

sam


People also ask

Where are Laravel controllers stored?

By default, controllers are stored in the app/Http/Controllers directory. Let's take a look at an example of a basic controller. Note that the controller extends the base controller class included with Laravel: App\Http\Controllers\Controller:

How to nest the resource controllers in Laravel routes?

To nest the resource controllers, you may use "dot" notation in your route declaration: This route will register a nested resource that may be accessed with URIs like the following: Laravel's implicit model binding feature can automatically scope nested bindings such that the resolved child model is confirmed to belong to the parent model.

What is the Laravel Service container used for?

The Laravel service container is used to resolve all Laravel controllers. As a result, you are able to type-hint any dependencies your controller may need in its constructor. The declared dependencies will automatically be resolved and injected into the controller instance:

How do I create a postcontroller in Laravel?

To make use of some traits the Laravel controllers offer, we'll first create our own base controller containing these traits in a src/Http/Controllers directory (resembling Laravel's folder structure) named Controller.php: Now, let's create a PostController in the src/Http/Controllers directory, starting first with the 'store' method:


1 Answers

The mistake was including the controllers path in the route. I had the following:

Route::get('/package', 'Vendor\Package\Controllers\HomeController@showWelcome');

The correct usage is:

Route::get('/package', 'Vendor\Package\HomeController@showWelcome');

With the namespace included in the controller:

namespace Vendor\Package;

Controller should extend illuminate:

\Illuminate\Routing\Controllers\Controller

Still can't use the package name (eg: Package::HomeController@showWelcome), but I can using the namespace. yay.

Problem solved.

like image 191
sam Avatar answered Sep 21 '22 00:09

sam