uniqueginun

Member Since 3 Months Ago

Experience Points
11,240
Total
Experience

3,760 experience to go until the next level!

In case you were wondering, you earn Laracasts experience when you:

  • Complete a lesson — 100pts
  • Create a forum thread — 50pts
  • Reply to a thread — 10pts
  • Leave a reply that is liked — 50pts
  • Receive a "Best Reply" award — 500pts
Lessons Completed
93
Lessons
Completed
Best Reply Awards
0
Best Reply
Awards
  • start your engines Created with Sketch.

    Start Your Engines

    Earned once you have completed your first Laracasts lesson.

  • first-thousand Created with Sketch.

    First Thousand

    Earned once you have earned your first 1000 experience points.

  • 1-year Created with Sketch.

    One Year Member

    Earned when you have been with Laracasts for 1 year.

  • 2-years Created with Sketch.

    Two Year Member

    Earned when you have been with Laracasts for 2 years.

  • 3-years Created with Sketch.

    Three Year Member

    Earned when you have been with Laracasts for 3 years.

  • 4-years Created with Sketch.

    Four Year Member

    Earned when you have been with Laracasts for 4 years.

  • 5-years Created with Sketch.

    Five Year Member

    Earned when you have been with Laracasts for 5 years.

  • school-in-session Created with Sketch.

    School In Session

    Earned when at least one Laracasts series has been fully completed.

  • welcome-newcomer Created with Sketch.

    Welcome To The Community

    Earned after your first post on the Laracasts forum.

  • full-time-student Created with Sketch.

    Full Time Learner

    Earned once 100 Laracasts lessons have been completed.

  • pay-it-forward Created with Sketch.

    Pay It Forward

    Earned once you receive your first "Best Reply" award on the Laracasts forum.

  • subscriber Created with Sketch.

    Subscriber

    Earned if you are a paying Laracasts subscriber.

  • lifer Created with Sketch.

    Lifer

    Earned if you have a lifetime subscription to Laracasts.

  • evangelist Created with Sketch.

    Laracasts Evangelist

    Earned if you share a link to Laracasts on social media. Please email [email protected] with your username and post URL to be awarded this badge.

  • chatty-cathy Created with Sketch.

    Chatty Cathy

    Earned once you have achieved 500 forum replies.

  • lara-veteran Created with Sketch.

    Laracasts Veteran

    Earned once your experience points passes 100,000.

  • 10k-strong Created with Sketch.

    Ten Thousand Strong

    Earned once your experience points hits 10,000.

  • lara-master Created with Sketch.

    Laracasts Master

    Earned once 1000 Laracasts lessons have been completed.

  • laracasts-tutor Created with Sketch.

    Laracasts Tutor

    Earned once your "Best Reply" award count is 100 or more.

  • laracasts-sensei Created with Sketch.

    Laracasts Sensei

    Earned once your experience points passes 1 million.

  • top-50 Created with Sketch.

    Top 50

    Earned once your experience points ranks in the top 50 of all Laracasts users.

  • Community Pillar

    Earned once your experience points ranks in the top 10 of all Laracasts users.

Level 3
11,240 XP
Jan
15
21 hours ago
Activity icon

Awarded Best Reply on Laravel API Resources Response Doesn't Contain Links And Meta For Paginated Collections

I found the solution in stackoverflow. for transforming resource data you have to do the following:

public function toArray($request)
{
    return $this->collection->map(function ($person) {
        return [
            'id' => $person->id,
            'first_name' => $person->first_name,
            'last_name' => $person->last_name,
            'email' => $person->email,
            'phone' => $person->phone,
            'city' => $person->city,
            'href' => [
                 'link' => route('person.show', $person->id),
            ],
        ];
    });

}

it's clearly changed since last time I used API resources. because in the past you don't have to map over the collection because it's already single resource.

and when returning the collection you don't wrap it inside response helper. you just return it as it is.

Route::get('users', function (Request $request) {

    $users = User::paginate(3);

    $users = new \App\Http\Resources\User($users);

    return $users;

});
Activity icon

Replied to Laravel API Resources Response Doesn't Contain Links And Meta For Paginated Collections

I found the solution in stackoverflow. for transforming resource data you have to do the following:

public function toArray($request)
{
    return $this->collection->map(function ($person) {
        return [
            'id' => $person->id,
            'first_name' => $person->first_name,
            'last_name' => $person->last_name,
            'email' => $person->email,
            'phone' => $person->phone,
            'city' => $person->city,
            'href' => [
                 'link' => route('person.show', $person->id),
            ],
        ];
    });

}

it's clearly changed since last time I used API resources. because in the past you don't have to map over the collection because it's already single resource.

and when returning the collection you don't wrap it inside response helper. you just return it as it is.

Route::get('users', function (Request $request) {

    $users = User::paginate(3);

    $users = new \App\Http\Resources\User($users);

    return $users;

});
Jan
14
1 day ago
Activity icon

