laravel-medailibrary getFirstMediaUrl("images") not work for joined tables - laravel

I have a problem getting media from a joined table in laravel-medailibrary, I used getFirstMediaUrl("images") to get photos from one table and it works, but if I join two or three tables it not work, how can I solve it?
I want to get photos from those posts that shared by a user.
this post table:
this is share_tb table:
this is users table:
this is the media table:

I find my answer after trying some ways:
public function getPosts(Request $request)
{
$result = [];
$postID = DB::table("share_tb")->where("user_id", Auth::user()->id)->get();
foreach ($postID as $id) {
if (count(Post::where("id", $id->related_id)->get()) > 0) {
$posts = Post::where("id", $id->related_id)->get();
foreach ($posts as $post) {
// $result = $post->getMedia('images');
array_push($result, [
"comment_count" => getTotalComment($post->id),
"course_id" => $post->course_id,
"id" => $post->id,
'post_image' => count($post->getMedia('images')) > 0 ? $post->getMedia('images')[0]->getFullUrl('big') : "",
'logo'=>GetCourseLogo::collection(Course::where('course_id',$post->course_id)->get()),
"post_author" => $post->post_author,
"post_date" => $post->post_date,
"post_excerpt" => $post->post_excerpt,
"post_modified" => $post->post_modified,
"post_parent" => $post->post_parent,
"post_title" => $post->post_title,
"post_type" => $post->post_type,
]);
}
}
}
return Response()->json($result);
}
and by this resource collection, I get the logo:
class GetCourseLogo extends JsonResource
{
public function toArray($request)
{
return $this->getFirstMediaUrl('logo');
}
}

Related

Laravel - Update a table using Maatwebsite Excel Import based on condition

Using Laravel-5.8 and Maatwebsite-3.1, I have a table called employees (Employee).
class FirstEmployeeSheetImport implements ToModel, WithBatchInserts, WithHeadingRow, SkipsOnError, WithValidation, SkipsOnFailure
{
use Importable, SkipsErrors, SkipsFailures;
public function model(array $row)
{
$this->department = $row['department'];
$employee_data = [
'employee_code' => $row['employee_code'],
'company_id' => Auth::user()->company_id,
'email' => $row['official_email'],
'department_id' => $this->getDepartment(),
];
$employee = Employee::create($employee_data);
}
public function getDepartment(){
if(!empty($this->department) || !$this->department){
return HrDepartment::where('dept_name',$this->department)->where('company_id',Auth::user()->company_id)->pluck('id')->first();
} else {
return 0;
}
}
}
I want to use the excel upload to update these two (2) fields: email and department_id for each of the employees where:
company_id = Auth::user()->company_id AND employee_code = $row['employee_code'].
Also, it should only perform the update for those that meet the condition. I should only perform update and don't crete.
How do I achieve this?
Thanks
You can use ToCollection to get your data into $rows then update your data accordingly.
class FirstEmployeeSheetImport implements ToCollection
{
public function collection(Collection $rows)
{
foreach ($rows as $row)
{
Employee::where('company_id', auth()->user()->company_id)
->where('employee_code', $row['employee_code'])
->update([
'email' => $row['email'],
...
]);
}
}
}

Laravel 7: How to use in data seeder array

