I am having trouble storing images in the 'public' folder of the Laravel framework (which I believe is the static content folder? Please correct me if I am wrong).
I am running a seed using faker which generates images and stores the images URL's in a table. This is all working correctly but the seed itself keeps failing as it can't seem to access or find the folder within the public folder I have created. This is my public folder structure:
/public/assets/images
And here is my seed which should save my images into this folder:
<?php
use Illuminate\Database\Seeder;
class ProductsTableSeeder extends Seeder
{
/**
* Run the database seeds.
*
* #return void
*/
public function run()
{
DB::table('products')->truncate();
$faker = Faker\Factory::create();
$limit = 30;
for($i = 0; $i < $limit; $i++) {
DB::table('products')->insert([
'title' => $faker->name,
'SKU' => $faker->name,
'description' => $faker->text,
'created_at' => $faker->dateTime,
'updated_at' => $faker->dateTime,
'images' => $faker->image(URL::to(Config::get('assets.images')) ,800, 600, [], [])
]);
}
}
}#
The 'assets.images' config file is:
<?php
return [
'images' => '/assets/images'
];
When I try and run the seed to populate my database I get the following error:
[InvalidArgumentException]
Cannot write to directory "http://localhost:8931/assets/images"
I cannot see where I am going wrong. Can anyone offer any insight?
Change your call of URL::to with the helper function public_path() like this:
$faker->image(public_path(Config::get('assets.images')) ,800, 600, [], [])
I'm not a laravel expert, but the thrown exception looks like you're trying to write to an url rather than a file path on the disk.
Maybe you want to check if the process owner running the php script has write access to that location.
Related
i have table 'case' that contains an image column, i want users to insert into the case table and be able to upload an image, on the home page users can view cases along with image of each case.
so far i have tried:
public function createcase(Request $request){
$validator = Validator::make($request->all(), [
'title' => 'required',
'image' => 'required|image|mimes:jpeg,png,jpg,gif,svg|max:2048',
'description' => 'required',
'caseTypeId' => 'required',
'amountneeded' =>'required',
'uid' => 'required',
'visible' => 'required',
]);
if ($validator->fails()) {
return response()->json(['error'=>$validator->errors()], 401);
}
$image = $request->file('image');
$path = $image->store('public');
$case = casee::create([
'title' => $request->title,
'description' => $request->description,
'caseTypeId' => $request->caseTypeId,
'amountneeded' => $request->amountneeded,
'uid' => $request->uid,
'visible' => $request->visible,
'image' => $path,
]);
return response()->json(['image' => $image]);
to upload:
<input type="file" id="image" #change="onFileChange" />
methods: {
onFileChange(e) {
this.image = e.target.files[0];
},
async postcase() {
const formData = new FormData();
formData.append('title', this.title);
formData.append('description', this.description);
formData.append('amountneeded', this.amountneeded);
formData.append('caseTypeId', this.selectedcasetype);
formData.append('uid', this.uid);
formData.append('visible', 1);
formData.append('image', this.image);
try {
await axios.post('http://127.0.0.1:8000/api/postcase', formData).then(response => {
console.log(response.data);
})
} catch (error) {
console.log(response.data);
}
}
to retrieve:
<v-flex class="ma-2" v-for="casee in cases" :key="casee.id" lg3 xs12 md6 sm4>
<img v-if="casee.image" :src="'/storage/' + casee.image" alt="Case Image">
mounted(){
this.getcases();
},
methods:{
async getcases(){
try {
const response = await axios.get('http://127.0.0.1:8000/api/cases');
this.cases = response.data.cases;
console.log(this.cases);
} catch (error) {
console.log(error);
}
},
everything works fine except for the image. it returns the error Cannot GET /storage/public/CQu7g4X98APkiMSbCGlqyiJhaXzLaEk8P0pZXaD3.jpg when i try to retrieve it
Frontend couldn't access filesystem as "/storage/public/FILENAME.jpg".
If you are based on Laravel 9.x, and didn't change any filesystem default settings, your file will stored under "<project root>/storage/app/public/", it's filesystem default path, but frontend can only access your "<project root>/public/" folder, do check list as below might help you slove issue.
1.Make sure you executed php artisan storage:link command, and it will created a symbolic link from your storage path to public path.
If you didn't change settings, it will create link from "<project root>/storage/app/public" to "<project root>/public/storage", once you done command you can see your storage folder under public folder.
You can access "<APP_URL>/storage/FILENAME.jpg" to see if link create success or not, if you ain't get 404 means your link created as well as it should be.
2. Use laravel helper to generate storage url.
Use the asset() helper create a URL to the files.
Your files will under "<project root>/public/storage" after step 1, and your nginx root will access public as default, so you don't need public as your url path anymore.
asset('storage/FILENAME.jpg');
// output will be "<APP_URL>/storage/FILENAME.jpg"
3. (Not required) Check if laravel cached your view.
For some new developer of laravel didn't notice that laravel will cached your view, and they keep thinking that code doesn't work.
You can easily check if laravel cached view by php artisan about command if you are using latest laravel version, and use php artisan view:clear to clear view cache.
Make sure that the storage directory is correctly linked to the public.
You can run this command to make it automatically:
php artisan storage:link
heres how i solved it if anyone comes across this issue :
based on the previous answers:
1. php artisan storage:link
replace 'image' => $path to 'image' => basename($path).
3.<img :src="'http://127.0.0.1:8000/storage/' + casee.image" alt="Case Image">
how to generate and download images in storage using laravel's faker?
I want when running seeders to download images and save them automatically in the storage/categories folder, but when running seeder the images are downloaded all for a second and then they disappear or are deleted, so I don't know what is happening.
this is CategoryFactory
<?php
namespace Database\Factories;
use Illuminate\Database\Eloquent\Factories\Factory;
class CategoryFactory extends Factory
{
public function definition()
{
return [
'image' => 'categories/' . $this->faker->image(storage_path('app' . DIRECTORY_SEPARATOR . 'public/categories'),640, 480, null, false)
];
}
}
Storage::makeDirectory('categories') will create a directory at storage/app/categories if the driver is set to public. So when using with faker->image() the path needs to be storage_path('app/dummy').
'image' => 'categories/' . $this->faker->image(storage_path('app/categories'),640, 480, null, false)
i'm using laravel6, and voyager, i'm creating artisan command for installation use cmd following php artisan make: command EcommerceInstall
, I recopy DataTypesTableSeeder from database/seeder and I rename it by DataTypesTableSeederCustom, I modify my file which I wrote EcommerceInstall.php but it gives me error class [DataTypesTableSeederCustom] does not exist.
i think i forget import the class but i don't know where .
EcommerceInstall.php
public function handle()
{
if ($this->confirm('this well delete all you current data and install the dummy default data, Are you sure ?')) {
File::deleteDirectory(public_path('storage/products/dummy'));
$this->callSilent('storage:link');
$copySuccess = File::copyDirectory(public_path('img/products'),public_path('storage/products/dummy'));
if($copySuccess){
$this->info('images succefully copied to storage folder');
}
$this->call('migrate:fresh', [
'--seed' => true,
]);
$this->call('db:seed', [
'--class' => 'DataTypesTableSeederCustom'
]);
$this->info('Dummy data installed');
}
I am using appendTimestamp of assetManager component
'assetManager' => [
//append time stamps to assets for cache busting
'appendTimestamp' => true,
],
'cache' => [
'class' => 'yii\caching\FileCache',
],
It correctly adds the timestamp after each asset as shown:
<link href="/frontend/web/assets/7b3fec74/css/arabic.css?v=1428761706" rel="stylesheet">
However when I make changes to that CSS file, the timestamp does not update. Is this because of the FileCache?
Every time I wish to test my new changes, I currently need to clear the contents of my web/assets folder
Am I required to delete the contents of the assets folder every time I wish to test my new assets?
I had same problem when I used $sourcePath as files source in my asset bundle. I solved it buy adding $publishOptions. Making 'forceCopy'=>true forces files to be published in assets folder each time:
class Asset extends AssetBundle
{
public $sourcePath = '...';
public $js = [..];
public $css = [...];
public $depends = [...];
public $publishOptions = [
'forceCopy' => true,
//you can also make it work only in debug mode: 'forceCopy' => YII_DEBUG
];
}
The FileCache component you referred to - has nothing to do with the assets. It is responsible with your defined cache items :
Yii::$app->cache->set('key', 'value')
Yii::$app->cache->get('key')
...
So there might be a problem with your assetManager.
I am trying to include a custom defined validation file that is local to my system and wish to use it with 'package' files from an application I downloaded online. The purpose is so that I can have my own custom validators since I made modifications to this application.
I keep getting the error -> 'Class 'Models\Validators\Photo' not found'
Controller:
use JeroenG\LaravelPhotoGallery\Controllers\AlbumsController; /* From Package */
use JeroenG\LaravelPhotoGallery\Controllers\PhotosController; /* From Package */
use JeroenG\LaravelPhotoGallery\Models\Album; /* From Package */
use JeroenG\LaravelPhotoGallery\Models\Photo; /* From Package */
use Models\Validators as Validators; /* Custom local file */
class EditPhotosController extends PhotosController {
public function __construct()
{
parent::__construct();
}
public function update($albumId, $photoId)
{
$input = \Input::except('_method');
$validation = new Validators\Photo($input); // Here's where error occurs
/* Validation check and update code etc. */
}
}
}
Photo.php -> File path: Models\Validators\Photo.php
namespace Models\Validators;
class Photo extends Validator {
public static $rules = array(
'album_id' => 'required',
'photo_name' => 'required',
'photo_description' => 'max:255',
);
}
Is this just a simple namespacing issue?
The most likely problem is that composer doesn't add file Models/Validators/Photo.php to the autoload index. Make sure you have provided correct path for your files in composer.json.
Try running
composer dump-autoload
to regenerate the autoload files.