Replied to Laravel API Resources Response Doesn't Contain Links And Meta For Paginated Collections

but what is the issue?? the class generated by artisan command

Activity icon

Replied to Laravel API Resources Response Doesn't Contain Links And Meta For Paginated Collections

yes you right. the meta and links disappear when I wrap the results in this resource

Activity icon

Started a new Conversation Laravel API Resources Response Doesn't Contain Links And Meta For Paginated Collections

I created a larave api resource like this:

php artisan make:resource UserTasksResource --collection

in my controller:

$tasks = $request->user->tasks()->with(['info.details'])->paginate(5);
$tasks = new UserTasksResource($tasks );

        return response([
            'tasks' => $tasks
        ], 200);

now I the response is like:

{
	"tasks": [
		{...},
		{...}, ...
	]
}

first of all: where are the "links" and "meta" mentioned in the docs. second of all when I edited the resource controller like so:

   /**
     * Transform the resource collection into an array.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return array
     */
    public function toArray($request)
    {
        return [
		'id' => $this->id,
		'infoTitle' => $this->info->title
	];
    }

when I do this I get this error:

Undefined property: Illuminate\Pagination\LengthAwarePaginator::$id

I worked with API resources before and I didn't encounter such issues in the past, what I missing here?

Jan
13
2 days ago
Activity icon

Started a new Conversation Livewire Weird Behavior

Seniors, I have a livewire component that acting weird when I click submit button. validation errors show up but it removes a whole and it's content and replacing it with another one from the form. note: I use select2 in one of my form-rows but I put wire:ignore on it.

Activity icon

Replied to Using Traits With Livewire

@snapey to not forget to write custom logic in every component. so whenever I make new component I'm forced to write this function. sorry about best answer click

Activity icon

Replied to Help Refactoring Monstrous Code

sorry @martinbean I thought I could set more than one best answer. I kinda used a little bit of both of your answers guys.

Jan
12
3 days ago
Activity icon

Replied to Using Traits With Livewire

anyone at all :( ??

Activity icon

Replied to Help Refactoring Monstrous Code

@michaloravec

<?php

namespace App\Http\Controllers;

use App\Models\User;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;

class UserRegisterationOperation extends Controller
{

    public function store(Request $request)
    {
        DB::transaction();

        try {
            $user = $this->createUserFromRequest($request);

            $task = $user->tasks()->create([
                'name' => $request->name,
                'desc' => $request->task_desc
            ]);

            $files = $this->getFilesData($request);

            $user->uploads()->insert($files);

            DB::commit();

            return response([
                'user' => $user,
                'task' => $task,
                'files' => $files
            ], 201);

        } catch (\Exception $exception) {
            DB::rollBack();
            Log::error($exception->getMessage());
            return response([
                'error' => $exception->getMessage()
            ], 500);
        }

    }

    protected function createUserFromRequest(Request $request): User
    {
        $user = User::firstOrCreate(['email' =>  $request->email], [
                    'name' => $request->name,
                    'password' => bcrypt($request->password)
                ]);

        if (!$user) {
            throw new \Exception('couldn\'t create or fetch user');
        }

        return $user;
    }

    /**
     * @param Request $request
     */
    protected function getFilesData(Request $request)
    {
        $files = collect($request->allFiles())->map(function ($file, $key) {
            return [
                'name' => $key,
                'path' => $file->store('photos')
            ];
        })->values()->toArray();

        if (!$files) {
            throw new \Exception('files not uploaded');
        }

        return $files;
    }
}
Activity icon

Replied to Using Traits With Livewire

@Snapey what you think :)

Jan
11
4 days ago
Activity icon

Replied to Security Concern About Livewire Render Method

what you mean full-page component? you mean your route in web.php refer to the component directly?

Activity icon

Started a new Conversation Using Traits With Livewire

I'm building livewire components that shares 50% of public properties and almost 90% of submit function logic.

each component using this trait has its own rules according to its html-form fields. and also each component perform some custom logic after validating the data. other that that they are all the same.

<?php

namespace App\Traits;

trait ParentServiceComponent
{

    public $desc = '';

    public function rules()
    {
        return [
            'desc' => 'required|max:2000'
        ];
    }

   public abstract function componentCustomLogic(array $data);

    public function submit()
    {
        $data = $this->validate();
        
        $performCusomLogic = $this->componentCustomLogic($data);
        
        // save to db and show success message
    }	
}

here an example of two components that uses this trait.

<?php

namespace App\Http\Livewire;

use Livewire\Component;

use App\Traits\ParentServiceComponent;

class RequestService extends Component
{

    public $type = '';

    use ParentServiceComponent { rules as traitRules; }

    public function rules()
    {
        return array_merge($this->traitRules, [
            'type' => 'required|max:200'
        ]);
    }

    public function componentCustomLogic(array $data)
    {
        // do the logic of this component here
    }

    public function render()
    {
        return view('livewire.request-service');
    }
}
<?php

namespace App\Http\Livewire;

