laravel 5.1 access package config values - php

I'm starting a package on laravel 5.1. Up till now using laravel 4.2
I've been able to publish the package config file using the following in the boot method of the service provider for my package as described in the documents:
public function boot()
{
$this->publishes([
__DIR__ . '/config/config.php' => config_path('/packages/longestdrive/googlecal/googlecal.php'),
]);
Now I'm trying to access the items in this config using:
config('googlecal.client_id');
This however returns null
If I simply do: config() I get a full array of the config arrays and can see my package config file there.
If I then do: config('longestdrive.googlecal.googlecal.client_id') I can access the variable.
In L4.2 I did not need to add effectively the full path to the variable.
Have I missed something to enable me to simply do: config('googlecal.client_id')
Thanks

You have to merge your config file in ServiceProvider
/**
* Register the service provider.
*/
public function register()
{
$this->app->bind('laravel-db-localization', function ($app) {
return new LaravelDbLocalization();
});
// Load the config file
$this->mergeConfigFrom(__DIR__.'/config/laravel-db-localization.php', 'laravel-db-localization');
}

May be you should run "php artisan config:cache", it works for me:)

Related

Localization in a custom Laravel Package

My service provider of my custom package has the following lines in the boot() method:
$this->loadTranslationsFrom(__DIR__.'/../resources/lang', 'name');
$this->publishes([
__DIR__.'/../resources/lang' => resource_path('lang/vendor/name'),
], 'lang');
I ran the php artisan vendor:publish command and the packages/vendorname/packagename/resources/lang/de.json file was successfully copied to the project.
The translation is not working. I tried copying to the /lang/vendor/name/ folder as well.
When I move my de.json file manually to /lang then the translation is working. To there is no issue with the file itself.
I tried to clear all caches already.
I am not sure why, But, it seems that Laravel just loads only the JSON translation files of the main project and the first package in the Vendor folder.
My solution is:
for loading the JSON translation files from your package, you have to
use loadJsonTranslationsFrom in your package's service provider:
class CustomeServiceProvider extends ServiceProvider
{
/**
* Bootstrap the package services.
*
* #return void
*/
public function boot()
{
$this->loadJsonTranslationsFrom(__DIR__.'/../resources/lang');
}
}
In your JSON file you can use your package name as a prefix for every key. for example, if your package name is MyPackage, your en.json file
looks like:
{
"MyPackage::email": "Email",
"MyPackage::username": "Username",
...
}
You can use some helper functions of Laravel to load your translation keys:
trans('MyPackage::email'); // returns "Email"
OR
__('MyPackage::username'); // returns "Username"
You can follow the links below for more information:
https://laracasts.com/discuss/channels/laravel/loadjsontranslationsfrom-does-not-load-all-json-translation-files
https://github.com/laravel/framework/issues/17923
Laravel 5 loadJsonTranslationsFrom method does not load all JSON translation files from packages
https://github.com/nWidart/laravel-modules/pull/412
https://github.com/laravel/framework/pull/20599

The Mix manifest does not exist when using orchestral/testbench

Creating a custom Laravel package using the orchestral/testbench package that helps package developer to help with PHPUnit test. So, my package on a different place and not in a Laravel installation exactly. Everything works great except the mix() function that I'm using on the blade view for resources.
<script src="{{ asset(mix('js/app.js', 'vendor/trade')) }}"></script>
And, I have the following test route set in the web.php:
<?php
use Illuminate\Support\Facades\Route;
Route::get('/', function() {
return view('trade::_layouts.app');
});
In addition, I have the following feature test in the ExampleTest.php file:
public function testBasicTest()
{
$response = $this->get('/');
$response->assertStatus(200);
}
When I am running phpunit I am seeing the following error:
Expected status code 200 but received 500.
Failed asserting that false is true.
After dumping the $response in the test, I see the The Mix manifest does not exist. error. After digging for an hour I found that mix() helper function is looking for the mix-manifest.json in the orchestral/testbench package located under the vendor instead of the public folder in my package.
I tried to the following in the package ServiceProvider.php but didn't work either:
$this->app->bind('path.public', function() {
return base_path().'/../public';
});
In addition, I see the laravel/horizon package also using the mix() helper function on the layout.blade.php file as I am doing right now and it is also using the orchestral/testbench package for the test. So, how horizon package is doing the test while I can't? What is the to override mix() helper to ensure the public path is on my package public path instead of the orchestral/testbench path?
There are two ways to override the public_path() returned path to ensure the mix() function can find the mix-manifest.json file.
One would be to override the public_path() method completely to the custom package. Laravel usage if (!function_exists()) {} before declaring any function which is good as we can define our own public_path() function in our package. However, we'll need to make sure that our override function loads before the Laravel helper method and that's another topic.
The easiest way would be to change the path.public from Laravel IoC Container from the particular PHPUnit test where we're having the issue.
public function testBasicTest()
{
$this->app->instance('path.public', $packagePublicDir);
$response = $this->get('/');
$response->assertStatus(200);
}
I think you missed to run npm install && npm run dev

