add new attribute to laravel eloquent collection - laravel-5

I would like to push in my eloquent model an extra attribute on calculation
and I would like to use it in my blade as $user->avatarImg
my model method look like
public function avatarImg()
{
if($this->hasMedia('avatar')) {
$image = $this->getMedia('avatar');
$img = \Intervention\Image\ImageManagerStatic::make($image[0]->getPath())->encode('data-url');
}
elseif ($this->blob->file) {
$img = 'data:image/jpeg;base64,'. base64_encode($this->blob->file);
} else {
$img = '';
}
$this->user->put('avatarImg', $img);
dd($this->user);
return $img;
}
but what I try does not working I get:
Call to a member function put() on null
how would I do this properly?

Looks like property user does not exists in your model.
If this is User model try just
$this->put('avatarImg', $img);

Related

Old File from storage is not being deleted on update Laravel

I am trying to delete the existing image from the storage while the new image is being updated.
But everytime the new image is inserted retaining the previous ones.
When I dd the image from database to unlink, I get full url
i.e.
http://127.0.0.1:8000/teacger-image/1598097262-85508.jpg
While only teacher-image/1598097262-85508.jpg
has been stored in the database.
Function to delete the image
public function deleteImageFromStorage($value)
{
if (!empty($value)) {
File::delete('public/' . $value);
}
}
I have called the method in the controller when there is image posted during update.
update method includes
if ($request->hasFile('image')) {
$teacher->deleteImageFromStorage($teacher->image);
$file = $request->file('image');
$filename = time() . '-' . mt_rand(0, 100000) . '.' . $file->getClientOriginalExtension();
$path = $file->storeAs('teacher-image', $filename);
$teacher->image = $path;
}
Also I have used Storage::delete() and unlink as well but none of them seem to work.
help
This is how I've been deleting files in Laravel.
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Storage;
class ImagesController extends Controller
{
public function deleteImageFromStorage($value)
{
if ( file_exists( storage_path($value) ) ) {
Storage::delete($value);
}
}
}
Make sure to use Illuminate\Support\Facades\Storage.
Try change your deleteImageFromStorage method to this:
public function deleteImageFromStorage($value)
{
if (!empty($value)) {
File::delete(public_path($value));
}
}
I had to do this to solve my problem.
The url was being taken by the configuration set on filesystems.php under config file.
public function deleteImageFromStorage($value)
{
$path_explode = explode('/', (parse_url($value))['path']); //breaking the full url
$path_array = [];
array_push($path_array, $path_explode[2], $path_explode[3]); // storing the value of path_explode 2 and 3 in path_array array
$old_image = implode('/', $path_array);
if ($old_image) {
Storage::delete($old_image);
}
}
If someone goes through the same problem in the future, this might be helpful.

Laravel : how to create unique tag in tags model

I want create tag for posts . I don't want tags repetitions to be saved,But it is stored repeated
public function store(Request $request)
{
$data = $request->all();
$post = Post::create($data);
if ($post && $post instanceof Post) {
$tags = $request->input('tags');
foreach ($tags as $tag){
$newTag = Tag::create(['name'=>$tag]);
$tags[] = $newTag->id;
}
$post->tags()->sync($tags);
return redirect()->back();
}
}
How can it be done?
updateOrCreate method will help check
It will create data if it not exists and update in case it already in db
Tag::updateOrCreate(['name'=>$tag]);

Laravel pass value from foreach loop in controller to view