use Livewire\Component;

use App\Traits\ParentServiceComponent;

class ReplyService extends Component
{

    public $body = '';

    use ParentServiceComponent { rules as traitRules; }

    public function rules()
    {
        return array_merge($this->traitRules, [
            'body' => 'required|max:200'
        ]);
    }

    public function componentCustomLogic(array $data)
    {
        // do the logic of this component here
    }

    public function render()
    {
        return view('livewire.reply-service');
    }
}

so my question is: am I doing it right?

Activity icon

Replied to Help Refactoring Monstrous Code

I get it. but at the end if I use form request the form-request controller will end up almost as same as this.

what I really did is I split the controller into many protected methods as @martinbean described. and then created service controller for each related-steps and then moved logic there.

Jan
08
1 week ago
Activity icon

Replied to Help Refactoring Monstrous Code

this series was very useful. I found this https://laracasts.com/series/whip-monstrous-code-into-shape/episodes/2 and was more suitable to my situation. thanx.

Activity icon

Replied to Help Refactoring Monstrous Code

isn't form request for validation/authorization only? I'm talking about dividing multi-step/task control action into separate class for each step/task.

Activity icon

Started a new Conversation Help Refactoring Monstrous Code

Seniors:

I have a controller method that has some complexity and it's doing several tasks at once:

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

class RegisterationController extends Controller
{
    public function store(Request $request)
    {
        // 1. check request for user unique identifier. then firstOrCreate this user then pass output to next step
        // 2. take the user and create new (requests) relationship record and pass that to the next step
        // 3. take the relationship record and create 2 (details records) relationships for that and pass the original record to next step
        // 4. run database procedure and take result to update the relationship record 
        // 4. if all of above went well, upload some attachment and add record to attachment table 
    }
}

the current code is working fine. I wrote everything on the store method with help of private functions but I don't like it and I think it's not maintainable and not really OOP.

I'm thinking about using Laravel *** Pipeline *** class and create didecated class for each step but I'm not sure if it's the right thing.

Also I can use Repository pattern but also I don't think it's very useful here.

any tips???

Jan
06
1 week ago
Activity icon

Started a new Conversation Livewire Component Class As Typical Laravel Controller

can I consider Livewire component class like a typical Laravel controller and do what I want inside it. I know technically I can but I'm asking generally here. Like for example can I dispatch a job? can I write more complex login inside it.

Activity icon

Replied to Livewire: Submit Uploaded File To Another Server

your answer is working if I add this before pass it to to file facade

$tempFile->path();
Activity icon

Replied to Livewire: Submit Uploaded File To Another Server

I did this instead. what you think?

$name = File::get(storage_path("app/livewire-tmp/".$this->attach->getFilename()));
Activity icon

Replied to File Upload Refactoring

I didn't understand why you don't like looping, but I guess your solution is solid if we exclude looping.

I will make a dedicated function for each potential uploaded file and check inside if it's exists then upload. is that what you mean?

Activity icon

Replied to File Upload Refactoring

what if I did:

protected $attachs = ['upload', 'attachment', 'another'];

if($request->hasFile($attachs)) {
	foreach($attachs as $attach) {
		if($request->hasFile($attach)) {
			//upload file
		}
	}
}

Activity icon

Replied to File Upload Refactoring

this route receives requests from multiple forms. some send "attachment" some send "upload" some send them both some send more than these two. I want the uploading to be dynamic.

Activity icon

Started a new Conversation File Upload Refactoring

Hey seniors:

How to refactor the following code, I mean the if-statement part

    if ($photo = $request->file('attachment')) {
       $photo->storeAs('photos', 'avatar' . time() . '.' . $photo->extension());
    }	

    if ($photo2 = $request->file('upload')) {
        $photo2->storeAs('photos', 'uploads' . time() . '.' . $photo2->extension());
    }
Jan
05
1 week ago
Activity icon

Started a new Conversation Livewire: Submit Uploaded File To Another Server

Hello,

I have a livewire component that uses WithFileUploads trait. I want when the user submit the upload I resend this uploaded file to API endpoint.

<div class="container mt-5">
    <div class="row justify-content-center mt-5">
        <div class="col-8 mt-4">
            <form wire:submit.prevent="upload">
                <div class="form-group">
                    <label for="uploaded-file">Choose</label>
                    <input type="file" wire:model="attach" class="form-control">
                </div>
                <br />
                <br />
                <div class="form-group">
                    <button class="btn btn-primary btn-sm btn-block">Upload</button>
                </div>
            </form>
        </div>
    </div>
</div>
<?php

namespace App\Http\Livewire;

use Illuminate\Support\Facades\Http;
use Livewire\Component;
use Livewire\WithFileUploads;

class RequestService extends Component
{

    use WithFileUploads;

    public $attach;

    private $serviceUrl = "http://multistep-form-livewire.test/api/";

