Laravel Public url for storage files - php

I want to retrieve public url for all the files stored using
storage::putFile('public/spares');
So, this is the issue I'm using
storage::files('public/spares');
but it provides this output from laravel storage directory
public/spares/image1.jpg
public/spares/image2.jpg
public/spares/image3.jpg
how can I get the public link for the above
http://localhost/laravel/public/storage/spares/image1.jpg
http://localhost/laravel/public/storage/spares/image2.jpg
http://localhost/laravel/public/storage/spares/image3.jpg
**Edit **
Sending last modified data of files to view
$docs = File::files('storage/document');
$lastmodified = [];
foreach ($docs as $key => $value) {
$docs[$key] = asset($value);
$lastmodified[$key] = File::lastmodified($value);
}
return view('stock.document',compact('docs','lastmodified'));
Is this correct

First you have to create the symbolic link from your public/storage directory to your storage/app/public directory so you can access the files. You can do that with:
php artisan storage:link
So then you can store your documents with:
Storage::putFile('spares', $file);
And access them as an asset with:
asset('storage/spares/filename.ext');
Check out the documentation on the public disk

What about Storage::url? It works even for local storage.
You can find more here: https://laravel.com/docs/5.4/filesystem#file-urls
If you want to return all files' urls from the directory, you can do something like this:
return collect(Storage::files($directory))->map(function($file) {
return Storage::url($file);
})
Don't forget to inject the \Illuminate\Filesystem\FilesystemManager instead of the Storage facade if you are looking for a not-facade way.
Edit:
There are 2 (or more) ways how you can deal with modified date:
Pass files to the view.
|ou can pass your Storage::files($directory) directly to the view and then in your template use following:
// controller:
return view('view', ['files' => Storage::files($directory)]);
// template:
#foreach($files as $file)
{{ Storage::url($file) }} - {{ $file->lastModified }} // I'm not sure about lastModified property, but you get the point
#endforeach
Return an array:
return collect(Storage::files($directory))->map(function($file) {
return [
'file' => Storage::url($file),
'modified' => $file->lastModified // or something like this
]
})->toArray()

I know this question is quite old, but i am putting this answer for anyone still having this issue from laravel 5.5+
To solve the issue update your filesystem's configuration by adding the 'url' key like below:
'public' => [
'driver' => 'local',
'root' => storage_path('app/public'),
'url' => env('APP_URL').'/storage',
'visibility' => 'public',
],
Hope it helps :)

Well I figured out the solution, instead of searching the storage
$docs = Storage:files('public/spares');
we can search the symbolic link
$docs = File:files('storage/spares');
then run it through the asset() function to get the public URL. Is there a better solution?

$file = Storage::disk('public')->put($folder, request()->file($key), 'public');
$file = Storage::url($file);

Related

Laravel - how to get a parameter of an object in a request file

I am using Laravel 5.3 and I would like to make a query in requests file which I made to have some validation rules for a form where a user can edit his channel. In that file I would like to make a query which would look something like this:
$channelId = Auth::user()->channels()->where('id', $this->id)->get();
So that I can get the channel id and exclude it from the rules array, this is how a file looks like:
public function rules()
{
$channelId = Auth::user()->channels()->where('id', $this->id)->get();
return [
'name' => 'required|max:255|unique:channels,name,' . $channelId,
'slug' => 'required|max:255|alpha_num|unique:channels,slug,' . $channelId,
'description' => 'max:1000',
];
}
I am not sure how to get the channel id of that object that is being updated in the requests file?
When inside of a Requestobject, you can access input as #Silwerclaw correctly said by calling $this->input("id") when you have an input with name "id".
When outside of the object, you can use the facade: Request::input("id").
I used model for that matter, in the request file we can access that object by $this and by model name using this we can access all property, So change just as below.
$channel = Auth::user()->channels()->where('id', $this->channel->id))->first();
But I am not doing like this, i am directly use $this->channel->id in rule as below.
return [
'name' => 'required|max:255|unique:channels,name,' . $this->channel->id,
'slug' => 'required|max:255|alpha_num|unique:channels,slug,' . $this->channel->id,
'description' => 'max:1000',
];
I used a session for that matter, I have stored a key in edit function and then retrieved it in the request file in my query like this and now it works, and the user is not able to manipulate it in the form:
$channel = Auth::user()->channels()->where('id', session('channel_id'))->first();

Codeigniter how to set API keys and Resource urls for easy access in applications

