ajw4sk
ajw4sk

Reputation: 105

Laravel can't find stored file

I'm trying to have a video embedded in a view, but I'm receiving a 404, and I'm not entirely sure why. I created a new laravel project and then did php artisan storage:link. This site doesn't need to use file uploads so I just stuck the file in the storage directory:

storage/app/public/product1/courses/announcements/Manager_Creating_an_Announcement.mp4

My migration file:

public function up()
{
    Schema::create('courses', function (Blueprint $table) {
        $table->increments('id');
        $table->timestamps();
        $table->string('title')->nullable($value = true);
        $table->string('certifcation')->nullable($value = true);
        $table->string('video')->nullable($value = true);
    });
}

Where video is the path

My CourseCountroller

<?php

namespace App\Http\Controllers;

use App\Course;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Storage;

class CourseController extends Controller
{
/**
 * Display a listing of the resource.
 *
 * @return \Illuminate\Http\Response
 */
public function index($id)
{
    $course = Course::findOrFail($id);

    //dd(Storage::allFiles('public'));
    //this returns an array with: 0 => "public/product1/courses/announcement/Manager_Creating_an_Announcement.mp4"
    return view('course.index', compact('course', $course));
}

The view that the user clicks on to go to this course looks like this:

<a href="/product/course/1">Manager Creating an Announcement</a>

The route in web.php looks like this:

Route::get('/product/course/{course}', 'CourseController@index');

And the course view looks like this:

@extends('layouts.app')

@section('content')

@php

@endphp

<div class="container">
    <div class="row justify-content-center">
        <div class="col-md-12">
            <div class="card">
                <div class="card-header">Welcome to your course: {{$course->title}}</div>

                <div class="card-body">
                    @if (session('status'))
                        <div class="alert alert-success" role="alert">
                            {{ session('status') }}
                        </div>
                    @endif

                    <h3>Watch the video first!</h3>
                    <div class="embed-responsive embed-responsive-16by9">
                        <iframe class="embed-responsive-item" src="{{asset($course->video)}}"></iframe>
                    </div>
                </div>
            </div>
        </div>
    </div>
</div>



@endsection

In tinker, the course looks like this:

>>> Course::all();
[!] Aliasing 'Course' to 'App\Course' for this Tinker session.
=> Illuminate\Database\Eloquent\Collection {#2921
     all: [
       App\Course {#2922
         id: 1,
         created_at: null,
         updated_at: null,
         title: "Manager creating an Announcement",
         certifcation: "Announcements",
         video: "public/csm/courses/announcement/Manager_Creating_an_Announcement.mp4",
       },
     ],
   }

The error is a 404 error, page not found. When I inspect the element, I see:

<iframe src="http://127.0.0.1:8000/public/product1/courses/announcement/Manager_Creating_an_Announcement.mp4" class="embed-responsive-item"></iframe>

I also tried it with the video tag, instead of embedding it, but no go. Any help would be much appreciated!

Upvotes: 0

Views: 4244

Answers (2)

latr.88
latr.88

Reputation: 859

If it is in storage, you ran php artisan storage:link, you should be able to access it like this:

"/storage/product1/courses/announcements/Manager_Creating_an_Announcement.mp4"

Upvotes: 1

Devon Bessemer
Devon Bessemer

Reputation: 35337

The Public Disk

The public disk is intended for files that are going to be publicly accessible. By default, the public disk uses the local driver and stores these files in storage/app/public. To make them accessible from the web, you should create a symbolic link from public/storage to storage/app/public. This convention will keep your publicly accessible files in one directory that can be easily shared across deployments when using zero down-time deployment systems like Envoyer.

To create the symbolic link, you may use the storage:link Artisan command:

php artisan storage:link

Of course, once a file has been stored and the symbolic link has been created, you can create a URL to the files using the asset helper:

echo asset('storage/file.txt');

https://laravel.com/docs/5.7/filesystem#the-public-disk

Upvotes: 0

Related Questions