I want to have controllers in my Laravel 4 package, but I can't get the routing to work.
I've followed the package instructions in the Laravel 4 documentation, and got the routes.php file working with non-controller routes.
Could someone please give me some instructions on how to get package controllers to work in Laravel 4, it would be very much appreciated.
Thanks in advance.
Lars
// EDIT:
// routes.php
Route::get('admin', 'Package::AdminController#index'); // Does not work
Route::get('admin', function(){ // Works fine
return 'Dashboard';
})
I don't know the specifics of your situation, nor do I know if this is the "proper" way to fix this issue, but since I came across the same problem I figured I'd share how I solved it.
I put my package controllers in the controllers subdirectory, so that my directory structure looks like this:
/src
/Vendor
/Package
PackageServiceProvider.php
/config
/controllers
/lang
/migrations
/views
/tests
/public
Then, I added the controllers folder to my package's composer.json autoload class map.
{
"name": "kevin-s-perrine/my-first-packge",
"description": "",
"authors": [
{
"name": "Kevin S. Perrine",
"email": "removed#somewhere.com"
}
],
"require": {
"php": ">=5.3.0",
"illuminate/support": "4.0.x"
},
"autoload": {
"classmap": [
"src/migrations",
"src/controllers"
],
"psr-0": {
"KevinSPerrine\\MyFirstPackage": "src/"
}
},
"minimum-stability": "dev"
}
Finally, I ran composer dump-autoload in the package's root directory, and then reference the controller by name in the routes file.
Route::get('myfirstpackage', 'MyFirstPackageHomeController#getIndex');
You'll need to reference the Controller with it's Namespace too
Route::get('/admin', 'PackageNS\Package\Controllers\AdminController#getIndex');
or even
Route::controller('PackageNS\Package\Controllers\AdminController', 'admin');
In your package's service provider, have you included your routes file? I don't believe L4 loads the route file automatically. You can do it anywhere but I suspect this would be the most appropriate place to do it.
public function register()
{
$this->package('vendor/pkgname');
require __DIR__.'/../routes.php';
}
Did you do this:
composer dump-autoload
The autoloader needs to be told about those shiny new classes. I also suggest you check the webserver logs for errors.
Related
Im relative new in laravel, before use laravel I used a file functions.php with all functions that I use in my projects (create slugs, format dates, etc).
where I can create my own functions in laravel to use in controllers and views like myfunction($data) ?
Use the Laravel composer example, where it creates some helper files:
"autoload": {
"files": [
"src/Illuminate/Foundation/helpers.php",
"src/Illuminate/Support/helpers.php"
],
"psr-4": {
"Illuminate\\": "src/Illuminate/"
}
},
Edit your composer.json file, where you could create a helper in the App folder
"autoload": {
"files": [
"app/helpers.php",
],
...
},
Then you just have to execute
composer dumpautoload
To tell composer to load it automatically.
In your app/Http directory, create a helpers.php file to add your functions
Within composer.json, in the autoload block, add:
"files": ["app/Http/helpers.php"].
On command line run "composer dump-autoload"
I'm developing my first Larvel-based package. I want to include the Socialite package, so I put it like this in my composer.json file
"require": {
"laravel/socialite": "^2.0"
},
Now, how do I include the provider and the alias as you'd normally do in /config/app.php ?
I think by now I've read every stackoverflow there is about this matter, but nothing seems to work.
This is my package's serviceprovider:
public function boot()
{
include __DIR__.'/routes.php';
$this->app->register('Laravel\Socialite\SocialiteServiceProvider');
$this->app->alias('Laravel\Socialite\Facades\Socialite', 'Socialite');
$this->loadViewsFrom(__DIR__.'/../views', 'package-name');
$this->loadTranslationsFrom(__DIR__.'/../lang', 'package-name');
$this->publishes([
__DIR__.'/../views' => resource_path('views/vendor/package-name'),
]);
$this->publishes([
__DIR__.'/../database/migrations/' => database_path('migrations')
], 'migrations');
}
Result:
Class 'Laravel\Socialite\SocialiteServiceProvider' not found
UPDATE
"psr-4": {
"App\\": "app/",
"Rubenwouters\\CrmLauncher\\": "packages/rubenwouters/crm-launcher/src/"
}
In your package's service provider in register method you can do:
public function boot() {
$this->app->register(ClassOfScialiteServiceProvider);
$this->app->alias(FacedeClass, 'Alias');
}
EDIT
But first of all... To add your package in the right way (to the vendor that you can adding a requirments) you have to some how add it to the main composer.json - required list. You can do it with one of below:
1
Adding you package to the official composer repository (packagist)
2
Make your own composer repository like Satis
3
The easiest way is to add your git repo dependanci inside composer.json like:
"repositories": [
{
"type": "vcs",
"url": "git#your_repo/crm-launcher.git"
},
],
"require": {
(...)
"rubenwouters/crm-launcher": "dev-master"
}
OR
or just move your dependencies ("laravel/socialite": "^2.0") to the main composer.json. :)
Register Laravel\Socialite\SocialiteServiceProvider::class, to Config\app.php as providers and also
Register 'Socialize' => Laravel\Socialite\Facades\Socialite::class, to Config\app.php as aliases.
May be this will solve your problem.
EDIT | I basically would like to tell composer to populate
autoload_classmap.php with a mapping of all files/classes under the
directory "web/". This houses all the application specific classes -
some which follow PSR-0 others do not.
I have a composer.json:
{
"name": "company/project",
"description": "Internal management system",
"require": {
"swiftmailer/swiftmailer": "^5.4",
"slim/slim": "2.4.2"
},
"autoload": {
"psr-0": {
"Application_Ancillary_": "web/private/module/rpi/ancillary/"
}
}
}
This "autoload" will kind of work - but there are cases where the classnames do no map according to PSR-0 the classname might be something like
Application_TestSomething => web/private/module/test/ApplicationTestSomething
When I tried to use 1:1 classname => file mapping it didn't work when I ran:
composer dumpautoload -o
Also the "Slim" classes are being included in the autoload_classmap.php
Ideally all the composer included packages (ie: Slim, etc) would not be part of the classmap file as I have hundreds of legacy files which I would rather include.
I assume that up until now someone manually edited the autoload_classmap.php
Any suggestions?
In case you don't follow any standard (PSR-0/PSR-4), use classmap:
"autoload": {
"classmap": [ "web" ]
}
I'm starting work on a new mini-framework project, which I have in a local GIT repo on my machine. I've set up a test project that pulls in the local repo via Composer, however the autoloader isn't working as expected (Fatal Error: Class X not found errors). This is the first time I've used autoloading outside of what is automatically generated (e.g. when using an existing framework) and despite reading around, I can't seem to solve this.
Package
In an attempt to get this working, the package only contains a src directory with a single App.php class on top of the composer.json file in the root.
composer.json
{
"name": "myvendor/framework",
"description": "Framework Description",
"license": "MIT",
"authors": [
{
"name": "Joe Bloggs",
"email": "joe#email.com"
}
],
"autoload": {
"psr-0": {
"Framework": "src/"
}
}
}
Project
composer.json
{
"repositories": [
{
"type": "vcs",
"url" : "../Framework"
}
],
"require": {
"myvendor/framework": "dev-master"
}
}
This successfully clones the local repo and adds the code to the vendor directory.
The namespace is also successfully added to Composer's autoload_namespaces.php file like so;
vendor/composer/autoload_namespaces.php
'Framework' => array($vendorDir . '/myvendor/framework/src'),
When I attempt to load the App class however using the following code, I get the error;
web/index.php
<?php
require_once '../vendor/autoload.php';
$app = new \Framework\App();
You're using the psr-0 specification for the class loader. This means that the full namespace has to be visible in the file structure. The prefix only tells the autoloader were to look for this namespace.
So in your case, you configured that the "Framework" namespace is available in the "src/" directory. This means that the class \Framework\App should life in src/Framework/App.php. In your case, it exists in src/App.php. This means that the autoloader cannot find your class.
However, there is a class loader specification that does what you want: psr-4. This is also the recommended specification (psr-0 might be removed in the future). With PSR-4, the file structure only includes the namespaces after the configured prefixes. So when doing "psr-4": { "Framework\": "src/" }, a class called \Framework\App should life in src/App.php and a class called \Framework\Some\Special\App should life in src/Some/Special/App.php.
Background
I know what I'm trying to do sounds a bit wrong but I do have my reasons.
Basically I have a central core app that's a default laravel app with a few tweaks and boilerplate code, I have then developed a series of packages that can be used to extend the app through composer. These packages are not meant to function without the core framework so a dependency upon it is fully expected.
What I want to do
What I would like to do is have a BaseController in my core app and have the various controllers in my package extend this BaseController to provide universal functionality throughout the various module packages.
I was expecting to be able to place the base controller in app/controllers/BaseController.php
and then extend it from my package using:
class PackageController extends \BaseController{}
Unfortunately when I do this it still looks within the package (currently workbenched) for the controller and I get the error:
include(/var/www/l4core.dev/workbench/myvendor/mypackage/src/controllers/BaseController.php):
failed to open stream: No such file or directory
Can anyone tell me what I'm doing wrong here. I am looking for a solution which allows me to easily move my packages between vendor dir and workbench for development. Any help greatly appreciated
Update
The previously mentioned error message appears to have been due to an include in my packages /vendor/composer/classloader.php - I have now deleted the vendor directory and done a fresh composer install. This has not solved the problem but it has at least shifted it as I now get the following error message:
Class 'BaseController' not found
My Packages composer.json
{
"name": "modules/sesame",
"description": "",
"authors": [
{
"name": "any",
"email": ""
}
],
"require": {
"php": ">=5.4.0",
"illuminate/support": "4.0.x",
"zizaco/confide": "dev-master",
"zizaco/entrust": "dev-master",
"conarwelsh/mustache-l4": "dev-master"
},
"autoload": {
"classmap": [
"src/controllers",
"src/models",
"src/migrations",
"src/seeds"
],
"psr-0": {
"Modules\\Sesame": "src/"
}
},
"minimum-stability": "dev"
}
Be sure to execute:
php artisan dump-autoload
And verify that your class BaseController is in /vendor/composer/autoload_classmap.php.
OR like the OP stated, removing the vendor directory and running composer install again could sometimes solve the problem.