    public function upload()
    {
        $this->validate([
            'attach' => 'max:2000'
        ]);

	// here i put static tmp name but how to get it dynamically 

        $name = File::get(storage_path('app/livewire-tmp/XHsQgMvQEcGz17BOOad1TrTjGhLhJ0-metaU2NyZWVuc2hvdCAyMDIwLTEyLTAyIDE4Mjg1OS5qcGc=-.jpg'));

        $url = $this->serviceUrl . "upload-external-file";

        $response = Http::attach('attachment', $name, "testname")
                    ->post($url, [
                        'name' => 'Sara',
                        'role' => 'Privacy Consultant',
                    ]);


        dd($response->status());
    }

    public function render()
    {
        return view('livewire.request-service');
    }
}

what I want is to get the actual file from livewire temporary directory and send it to the API endpoint.

Activity icon

Replied to Send A Post Request From Laravel Site To Another Laravel Site

yes. but now I want to implement some protection to my site. knowing I don't have users. I just want to check if the coming request is really sent by my second site and not from somewhere else. do you suggest something?

Activity icon

Replied to Send A Post Request From Laravel Site To Another Laravel Site

Ok, I will go with the API option. but as you mentioned I must implement token mechanism to protect my site. do you suggest anything? or it's as simple as just sending static long-length string and check it on the other side

Activity icon

Started a new Conversation Send A Post Request From Laravel Site To Another Laravel Site

I want to send a POST request from one site to another knowing they both Laravel. but the csrf_token middleware won't let me.

How to turn it of for specific route and it is safe to do that?

Jan
03
1 week ago
Activity icon

Replied to Livewire Listen For Every Coming Response From The Component Class

I'm aware of wire:ignore. I noticed that even when I use it and I submit the form when I don't change dropdown the (name is required) error shows but I lose select2 functionality. but if I select anything then return back to empty option and click submit the error of required shows but the component does not re-render.

<div x-data="{ }" x-init="() => {
        $('.select2').select2();

        $('#dropdown-tecks').change(e => {

            const val = e.target.value;

            console.log(val);

            $wire.set('name', val);

            Livewire.hook('message.processed', (m, component) => {
                $('.select2').select2();
            })
        })
    }" class="row mt-5">
    <form wire:submit.prevent="send">
        @error('name') <span class="error">{{ $message }}</span> @enderror
        <div wire:ignore class="col-12">
            <p><strong>{{ $name }}</strong></p>
            <br />
            <select wire:model="name" id="dropdown-tecks" class="form-control select2">
                <option value="">-----select-----</option>
                @foreach($names as $name)
                    <option value="{{ $name }}">{{ $name }}</option>
                @endforeach
                    <option value="we">We</option>
            </select>
            @error('name') <span class="error">{{ $message }}</span> @enderror
        </div>
        <div class="mt-4 col-12">
            <button type="submit" class="btn btn-success">
                Submit
            </button>
        </div>
    </form>
</div>
======================================
<?php

namespace App\Http\Livewire;

use Illuminate\Validation\Rule;
use Livewire\Component;

class Dropdown extends Component
{

    public $name = "";

    public $names;

    protected $rules = [];

    protected function rules()
    {
        return [
            'name' => [
                'required',
                'max:2',
                Rule::in($this->tachs)
            ],
        ];
    }

    protected $tachs = [
        'Laravel', 'Livewire', 'Inertia', 'Jetstream', 'Fortify', 'Sanctum', 'we'
    ];

    public function mount()
    {
        $this->fill([
            'names' => $this->tachs
        ]);
    }

    public function updated($propertyName)
    {
        $this->validateOnly($propertyName);
    }

    public function send()
    {
        $this->validate();

        dd($this->name);
    }

    public function render()
    {
        return view('livewire.dropdown');
    }
}

Dec
31
2 weeks ago
Activity icon

Started a new Conversation Livewire Listen For Every Coming Response From The Component Class

Hello friend

I'm building a component and I'm using Select2 in my dropdown. here is my view:

<div x-data="{ }" x-init="() => {
        $('.select2').select2();
        $('.select2').change(e => {
            $wire.set('name', e.target.value);

            Livewire.hook('message.processed', (m, component) => {
                $('.select2').select2();
            })

        })
    }" class="row mt-5">
    <form wire:submit.prevent="send">
        <div class="col-12">
            <p><strong>{{ $name }}</strong></p>
            <br />
            <select wire:model="name" class="form-control select2">
                <option value="">-----select-----</option>
                @foreach($names as $name)
                    <option value="{{ $name }}">{{ $name }}</option>
                @endforeach
            </select>
            @error('name') <span class="error">{{ $message }}</span> @enderror
        </div>
        <div class="mt-4 col-12">
            <button type="submit" class="btn btn-success">
                Submit
            </button>
        </div>
    </form>
</div>

in my alpine code I use "message.processed" hook to reapply Select2 functionality otherwise the component re-render will mess it up. now there is a case if submit the form first thing when page loads and component class responses with validation error in this case this hook never happens and I lose Select2 functionality. what can I do in my javascript side to listen to every response from component class to reapply my select2 coz I didn't find in docs.