I am trying to clean up my site by putting all of my configurations in one place for easy access.
I have many different configuration dependencies for example, PayPal and Stripe public/private and sandbox/live keys as well as a number of links e.g. google recaptcha links.
I don't want to be spreading these keys around my app and then need to go hunting for them if I want to go from sandbox to live for example.
I am trying to define my API keys and most used links in the CodeIgniter config.php file like this...
$config['stripe_live'] = [
'secret' => 'secret_key_xyz',
'private' => 'private_key_xyz',
]
$config['stripe_sandbox'] = [
'secret' => 'secret_key_xyz',
'private' => 'private_key_xyz',
]
$config['paypal'] = [
'secret' => 'secret_key_xyz',
'private' => 'private_key_xyz',
]
$config['recaptcha'] = [
'site_key' => 'xyz_one_two_three',
'secret_key' => 'xyz_one_two_three',
];
$config['jquery'] = [
['jquery_link'] => base_url() . 'Public/js/jquery.js',
]
$config['bootstrap'] = [
['bootstrap_link'] => base_url() . 'Public/js/jquery.js',
]
$config['fontawesome'] = [
]
$config['google_fonts'] = [
];
$config['groupworld'] = [
'groupworld_api' => 'api_key_xyz';
];
Question one:
If I wanted to access my Stripe live private key I would have to write...
$stripe_live = $this->config->item('stripe_live');
$stripe_live['public_key'];
This is almost as much work as just copying the key to where I need it (one or two places). So is there a simpler way?
Question two:
Is is okay to put my urls in the config file like in my example above? Or would it be better to define my URLs as constants (in the constants file) and then simply access them as constants instead of writing out $this->config->item('bootstrap_link')
Thanks.
After looking at the CodeIgniter Config documentation I have come up with the following solution at least for my API configuration settings, in the example below I am using the google recaptcha API.
1 - Make a new file inside of the application/config folder and call it whatever you want... e.g. api_config.php
Inside this file put your API keys like this:
// stripe api
$config["stripe_live_public_key"] = "public_key_xyz";
$config["stripe_live_private_key"] = "public_key_xyz";
$config["stripe_sandbox_public_key"] = "public_key_xyz";
$config["stripe_sandbox_private_key"] = "public_key_xyz";
// paypal api
$config["paypal_live_public_key"] = "public_key_xyz";
$config["paypal_live_private_key"] = "public_key_xyz";
$config["paypal_sandbox_public_key"] = "public_key_xyz";
$config["paypal_sandbox_private_key"] = "public_key_xyz";
// recaptcha api
$config["recaptcha_api_url"] = 'https://www.google.com/recaptcha/api.js';
$config["recaptcha_verification_url"] = "https://www.google.com/recaptcha/api/siteverify";
$config["recaptcha_public_key"] = "lfgksl;dfg;kkkkdsjfhskjfhkjsdhfjshjksjdh";
$config["recaptcha_private_key"] = "sfkljslfjsjfahjjjjjjhjhsdfjskhajkakkajdj";
// groupworld api
// phpmailer api
2 - In the controller file load your config file and mass the data to the view like this...
$this->config->load('api_config');
$data['recaptcha_api_url'] = $this->config->item('recaptcha_api_url');
$data['recaptcha_public_key'] = $this->config->item('recaptcha_public_key');
3 - In the view file simply display your data...
<script src="<?php echo $recaptcha_api_url; ?>"></script>
<div class="g-recaptcha" data-sitekey="<?php echo $recaptcha_public_key; ?>"></div>
Now to change your config data in multiple places simply go to the api_config.php file and paste in your new keys.
As I'm a newbie can't comment :/ .
I will start with question 2. Its ok to keep like this. But stripe,paypal are payment gateways it will be good to store it in db as Yogesh said and retrieve to use it.It will also comes in handy if you want to provide user to edit it.
For js,css links you can put them in a view like 'includefiles.php' and load it in all pages as we load views.
for easy retrieval of your data, you can use helper functions.
<?php
//paymentdetail_helper
function getpaymentdetailhelper(someid or gateway name as arg eg.$id){
$ins=& get_instance();
$ins->load->database();
//your queries $ins->db->query();
return $data;
}
?>
Save this in application/helpers as paymentdetail_helper.php and load it as usual. more info about helpers in questionInfo about helper
Its my idea. :) You're welcome with suggestions

Having constants for all pages in Laravel