How to make distinct inserts using a custom array using database seeder?
Using the following code:
$categories = ['Hardware', 'Software', 'Planning', 'Tools'];
foreach ($categories as $category) {
App\Category::insert([
'name' => $category,
'slug' => Str::slug($category),
]);
}
It doesn't work without a factory for a category that is the problem matter if I use insert or create.
It gives this error
Unable to locate factory for [App\Category].
at vendor/laravel/framework/src/Illuminate/Database/Eloquent/FactoryBuilder.php:273
269| */
270| protected function getRawAttributes(array $attributes = [])
271| {
272| if (! isset($this->definitions[$this->class])) {
> 273| throw new InvalidArgumentException("Unable to locate factory for [{$this->class}].");
274| }
275|
276| $definition = call_user_func(
277| $this->definitions[$this->class],
Thanks
Create an array of data in the run method of you seeder file
public function run()
{
$categories = [
['name' => 'Music'],
['name' => 'Gaming'],
['name' => 'Entertainment'],
['name' => 'Non-Profit & Activism'],
['name' => 'Other'],
];
foreach ($categories as $category) {
Category::create($category);
}
}
You are pushing all data into the Model, so you need to set fillable or guarded in the Model.
class Category extends Model
{
protected $guarded = [];
}
try using insert witch take an array as parameter:
public function run()
{
$inputs[] = ['name'=> 'Hardware'];
$inputs[] = ['name'=> 'Software'];
$inputs[] = ['name'=> 'Planning'];
$inputs[] = ['name'=> 'Tools'];
App\Category::insert($inputs);
}
or you can do it in another way:
public function run()
{
$inputsNames = ['Hardware', 'Software', 'Planning', 'Tools'];
foreach($inputsNames as $categoryName)
{
$inputs[]=['name'=>$categoryName];
}
App\Category::insert($inputs);
}

Is there any efficient method on how to get id of object to my create method

I am creating a web module, and want to get ID of table licensing level two parse into my create method. Hence each ID of level will have a task and the ID need to be stored within my licensing table as a foreign key which reflects ID in Level Two table. How could I solve this, anyone can give me a good suggestion or way on doing this
public function add_show($id)
{
$level = PreLicensingLevelTwo::where('id', $id)->first();
$level->prelicensingtask = PreLicensingTask::where('pre_licensing_level_two_id', $level->id)->with('staff', 'statusdesc', 'prelicensingtaskstaff')->get();
return view('staff.regulatory.statutory.approval.display',compact('level'));
}
public function create()
{
$staff = Staff::pluck('staff_name');
$status = PreLicensingStatus::pluck('status_description', 'id');
return view('staff.regulatory.statutory.approval.create', compact('staff','status'));
}
public function show($id)
{
$one = PreLicensingLevelOne::where('pre_licensing_main_id', $id)->get();
foreach ($one as $key => $license)
{
$license->two = PreLicensingLevelTwo::where('pre_licensing_level_one_id', $license->id)->get();
}
$rendered = view('staff.regulatory.statutory.approval.show')->with('one', $one)->render();
return response()->json(array('status' => 1, 'tableData' => $rendered));
}
With help from my working collegue this is how i able to solve the question i asked
public function store(Request $request)
{
$this->validate($request, [
'task_title' => 'required',
'task_description' => 'required',
'task_due_date' => 'required',
]);
$leveltwo = PreLicensingLevelTwo::find($request->input('pre_licensing_level_two_id'));
$prelicensingtask = new PreLicensingTask;
$prelicensingtask->task_title =$request->input('task_title');
$prelicensingtask->task_description =$request->input('task_description');
$prelicensingtask->task_due_date =$request->input('task_due_date');
$prelicensingtask->created_by_staff_id = Auth::user()->ref_user->staff_id;
$prelicensingtask->status = $request->input('status');
$prelicensingtask->pre_licensing_level_two_id = $leveltwo->id;
$prelicensingtask->pre_licensing_level_one_id = $leveltwo->pre_licensing_level_one_id;
$prelicensingtask->pre_licensing_main_id = $leveltwo->pre_licensing_main_id;
$prelicensingtask->centre_id = Auth::user()->ref_user->centre_id;
$prelicensingtask->save();
return redirect()->back();
}

Send a push Notifications to users who have changed the password 30 days before

This is my case:
In my database, I have a table users. The rows in the table also have a field password_changed_at. Now I would like to select all users where the password_changed_at field is older than 30 days and send a push notification But I'm stuck on how to do this with Carbon. My code now looks like this:
public function passwordExpired() {
$dateTime = new DateTime();
$currentDateTime = $dateTime->format('Y-m-d H:i');
$users = User::where('password_changed_at', $currentDateTime)->get();
// $user = $request->user();
foreach ($users as $user) {
$password_changed_at = new Carbon(($user->password_changed_at) ? $user->password_changed_at : "");
if (Carbon::now()->diffInDays($password_changed_at) >= 30) {
foreach ($password_changed_at as $password)
{
// $user = $user->id;
$user->notify(new ReminderPassword($user));
$push = new PushNotification('apn');
$push->setMessage([
'aps' => [
'alert' => 'Reminder for your password "'.$user->email.'"',
'sound' => 'default',
'badge' => $user->unreadNotifications->count()
],
'extraPayLoad' => [
'custom' => 'My custom data',
]
]);
$push->setDevicesToken($user->deviceToken);
$push->send();
$feedback = $push->getFeedback();
}
Looks like diffInDays works the other way round (i.e. diffing an older day returns a negative value). See: https://carbon.nesbot.com/docs/#api-difference
So you can change your code like this:
public function passwordExpired() {
$dateTime = new DateTime();
$currentDateTime = $dateTime->format('Y-m-d H:i');
$users = User::where('password_changed_at', $currentDateTime)->get();
foreach ($users as $user) {
$password_changed_at = new Carbon(
($user->password_changed_at) ? $user->password_changed_at : ""
);
// DiffIndays works the other way round:
if ($password_changed_at->diffInDays(Carbon::now()) >= 30) {
$user->notify(new ReminderPassword($user));
$push = new PushNotification('apn');
$push->setMessage([
'aps' => [
'alert' => 'Reminder for your password "' . $user->email . '"',
'sound' => 'default', 'badge' => $user->unreadNotifications->count()
],
'extraPayLoad' => ['custom' => 'My custom data', ]
]);
$push->setDevicesToken($user->deviceToken);
$push->send();
$feedback = $push->getFeedback();
}
}
}
With $users = User::where('password_changed_at', $currentDateTime)->get(); you selecting all users who has changed their date today, but you want select all users which has changed their password +30 days before.
So you can just select these with using a query scope. In your Users class add this:
class Users extends Authenticatable
{
// ...
public function scopePasswordOlderThan30Days(Builder $builder)
{
$expirationDate = Carbon::now()->subDays(30);
return $builder->where('password_changed_at', '<=', $expirationDate);
}
}
In your function use it like:
public function passwordExpired()
{
$users = User::passwordOlderThan30Days()->get();
$users->each(function(User $user) {
// notify the user
})
}

update table with csv using laravel

I'm trying to update a table using Maatwebsite/Laravel-Excel.
public function import(Request $request)
{
if($request->file('imported-file'))
{
$path = $request->file('imported-file')->getRealPath();
$data = Excel::load($path, function($reader)
{
})->get();
if(!empty($data) && $data->count())
{
foreach ($data->toArray() as $row)
{
if(!empty($row))
{
$dataArray[] =
[
//'name' => $row['name'],
'age' => $row['age'],
'phone' => $row['phone'],
//'created_at' => $row['created_at']
];
}
if(!empty($dataArray))
{
//Item::insert($dataArray);
DB::table('items')
->where('name', $row['name'])->update($dataArray);
return view('imported')->with('success', 'Course updated');
}
}
}
}
}
But its giving error:
SQLSTATE[42S22]: Column not found: 1054 Unknown column '0' in 'field list' (SQL: update items set 0 = 20 where name = james
Here's my csv
name,age,phone
James,20,888839939
Joseph,54,3444444
Hanson,30,99999999
The above is the csv file i'm trying to update.
The problem is that $dataArray is an array of arrays, so to make it work you have to loop each one:
if(!empty($dataArray)) {
foreach ($dataArray as $array) {
DB::table('items')
->where('name', $row['name'])
->update($array);
}
return view('imported')->with('success', 'Course updated');
}
But this wouldn't make much sense, because every time it would be updating the row with name = $row['name'], so you probbaly need to update the line where you set a value to the $dataArray from $dataArray[] = ... to $dataArray = ...*, so it could have a single value.
In case any body comes across this, this is how i solved it.
public function import(Request $request)
{
if($request->file('imported-file'))
{
$path = $request->file('imported-file')->getRealPath();
Excel::load($path)->each(function (Collection $csvLine) {
DB::table('items')
->where('id', $csvLine->get('id'))
->update(['name' => $csvLine->get('name'),'phone' => $csvLine->get('phone'),'age' => $csvLine->get('age')]);
});
return view('imported')->with('success', 'Course updated');
}
}
I used the each() collection method to loop through the csv file and it won the battle.

Resources