Dec
29
2 weeks ago
Activity icon

Awarded Best Reply on Livewire Emitting Event From Child To Parent In Nested Components

found the issue

I was setting the key inside show component call

<livewire:contact.show :contacts="$contacts" :key="$contact->id" />

and not in the foreach loop

@foreach($contacts as $contact)
       <livewire:contact.single-contact :contact="$contact" />
@endforeach

so I put it in the right place and everything working like a charm now:

 <livewire:contact.single-contact :contact="$contact" :key="$contact->id" />
Activity icon

Replied to Livewire Emitting Event From Child To Parent In Nested Components

found the issue

I was setting the key inside show component call

<livewire:contact.show :contacts="$contacts" :key="$contact->id" />

and not in the foreach loop

@foreach($contacts as $contact)
       <livewire:contact.single-contact :contact="$contact" />
@endforeach

so I put it in the right place and everything working like a charm now:

 <livewire:contact.single-contact :contact="$contact" :key="$contact->id" />
Activity icon

Replied to Single Method Instead Of Multiple Boot Methods For Each Model

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class CustomModel extends Model
{
    protected static function boot()
    {
        static::creating(function($model){
            $model->fill([
                'created_by' => auth()->user()->id,
                'updated_by' => auth()->user()->id
            ]);
        });

        static::updating(function($model){
            $model->fill([
                'updated_by' => auth()->user()->id
            ]);
        });
    }
}

Then in any given model that you want to use this functionality, just do this:

use App\Models\CustomModel;

class Contact extends CustomModel
{

}

Activity icon

Started a new Conversation Livewire Emitting Event From Child To Parent In Nested Components

I have a parent component called Show

<?php

namespace App\Http\Livewire\Contact;

use Illuminate\Database\Eloquent\Collection;
use Livewire\Component;

class Show extends Component
{
    public $contacts;

    public $count = 0;

    protected $listeners = [
        'contactEdited' => 'contactEdited'
    ];

    public function contactEdited($contactId)
    {
        session()->flash('message', 'Contact #'.$contactId.' successfully updated.');
        $this->count++;
    }

    public function mount(Collection $contacts)
    {
        $this->contacts = $contacts;
    }

    public function render()
    {
        return view('livewire.contact.show');
    }
}

and this is it's view

<div>
    <div class="mb-5">
        @if (session()->has('message'))
            <div class="alert alert-success">
                {{ session('message') }}
            </div>
        @endif
    </div>

    <div class="mb-5">
        @if($count)
            <span class="font-bolder">
                {{ $count }}
            </span>
        @endif
    </div>

    <table class="table table-stripped">
        <tr>
            <th>Name</th>
            <th>Email</th>
            <th>Create date</th>
            <th>Actions</th>
        </tr>
        @foreach($contacts as $contact)
            <livewire:contact.single-contact :contact="$contact" />
        @endforeach
    </table>
</div>

now this is single-contact component

<?php

namespace App\Http\Livewire\Contact;

use App\Models\Contact;
use Illuminate\Validation\Rule;
use Livewire\Component;

class SingleContact extends Component
{
    public $contact;

    public $name;

    public $email;

    public $editMode = false;

    public function mount(Contact $contact)
    {
        $this->contact = $contact;
        $this->name = $contact->name;
        $this->email = $contact->email;
    }

    public function update()
    {
        $this->validate([
            'name' => [
                'required',
                'max:20'
            ],
            'email' => [
                'required',
                Rule::unique('contacts')->ignore($this->contact->id)
            ]
        ]);

        $this->contact->update([
            'name' => $this->name,
            'email' => $this->email
        ]);

        $this->contact->fresh();

        $this->editMode = false;

        $this->emit('contactEdited', $this->contact->id);
    }

    public function render()
    {
        return view('livewire.contact.single-contact');
    }
}

and here's the view for single-component

@if($editMode === false)
    <tr>
        <td>{{ $contact->name }}</td>
        <td>{{ $contact->email }}</td>
        <td>{{ $contact->created_at->format('Y-M') }}</td>
        <td>
            <button class="btn btn-sm btn-success" wire:click="$set('editMode', true)" type="button">Edit</button>
            <button class="btn btn-sm btn-danger" type="button">Delete</button>
        </td>
    </tr>
@else
    <tr :key="{{ $contact->id }}">
        <td>
            <input type="text" class="form-control" wire:model="name">
            @error('name')<span class="text-danger font-bolder">{{ $message }}</span>@enderror
        </td>
        <td>
            <input type="text" class="form-control" wire:model="email">
            @error('email')<span class="text-danger font-bolder">{{ $message }}</span>@enderror
        </td>
        <td>{{ $contact->created_at->format('Y-M') }}</td>
        <td>
            <button id="nah-{{ $contact->id }}" class="btn btn-sm btn-danger" type="button" wire:click="$set('editMode', false)">
                nah
            </button>
            <button id="update-{{ $contact->id }}" class="btn btn-sm btn-success" type="button" wire:click="update">update</button>
        </td>
    </tr>