I want to have some constants to have IP, platform, browser to be placed in a single file and to be used in all views and controllers like so:
// inside app/config/constants.php
return [
'IP' => 'some ip'
];
// inside controller
echo Config::get('constants.IP');
But instead of 'some ip', I want to use Request::ip() at least or even better, to use parse_user_agent()['platform'] that its code link is here
Simply you may put something like this in your config file:
return [
'ip' => app('request')->ip()
];
I use a little customized one for my sitewise configs, for example, let's say you want to use something like this:
/**
* Get config/constants.php
*
* [
* 'person' => [
* 'name' => 'Me',
* 'age' => 1000
* ]
* ];
*/
$name = constants('person.name');
So, to achieve this you need to write a function like:
// Helpers/Common.php
function constants($key = null)
{
$constants = config('constants');
return is_null($key) ? $constants : array_get($constants, $key);
}
Now, in your composer.json file you may add the following files entry:
"psr-4": {
"App\\": "app/"
},
"files": ["Helpers/Common.php"]
Then you need to add the constants.php in config directory for example:
<?php
return [
"ip" => app('request')->ip(),
"person" => [
"name" => "Sheikh Heera",
"age" => 10000
],
];
Finally, just run composer-dump from terminal and you are done. So, if the ip key is available in the array then you may just try this:
$ip = constants('ip');
From the view (Blade), you may use following to echo out the ip:
{{ constants('ip') }}
Let's sum up the whole process:
Create a directory in your project root (or inside app if you wish) as Helpers.
Create the Common.php file in that directory and put the array (return it)
Put the constants function (given above) in the Common.php file
Add the files (given above) key in your composer.json file
Run composer-dump to update autoload files
That's it. Use the file name and helper function name that describes your domian, so instead of constants you may use for example: site or your domain name as well.
You can create (or use an existing) a service provider and in the register method use the following code:
view()->share('constants', config('constants', []));
Using share on the view helper function will share the variable over all views.
You can now access this variable in any view, for instance with blade:
{{ array_get($constants, 'ip') }}

file_get_contents doesn't work in seed file but work in the routes file in laravel 5

I am trying to seed a table in laravel using a JSON output of the old table.
When I tried to file_get_contents('services.json') in the seed file, I get an exception that the file does not exist and also I tried using file_exists('services.json') and it returned false but when I tried it from the routes file, it works perfectly fine and my table seeds. My route looks like so:
Route::get('test', function(){
// return JWTAuth::parseToken()->getPayload()->get('username');
Illuminate\Database\Eloquent\Model::unguard();
// \Db::table('service')->truncate();
$servicesDataFromOldDB = file_get_contents('../database/seeds/services.json');
$servicesJson = json_decode($servicesDataFromOldDB);
$services = Illuminate\Support\Collection::make($servicesJson);
$services->each(function($service){
App\Service::create([
'id' => $service->id,
'name' => $service->title,
'description' => $service->desc,
'category' => $service->cat,
'type' => $service->type,
'hours' => $service->hours,
'price' => $service->price,
'note' => $service->note,
'devdays' => $service->devdays
]);
});
Illuminate\Database\Eloquent\Model::reguard();
});
I am fetching the same file from the same path and it is able to fetch it but not in the seed file. What am I missing?
EDIT
dd(file_exists(app_path() . '/database/seeds/services.json'));
Even this is returning false
And moreover I did a dd(__DIR__) in the seed file and it was the right path /var/www/html/archive/database/seeds
Using __DIR__ you can get the directory that the current file is in, then using realpath(), you can get the full, qualified path to the file.
realpath(__DIR__ . '../database/seeds/services.json');
This means that you can set the path relative to the directory of the file you're working in, and be sure that it will work from anywhere else in the code.

how to set common code once in YII

i wanted to know in which file we can set common code, for example i wanted to set timezone to UTC, instead of putting same code in all controllers file is there any way to put the code once and it will be reflect in all files.
You may create your file in ''components'' folder. You can see this folder in "protected" folder.
Or you can write your code in controller.php
File path: webroot/protected/components/Controller.php
Can you please try to add the codes in bootstrap.php file
If you need to set the server time you can check here.It is a simple method
Change time zone
Use application params, ie:
// config part
return array(
// ...
'params' => array(
'myParam' => 123
)
// ...
);
// Then in app use
Yii::app()->params['myParam'] // Will return 123
You can also create your own params holder as component, ie:
// config part
'components' => array(
'myConfigs' => array(
'class' => 'ext.MyConfigs'
'myParam1' => 123,
'myParam2' => 'blah'
)
)
// Component in extensions
class MyConfigs extends CComponent
{
public $myParam1;
public $myParam2 = 'defaultValue';
}
// Then in app use it:
Yii::app()->myConfigs->myParam1 // will return 123

Categories