Laravel localization throws htmlspecialchars() error - php

When I try to use the localization and retrieve translation strings, Laravel for some reason throws: .
From the controller to the view (products index page), I pass the $products variable. On that page, I use the translation string {{ __('Products') }} and getting htmlspecialchars() error. As I understood it, translation string for some reason thinks that I passing $products variable to {{ __('Products') }} translation string, because if I change translation string to (for example) {{ __('Products page') }}, I not getting this error anymore. Can someone explain, why this error is occurring?
Controller
Code when an error is occurring
Code when an error no more occurring
UPDATE
Fixed problem when added en.json file in the lang folder.

protected $middlewareGroups = [
'web' => [
\App\Http\Middleware\Localization::class,
],
you add this created middleware to the list and then you go to the web.php routes file and add
Route::get('/locale/{locale}', function ($locale){
\Session::put('locale', $locale);
return redirect()->back();
})->name('traduction');
et ensuite vous pouvez récupérer la session de cette facon
<a href="{{route('traduction',['locale'=>'en'])}}" class="menu-link d-flex px-5 active">
<a href="{{route('traduction',['locale'=>'fr'])}}" class="menu-link d-flex px-5 active">
in case you want to display an image according to the session
<a href="#" class="menu-link px-5">
<span class="menu-title position-relative">Langue {{ Session::get('locale') }}
#if (Session::get('locale') == "fr")
<span class="fs-8 rounded bg-light px-3 py-2 position-absolute translate-middle-y top-50 end-0">Francais
<img class="w-15px h-15px rounded-1 ms-2" src="assets/media/flags/france.svg" alt="" /></span></span>
#else
<span class="fs-8 rounded bg-light px-3 py-2 position-absolute translate-middle-y top-50 end-0">English
<img class="w-15px h-15px rounded-1 ms-2" src="assets/media/flags/united-states.svg" alt="" /></span></span>
#endif
</a>
sorry but you have to use both answers as they are complementary

in truth to translate i don't do it that way. in fact i create a midleware and i create a fair route. let's take the case of french and english. let's create a midleware Location
php artisan make:middleware Localisation
then fill in the middleware
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Http\Request;
class Localization
{
public function handle(Request $request, Closure $next)
{
if(\Session::has('locale'))
{
\App::setlocale(\Session::get('locale'));
}
return $next($request);
}
}

Related

(Laravel 9) Foreach Loop is showing multiple items for one row of data and not showing other data in one view

So I have this problem with my Laravel project that I'm working on right now when I'm trying to store one data to the database but in the view, it shows five of it. And whenever I add another data. It won't stack. Kind of confusing, ain't it?
So What I'm actually trying to do is that I have 2 Models and is trying to overlap them to each other. As I search for ways to make them show in one view, I concluded in putting them into one Controller.
I made their Store CRUD separate so that it would work and this is how it looks like:
public function groupStore(Request $request)
{
$request->validate([
'title'=>'required',
'subject'=>'required',
'section'=>'required',
'team'=>'required',
'advisor'=>'required',
]);
GroupProject::create($request->all());
return redirect()->back()->with('success', 'Created Project Successfully.');
}
public function projectStore(Request $request)
{
$request->validate([
'title'=>'required',
'file'=>'required',
'description'=>'required',
]);
$file = $request->file('file');
$fileName = time().'_'.$file->getClientOriginalName();
$file->move(public_path('files'), $fileName);
$data = array(
'title'=>$request->title,
'file'=>$fileName,
'description'=>$request->description
);
Project::create($data);
return redirect()->back()->with('success', 'Posted Project Successfully.');
}
And here is how the Show CRUD looks like:
public function show(GroupProject $group_projects, Project $projects, $id)
{
$group_projects = GroupProject::find($id);
$projects = Project::find($id);
if (auth()->user()->type == 'faculty') {
return view('faculty/project', compact(['group_projects', 'projects']));
}else if (auth()->user()->type == 'office') {
return view('office/project', compact(['group_projects', 'projects']));
}else{
return view('student/project', compact(['group_projects', 'projects']));
}
}
PS: I'm trying to have Three users which makes the if else statements.
Now here's where the real problem comes from. As I make the "Group Project", I made the view with a foreach loop in order to show everything from my datastore, such as this and the corresponding program for it looks like this:
#foreach($group_projects as $key => $groupProject)
<div class="col flex">
<div class="card h-100">
<div class="card-body">
<h3 class="card-title">{{ $groupProject->title }}</h3>
<h6>{{ $groupProject->subject }}</h6>
<h6>{{ $groupProject->section }}</h6>
<h6>{{ $groupProject->team }}</h6>
<h6>{{ $groupProject->advisor }}</h6>
<div class="dropdown">
<button id="dropdownMenu" class="btn btn-secondary dropdown-toggle" type="button" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
{{ __('Actions') }}
</button>
<ul class="dropdown-menu" aria-labelledby="dropdownMenu">
<li><a class="dropdown-item" href="{{ URL::to('project/' . $groupProject->id) }}">
{{ __('Show')}}
</a></li>
</ul>
</div>
</div>
</div>
</div>
#endforeach
On this case, there seems to be no problem at all and it works perfectly fine even if I try to add another one.
But as I try to click it and change the view, this would be how it looks like after storing a "Project" and here's its corresponding Code:
#if (is_array($projects) || is_object($projects))
#foreach($projects as $key => $project)
<div class="col flex my-2">
<div class="card">
<div class="card-body">
<h3 class="card-title">{{ $projects->title }}</h3>
<iframe src="/files/{{ $projects->file }}"></iframe>
<h6>{{ $projects->description }}</h6>
</div>
</div>
</div>
#endforeach
#endif
And after adding another "Project" it will not show up on the "Test Title 1" but instead in "Test Title 2" which is pretty frustrating.
At first I'm thinking that it might be because I made the if statement of "#if (is_array($projects) || is_object($projects))" but if I remove this part, it would show an error when I'm trying to view a "Group Project" While there's nothing in the "Project" yet.
Another is that after making the foreach loop "#foreach($projects as $key => $project)" , I still call the "$projects->title" instead of "$project->title". but the reason for this is that it shows an error of "Attempt to read property "title" on bool".
I wonder, what should I do?
EDIT:
Nevermind Guys, I actually solved it just now.
So the real problem was on my Show CRUD. Instead of listing it as
$group_projects = GroupProject::find($id);
$projects = Project::find($id);
I should've called it as
$group_projects = GroupProject::find($id);
$projects = Project::all();
And Everything will be solved lol..... Now my problem is how to overlap them into one another such as 1 "Group Project" can have multiple "Project"....

Laravel Eloquent Query within Foreach Loop

Back again with another question I am hoping someone might have an idea for regarding the app that I am working on.
In this educational assessment application, I have assessments which have a one-to-many relationship with Competencies (similar to a Blog Post Category) and a many-to-many relationship with Contexts (similar to a Blog Tag).
I am trying to create a report view which will allow me to show a card for each of the Competency & Context combinations and then count all assessments where that competency & context combination exists (think of this as counting how many blog posts are in each category & tag combination, even if that number is 0).
So far I am able to produce the report which lists a card for each competency and context combination but I can't figure out how to pass that information to the controller for use in the query which will find the relevant assessments.
Here is my Report View
<x-app-layout title="{{ config('app.name', 'Laravel') }}">
<div class="container grid px-6 mx-auto">
<h2 class="my-6 text-2xl font-semibold text-gray-700 dark:text-gray-200">
{{ __('Reports') }}
</h2>
<div class="grid gap-6 mb-8 md:grid-cols-2 xl:grid-cols-4">
#foreach ($competencies as $competency) <br>
#foreach ($contexts as $context)
<div class="flex items-center p-4 bg-white rounded-lg shadow-xs dark:bg-gray-800">
<div>
<p class="text-lg font-semibold text-gray-700 dark:text-gray-200">
{{ $competency->name}}
</p>
<p class="mb-2 text-sm font-medium text-gray-600 dark:text-gray-400">
{{ $context->name }}
</p>
{{ $assessments }}
</div>
</div>
#endforeach
#endforeach
</div>
</x-app-layout>
Here is my Report Controller
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Models\Assessment;
use App\Models\Competency;
use App\Models\Context;
use App\Models\User;
use Illuminate\Support\Facades\Auth;
class ReportController extends Controller
{
public function index(Competency $competency, Context $context)
{
return view('dashboard.reports.index', [
'competencies' => Competency::where('team_id', Auth::user()->currentTeam->id)->get(),
'contexts' => Context::where('team_id', Auth::user()->currentTeam->id)->get(),
'assessments' => Assessment::where('competency_id', $competency->id)->whereRelation('contexts', 'context_id', $context->id)->count(),
]);
}
}
Here is an image of what this currently produced in the Report View: https://imgur.com/a/SQSf7UM
Please let me know if there is additional detail which would be helpful
it's better you declare the relation in the model, let's assume:
an assessment has one category,
an assessment has many contexts,
You can create an additional table with its model to store assessment contexts (because it assessent can has many contexts), let's say the table name is assessment_contexts and the model name is AssesmentContext. Or you can just run php artisan make:model AssessmentContext -m.
At least it has 2 columns, assessment_id and context_id,
Then inside AssessmentContext, add this function to create a simple relation,
public function assessment() {
return $this->hasOne(Assessment::class);
}
public function context() {
return $this->hasOne(Context::class);
}
Declare this functions inside the Assessment model,
public function competency() {
return $this->hasOne(Competency::class);
}
public function contexts() {
return $this->hasMany(AssesmentContext::class);
}
And add the this to the Competency model,
public function assessments() {
return $this->hasMany(Assessment::class);
}
And this for the Context model,
public function assessments() {
return $this->hasMany(AssessmentContext::class);
}
You have to add foreign key inside assessments table that refers to category primary key id, (I recommend you the column name is category_id).
Then finally in your controller, you can just declare the competencies list, and inside your view, you can access all the relate data. i.e:
return view('dashboard.reports.index', [
'competencies' => Competency::where('team_id', Auth::user()->currentTeam->id)->get()
]);
Inside view,
#foreach ($competencies as $competency) <br>
#foreach ($competency->assessments as $assessment)
<div class="flex items-center p-4 bg-white rounded-lg shadow-xs dark:bg-gray-800">
<div>
<p class="text-lg font-semibold text-gray-700 dark:text-gray-200">
{{ $competency->name}}
</p>
#foreach ($assessment->contexts as $context)
<p class="mb-2 text-sm font-medium text-gray-600 dark:text-gray-400">
{{ $context->name }}
</p>
#endforeach
</div>
</div>
#endforeach
#endforeach
This is just simple scheme of relation, there are other ways to do it that maybe better and more optimal.

Can i set a custom tag and a custom value in laravel component?

<div class="bg-white dark:bg-custom-black-600 dark:text-white rounded px-4 pb-4 pt-2">
<div class="flex-shrink-0 flex justify-between items-center">
<h4 class="font-semibold flex-shrink-0">
{{ __('services') }}
</h4>
<i class="ri-hard-drive-2-fill text-blue-600 dark:text-blue-600"></i>
</div>
<p class="text-3xl text-blue-600">
{{ Auth::user()->services->count() }}
</p>
</div>
this is my code from the component card.blade.php. Now the question: "Can I make a custom value that I have to specify in the tag <x-card title="" service=""> or is that not possible? I would like {{ __('services') }} and {{ Auth::user()->services->count() }} not to be static in the code example.
You'd need to write a component class to handle variables in the template. That class would interpret the input and store it in variables that can be accessed in the template. This is all described in the documentation.
<?php
namespace App\View\Components;
use Illuminate\View\Component;
class Card extends Component
{
public function __construct(
public string $title,
public string $service,
)
{}
public function render()
{
return view('components.card');
}
}
Call the component like this:
<x-card title="Something" service="something else"/>
And you should then be able to use $title and $service in the Blade template file. Note if you want to use PHP values, you'll need to do something like this:
<x-card :title="__('something')" service="something else"/>
Note the colon preceding the attribute name.

Getting error "Typed property must not be accessed before initialization" - Laravel Livewire

Description
I am type hinting model properties and trying to delete the invitation data. Below is the error which its throwing me back. Please help me with it, as I am unable to spot what is it that I'm missing.
Typed property App\Http\Livewire\Backend\UserManagement\FormComponent\InvitationManagementModal::$invitation must not be accessed before initialization
Stripped-down, copy-pastable code snippets
Livewire\InvitationManagementModal.php
<?php
namespace App\Http\Livewire\Backend\UserManagement\FormComponent;
use Livewire\Component;
use Livewire\WithPagination;
use App\Http\Livewire\Backend\DataTable\WithCachedRows;
use App\Models\Invitation;
class InvitationManagementModal extends Component
{
use WithPagination, WithCachedRows;
public $showInvitationManagementModal = false;
public Invitation $invitation;
protected $listeners = ['manageInvitation'];
public function manageInvitation()
{
$this->showInvitationManagementModal = true;
}
public function deleteInvitation(Invitation $invitation)
{
$this->invitation->delete();
}
public function getInvitationRowsProperty()
{
return $this->cache(function () {
$invitations = Invitation::where('registered_at', null)->paginate(5);
return $invitations;
});
}
public function render()
{
return view('livewire.backend.user-management.form-component.invitation-management-modal', ['invitations' => $this->invitationRows]);
}
}
livewire\invitation-management-modal.blade.php
<div>
<x-modal.stacked wire:model.defer="showInvitationManagementModal" id="scroll-lock">
<x-slot name="title">Manage Invitation</x-slot>
<x-slot name="description">Manage all the invitations which are yet to be accepted.</x-slot>
<x-slot name="content">
<div class="p-8 space-y-4">
<ul class="flex flex-col divide divide-y w-full bg-white rounded-lg shadow">
#forelse($invitations as $key => $invitation)
<li class="flex flex-row">
<div class="flex flex-1 items-center px-8 py-4">
<div class="flex-1 mr-16">
<div class="text-sm dark:text-white">
{{ $invitation->email }}
</div>
</div>
<button wire:click="deleteInvitation" class="text-right flex justify-end">
<x-icon.trash />
</button>
</div>
</li>
#empty
#endforelse
</ul>
<div>
{{ $invitations->links() }}
</div>
</div>
</x-slot>
<x-slot name="footer">
<x-button.secondary wire:click.defer="$set('showInvitationManagementModal', false)">Cancel</x-button.secondary>
</x-slot>
</x-modal.stacked>
</div>
Context
Livewire version: 2.3.5
Laravel version: 8.20.1
Alpine version: 2.8.0
Browser: Chrome
The other answers here both have some minor things to note about them. You don't have to check $invitation, because the typehinting Invitation makes Laravel use Model-Route-Binding, which fetches the corresponding record - or throws a HTTP 404 status code if not found.
Secondly, and this is the actual error you are currently seeing yourself, is that you don't have to do anything to the $this->invitation, since its not set. You should instead pass a parameter to the method.
When looping data in Livewire, it is always recommended to use wire:key, so that Livewire can keep track of each record in the loop.
So for the actual delete method, just call the delete method on the input-variable.
public function deleteInvitation(Invitation $invitation)
{
$invitation->delete();
// Emit an event to notify the user that the record was deleted
// Refresh the parent component to remove the invitation from the list
}
For your blade, add wire:key to the first element in the loop and pass the ID to the method.
(so wire:click="deleteInvitation({{ $invitation->id }})" instead of wire:click="deleteInvitation").
#forelse($invitations as $key => $invitation)
<li class="flex flex-row" wire:key="invitation_{{ $invitation->id }}">
<div class="flex flex-1 items-center px-8 py-4">
<div class="flex-1 mr-16">
<div class="text-sm dark:text-white">
{{ $invitation->email }}
</div>
</div>
<button wire:click="deleteInvitation({{ $invitation->id }})" class="text-right flex justify-end">
<x-icon.trash />
</button>
</div>
</li>
#empty
#endforelse
This in turn means that, since its never used, you can remove the declaration of the $invitation property of that class, the line just after public $showInvitationManagementModal = false;.
public Invitation $invitation;
Try this:
public function deleteInvitation(Invitation $invitation)
{
$this->invitation = $invitation;
$this->invitation->delete();
}

Laravel 5.2 redirect back with success message

I'm trying to get a success message back to my home page on laravel.
return redirect()->back()->withSuccess('IT WORKS!');
For some reason the variable $success doesn't get any value after running this code.
The code I'm using to display the succes message:
#if (!empty($success))
<h1>{{$success}}</h1>
#endif
I have added the home and newsletter page to the web middleware group in routes.php like this:
Route::group(['middleware' => 'web'], function () {
Route::auth();
Route::get('/', function () {
return view('home');
});
Route::post('/newsletter/subscribe','NewsletterController#subscribe');
});
Does anyone have any idea why this doesn't seem to work?
You should remove web middleware from routes.php. Adding web middleware manually causes session and request related problems in Laravel 5.2.27 and higher.
If it didn't help (still, keep routes.php without web middleware), you can try little bit different approach:
return redirect()->back()->with('message', 'IT WORKS!');
Displaying message if it exists:
#if(session()->has('message'))
<div class="alert alert-success">
{{ session()->get('message') }}
</div>
#endif
you can use this :
return redirect()->back()->withSuccess('IT WORKS!');
and use this in your view :
#if(session('success'))
<h1>{{session('success')}}</h1>
#endif
Controller:
return redirect()->route('subscriptions.index')->withSuccess(['Success Message here!']);
Blade
#if (session()->has('success'))
<div class="alert alert-success">
#if(is_array(session('success')))
<ul>
#foreach (session('success') as $message)
<li>{{ $message }}</li>
#endforeach
</ul>
#else
{{ session('success') }}
#endif
</div>
#endif
You can always save this part as separate blade file and include it easily.
fore example:
<div class="row">
<div class="col-md-6">
#include('admin.system.success')
<div class="box box-widget">
You can simply use back() function to redirect no need to use redirect()->back() make sure you are using 5.2 or greater than 5.2 version.
You can replace your code to below code.
return back()->with('message', 'WORKS!');
In the view file replace below code.
#if(session()->has('message'))
<div class="alert alert-success">
{{ session()->get('message') }}
</div>
#endif
For more detail, you can read here
back() is just a helper function. It's doing the same thing as redirect()->back()
One way to do that is sending the message in the session like this:
Controller:
return redirect()->back()->with('success', 'IT WORKS!');
View:
#if (session()->has('success'))
<h1>{{ session('success') }}</h1>
#endif
And other way to do that is just creating the session and put the text in the view directly:
Controller:
return redirect()->back()->with('success', true);
View:
#if (session()->has('success'))
<h1>IT WORKS!</h1>
#endif
You can check the full documentation here: Redirecting With Flashed Session Data
I hope it is very helpful, regards.
All of the above are correct, but try this straight one-liner:
{{session()->has('message') ? session()->get('message') : ''}}
In Controller
return redirect()->route('company')->with('update', 'Content has been updated successfully!');
In view
#if (session('update'))
<div class="alert alert-success alert-dismissable custom-success-box" style="margin: 15px;">
×
<strong> {{ session('update') }} </strong>
</div>
#endif
You can use laravel MessageBag to add our own messages to existing messages.
To use MessageBag you need to use:
use Illuminate\Support\MessageBag;
In the controller:
MessageBag $message_bag
$message_bag->add('message', trans('auth.confirmation-success'));
return redirect('login')->withSuccess($message_bag);
Hope it will help some one.
Adi
in Controller:
`return redirect()->route('car.index')->withSuccess('Bein ajoute')`;
In view
#if(Session::get('success'))
<div class="alert alert-success">
{{session::get('success')}}
</div>
#endif

Categories