Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

unhingedmonkey's avatar

New to Laravel, am I approaching this controller correctly

Hi,

I am creating a simple app that lets you add/edit contacts, and apply notes to those contacts. Its using Livewire and editing is done within Modals.

I've got the logic working but wanted to sense check that I'm doing things correctly.

I've got a EditContact controller. Within this I'm performing all actions that are occuring when interacting with the Edit Contat modal. E.g. updating details. I'm also handling interacting with the Notes model in the same Controller. See code below.

My questions are: firstly should notes by handled within this same controller, or should they be moved elsewhere somehow?

Are they any other glaring things I could do to simplify the below code?

Thanks!

namespace App\Livewire;

use LivewireUI\Modal\ModalComponent;
use WireUi\Traits\Actions;

use App\Models\Contact;
use App\Models\Note;
use Auth;
use Illuminate\Support\Str;

class EditContact extends ModalComponent
{
    use Actions;

    public $editing = false;
    public $editingNotesIndex = null;

    public $contact;
    public $notes;
    public $title,$first_name, $last_name, $middle_name, $suffix,$known_as;
    public $sex,$pronouns,$formal;

    public $phone_mobile,$phone_other,$phone_landline,$phone_preference;
    public $email,$email_work,$email_other,$email_preference;
    public $dob,$dod;

    public $note_type,$note_title,$note_note;

    private $note_fields = ['note_type','note_title','note_note'];

    //Used to make the notifications prettier
    private $field_nicenames = ['first_name'     => 'given_name',
                                'last_name'      => 'family_name',
                                'dod'            => 'date_of_death',
                                'dob'            => 'date_of_birth',
                                'phone_mobile'   => 'mobile',
                                'phone_landline' => 'landline',
                                'phone_other'    => 'other_phone',
                                'email_work'     => 'work_email',
                                'email_other'    => 'other_email',
                                'formal'         => 'formality'];

    protected $listeners = ['noteAdded'     => 'addNoteListener',
                            'noteRemoved'   => 'removedNoteListener'];

    public function mount($id = 0) {

        if ($id > 0) {
            $this->contact = Contact::where('id', $id)->first();

            $this->title = $this->contact->title;
            $this->first_name = $this->contact->first_name;
            $this->middle_name = $this->contact->middle_name;
            $this->last_name = $this->contact->last_name;
            $this->suffix = $this->contact->suffix;
            $this->known_as = $this->contact->known_as;
            $this->sex = $this->contact->sex;
            $this->pronouns = $this->contact->pronouns;
            $this->formal = $this->contact->formal;
            $this->phone_mobile = $this->contact->phone_mobile;
            $this->phone_landline = $this->contact->phone_landline;
            $this->phone_other = $this->contact->phone_other;

            $this->phone_preference = $this->contact->phone_preference;
            $this->email = $this->contact->email;
            $this->email_work = $this->contact->email_work;
            $this->email_other = $this->contact->email_other;
            $this->email_preference = $this->contact->email_preference;
            $this->dob = $this->contact->dob;
            $this->dod = $this->contact->dod;
            $this->editing = true;

            $this->notes = $this->contact->notes->sortByDesc('created_at');

        } else {
            $this->contact = new Contact();
            $this->setDefaultValues();
        }

    }

    //Sets the default values for a contact
    private function setDefaultValues() {
        $this->title = 'Mr';
        $this->sex = 'M';
        $this->pronouns = 'Default';
        $this->phone_preference = 'No';
        $this->email_preference = 'No';
        $this->formal = 1;
    }

    public static function modalMaxWidth(): string
    {
        return '6xl';
    }

    /**
     * Inline updating of contact fields (not notes).
     * @param $name
     * @param $value
     * @return void
     * @throws \Illuminate\Validation\ValidationException
     */
    public function updated($name, $value)
    {

        if (!in_array($name,$this->note_fields) && !Str::contains($name,'notes')) {

            $this->validateOnly($name);

            $this->contact->update([$name => $value]);

            if ($this->editing) {
                $this->updateNotifications($name);
            }

        }
    }


    private function updateNotifications($field) {
        $this->notification()->success('Field updated',$this->formatFieldName($field) . ' successfully updated');
    }

