Is it possible to write to a language file located at resources/lang/en/file.php from a controller? I moved my translations to database so user can edit them and now want to write the content from database to lang file each time content is changed.
You can write to anywhere in your filesystem provided you have the correct permissions. file_put_contents will write your contents to the desired path.
But you have the translation in a db, what's the use of writing to a file? You're just creating redundant data unnecessarily.
Edit:
You should define an entry in config/filesystems.php to use with the Storage facade.
'translations' => [
'driver' => 'local',
'root' => resource_path('translations'),
],
Found this function that helps me to write to resources folder:
app()['path.lang']
Related
Within a Laravel project, I have an API that is powered by a flat JSON file. I'd like to use the JSON file where it currently resides, which is inside the /resources/modules/ folder in project. Problem is I'm having trouble targeting this location with the Storage:: method. Currently I have the file located in storage/app/public, which works fine with the code below, but ideally I'd reference the /resources/modules/ file.
$this->json_path = Storage::disk('public')->get('file.json');
$this->config_decoded = json_decode($this->json_path, true);
How do I do this using the Storage:: method?
Unless you've updated your public disk to point to the resources/modules directory, this is to be expected. By default, the public disk points to your storage/app/public directory.
You can either set up a new disk in your config/filesystems.php file by adding the something like the following to the disks array:
'modules' => [
'driver' => 'local',
'root' => resource_path('modules'),
'throw' => false,
],
Then your code would be:
$this->json_path = Storage::disk('modules')->get('file.json');
$this->config_decoded = json_decode($this->json_path, true);
Alternatively, you could use the File facade instead:
use Illuminate\Support\Facades\File;
$this->json_path = File::get(resource_path('modules/bob.json'))
As I checked on multiple sources, the Laravel way of defining constant variables is through config files. However, in my case, I want to use constants across my config files which is not possible since, as I read, it's not possible/advisable to call a config from another.
EXAMPLE
Constants:
define('THE_ID_OF_SOMETHING_NICE', 1);
define('THE_ID_OF_SOMETHING_UGLY', 2);
define('THE_ID_OF_SOMETHING_BAD', 12372);
config1.php
return [
THE_ID_OF_SOMETHING_NICE = ['many', 'nice', 'data'],
]
config2.php
return [
['many', 'nice', 'data', THE_ID_OF_SOMETHING_NICE],
]
As you can see, I just can't use the actual value of the defined constants since it'll be too unreadable. Also I don't want to clump up my .env file with these constants since it's not really meant for it.
Any workaround for this? Thanks.
P.S
Why does this so hard whilst it should be very basic principle of PHP to utilise constant definitions. CI has these figured out :/
I think you can use php include on your config.php if you don't want add a lot of to .env file. Just like that
<?php
include 'something_constant.php';
return [
THE_ID_OF_SOMETHING_NICE = ['many', 'nice', 'data'],
];
The best way to do this is to add them to the config/app.php file. Somewhere above the providers[] list you could add
'CONST' => ['THE_ID_OF_SOMETHING_NICE' => 1,
'THE_ID_OF_SOMETHING_UGLY' => 2,
],
and anywhere in the code access the values with the laravel helper config('app.CONST.THE_ID_OF_SOMETHING_NICE');
You can make use of the .env file but beware that in production, this file is ignored because the config is automatically cached. In .env you could add the line THE_ID_OF_SOMETHING_NICE=1 and in the config/app.php file you add
'CONST' => ['THE_ID_OF_SOMETHING_NICE' => env('THE_ID_OF_SOMETHING_NICE'),],
from where you can access the value just the same with the config() helper.
Personally I add the values in the app.php file and don't bother with adding values to .env, because mostly these contain non-critical information (i.e. your private keys etc)
If you'd like to create a separate file to isolate from the other config files, you could create a file f.ex. config/constants.php and return an array as it is done in other config files. Make it a flat array (no 'CONST' key). In the app/providers/AppServiceProvider in the register() method add
$this->mergeConfigFrom('config/constants.php', 'constants');
This way you can access your constants with config('constants.THE_ID_OF_SOMETHING_NICE');
I have created a designated location to store all the uploaded images in public dir like this:
and I have the default config/filesystem.php for public driver like this:
'public' => [
'driver' => 'local',
'root' => storage_path('app/public'),
'url' => env('APP_URL').'/storage',
'visibility' => 'public',
],
Within my repository, I am trying to save the uploaded image like this:
// ... snipped
if (array_key_exists('logo', $validated)) {
$logoPath = $validated['logo']->store(
'uploads/logos',
'public'
);
$company->logo = url($logoPath);
}
$company->save();
In the database, I can see the value of logo field for the company record like this: http://my-app.local/uploads/logos/3hlsAhnnIPjd4zhdpfhvKw4tqDkpcCz23NczwhVM.png
However, the public/uploads/logos dir is empty. Any idea what might be wrong here? Am I supposed to use the ->move() method on the UploadedFile instead of ->store()?
You can use an alternative method for uploading images in your public directory.
$request->validate([
'logo' => 'image|required',
]);
if($request->hasFile('logo')){
$company->logo = $request->image->move('uploads/logo', $request->logo->hashName());
}
$company->save()
Actually, yes, it was your mistake, but not the one you just found. By default laravel local storage points to storage/app/public directory, because laravel wants you to act professionally and store all uploaded files in storage, not in some kind of public directory. But then you would ask - how on earth user should access non-public storage directly? And there is a caught - php artisan storage:link command. It creates symbolic link from public directory to storage directory (storage/app/public -> public/storage). This is mostly because of deployments and version management.
I'm having problem using trans() function in config file, I feel it not supposed to be used that way. However I've no clue on what would be the most efficient way to translate string text in config files (files in /config folder).
Original code
<?php
return [
'daily' => 'Daily'
];
When I try to implement trans() application crashes and laravel return white page without any error messages
<?php
return [
'daily' => trans('app.daily_text')
];
The config files are one of the first stuff Laravel initialize, it means you can't use Translator nor UrlGenerator inside a config file.
I don't know what you are trying to do, but you shouldn't need to use Translator inside a config file though...
You cannot not use trans or route method inside the Laravel config file. At the time the config file is loaded, these methods are not available to run. Also, the purpose of the configuration file is used for storing pure value and we should not trigger any actions inside the configuration file.
I know sometimes you want to put things into config file with dynamic data generated from route or text from language key. In my usecase is: configure the menu structure inside the config file. On that case, you should choose the approach of: storing only the translation key and an array which include information that you can generate the URL at run time.
I put my gist here for you to look up on the approach.
You can just store the key in config file like and then use the trans function in the view to get the translations:
Config file:
<?php
return [
'foo' => 'bar'
];
Then in the view:
{{ trans(config('config.foo') }}
I don't know if this is good practice but I ended doing this in my similar situation.
Config.php:
'Foo' => array('
'route' => 'route.name',
'name' => 'translated_line', //translated in lang file ex. /en/general.php
'),
Then in the view I used:
{{ Lang::get('general.'.Config::get('foo.name'))) }}
Maybe this is too late but I posted it here anyway so that maybe someone will find it useful, like me :))
As of Laravel v5.4, you can use the __ helper function to access the translations after Laravel has booted.
Example:
config/example.php
<?php
return [
'daily' => 'Daily',
'monthly' => 'app.monthly_text',
'yearly' => 'app.yearly_text'
];
resources/lang/en/app.php
<?php
return [
'monthly_text' => 'Monthly'
];
You can access the translations like so:
<?php
// ...
$daily = config('example.daily');
$a = __($daily); // "Daily"
$monthly = config('example.monthly');
$b = __($monthly); // "Monthly"
$yearly = config('example.yearly');
$c = __($yearly); // "app.yearly_text"
There is an issue related to my laravel 5 web application regarding the file deletion.
I want to delete an entry from my table with corresponding image file.
Here is my table structure.
Schema::create('master_brands',function($table){
$table->increments('pk_brand_id');
$table->string('brand_name');
$table->string('brand_logo');
$table->timestamps();
});
I added 3 brands to db and storing image path in brand_logo field like : (/uploads/masters/logocatagory_Computers & IT.png).
When deleting the record from database I want to delete the image file from uploads folder also.
But the File was not deleting when I performing delete action.
here is my delete controller.
public function branddelete($id)
{
$filename = DB::table('master_brands')->where('pk_brand_id', $id)->get();
$filname = url()."/app".$filename[0]->brand_logo;
File::delete($filname); // http://localhost/genie-works/devojp/app//uploads/masters/logocatagory_Computers & IT.png
}
The file is exist in my directory and the directory having 777 permission. !!
I also tried the Storage class to delete file.But there is no way !!!..
How can I solve this issue? Any Ideas... :(
You are doing it the wrong way. You can't possibly delete a file from URL, you must provide file PATH not URL
Edited
Assuming the file you wish to delete is located in public/uploads/masters/logocatagory_Computers you could do this:
public function branddelete($id)
{
$filename = DB::table('master_brands')->where('pk_brand_id', $id)->get();
$filname = $filename[0]->brand_logo;
//example it.png, which is located in `public/uploads/masters/logocatagory_Computers` folder
$file_path = app_path("uploads/masters/logocatagory_Computers/{$filname}");
if(File::exists($file_path)) File::delete($file_path);
}
If you have the file out Storage/app/ , Storage:: does not work, change the /Config/Filesystems.php try put your 'local' at base_path() and comment default storage_path(),
'disks' => [
'local' => [
'driver' => 'local',
'root' => base_path(),
// 'root' => storage_path('app'),
],
Then in Controller
use Illuminate\Support\Facades\Storage;
Then in public funtion use Storage Model
$path= 'uploads/masters/';
Storage::delete($path . $filname);
In Laravel 5.1. When using the local driver, note that all file operations are relative to the root directory defined in your configuration file. By default, this value is set to the storage/app directory. Therefore,
the following method would store a file in storage/app/file.txt:
Storage::put('file.txt', 'Contents');
this would delete file.txt in storage/app
Storage::delete('file.txt');
If you want to change the root directory,take 'storage/app/uploads/' for example , you could set the filesystem.php as following :
'disks' => [
'local' => [
'driver' => 'local',
'root' => storage_path('app/uploads/'),
],
...
then this following method would store a file in storage/app/uploads/file.txt:
Storage::put('file.txt', 'Contents');
this would delete file.txt in storage/app/uploads directory.
Storage::delete('file.txt');
Something that took me quite some time to figure out today:
In case you're trying to delete a list of files that are wrapped in Laravel's own Collection wrapper, you might need to call ->all() to get the underlying array instance:
// The following is an example scenario
$files = Storage::list('downloads');
$collection = collect($files)->filter(function ($file) {
return str_contains($file, 'temp');
});
Storage::delete($collection->all()); // Note the "all()" call here