Laravel default helper method and facade doesn't work on custom package

I am developing a custom package where I need an access to the config data. I was able to pull data from config through my blade files, however, when I tried to call it from any custom classes I made, it's throwing an error:
Error: Call to undefined function Acme\Package\config()
What's interesting though, is that, when I tried using the facade Illuminate\Support\Facades\Config, it cannot find the class.
Is there any way I could retrieve data from the config (from the package and/or the app)?
<?php
namespace Acme\Package;
class MyClass {
public function test() {
config('app.name');
}
}
UPDATE: It works when running in the browser (package installed in a Laravel project) but fails when running package's test
UPDATE: If this helps, my package can be found here
Call to the config() is from here
And the test case that fails can be found here
<?php
namespace Acme\Package;
class MyClass {
public function test() {
\Illuminate\Support\Facades\Config::get('app.name');
}
}
Try like this, to use the full namespace to the Config Facade. You could also make a use statement under your namespace to inject the facade and then use Config::get('app.name). The reason it is not working is that your package cannot resolve the namespace of that facade as it is outside of the IoC container
You should try this:
<?php
namespace Acme\Package;
use Config;
class MyClass {
public function test() {
Config::get('app.name');
}
}
Updated answer
Please add below line in config/app.php in aliases section
'Config' => Illuminate\Support\Facades\Config::class,
then run below command
php artisan config:cache
php artisan cache:clear

Class 'Vendor\PackageName\ClassName' not found for newly created Laravel package

I've a problem running my newly created Laravel package which please check out https://github.com/Younesi/laravel-aparat
I can download it via Composer with no problem and it's auto-discovered via Laravel but when I try to use it, It gives me the following error of not finding class.
Class 'Younesi\LaravelAparat\Aparat' not found
My service Provider code is like:
/**
* Register the service provider.
*
* #return void
*/
public function register()
{
$this->app->bind('aparat', function ($app) {
return new Aparat;
});
}
/**
* Get the services provided by the provider.
*
* #return array
*/
public function provides()
{
return array('aparat');
}
Any help would be appreciated.
Looking at the package it's working fine, in composer.json of that package there is:
"autoload": {
"psr-4": {
"Younesi\\laravelAparat\\": "src"
}
},
Notice that laravel is not with capital letter here, so in your code you should import rather this way:
use Younesi\laravelAparat\Aparat;
instead of:
use Younesi\LaravelAparat\Aparat;
I also see that you are author of this package, so I would recommend using standard conversion (namespace starting with capital letter) instead of current namespace.
Looking further at package code, I also see that in service provider there is:
namespace Younesi\LaravelAparat;
namespace so it's nothing weird it won't work if you autoload it with lower-case letter and have namespace with upper-case letter
There were some cases with registration problem, cache issues, etc. Try one of these solutions:
register your provider (in main composer.json, then in config/app.php [provider & alias] ), then run composer dump-autoload
make sure you have initiated your package : go to the folder, then composer init
try php artisan config:cache or delete everything in bootstrap/cache/

'There are no commands defined in the "baum" namespace' error when using "baum" for implementing Nested Set

For implement of a Nested Set for my news category I want to use Baum package.
After installing this Package via Composer and add BaumServiceProvider to config/app.php providers, I try to install a new Model named Category via Below command:
php artisan baum:install MODEL
But I faced to the following error :
[InvalidArgumentException]
There are no commands defined in the "baum" namespace.
Of course I ran php artisan command and But there were no command named Baum on generated commands list.
What should I do?
First you have to add the code below in config/app.php:
Baum\Providers\BaumServiceProvider::class
If the problem still persists configuration files may be cached. Just call:
php artisan config:clear
Make sure that you added
Baum\Providers\BaumServiceProvider::class
To the providers array in the app.php file located in config/app.php
Whenever I know that I have added something into Laravel's core files, and it's not working from the command line, I typically just run
php artisan optimize
to regenerate all of the classes, and it will typically work. Running this command is something that I find myself doing fairly often.
In AppServiceProvider.php (app\Providers) you can modify register function: public function register()
{
$this->app->register(\Baum\Providers\BaumServiceProvider::class);
}
Not sure why 5.2 have error, just tweak a bit myself.
Try add this on APP/Console/kernel.php
protected $commands = [
//Commands\Inspire::class,
// Register Baum nestedset command
Commands\BaumCommand::class,
Commands\InstallCommand::class
];
and create two files and copy BaumCommand.php and InstallCommand in /vendor/baum/baum/src/Baum/console.
then change a namespace at the top.
namespace Baum\Commands;
to
namespace App\Console\Commands;

Categories