I am trying to get the data from a foreach loop in my controller to pass to my view. How do I do it?
Controller
class FormteachersController extends Controller
{
public function form_teachers_view(){
$UniqueStudent = Student::where('Student_ClassID','JSS 1C')->get();
foreach ($UniqueStudent as $keydata) {
$student = $keydata->Stud_id;
$result= Result::where('Term_ID','1st Term')->where('Student_ID',$student)->where('Class_ID','JSS 1C')->where('Session_ID','2225/2222')->get();
foreach ($result as $keyresult) {
echo '<br>'.'<br>'.$student.'-'.$result;
}
return view('teachers.form_teachers_comment_sec');
}
}
}
This is the output.
You can do something like this:
class FormteachersController extends Controller
{
public function form_teachers_view(){
$uniqueStudent = Student::where('Student_ClassID','JSS 1C')->get();
$uniqueStudentsData = [] ;
foreach ($uniqueStudent as $keydata) {
$student = $keydata->Stud_id;
$result = Result::where('Term_ID','1st Term')->where('Student_ID',$student)->where('Class_ID','JSS 1C')->where('Session_ID','2225/2222')->get();
foreach ($result as $keyresult) {
$uniqueStudentsData[] = '<br>'.'<br>'. $student.'-'. $keyresult;
}
}
return view('teachers.form_teachers_comment_sec', compact('uniqueStudentsData'));
// or pass array
return view('teachers.form_teachers_comment_sec',[
'uniqueStudentsData' => $uniqueStudentsData,
]);
}
}
Now, in your form_teachers_comment_sec.blade.php, run your foreach loop and do what do you want to there
// $uniqueStudentsData
#foreach($uniqueStudentsData as $data)
// do what do you want
#endforeach
Hopefully, it will be work. more documentation please visit laravel documentation

Running same query in 2 different views: What's the proper way?

Just getting started into laravel and need to run the same db query for 2 different views, I know I could just create 2 controllers and perform the same query in both passing it to each view.
But, is that the proper way? Or is there a way without repeating my code?
Thanks!
Edit:
I have the following function inside a controller:
protected function getLocation($url)
{
$match = ['url' => $url];
$location = DB::table('location')->where($match)->first();
if (!$location) {
abort(404);
}
return $location;
}
the controller is returning that data to a view:
public function showsubcatandlocation($service)
{
$category = $this->getCat($service);
$location = $this->getLocation($category);
$id = $category->id;
$locID = $location->id;
$profiles = $this->getProfileswLoc($id, $locID);
return view('category', ['profile' => $profiles]);
}
What's the proper way to reuse the getLocation function? Or should I just copy it in the new controller? I just need to use it in those 2 views.
maybe scope Query helps?
class Location extends Model
{
public function scopeMatch($query, $url)
{
return $query->where('url', $url);
}
}
And then your two controllel methods will be
$location = Task::match($url)->first();
if (!$location) {
abort(404);
}
return $location;
$category = $this->getCat($service);
$location = Task::match($category['url'])->first();
$id = $category->id;
$locID = $location->id;
$profiles = $this->getProfileswLoc($id, $locID);
return view('category', ['profile' => $profiles]);

Laravel returns old model after update

When i store a new record, Laravel returns the new record. Everything works fine.
When i update a record, Laravel returns the old record. I like to return the updated record.
Controller
public function store(StoreProjectRequest $request)
{
$data = $this->repo->create( $request->all());
return response()->json(new ProjectResource($data));
}
public function update(UpdateProjectRequest $request, Project $project)
{
$data = $this->repo->update($project, $request->all());
return response()->json(new ProjectResource($data));
}
Repository
public function create( $data)
{
$this->model->name = $data['name'];
$this->model->description = $data['description'];
$this->model->sales_order_id = $data['sales_order_id'] ? $data['sales_order_id'] : NULL;
$this->model->project_leader_id = $data['project_leader_id'];
$this->model->project_type_id = $data['project_type_id'];
$this->model->project_status_id = $data['project_status_id'];
$this->model->creator_id = Auth()->id();
$this->model->save();
return $this->model;
}
public function update($model, $data)
{
$model->name = $data['name'];
$model->description = $data['description'];
$model->sales_order_id = $data['sales_order_id'];
$model->project_leader_id = $data['project_leader_id'];
$model->project_type_id = $data['project_type_id'];
$model->project_status_id = $data['project_status_id'];
$model->save();
return $model;
}
When i add $data = Project::find($project->id)i receive the updated model.
But is this the only way?
The reason the $data is returning as the old data is because it still stores the data from when the variable was created. When you call $data->fresh() it will go fetch the new data and return it. Does that make sense?

Resources