@endif

the problem is when emitting contactEdited event from any child component the flash message shows only at the first time and the counter variable stops at 1. even if I fired the event from the console using:

livewire.emit('contactEdited', 4);
livewire.emit('contactEdited', 3);

it happens only at the first time.

Activity icon

Replied to Does Laravel Default Session Name So Imortant?

the answer I was looking for, thank you.

Activity icon

Replied to HasOne Relationship With Condition

No, have you tried it?

	public function substitutionEmployee()
	{
		//$this->start_date at this point is equal to null.
		$this->hasOne(Vacation::class, 'emp_id', 'emp_id')
                      ->where('start_date', $this->start_date);
	}
Activity icon

Replied to HasOne Relationship With Condition

what if the (start_date , end_date ) are field in Task model. will not work if I do:

	$this->hasOne(Model::lcass)->where('start_date', $this->start_date);
Activity icon

Started a new Conversation HasOne Relationship With Condition

Hello, I have a relationship between two models:

Task: id, start_date, end_date, emp_id

Vacation: id, start_date, end_date, emp_id, substitution_emp

	//in Task model i want:
	public function substitutionEmployee()
	{
		$this->hasOne(Vacation::class, 'emp_id', 'emp_id');
	}
	//but alson where start_date=start_date and end_date=end_date to get exact substitution_emp
Dec
27
2 weeks ago
Activity icon

Started a new Conversation Does Laravel Default Session Name So Imortant?

Hello,

when a user login Laravel sets a cookie name as the following:

env('APP_NAME') . "_session";

But I have seen some people make it complicated and generate like big string for session name.

Does this really matter?

Dec
22
3 weeks ago
Activity icon

Replied to Authenticate Different Frontend With Sanctum

first off, thank you so much for your reply.

Ok let's say I used default authentication for my web app and then use sanctum to authenticate my mobile app.

now what about the endpoints that both web and mobile shares. they will be using the same endpoints. how I manage that. since I want them both to consume API routes and not having endpoints for each in (web/API).

Dec
21
3 weeks ago
Activity icon

Started a new Conversation Authenticate Different Frontend With Sanctum

Hello everybody,

I want to build a Laravel website that shares almost everything with a React-Native mobile application like authentication. and I want to use Laravel sanctum for this process but then in the docs I found three type of auth that sanctum provides:

SPA Authentication

API Token Authentication

Mobile Application Authentication

I know if I build a Vue client for web I can use (API Token Authentication) to authenticate both with the same approch. but I want a Laravel app for web so what is the best choice for me.

Nov
12
2 months ago
Activity icon

Replied to Livewire Weird Behavior When Toggling Public Property From Blade

It worked!

but what is the best solution of these two:

1- like this by passing just the object prop and call the method from the instance.

    public $object;


    public function mount($object)
    {
        $this->object = $object;
    }

2- or pass it as you mentioned in render method

public function render()
 {
        return view('livewire.file-browser', [
            'ancestors' => $this->object->ancestors()
        ]);
  }

OR it doesn't matter?

Activity icon

Replied to Livewire Weird Behavior When Toggling Public Property From Blade

it's a function in Obj model

public function ancestors()
{
        $ancestor = $this;

        $ancestors = collect();

        while ($ancestor->parent) {
            $ancestor = $ancestor->parent;
            $ancestors->push($ancestor);
        }

        $ancestors->push($this);

	return $ancestors->sortBy('id');

}

hrer's parent relation function

public function parent()
{
        return $this->belongsTo(self::class, 'parent_id', 'id');
}
Nov
11
2 months ago
Activity icon

Started a new Conversation Livewire Weird Behavior When Toggling Public Property From Blade

Hello there everybody, this is my first livewire application and I'm facing this weird issue with it.

basically, I have a component that I pass two args for it

public function index(Request $request)
    {
        $rootObj = optional(Obj::root()->forCurrentTeam()->first())->uuid;

        $object = Obj::forCurrentTeam()
                    ->where('uuid', $request->get('uuid', $rootObj))
                    ->with(['children.objectable'])
                    ->firstOrFail();

        return view('files.index', [
            'object' => $object,
            'ancestors' => $object->ancestors()
        ]);
    }

and here's my "files.index" blade file:

<div class="py-12">
        <div class="max-w-7xl mx-auto sm:px-6 lg:px-8">
            <livewire:file-browser :object="$object" :ancestors="$ancestors" />
        </div>
 </div>

here's my file-browser component class:

<?php

namespace App\Http\Livewire;

use Livewire\Component;

class FileBrowser extends Component
{

    public $object;

    public $ancestors;

    public $creatingNewFolder = false;

    public function createFolder()
    {
        dd('add');
    }

    public function render()
    {
        return view('livewire.file-browser');
    }
}

