Laravel can't find stored file - laravel

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:
Manager Creating an Announcement
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!

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"

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

Related

How to change the number of links in the pagination block? (Laravel 8)

I use Laravel Framework 8 (8.83.23). Please help me understand how to set a limit on the number of links.
I have this (custom template in views/vendor/pagination):
And want to get this:
Already tried this:
/** In controller */
public function index()
{
return view('pages.products.index')
->with(
'products',
Product::latest()
->paginate(12)
->onEachSide(2)
);
}
And this (without using onEachSide in controller):
/** In blade */
<div class="row py-5">
<div class="col-auto mx-auto">
{{ $products->onEachSide(2)->links() }}
</div>
</div>

The #edit Route is not working... showing 404 not found

the #edit route is not creating. everything is ok but showing 404 not found
the problem is on the last route. I ran the php artisan route:list code but not showing any route named /profile/{user}/edit
the web.php code ->>>>>
<?php
use Illuminate\Support\Facades\Route;
use App\Http\Controllers\ProfilesController;
/*
|--------------------------------------------------------------------------
| Web Routes
|--------------------------------------------------------------------------
|
| Here is where you can register web routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| contains the "web" middleware group. Now create something great!
|
*/
Route::get('/', function () {
return view('welcome');
});
Auth::routes();
Route::get('/p/{post}','App\Http\Controllers\PostsController#show');
Route::get('/p/create','App\Http\Controllers\PostsController#create');
Route::post('/p','App\Http\Controllers\PostsController#store');
Route::get('/profile/{user}', [App\Http\Controllers\ProfilesController::class, 'index'])->name('profile.show');
Route::get('/profile/{user}/edit','ProfilesController#edit')->name('profile.edit');
the profiles controller code ->>>>>
<?php
namespace App\Http\Controllers;
use App\Models\User;
use Illuminate\Http\Request;
class ProfilesController extends Controller
{
public function edit(User $user)
{
return view('profiles.edit', compact('user'));
}
public function index(User $user)
{
return view('profiles.index', compact('user'));
}
}
the index.blade.php code --->>>>>>>>>>>>>>>
#extends('layouts.app')
#section('content')
<div class="container">
<div><h1>here is a big design</h1></div>
<br>
<div class="d-flex justify-content-between align-items-baseline">
<h1>{{ $user->username}}</h1>
Add New Post
</div>
Edit Profile
<div class="pr-5"><strong>{{$user->posts->count()}}</strong> posts</div>
<div class="pr-5"><strong></strong> followers</div>
<div class="pr-5"><strong></strong> following</div>
<br>
<div><h1>{{ $user->profile->title}}</h1></div>
<br>
<div><h1>{{ $user->profile->description}}</h1></div>
<br>
<div><h1>{{ $user->profile->url ?? 'N/A'}}</h1></div>
<h1>Posts</h1>
<hr>
<div class="row pt-5">
#foreach($user->posts as $post)
<div class="col-4 pb-4">
<a href="/p/{{$post->id}}">
<img src="/storage/{{$post->image}}" class="w-100">
</a>
</div>
#endforeach
</div>
</div>
#endsection
Change your route to
Route::get('/profile/{user}/edit',[ProfilesController::class, 'edit'])->name('profile.edit');
Your way 'ProfilesController#edit' doesn't take use App\Http\Controllers\ProfilesController; into account.
Offtopic suggestion: since you already named your routes I suggest you use the named routes in your blade files instead of hardcoding them:
Edit Profile
instead of
Edit Profile
This way, should you decide to change a URL some time later, you only need to change it in your web.php file once, not all of your hardcoded occurences

property does not refresh in the internal components of Livewire

