I am trying to work out the 'best' way of structuring my controllers/models in a new Laravel 4 app.
Obviously I want to keep the controllers thin and lightweight. So I want to work with Repos/Services to separate things, however I don't really know how to implement this in Laravel 4. Laravel 3 gave us some idea of how this should work, but no samples.
Has any one figured out the neatest way to do this, or have any sample code I could take a peek at?
I agree on the fact that it isn't very clear where to store these classes in Laravel 4.
A simple solution would be creating repositories/services folders in your main app/ folder and updating your main composer.json file to have them autoloaded:
{
"require": {
"laravel/framework": "4.0.*"
},
"autoload": {
"classmap": [
"app/commands",
"app/controllers",
"app/models",
"app/database/migrations",
"app/tests/TestCase.php",
"app/repositories",
"app/services"
]
},
"minimum-stability": "dev"
}
Note: everytime you create a new class you have to run composer dump-autoload.
In case of repositories, you can have Laravel inject them into your controllers automatically. I find this a good screencast on this subject.
I found this collection of tutorials to be a great introduction on the proper place to store your custom service providers and other files that you want to inject into your project:
http://fideloper.com/laravel-4-application-setup-app-library-autoloading
http://fideloper.com/laravel-4-where-to-put-bindings
http://fideloper.com/error-handling-with-content-negotiation
These tutorials come from this collection:
http://fideloper.com/tag/laravel-4
The first thing that I do when I get a fresh install of Laravel is:
Remove the "models" folder
Create a src folder
Under the src, create a Application folder (or the name of the app)
On Application folder, create Entities, Repositories, Services and Tests
So, in this case your namespace will be Application\Entities, Application\Repositories and Application\Services
In composer.json:
{
"require": {
"laravel/framework": "4.0.*"
},
"autoload": {
"psr-0": {
"Application": "app/src/"
},
"classmap": [
"app/commands",
"app/controllers",
"app/database/migrations",
]
},
"minimum-stability": "dev"
}
To each one of those you'll need to create the classes and a service provider to bind a repository to an entity.
Here is a tutorial explaining how to create the repositories:
http://culttt.com/2013/07/08/creating-flexible-controllers-in-laravel-4-using-repositories/
Anyway, I'm still looking for the best architecture. If anyone has a better idea, I'll be glad to hear it!
Related
i have edited psr-4 on composer.json
"autoload": {
"classmap": [
"database"
],
"psr-4": {
"Marka\\Urun\\": "vendor/Marka/Urun/src/",
"App\\": "app/"
},
"files": [
"vendor/Marka/Urun/src/helpers.php"
]
},
I want to change file(routes.php, helpers.php and Models,Views,Controllers) pathes to :
Vendor/Marka/Urun/
How can I do it ?
You're trying to get some modular structure if I get it right.
If so, instead of trying to set a different namespacing from composer for each of your modules under vendor directory; i think you may try to use something like http://sky.pingpong-labs.com/docs/2.0/modules
Otherwise as you may know, by using PSR-4 and directory structure, if you coded your files properly all necessary files would be loaded automatically as you named (namespaced) them.
By the way, just in case you didn't know you may also need a ServiceProvider to boot everything up for Laravel on your package.
I also suggest you to read https://laravel.com/docs/5.2/packages if you need any help about development structure/functionality.
I am new to Laravel and am trying to find my way around.
I want to create multiple custom Exception classes. I am a little confused as to where they should reside.
Should I create a folder in 'app' and place them in there and include the files manually from global.php?
Should I create a service provider?
For now, I have created a folder called 'exceptions' in app and added the path to ClassLoader::addDirectories. I could really do with some advice.
Are you using Composer? For example, using Composer you can put your configuration for autoloading:
"autoload": {
"classmap": [
"app/commands",
"app/controllers",
"app/database/migrations",
"app/database/seeds"
],
"psr-4": {
"Exceptions\\": "src/Exceptions",
"Services\\": "src/Services",
"Api\\": "src/Api"
}
},
As result your Exception file /src/Exceptions/Specific/ExtraSpecificException.php will be available
namespace Exceptions\Specific;
class ExtraSpecificException extends \Exception
{}
Laravel doesn't have a set place to store custom exceptions, you can place them anywhere you like.
Creating an app/exceptions/ directory works fine - You can autoload them all in your global.php file by adding
app_path() . '/exceptions/'
to the ClassLoader::addDirectories array.
If you have a lot and prefer to be more organised you can namespace your exception classes and take advantage of PSR-4 autoloading with composer.
I have just started learning Laravel and during the process, I found out that we can introduce our custom classes into Laravel using the following:
Create a folder say app/MyLib
Create my class inside app/MyLib, say I created MyDates
Now modify the ClassLoader::addDirectories inside the app/start/global.php as follows:
ClassLoader::addDirectories(array(
...
app_path().'/MyLib'
));
Access MyDates class, however I want
I then came across this article Laravel 4 Application Setup: App library, Autoloading, Binding that uses composer to autoload the custom libraries. Now the question is, what's the best way to introduce my custom libraries in Laravel i.e. what's the recommended approad and if there are any differences between these approaches, what are those?
its best practice and the only way you should do it, if you modify your composer.json as follows
"autoload": {
"classmap": [
"app/commands",
"app/controllers",
"app/models",
"app/database/migrations",
"app/database/seeds",
"app/tests/TestCase.php"
/* HERE YOUR LIBRARY FOLDER */
"app/MyLib",
]
},
EDIT:
You should run after the change composer dump-autoload to autoload your changes
I am attempting to move all my User code in to it's own package for potential use on multiple projects, everything is working fine except for when I try to login and I get the following error:
Class '\User' not found
Now, I am assuming that this is because for some reason it is not finding the User model (I am using the default one that comes with Laravel but just moved to
'Vendor/VendorName/PackageName/src/models'
I can see that I can reference the User model from app/config/auth.php but if I change this to my package namespace I am seeing the same error but with the different path, also, I don't think that this is the best way to do this as for every project I will need to set the app/config/auth.php model which could prove to be pain, especially as I forget things!
My guess is that you have not autoloaded User. Below is an example of how Laravel do use autoload in composer, the User class is at installation placed inside "app/models", which is autoloaded there. If you have moved your User anywhere else you need to autoload it from there.
"autoload": {
"classmap": [
"app/commands",
"app/controllers",
"app/models", // original path for User.php
"app/database/migrations",
"app/database/seeds",
"app/tests/TestCase.php",
"your/new/path" // here you add your new path that should autoload
]
}
And do not forget to run composer dump-autoload after updating your composer.json file!
I found that I can create a callback function using view composer
http://laravel.com/docs/responses#view-composers
so how to use class based composer:
View::composer('profile', 'ProfileComposer');
where to place ProfileComposer class?
thanks,
The view composer class should be defined as any regular class and might be stored in a libraries folder or if it is only used by a model you might store it there, there is no convention of where to store it. The class can hold some processes you want to reuse and you can register the call in a serviceprovider. This is a great tutorial on how to use it.
http://culttt.com/2014/02/10/using-view-composers-laravel-4/
You can have that ProfileComposer class inside ProfileComposer.php file and that will be in anywhere you want, if that file is autoloaded. You should be watching a video tutorial about Composers in Laracasts, and it will explain you why we have to use View::composer and how we can use.
I just find the answer in official decumentation.
you can put composer files anywhere in application file system, ex app/composer
and add it to composer.json
"autoload": {
"classmap": [
"app/commands",
"app/controllers",
"app/models",
"app/filters",
"app/database/migrations",
"app/database/seeds",
"app/tests/TestCase.php",
"app/composer"
]
},
then run artisan autoload:
php artisan dump-autoload
thanks everybody,