file-browser component blade file

<div class="py-12">
    <div class="max-w-7xl mx-auto sm:px-6 lg:px-8">
        <div class="bg-white overflow-hidden shadow-xl sm:rounded-lg p-6">
            <div>
                <div class="flex flex-wrap items-center justify-between mb-4">
                    <div class="flex-grow mr-0 mt-4 md:mt-2 w-full md:w=auto order-3 md-order-1">
                        <input type="search" placeholder="Search files and folders" class="w-full px-3 h-12 border-2 rounded-lg outline-none">
                    </div>
                    <div class="order-2">
                        <div>
                            <button wire:click="$set('creatingNewFolder', true)" class="bg-gray-200 px-6 h-12 rounded-lg mr-2">
                                New folder
                            </button>
                            <button class="bg-blue-600 text-white px-6 h-12 rounded-lg mr-2 font-bold">
                                Upload files
                            </button>
                        </div>
                    </div>
                </div>
                <div class="border-2 border-gray-200 rounded-lg">
                    <div class="py-2 px-3">
                        <div class="flex items-center">
                            @foreach($ancestors as $ancestor)
                                <a href="{{ route('files', ['uuid' => $ancestor->uuid]) }}" class="font-bold text-gray-400">
                                    {{ $ancestor->objectable->name }}
                                </a>
                                @if(!$loop->last)
                                    <svg class="mx-1 w-5 h-5 text-gray-300" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor">
                                        <path fill-rule="evenodd" d="M7.293 14.707a1 1 0 010-1.414L10.586 10 7.293 6.707a1 1 0 011.414-1.414l4 4a1 1 0 010 1.414l-4 4a1 1 0 01-1.414 0z" clip-rule="evenodd" />
                                    </svg>
                                @endif
                            @endforeach
                        </div>
                    </div>
                    <div class="overflow-auto">
                        <table class="w-full">
                            <thead class="bg-gray-100">
                                <tr>
                                    <th class="text-left py-2 px-3">Name</th>
                                    <th class="text-left py-2 px-3 w-2/12">Size</th>
                                    <th class="text-left py-2 px-3 w-3/12">Created</th>
                                    <th class="p-2 w-2/12"></th>
                                </tr>
                            </thead>
                            <tbody>

                                @if($creatingNewFolder)
                                    <tr class="border-b-2 border-gray-100 hover:bg-gray-100">
                                        <td class="py-2 px-1">
                                            <form wire:submit.prevent="createFolder" class="w-full flex items-center ">
                                                <input type="search" placeholder="Enter folder name" class="w-full px-3 h-10 border-2 rounded-lg outline-none mr-2">
                                                <button type="submit" class="bg-blue-600 text-white px-3 h-9 rounded-lg mr-2 font-bold">
                                                    Make
                                                </button>
                                                <button type="button" wire:click="$toggle('creatingNewFolder')" class="bg-gray-200 px-3 h-9 rounded-lg mr-2">
                                                    Forget
                                                </button>
                                            </form>
                                        </td>
                                        <td></td>
                                        <td></td>
                                        <td></td>
                                    </tr>
                                @endif

                                @forelse($object->children as $child)
                                    <tr class="@if(!$loop->last) border-b-2 border-gray-100 @endif hover:bg-gray-100">
                                        <td class="flex items-center py-2 px-3">
                                            @if($child->isFile())
                                                <svg xmlns="http://www.w3.org/2000/svg" class="w-6 h-6 text-blue-700" fill="none" viewBox="0 0 24 24" stroke="currentColor">
                                                    <path d="M7 21h10a2 2 0 002-2V9.414a1 1 0 00-.293-.707l-5.414-5.414A1 1 0 0012.586 3H7a2 2 0 00-2 2v14a2 2 0 002 2z" />
                                                </svg>
                                                <a href="#" class="p-2 font-bold text-blue-700 flex-grow">
                                                    {{ $child->objectable->name }}
                                                </a>
                                            @endif
                                            @if($child->isFolder())
                                                <svg xmlns="http://www.w3.org/2000/svg" class="w-6 h-6 text-blue-700" viewBox="0 0 20 20" fill="none" stroke="currentColor">
                                                    <path d="M2 6a2 2 0 012-2h5l2 2h5a2 2 0 012 2v6a2 2 0 01-2 2H4a2 2 0 01-2-2V6z" />
                                                </svg>
                                                <a href="{{ route('files', ['uuid' => $child->uuid]) }}" class="p-2 font-bold text-blue-700 flex-grow">
                                                    {{ $child->objectable->name }}
                                                </a>
                                            @endif
                                        </td>
                                        <td class="py-2 px-3">
                                            @if($child->isFile())
                                                {{ $child->objectable->size }}
                                            @else
                                                &mdash;
                                            @endif
                                        </td>
                                        <td class="py-2 px-3">
                                            {{ $child->created_at }}
                                        </td>
                                        <td class="py-2 px-3">
                                            <div class="flex items-center justify-end">
                                                <ul class="flex items-center">
                                                    <li class="mr-2">
                                                        <button class="text-gray-400 font-bold">Rename</button>
                                                    </li>
                                                    <li class="mr-2">
                                                        <button class="text-red-400 font-bold">Delete</button>
                                                    </li>
                                                </ul>
                                            </div>
                                        </td>
                                    </tr>
                                @empty
                                    <tr class="border-b-2 border-gray-100 hover:bg-gray-100">
                                        <td colspan="4" class="py-2 px-3">
                                            this folder is empty
                                        </td>
                                    </tr>
                                @endforelse
                            </tbody>
                        </table>
                    </div>
                </div>
            </div>
        </div>
    </div>