    /**
     * Formats the name of a field nicely.
     * @param $name
     * @return string
     */
    private function formatFieldName($name) {

        if (array_key_exists($name,$this->field_nicenames))
            $name = $this->field_nicenames[$name];

        $name = str_replace('_',' ',$name);
        $name = ucfirst($name);

        return $name;
    }

    public function render()
    {
        return view('livewire.contacts.edit-contact',['notes' => $this->notes]);
    }



    public function saveContact() {

        $this->validate();

        $this->contact->title               = $this->title;
        $this->contact->first_name          = $this->first_name;
        $this->contact->middle_name         = $this->middle_name;
        $this->contact->last_name           = $this->last_name;
        $this->contact->suffix              = $this->suffix;
        $this->contact->known_as            = $this->known_as;
        $this->contact->sex                 = $this->sex;
        $this->contact->pronouns            = $this->pronouns;
        $this->contact->formal              = $this->formal;
        $this->contact->phone_mobile        = $this->phone_mobile;
        $this->contact->phone_other         = $this->phone_other;
        $this->contact->phone_landline      = $this->phone_landline;
        $this->contact->phone_preference    = $this->phone_preference;
        $this->contact->email               = $this->email;
        $this->contact->email_work          = $this->email_work;
        $this->contact->email_other         = $this->email_other;
        $this->contact->email_preference    = $this->email_preference;
        $this->contact->dob                 = $this->dob;
        $this->contact->dod                 = $this->dod;

        $this->contact->save();

        //Emit a notification and let powergrid know to refresh the table
        $this->notification()->success('Contact successfully created');
        $this->closeModalWithEvents([
            ContactTable::class => 'pg:eventRefresh-default',
        ]);

    }

    protected function rules()
    {
        return [
            'first_name'    => 'required|min:3',
            'last_name'     => 'required|min:3',
            'email'         => 'email|nullable',
            'email_work'    => 'email|nullable',
            'email_other'   => 'email|nullable',

            'notes.*.type' => 'required',
            'notes.*.title' => 'required',
            'notes.*.note'  => 'required',
        ];

    }

    /**
     * Adds a new note to a contact.
     * @return void
     */
    public function addNote()
    {
        $this->validate([
            'note_type'  => 'required',
            'note_title' => 'required|min:3'
        ]);


        $this->note = new \App\Models\Note();
        $this->note->title      = $this->note_title;
        $this->note->user_id    = Auth::user()->id;
        $this->note->contact_id = $this->contact->id;
        $this->note->type      = $this->note_type;
        $this->note->note      = $this->note_note;
        $this->note->save();

        $this->dispatch('noteAdded');

        //Emit a notification and let powergrid know to refresh the table
        $this->notification()->success('Note successfully added.');
    }

    /**
     * Listens for a new note being added.
     * @return void
     */
    public function addNoteListener() {

        $this->notes = $this->contact->notes->sortByDesc('created_at');
    }

    public function removedNoteListener() {

    }

    /**
     * Deletes a note
     * @param $note_id
     * @return void
     */
    public function deleteNote($note_id) {

        $note = Note::where('id', $note_id)->first();
        $note->delete();

        $this->notes = Contact::where('id',$this->contact->id)->first()->notes;

    }

    /**
     * Tell livewire which note we're editing.
     * @param $index
     * @return void
     */
    public function editNote($index) {
        $this->editingNotesIndex = $index;
    }

    /**
     * Called when cancelling inline note editing.
     * @return void
     */
    public function cancelEditNote() {
        $this->editingNotesIndex = null;
    }

    /**
     * Saves an existing note after editing
     * @param $noteIndex
     * @return void
     */
    public function saveNote($noteIndex)
    {
        $this->validate();
        $note = $this->notes[$noteIndex] ?? NULL;

        if (!is_null($note)) {
            $editedNote = Note::find($note['id']);
            if ($editedNote) {
                $editedNote->type = $note['type'];
                $editedNote->title = $note['title'];
                $editedNote->note  = $note['note'];
                $editedNote->save();
            }
        }
        $this->editingNotesIndex = null;
    }
}
0 likes
0 replies

Please or to participate in this conversation.