Take a look at the following examples:
showPost.blade.php:
<div>
<livewire:content-box :content="$post"/>
<button wire:click="nextPost" >Next Post >></button>
</div>
and
content-box.blade.php :
<div>
<h1>{{ $content->title }}</h1>
<p>{{ $content->content }}</p>
</div>
So far, it is completely clear what is going to happen ...: First, the information of the content to be viewed is received through showPost and passed to the contentBox, and everything is OK ..
Well now I want to get the information of the next content via the account through the button I put and calling the nextPost method:
class ShowPost extends Component
{
public Post $post;
public function render()
{
return view('livewire.show-post');
}
public function nextPost()
{
$id = $this->post->id;
$nextPost = Post::where('id', '>', $id)->first();
$this->post = $nextPost;
}
...
But nothing happens and the contentBox component has no reaction .... Has anyone had this problem ???!
I'm not sure livewire works well with nested components. could use the pagination instead. The livewire docs suggest you should not use them for little snippets or use blade components for that kind of nesting.
You can achieve what you're doing at the moment with some simple pagination.
<?php
namespace App\Http\Livewire;
use App\Models\User;
use Livewire\Component;
use Livewire\WithPagination;
class SomeContent extends Component
{
use WithPagination;
public function render()
{
// Using simplePaginate(1) instead of paginate(1).
// simplePaginate only shows "<- Previous" and "Next ->" links
// paginate shows those 2 buttons but also page numbers which you don't seem to want.
return view('livewire.some-content', [
'users' => User::simplePaginate(1),
]);
}
}
<div>
{{-- This might look wrong, but essentially it's looping through an array of length 1 because we're paginating --}}
#foreach ($users as $user)
<h1>{{ $user->name }}</h1>
<h2>{{ $user->email }}</h2>
#endforeach
{!! $users->links() !!}
</div>
EDIT
I can confirm blade components work.
Here, nextUser is the same implementation you gave.
public function nextUser()
{
$id = $this->user->id;
$nextUser = User::where('id', '>', $id)->first();
$this->user = $nextUser;
}
<div class="container">
<div class="content">
{{-- These two have the exact same template --}}
<livewire:child :user="$user" />{{-- Doesn't update when clicking Next --}}
<x-blade-child :user="$user" />{{-- Updates when clicking Next --}}
</div>
<div>
<button wire:click="nextUser">Next</button>
</div>
</div>
When clicking nextUser, the blade component updates but the livewire one doesn't.
Livewire doesn't like nested components. In your case, we can use basic blade component:
<div>
<x-content-box :content="$post"/>
<button wire:click="nextPost" >Next Post >></button>
</div>
And then:
Move content-box.blade.php to resources/views/components/
Remove component_name.php file in app/Http/Livewire
Most of the time, we can change 2 nested livewire components to livewire(parent) + basic blade component(child),

Laravel NotFoundHttpException although route exits

I added a new route as:
Route::post('friendSend/{uid}','FriendController#sendFriendRequest')->name('friends.add');
and called it as a hyperlink to submit form:
<a href="{{route('friends.add',$user->uid)}}"
onclick="event.preventDefault();
document.getElementById('addfriend-form).submit();">
<i class="glyphicon glyphicon-facetime-video" style="color:#F44336;"></i> Add Friend
</a>
<form action="{{route('friends.add',$user->uid)}}" method="post" id="addfriend-form">
{{ csrf_field() }}
</form>
However when I click on the said link, I get redirected to /friendSend with the said error.
the route is visible in:
php artisan route:list
which makes sense since I called it via it's name 'friends.add'. It doesn't even go the controller.
I've already tried the following:
Laravel NotFoundHttpException although route exists
Controller:
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Friend;
use Auth;
class FriendController extends Controller
{
public function __construct()
{
$this->middleware('auth');
}
public function index()
{
return redirect()->route('home');
}
public function sendFriendRequest($id)
{
echo "hello world";
}
}
Update:
Manually entering the url as /friendSend/2 (or any number for that matter) works.
You are missing a ' in the onclick javascript.
<a href="{{route('friends.add',$user->uid)}}"
onclick="event.preventDefault();
document.getElementById('addfriend-form').submit();">
<i class="glyphicon glyphicon-facetime-video" style="color:#F44336;"></i> Add Friend
</a>
<form action="{{route('friends.add',$user->uid)}}" method="post" id="addfriend-form">
{{ csrf_field() }}
</form>
If this doesn't work, what is the href on the generated page? Do you have multiple of these forms on a single page?
I thing you are doing wrong on set the url in form submit.You are adding route like
href="{{route('friends.add',$user->uid)}}"
Just modified it as
href="{{route('friends.add',['uid' => $user->uid])}}"
You can refer Laravel Named Routes

Undefined variable: names

I am facing difficulties pushing data from the Controller to the View. Below is my code script.
I created my controller ListController using artisan
php artisan make:controller ListController
ListController - show method
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class ListController extends Controller
{
public function listNames()
{
$names = array(
'Daenerys Targaryen',
'Jon Snow',
'Arya Stark',
'Melisandre',
'Khal Drogo'
);
return view('welcome', ['names' => $names]);
}
}
Created a view welcome.blade.php (which is default)
#extends('layouts.app')
#section('content')
<div class="container">
<div class="row">
<div class="col-md-8 col-md-offset-2">
<div class="panel panel-default">
<div class="panel-heading">API DOCUMENTATION</div>
<div class="panel-body">
#foreach ($names as $n)
<p>{{$n}}</p>
#endforeach
</div>
</div>
</div>
</div>
</div>
#endsection
Then, added the appropriate route for it (routes.php)
<?php
Route::get('/', 'ListController#listNames');
When opening localhost:8000 after running php artisan serve, it throws an Exception
ErrorException in 56f6d37e6c39b528e3f5a170141b734befe0f7a2.php line 14:
Undefined variable: names (View: /Applications/MAMP/.../views/welcome.blade.php)
So far I have tried the following:
In the Controller:
return view('welcome', compact('names')); --> DOESN'T WORK
return view('welcome', $names); --> DOESN'T WORK
return view('welcome')->with($names); --> DOESN'T WORK
return view('welcome')->with('names', $names); --> DOESN'T WORK
Hard coding the array in the view and assigning it a variable works
<?php $names = array('John Snow', 'Arya Stark');?>
<?php foreach ($names as $n):?>
<tr>
<td><?php echo $n;?></td>
</tr>
<?php endforeach;?>
I can't seem to detect the problem. Any help is appreciated.
You should pass variables using an array:
return view('welcome', ['names' => $names]);
Or just:
return view('welcome', compact('names'));
To check it do this in the view:
{{ dd($names) }}
First, pass your variables as Alexey said,
return view('welcome', ['names' => $names]);
And then, on the view, do
#foreach ($names as $n)
<p>This is name {{ $n }}</p>
#endforeach
Documentation here: https://laravel.com/docs/master/blade#displaying-data
Managed to resolve the issue.
After spending so much time looking for the bug, I tried to check if laravel version could have something to do with this. The routes.php doesn't work in Laravel v5.3+ and I was using Laravel v5.4.x.
The routes are available in a directory called routes and so I pasted the code from routes.php to routes/web.php and it worked.
<?php
Route::get('/', 'ListController#listNames');

Resources