Let's take a look at upgrading a package service provider to work with Laravel 5. The service provider is intended to inform the application of the package's existance and register its assets. Exactly how this is done will vary depending on the needs of the pacakge, but there are several common items which we will discuss here: Configuration, Language Files, Views and Public Assets. John Hout has a great write up about this, which I will be expanding on.
Two important things before we begin. First have to remove this line from our boot()
method, because it is no longer needed:
$this->package('rydurham/sentinel');
Secondly, Laravel 5 now ships with a vendor:publish
command, which greatly simplifies copying files from the vendor/package directory into the main application. Any folders or files added to the $this->publishes
array in the boot()
method will be published when you run the vendor:publish
command. (Vendor in this case is literally 'vendor', not the vendor name of your package.) As per the documentation, add this to your boot()
command:
1 | public function boot() |
2 | { |
3 | // ... |
4 | |
5 | $this->publishes([ |
6 | __DIR__.'/path/to/file1.php' => base_path('location/in/main/application/file1.php'), |
7 | __DIR__.'/path/to/directory' => base_path('location/in/main/application/directory'), |
8 | // Add as items as you want, pointing to any location. |
9 | // Works with both files and directories |
10 | ]); |
11 | |
12 | // ... |
13 | } |
Configuration
Configuration management in Laravel 5 has been greatly simplified, and there is no longer a need for accessing config options via a namespace. Add your package config file to the $this->publishes
array and publish it to the main application config folder: base_path('config/sentinel.php')
. You can name it whatever you want, but I would reccomend giving it the same name as your package.
Accessing config values can be done in the same way you are used to:
Config::get('sentinel.allow_usernames')
or you can use this new helper function:
config('sentinel.allow_usernames')
It is possible that someone using your package may not publish the config file, or they only have a subset of the configurable values in their local version of the config file. In those situations it can be beneficial to selectively merge their config file with the default config file in the package repository. This can be done with the mergeConfigFrom
method in the boot
function:
1 | public function boot() |
2 | { |
3 | // ... |
4 | |
5 | $this->mergeConfigFrom(__DIR__.'/../config/sentinel.php', 'sentinel'); |
6 | |
7 | // ... |
8 | } |
Views and Assets
Package views can still be accessed via a namespace. In lieu of the old view:publish
command, you should add your views to the publishes
array. The loadViewsFrom
function allows you to register the view namespace, however you may want to check to see if the views have been published before you create the namespace:
1 | public function boot() |
2 | { |
3 | // ... |
4 | |
5 | // Establish Views Namespace |
6 | if (is_dir(base_path() . '/resources/views/packages/rydurham/sentinel')) { |
7 | // The package views have been published - use those views. |
8 | $this->loadViewsFrom(base_path() . '/resources/views/packages/rydurham/sentinel', 'Sentinel'); |
9 | } else { |
10 | // The package views have not been published. Use the defaults. |
11 | $this->loadViewsFrom(__DIR___ . '/../views/bootstrap', 'sentinel'); |
12 | } |
13 | |
14 | // ... |
15 | } |
Assets like javascript files or images should be added to the publishes
array and pointed to the public folder.
Language Files
Making translation files available to the application is very straightforward, and translation strings can still be accessed with the trans()
function using a namespace:
1 | public function boot() |
2 | { |
3 | // ... |
4 | |
5 | // Establish Translator Namespace |
6 | $this->loadTranslationsFrom(__DIR__ . '/../lang', 'Sentinel'); |
7 | |
8 | // ... |
9 | } |
Controllers & Routes
Some packages might make use of their own controllers and routing. To add routes, just include the routes.php file as such:
1 | public function boot() |
2 | { |
3 | // ... |
4 | |
5 | // Add Sentinel Routes |
6 | include __DIR__ . '/../routes.php'; |
7 | |
8 | // ... |
9 | } |
Controllers should be namespaced, and autoloaded via the composer.json file:
1 | "autoload": { |
2 | "classmap": [ |
3 | "src/seeds", |
4 | "src/controllers" |
5 | ], |
6 | "psr-4": { |
7 | "Sentinel\\": "src/Sentinel" |
8 | } |
9 | }, |