</div>

then in file-browser component blade file, when I try to click "New Folder" button to toggle $creatingNewFolder property I get this error in the foreach of ancestors foreach loop:

Trying to get property 'uuid' of non-object (View: C:\laragon\www\larawire\resources\views\livewire\file-browser.blade.php)

what am I missing here?

Oct
16
2 months ago
Activity icon

Replied to Laravel Group By Clause

why did you check if hour >= 3pm ?

Oct
15
3 months ago
Activity icon

Started a new Conversation Laravel Group By Clause

I have a very hard situation and I been trying to find a solution either with query builder or eloquent but had no luck for days.

I have a database table/eloquent model "Attendance" with the following fields:

id, employee_id, timesheet_id, attendance_time 'datetime'

this table represents fingerprint log for every employee in particular branch.

timesheet_id: represents employee work shift during the day and I have two of those:

  1. from 6 am to 3 pm
  2. from 3 pm to 12 am next day "which causing the problem"

now I want to make a monthly report that grab all data in this table in particular period of time let say from 01-09-2020 to 30-09-2020 which is very easy for employees whom in work shift one, but for those who work in shift two it's kinda hard because when grouping records by date - they logout record which more likely would be in the next day - will not be grouped with that date if it makes sense.

let's take employee #3 records at 26-09-2020 for example:

(a) 2020-09-25 15:02:06 (b) 2020-09-26 00:19:21 (c) 2020-09-26 14:52:48 (d) 2020-09-27 05:29:55

see the (b) record is a logout record of day 2020-09-25 and not login record of 2020-09-26, which means if this employee had only one record in the day I must check the time if it's less than or equal to 6 am it means it's logout record for previous day otherwise it's login record for this day.

what I tried is I grab all records from 01-09-2020 00:00:00 to 01-10-2020 06:00:00 so I can catch logout for 30-09 and then I group by attendance_time but how do I check that employee has logout record in the next day when grouping by date.

$start = "2020/09/01 00:00:00";
$end = "2020/10/01 06:00:00";
$branch_id = 1;
$timesheet = 2; // employees who work from 3pm to 00 am

$attendances = Attendance::oldest()
                ->where([
                    'timesheet_id' => $timesheet
                ])
                ->whereHas('employee', function ($q) use ($branch_id) {
                    $q->where('branch_id', $branch_id);
                })
                ->whereBetween('attendance_time', [$start, $end])
                ->where('employee_id', 3)
                ->get(['employee_id', 'attendance_time']);

$monthly = $attendances->groupBy(function ($item) {
               return $item->attendance_time->toDateString();
            });

I know it's complicated, if anyone can help I would appreciate that so much.

Oct
14
3 months ago
Activity icon

Replied to Improve My Laravel App Regarding N+1 Problem

yes, here's the whole business in this function

public function getDateDetails($employee, $date)
    {        

	// here I run another sql query in {isAbsentAt} function
        $employee['absent'] = !($employee->isAbsentAt($date));

        if ($employee['absent']) {
            return $employee;
        }

	// here I get all records in time ranges for this employee in specific date and determine login and logout records

        // I calculate login from 00 am to 11 am for timesheet 1
       // and from 6:01 am to 6 pm for timesheet 2 
 
	$start = Carbon::parse($date);
        $end = Carbon::parse($date)->addHours(11);

        if((int) $employee->timesheet === 2) {
            $start = Carbon::parse($date)->addHours(6)->addMinutes(1);
            $end = Carbon::parse($date)->addHours(18);
        }

       //here I use builder not collection relation to be able to use builder functions
	// i think if i use it as collection like this {$employee->attendances} would solve the issue

	$attendance = $employee->attendances()
                            ->where(function($q) use ($start, $end) {
                                $q->where('attendance_time', '>=' , $start)
                                ->where('attendance_time', '<=', $end);
                            })
                            ->orderBy('attendance_time');

        $loginRecords = $attendance->get();

        if ($loginCount = $loginRecords->count()) {
            $employee['in_time'] = $loginRecords->first()->attendance_time->format('H:i');
            $employee['login_late'] = $loginRecords->first()->loginLate();
        }


        if ($employee['in_time'] === null) {
            $employee['absent'] = true;
        }

        return $employee;
    }