cuartas15

cuartas15

Member Since 6 Months Ago

Experience Points
920
Total
Experience

4,080 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
0
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.

Level 1
920 XP
May
30
1 day ago
Activity icon

Replied to Adding A Notification Makes A Portion Of Code To Execute Twice In Production

Yes, this is definitely happening in other similar scenarios, the functions are being executed twice and giving the expired token message will definitely mislead the users.

Like I said, this is happening in production exclusively

EDIT: Alright, I'm gonna autorespond myself: This is not a Laravel issue at all, it's a mail provider issue, to be more specific, an outlook issue. I don't know what they did lately but the masked address which contains their safelink protection stuff is apparently causing this issue, it seems like they're artificially visiting the site in the link before letting the real user to be redirected, so the first request is being performed by their measures, and the second one is the real one.

Well.... this is an issue, because copying the link directly in the bar address or even clicking the button from gmail is giving the expected result, I don't know how it goes with Yahoo, AOL or the hundreds of other cosumer and gubernamental mail providers but now this raises the question, what to do in this case where a one time use link is compromised?

Activity icon

Replied to Adding A Notification Makes A Portion Of Code To Execute Twice In Production

ok I feel really stupid, but it seems like the notification is not the issue? I commented that line to revert it while a solution is found and tested again, and again got the same issue. I don't know what could've caused it, but I'll take a hard guess that this probably happened when I upgraded from Laravel 6 to 7

Activity icon

Replied to Adding A Notification Makes A Portion Of Code To Execute Twice In Production

I'm clicking it once, unless the Laravel email template is reporting multiple clicks, which I don't think since it's opening a new tab the moment I press it

Activity icon

Replied to Adding A Notification Makes A Portion Of Code To Execute Twice In Production

I don't change anything based on the environment in this case. I only queue in a cron job which sends multiple emails, the rest are sync

Activity icon

Started a new Conversation Adding A Notification Makes A Portion Of Code To Execute Twice In Production

Basically, if I add a notification to send an email to my code, that code, or rather, the function containing the code will execute twice. I'm getting a link button from another previous email which contains a token and based on that does stuff. The email is a regular Laravel 7.0.x email template

In web.php:

Route::get('finish-review-post/{token}', '[email protected]')->name('review.confirm');

In ProfileController.php:

public function finishReviewConfirm(Request $request, $token = null)
{
    try {
        return DB::transaction(function () use ($request, $token) {
            \Log::info('logging this: token: ' . $token); // Added this to check if it's logged more than once
            $confirmation = ReviewConfirmation::where('token', $token);
            $confirmationData = $confirmation->first();

            if ($confirmationData) {
                Office::find($confirmationData->office_id)->sendReviewNotification($confirmationData->full_name, $confirmationData->gender, $confirmationData->email, $confirmationData->comment); // This is the new line added where I send the notification

                Review::create([
                    'office_id' => $confirmationData->office_id,
                    'full_name' => $confirmationData->full_name,
                    'gender' => $confirmationData->gender,
                    'comment' => $confirmationData->comment,
                    'email' => $confirmationData->email,
                ]);

                $specialistName = Office::find($confirmationData->office_id)->name;
                $link = $confirmationData->link;

                $response = 'La valoración para el especialista ' . $specialistName . ' fue guardada correctamente.';
                $success = true;
                $confirmation->delete();

                return view('finish_review_post', compact('response', 'link', 'success'));
            } else {
                $response = 'El vínculo para confirmar la valoración ya no es válido, regresa al perfil del especialista e inténtalo nuevamente.';
                $success = false;

                return view('finish_review_post', compact('response', 'success'));
            }
        }, 3);
    } catch (\Exception $e) {
        throw new \App\Exceptions\SmeException('Exception: File: ' . $e->getFile() . ', Line: ' . $e->getLine() . ', Message: ' . $e->getMessage());
        $response = 'Ha fallado la operación, inténtalo nuevamente.';
        $success = false;
        return view('finish_review_post', compact('response', 'success'));
    } catch (\Throwable $e) {
        throw new \App\Exceptions\SmeException('Throwable: File: ' . $e->getFile() . ', Line: ' . $e->getLine() . ', Message: ' . $e->getMessage());
        $response = 'Ha fallado la operación, inténtalo nuevamente.';
        $success = false;
        return view('finish_review_post', compact('response', 'success'));
    }
}

In Office.php:

public function sendReviewNotification($name, $gender, $email, $message)
{
    $this->notify(new PerlaReviewMessage($name, $gender, $email, $message, $this->module_title));
}

In PerlaReviewMessage.php:

<?php

namespace App\Notifications;

use App\Office;
use App\Review;
use Illuminate\Bus\Queueable;
use Illuminate\Notifications\Messages\MailMessage;
use Illuminate\Notifications\Notification;
use Illuminate\Support\HtmlString;

class PerlaReviewMessage extends Notification
{
    use Queueable;

    public $name;
    public $gender;
    public $email;
    public $message;
    public $id;
    public $module_title;

    /**
     * Create a new notification instance.
     *
     * @param  string  $name
     * @param  string  $gender
     * @param  string  $email
     * @param  string  $message
     * @param  string  $module_title
     * @return void
     */
    public function __construct($name, $gender, $email, $message, $module_title)
    {
        $this->name = $name;
        $this->gender = $gender;
        $this->email = $email;
        $this->message = $message;
        $this->id = Review::select('id')->where('office_id', Office::where('module_title', $module_title)->first()->id)->orderBy('id', 'desc')->first()->id;
        $this->module_title = $module_title;
    }

    /**
     * Get the notification's delivery channels.
     *
     * @param  mixed  $notifiable
     * @return array
     */
    public function via($notifiable)
    {
        return ['mail'];
    }

    /**
     * Get the mail representation of the notification.
     *
     * @param  mixed  $notifiable
     * @return \Illuminate\Notifications\Messages\MailMessage
     */
    public function toMail($notifiable)
    {
        $htmlString = '<p>Nombre ' . ($this->gender === 'M' ? 'del' : 'de la') . ' paciente: <b>' . $this->name . '</b></p>' .
            '<p>Correo electrónico: <b>' . $this->email . '</b></p>' .
            '<p>Mensaje de valoración: <b>' . $this->message . '</b></p>' .
            '<p>Id de valoración: <b>' . $this->id . '</b></p>';

        return (new MailMessage)
            ->from(config('app.notification_email'), config('app.notification_email_name'))
            ->subject('Su Médico Especialista - Notificación de valoración')
            ->greeting('Estimado usuario')
            ->line('Acabas de recibir una valoración en tu perfil de Su Médico Especialista!')
            ->line(new HtmlString($htmlString))
            ->line('Si consideras que esta valoración es inapropiada, podemos eliminarla de tu perfil, solo tienes que abrir un ticket de soporte desde perla proporcionando el id de la valoración y la razón por la cual consideras que debería ser eliminada.')
            ->line('También puedes visitar tu perfil y revisar todas tus valoraciones haciendo clic en el siguiente botón:')
            ->action('Visita tu perfil', url(config('app.exturllink') . 'p/' . $this->module_title));
    }

    /**
     * Get the array representation of the notification.
     *
     * @param  mixed  $notifiable
     * @return array
     */
    public function toArray($notifiable)
    {
        return [
            //
        ];
    }
}

The issue here is, since this is being executed twice I get redirected to the failed message page which basically says that the token expired (the else portion of the code), but the first execution is taking care of everything and everything is going as expected there, the only thing I need to figure out is why is being executed twice.

if you need the code of the other notification which contains the button with the token let me know, but it's basically a copy-paste of the code above, same structure.

Remember, this is only happening in production, in testing environment it works as intended with only one execution.

Hopefully you can help me out.

Thanks in advance.

Apr
25
1 month ago
Activity icon

Replied to Query Working On Local, Failing On Production

Answering myself. The solution was to avoid doing the union of two variables that are anoter union operation, better to nest them at the end when you're gonna do the actual query.

My final code is this:

if ($request->date === null) {
    $direction[0] = $request->direction ? 'max(date)' : 'min(date)';
    $direction[1] = $request->direction ? 'DESC' : 'ASC';

    $dataRevToday = Revision::select((DB::raw($direction[0] . ' as "date"')))
        ->where('office_id', auth()->user()->office_id)
        ->whereDate('date', '=', Carbon::now()->toDateString())
        ->where('time', '>', Carbon::now()->toTimeString())
        ->where('available', 1)
        ->where('locked', 0)
        ->where('active', 1)
        ->when($request->location_filter !== null, function ($query) use ($request) {
            return $query->where('location_id', $request->location_filter);
        });

    $dataRevAfterToday = Revision::select((DB::raw($direction[0] . ' as "date"')))
        ->where('office_id', auth()->user()->office_id)
        ->whereDate('date', '>', Carbon::now()->toDateString())
        ->where('available', 1)
        ->where('locked', 0)
        ->where('active', 1)
        ->when($request->location_filter !== null, function ($query) use ($request) {
            return $query->where('location_id', $request->location_filter);
        });
    if ($request->entity_filter === null) {
        $dataAppToday = Appointment::select((DB::raw($direction[0] . ' as "date"')))
            ->where('office_id', auth()->user()->office_id)
            ->whereDate('date', '=', Carbon::now()->toDateString())
            ->where('time', '>', Carbon::now()->toTimeString())
            ->where('available', 1)
            ->where('locked', 0)
            ->where('active', 1)
            ->when($request->location_filter !== null, function ($query) use ($request) {
                return $query->where('location_id', $request->location_filter);
            });

        $dataAppAfterToday = Appointment::select((DB::raw($direction[0] . ' as "date"')))
            ->where('office_id', auth()->user()->office_id)
            ->whereDate('date', '>', Carbon::now()->toDateString())
            ->where('available', 1)
            ->where('locked', 0)
            ->where('active', 1)
            ->when($request->location_filter !== null, function ($query) use ($request) {
                return $query->where('location_id', $request->location_filter);
            });
    } else {
        $dataAppToday = Appointment::select((DB::raw($direction[0] . ' as "date"')))
            ->join('appointment_entity', 'appointments.id', '=', 'appointment_entity.appointment_id')
            ->where('office_id', auth()->user()->office_id)
            ->whereDate('date', '=', Carbon::now()->toDateString())
            ->where('time', '>', Carbon::now()->toTimeString())
            ->where('available', 1)
            ->where('locked', 0)
            ->where('active', 1)
            ->where('entity_id', $request->entity_filter)
            ->when($request->location_filter !== null, function ($query) use ($request) {
                return $query->where('location_id', $request->location_filter);
            });

        $dataAppAfterToday = Appointment::select((DB::raw($direction[0] . ' as "date"')))
            ->join('appointment_entity', 'appointments.id', '=', 'appointment_entity.appointment_id')
            ->where('office_id', auth()->user()->office_id)
            ->whereDate('date', '>', Carbon::now()->toDateString())
            ->where('available', 1)
            ->where('locked', 0)
            ->where('active', 1)
            ->where('entity_id', $request->entity_filter)
            ->when($request->location_filter !== null, function ($query) use ($request) {
                return $query->where('location_id', $request->location_filter);
            });
    }

    $data = $dataRevToday->union($dataRevAfterToday)->union($dataAppToday)->union($dataAppAfterToday)
        ->orderByRaw('date ' . $direction[1])
        ->limit(1)
        ->first();
} else {
    $formatDate = Carbon::createFromFormat('Y-m-d', date('Y-m-d', strtotime($request->date)));
    $direction[0] = $request->direction ? '>' : '<';
    $direction[1] = $request->direction ? 'ASC' : 'DESC';

    $dataRevToday = Revision::select('date')
        ->where('office_id', auth()->user()->office_id)
        ->whereDate('date', '=', Carbon::now()->toDateString())
        ->where('time', '>', Carbon::now()->toTimeString())
        ->where('available', 1)
        ->where('locked', 0)
        ->where('active', 1)
        ->when($request->location_filter !== null, function ($query) use ($request) {
            return $query->where('location_id', $request->location_filter);
        });

    $dataRevAfterToday = Revision::select('date')
        ->where('office_id', auth()->user()->office_id)
        ->whereDate('date', '>', Carbon::now()->toDateString())
        ->where('available', 1)
        ->where('locked', 0)
        ->where('active', 1)
        ->whereDate('date', $direction[0], $formatDate->toDateString())
        ->when($request->location_filter !== null, function ($query) use ($request) {
            return $query->where('location_id', $request->location_filter);
        });
    if ($request->entity_filter === null) {
        $dataAppToday = Appointment::select('date')
            ->where('office_id', auth()->user()->office_id)
            ->whereDate('date', '=', Carbon::now()->toDateString())
            ->where('time', '>', Carbon::now()->toTimeString())
            ->where('available', 1)
            ->where('locked', 0)
            ->where('active', 1)
            ->when($request->location_filter !== null, function ($query) use ($request) {
                return $query->where('location_id', $request->location_filter);
            });

        $dataAppAfterToday = Appointment::select('date')
            ->where('office_id', auth()->user()->office_id)
            ->whereDate('date', '>', Carbon::now()->toDateString())
            ->where('available', 1)
            ->where('locked', 0)
            ->where('active', 1)
            ->whereDate('date', $direction[0], $formatDate->toDateString())
            ->when($request->location_filter !== null, function ($query) use ($request) {
                return $query->where('location_id', $request->location_filter);
            });
    } else {
        $dataAppToday = Appointment::select('date')
            ->join('appointment_entity', 'appointments.id', '=', 'appointment_entity.appointment_id')
            ->where('office_id', auth()->user()->office_id)
            ->whereDate('date', '=', Carbon::now()->toDateString())
            ->where('time', '>', Carbon::now()->toTimeString())
            ->where('available', 1)
            ->where('locked', 0)
            ->where('active', 1)
            ->where('entity_id', $request->entity_filter)
            ->when($request->location_filter !== null, function ($query) use ($request) {
                return $query->where('location_id', $request->location_filter);
            });

        $dataAppAfterToday = Appointment::select('date')
            ->join('appointment_entity', 'appointments.id', '=', 'appointment_entity.appointment_id')
            ->where('office_id', auth()->user()->office_id)
            ->whereDate('date', '>', Carbon::now()->toDateString())
            ->where('available', 1)
            ->where('locked', 0)
            ->where('active', 1)
            ->whereDate('date', $direction[0], $formatDate->toDateString())
            ->where('entity_id', $request->entity_filter)
            ->when($request->location_filter !== null, function ($query) use ($request) {
                return $query->where('location_id', $request->location_filter);
            });
    }

    $data = $dataRevToday->union($dataRevAfterToday)->union($dataAppToday)->union($dataAppAfterToday)
        ->orderByRaw('date ' . $direction[1])
        ->limit(1)
        ->first();
}

This was the key to fix it:

$data = $dataRevToday->union($dataRevAfterToday)->union($dataAppToday)->union($dataAppAfterToday)

As to why is working on local, I really have no idea

Activity icon

Started a new Conversation Query Working On Local, Failing On Production

So I'm pretty confused because I have a query that passed all tests on the local environment but on production it fails.

This is the query.

if ($request->date === null) {
    $direction[0] = $request->direction ? 'max(date)' : 'min(date)';
    $direction[1] = $request->direction ? 'DESC' : 'ASC';

    $dataRevToday = Revision::select((DB::raw($direction[0] . ' as "date"')))
        ->where('office_id', auth()->user()->office_id)
        ->whereDate('date', '=', Carbon::now()->toDateString())
        ->where('time', '>', Carbon::now()->toTimeString())
        ->where('available', 1)
        ->where('locked', 0)
        ->where('active', 1)
        ->when($request->location_filter !== null, function ($query) use ($request) {
            return $query->where('location_id', $request->location_filter);
        });

    $dataRevAfterToday = Revision::select((DB::raw($direction[0] . ' as "date"')))
        ->where('office_id', auth()->user()->office_id)
        ->whereDate('date', '>', Carbon::now()->toDateString())
        ->where('available', 1)
        ->where('locked', 0)
        ->where('active', 1)
        ->when($request->location_filter !== null, function ($query) use ($request) {
            return $query->where('location_id', $request->location_filter);
        });

    $dataRev = $dataRevToday->union($dataRevAfterToday);

    if ($request->entity_filter === null) {
        $dataAppToday = Appointment::select((DB::raw($direction[0] . ' as "date"')))
            ->where('office_id', auth()->user()->office_id)
            ->whereDate('date', '=', Carbon::now()->toDateString())
            ->where('time', '>', Carbon::now()->toTimeString())
            ->where('available', 1)
            ->where('locked', 0)
            ->where('active', 1)
            ->when($request->location_filter !== null, function ($query) use ($request) {
                return $query->where('location_id', $request->location_filter);
            });

        $dataAppAfterToday = Appointment::select((DB::raw($direction[0] . ' as "date"')))
            ->where('office_id', auth()->user()->office_id)
            ->whereDate('date', '>', Carbon::now()->toDateString())
            ->where('available', 1)
            ->where('locked', 0)
            ->where('active', 1)
            ->when($request->location_filter !== null, function ($query) use ($request) {
                return $query->where('location_id', $request->location_filter);
            });

        $dataApp = $dataAppToday->union($dataAppAfterToday);
    } else {
        $dataAppToday = Appointment::select((DB::raw($direction[0] . ' as "date"')))
            ->join('appointment_entity', 'appointments.id', '=', 'appointment_entity.appointment_id')
            ->where('office_id', auth()->user()->office_id)
            ->whereDate('date', '=', Carbon::now()->toDateString())
            ->where('time', '>', Carbon::now()->toTimeString())
            ->where('available', 1)
            ->where('locked', 0)
            ->where('active', 1)
            ->where('entity_id', $request->entity_filter)
            ->when($request->location_filter !== null, function ($query) use ($request) {
                return $query->where('location_id', $request->location_filter);
            });

        $dataAppAfterToday = Appointment::select((DB::raw($direction[0] . ' as "date"')))
            ->join('appointment_entity', 'appointments.id', '=', 'appointment_entity.appointment_id')
            ->where('office_id', auth()->user()->office_id)
            ->whereDate('date', '>', Carbon::now()->toDateString())
            ->where('available', 1)
            ->where('locked', 0)
            ->where('active', 1)
            ->where('entity_id', $request->entity_filter)
            ->when($request->location_filter !== null, function ($query) use ($request) {
                return $query->where('location_id', $request->location_filter);
            });

        $dataApp = $dataAppToday->union($dataAppAfterToday);
    }

    $data = $dataRev->union($dataApp)
        ->orderByRaw('date ' . $direction[1])
        ->limit(1)
        ->first();
} else {
    $formatDate = Carbon::createFromFormat('Y-m-d', date('Y-m-d', strtotime($request->date)));
    $direction[0] = $request->direction ? '>' : '<';
    $direction[1] = $request->direction ? 'ASC' : 'DESC';

    $dataRevToday = Revision::select('date')
        ->where('office_id', auth()->user()->office_id)
        ->whereDate('date', '=', Carbon::now()->toDateString())
        ->where('time', '>', Carbon::now()->toTimeString())
        ->where('available', 1)
        ->where('locked', 0)
        ->where('active', 1)
        ->whereDate('date', $direction[0], $formatDate->toDateString())
        ->whereDate('date', '>=', Carbon::createFromFormat('Y-m-d', Carbon::now()->toDateString()))
        ->when($request->location_filter !== null, function ($query) use ($request) {
            return $query->where('location_id', $request->location_filter);
        });

    $dataRevAfterToday = Revision::select('date')
        ->where('office_id', auth()->user()->office_id)
        ->whereDate('date', '>', Carbon::now()->toDateString())
        ->where('available', 1)
        ->where('locked', 0)
        ->where('active', 1)
        ->whereDate('date', $direction[0], $formatDate->toDateString())
        ->whereDate('date', '>=', Carbon::createFromFormat('Y-m-d', Carbon::now()->toDateString()))
        ->when($request->location_filter !== null, function ($query) use ($request) {
            return $query->where('location_id', $request->location_filter);
        });

    $dataRev = $dataRevToday->union($dataRevAfterToday);

    if ($request->entity_filter === null) {
        $dataAppToday = Appointment::select('date')
            ->where('office_id', auth()->user()->office_id)
            ->whereDate('date', '=', Carbon::now()->toDateString())
            ->where('time', '>', Carbon::now()->toTimeString())
            ->where('available', 1)
            ->where('locked', 0)
            ->where('active', 1)
            ->whereDate('date', $direction[0], $formatDate->toDateString())
            ->whereDate('date', '>=', Carbon::createFromFormat('Y-m-d', Carbon::now()->toDateString()))
            ->when($request->location_filter !== null, function ($query) use ($request) {
                return $query->where('location_id', $request->location_filter);
            });

        $dataAppAfterToday = Appointment::select('date')
            ->where('office_id', auth()->user()->office_id)
            ->whereDate('date', '>', Carbon::now()->toDateString())
            ->where('available', 1)
            ->where('locked', 0)
            ->where('active', 1)
            ->whereDate('date', $direction[0], $formatDate->toDateString())
            ->whereDate('date', '>=', Carbon::createFromFormat('Y-m-d', Carbon::now()->toDateString()))
            ->when($request->location_filter !== null, function ($query) use ($request) {
                return $query->where('location_id', $request->location_filter);
            });

        $dataApp = $dataAppToday->union($dataAppAfterToday);
    } else {
        $dataAppToday = Appointment::select('date')
            ->join('appointment_entity', 'appointments.id', '=', 'appointment_entity.appointment_id')
            ->where('office_id', auth()->user()->office_id)
            ->whereDate('date', '=', Carbon::now()->toDateString())
            ->where('time', '>', Carbon::now()->toTimeString())
            ->where('available', 1)
            ->where('locked', 0)
            ->where('active', 1)
            ->whereDate('date', $direction[0], $formatDate->toDateString())
            ->whereDate('date', '>=', Carbon::createFromFormat('Y-m-d', Carbon::now()->toDateString()))
            ->where('entity_id', $request->entity_filter)
            ->when($request->location_filter !== null, function ($query) use ($request) {
                return $query->where('location_id', $request->location_filter);
            });

        $dataAppAfterToday = Appointment::select('date')
            ->join('appointment_entity', 'appointments.id', '=', 'appointment_entity.appointment_id')
            ->where('office_id', auth()->user()->office_id)
            ->whereDate('date', '>', Carbon::now()->toDateString())
            ->where('available', 1)
            ->where('locked', 0)
            ->where('active', 1)
            ->whereDate('date', $direction[0], $formatDate->toDateString())
            ->whereDate('date', '>=', Carbon::createFromFormat('Y-m-d', Carbon::now()->toDateString()))
            ->where('entity_id', $request->entity_filter)
            ->when($request->location_filter !== null, function ($query) use ($request) {
                return $query->where('location_id', $request->location_filter);
            });

        $dataApp = $dataAppToday->union($dataAppAfterToday);
    }

    $data = $dataRev->union($dataApp)
        ->orderByRaw('date ' . $direction[1])
        ->limit(1)
        ->first();
}

and this is the error log in production:

SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '((select date from appointments where office_id = ? and date(date) = ? a' at line 1 (SQL: (select date from revisions where office_id = 1 and date(date) = 2020-04-25 and time > 12:34:06 and available = 1 and locked = 0 and active = 1 and date(date) > 2020-04-25 and date(date) >= 2020-04-25) union (select date from revisions where office_id = 1 and date(date) > 2020-04-25 and available = 1 and locked = 0 and active = 1 and date(date) > 2020-04-25 and date(date) >= 2020-04-25) union ((select date from appointments where office_id = 1 and date(date) = 2020-04-25 and time > 12:34:06 and available = 1 and locked = 0 and active = 1 and date(date) > 2020-04-25 and date(date) >= 2020-04-25) union (select date from appointments where office_id = 1 and date(date) > 2020-04-25 and available = 1 and locked = 0 and active = 1 and date(date) > 2020-04-25 and date(date) >= 2020-04-25)) order by date ASC limit 1)

I will assume there's a module in place in my forge + DO server doing some extra checks on this then failing?

Thanks in advance for any help

EDIT: Yes, I have noticed I have some redundancies I gotta fix, that was after a change yesterday, apologies for that

Feb
18
3 months ago
Activity icon

Replied to Laravel Websockets Is Not Working Sometimes

hmm, no solution to this? maybe it has something to do with the way I configured Websockets in my forge server? not enough resources allocated? but to be perfectly honest, it's weird because at this moment there's probably less than 10 people using the application.

Forgot to mention, I'm using a Digital Ocean 2nd (or 3rd?) tier server (4GB RAM 80GB disk, 2 vCPU)

Feb
14
3 months ago
Activity icon

Started a new Conversation Laravel Websockets Is Not Working Sometimes

I'm using the latest version of everything, Laravel Websockets, Laravel, Laravel Echo, Axios and so on and so forth.

I 100% based my Forge configuration on this guide https://alex.bouma.dev/installing-laravel-websockets-on-forge/

One of my clients reported thay they weren't getting any updates at some point for changes on an appointments module, he had to refresh the page to get it working again.

The weird part is that he was still receiving messages from a small chat module my app has that is based on the same principle.

This is a little bit of code: My Vue file:

/**
* Starts listening to update appointments events.
*
*/
updateAppointments() {
    Echo.channel(`update-appointments.${this.office_id}`)
        .listen('.list.new.appointments', (event) => {
            if (!this.isEditingAppointment) {
                this.checkAppointments();
            } else {
                this.pendingUpdateFlag = true;
            }
        })
        .listen('.list.updated.dates', (event) => {
            this.listDates(false);
        })
        .listen('.list.updated.entities', (event) => {
            this.listEntities();
        })
        .listen('.list.updated.locations', (event) => {
            this.listLocations();
            this.listAppointments();
        });
}

Channels.php:

// Appointments events
Broadcast::channel('update-appointments.{officeId}', function ($user, $officeId) {
    return ($user->hasPermission('appointments') && $user->office_id === $officeId);
});

Then the event files you know that I'm not going to include here to simplify this post.

As a side note, I'm forced to subscribe the users to regular channels since private ones won't work when a parameter is included on the channel's name (like this.office_id) it happens with either Laravel Websockets or an old Echo + Socket.io + redis method I was using in the past.

SMALL UPDATE: As I was writing this post, the same client reported that he didn't receive some chat messages, I asked him if maybe the sender typed both messages very quickly or something, maybe the fake pusher server is not fast enough to give updates in really short periods of time? but yeah, Websockets is not being reliable right now.

I hope you can give me a solution to this.

Thanks in advance

Jan
23
4 months ago
Activity icon

Replied to CSRF Token Mismatch When Working On 2 Different Routes At The Same Time

that's a situation where the user is already logged and wants to relog somehow, this is something that happens to an user doing stuff in places where it doesn't require any authentication. It's like if facebook had a landing page showing a batch of user photos each 20 seconds, the user logs in another tab and the landing page will get unusable, it won't change photos anymore. This is the most simplest of cases, but I hope you get my point

Activity icon

Replied to CSRF Token Mismatch When Working On 2 Different Routes At The Same Time

So no feasible solution? I think this is an important issue, the CSRF token is not accounting for people opening multiple tabs/windows so it's bound to fail in different situations.

Jan
15
4 months ago
Activity icon

Replied to CSRF Token Mismatch When Working On 2 Different Routes At The Same Time

correct me if I'm wrong, but not really? because caffeine is just looking to keep the session opened, remember the token is set either in the form html or the javascript boostrap file (for AJAX calls and such), that validation is what is failing, so basically there needs to be a way to update the token client-side when it changes server-side due to the log in, right?

In my particular case is a problem, my site is a system to make medical appointments, the patients sometimes get lost in the process so they call the medic in charge (or their secretary), they are logged in at that point, so they open the page to make appointments to run the patients through the process and that's where they can randomly face this issue

Activity icon

Replied to CSRF Token Mismatch When Working On 2 Different Routes At The Same Time

Hmm, then I wonder how can I fix that, because it would be weird to tell people not to log in when they also are navigating the "visitor" pages, people will hardly figure out they need to refresh the page so that'll end up in an unnecessary support ticket

Jan
14
4 months ago
Activity icon

Replied to CSRF Token Mismatch When Working On 2 Different Routes At The Same Time

Expired after 2 minutes? because that's how it is honestly.

Jan
13
4 months ago
Activity icon

Started a new Conversation CSRF Token Mismatch When Working On 2 Different Routes At The Same Time

I have 2 routes for 2 different pages, one is the user panel that requires to be authenticated to do anything (pure AJAX/Axios calls, Laravel Websockets with Echo and such) then there's the other page, free for anyone, it also has some operations with AJAX but of course it doesn't go through the auth middleware.

What happens is that if an user is logged and also visits the "visitor" page so to speak in a new window/tab, at some random point (literally random, there's no pattern that causes this) one of the 2 pages stop doing successful requests due to an Error 419: CSRF Token Mismatch and the user is forced to refresh the page in order to get it working once again, I would assume there's a conflict produced when one page loads after the other and replaces the token contained for the first page? shouldn't both pages have the same token all the time in the same browser? if not, how do I fix this?

Thanks in advance.

Jan
01
4 months ago
Activity icon

Started a new Conversation How To Send A Notification Email To Non-stored Emails In Bulk?

I know you can send a notification in bulk using the Notification facade like so:

Notification::send($users, new InvoicePaid($invoice));

but it requires a collection of a model which contains the Notifiable trait and cannot just receive an array of emails or something like that.

I also know you can use something like:

Notification::route('mail', '[email protected]')

To send an email to a mail that is not stored in any of our models. I might've thought I can use Notification::route because route can be called multiple times, but I'm not sure if I can use the 'mail' route configuration more than once or the proper way to construct the notification, I've been testing:

$notification = Notification::route('mail', $mailList[0]);
for ($i = 1; $i < count($mailList); $i++) {
    $notification->route('mail', $mailList[0]);
}
$notification->notify(new notificationMessage);

and it just sends it to the latest route set in the for, so it's just overwritting one over another.

Also, I should consider sending the mails with BCC in mind. is there a way to do this other than calling Notification over an over for each email passed to the array? doing it this way will hit performance one way or another?

Thanks in advance

Activity icon

Replied to Required_if Not Working As Intended With Other Rules?

Ok, so the solution.

'email_list' => ['bail', 'required_if:this_office,0', 'nullable', 'array'],

This guaranteed me to show the messages where they're actually needed, don't ask me why

jlrdw please pay attention to the screenshot I sent, it is coming as a 0 or a 1, maybe you're confused because you think I'm using the default form submit, no, I'm using Ajax via Axios.

Dec
31
5 months ago
Activity icon

Replied to Required_if Not Working As Intended With Other Rules?

Not a checkbox, 2 radio buttons and like I said, this is what I get on the request, you can see this in telescope:

https://i.gyazo.com/d32c1226ea2c7da3c1835f8eac810527.png

Even changed the 0,1 to a yes and no and yet still I'm getting the same result

Activity icon

Started a new Conversation Required_if Not Working As Intended With Other Rules?

No matter what I throw to the first field, required_if will not even validate the field and will even start validating the next rules

$request->validate([
          'this_office' => ['bail', 'required', 'in:0,1'],
          'email_list' => ['bail', 'required_if:this_office,0', 'array'],
    ],

so in this case, I'm sending:

"this_office": 0,
"email_list": null,

And I'm not getting the required_if message but the array one, why?

Also, if "this_office" is 1 or no matter what number, "email_list" will still validate against array.

Is there a way to fix this? I'm using the latest Laravel version.

Thanks in advance

Dec
18
5 months ago
Activity icon

Replied to Upgrading From 5.8 To 6.7.2 Made Eloquent Union Function To Cast An Integer To A String

Just an update, $casts did nothing, even on columns I wanted to purposedly cast to string.

my forge server also has mysqlnd

EDIT: finally fixed this issue, in my DB::raw had to do a mysql cast fo unsigned like so:

// from
DB::raw('null as appointment_id')
// to
DB::raw('cast(null as unsigned) as appointment_id')
Activity icon

Replied to Upgrading From 5.8 To 6.7.2 Made Eloquent Union Function To Cast An Integer To A String

Ok, I'm gonna try 2 things then in a couple hours:

  • I'm going to take the sql query generated by telescope and paste it on phpmyadmin and then see if I get exactly the same result
  • I'll use protected $casts on my Revision model and see if that makes any difference
Dec
15
5 months ago
Activity icon

Replied to Upgrading From 5.8 To 6.7.2 Made Eloquent Union Function To Cast An Integer To A String

Alright, I've found the issue, and it's not something I would've thought.

This behaviour is happening with Laravel 5.8 and php 7.1.2 as well, appointment_id is coming with a string value instead of an integer.

Thing is, I've never encountered this issue because I was never doing operations with this data specifically, now I added a new feature to my application client side (javascript/vue) where the data type is essential since I'm using the === operator, and of course this will fail. As a workaround I'm using == but this is far from ideal, I think I found a bug in the framework maybe?

Activity icon

Replied to How To Change The Email Configuration For Laravel Notifications On The Fly?

Yeah, that'll do the trick, but I have a question, what if there's more than one operation of sending an email at the same time? am I directly messing with the .env file by doing this? is this gonna affect other notifications that need the default configuration instead of the one modified on runtime?

Dec
14
5 months ago
Activity icon

Replied to Upgrading From 5.8 To 6.7.2 Made Eloquent Union Function To Cast An Integer To A String

afaik that's a linux command, I'm using windows 10 and using xampp for database, wouldn't just mysqlnd be enabled by default?

Installation on Windows

In the official PHP Windows distributions from 5.3 onwards, MySQL Native Driver is enabled by default, so no additional configuration is required to use it. All MySQL database extensions will use MySQL Native Driver in this case.

And anyways, phpinfo is reporting mysqlnd 5.0.12-dev - 20150407 as the Client API library version

I don't think that's the issue honestly

Activity icon

Started a new Conversation Upgrading From 5.8 To 6.7.2 Made Eloquent Union Function To Cast An Integer To A String

I ugraded my app's laravel version to the latest (among other composer dependencies, including php from 7.1.2 to 7.2) and now union is doing some weird stuff with my data:

    $appointmentList = Appointment::select('id', DB::raw('null as appointment_id'), 'office_id', 'patient_id', 'date', 'time', 'minutes', 'selected_entity', 'available', 'locked', 'active', 'description', DB::raw('1 as isAppointment'))
        ->with('patient')
        ->with('appointmentsEntities')
        ->where('office_id', auth()->user()->office_id)
        ->where('date', $formatDate->toDateString())
        ->where('active', '1');

    $revisionList = Revision::select('id', 'appointment_id', 'office_id', 'patient_id', 'date', 'time', 'minutes', 'selected_entity', 'available', 'locked', 'active', 'description', DB::raw('0 as isAppointment'))
        ->with('patient')
        ->where('office_id', auth()->user()->office_id)
        ->where('date', $formatDate->toDateString())
        ->where('active', '1');

    $appointmentRevisionList = $appointmentList->union($revisionList)
        ->orderBy('time')
        ->get();

        \Log::info($appointmentRevisionList);

    return Response::json([
        'success' => true,
        'data' => $appointmentRevisionList,
    ], 200);
}

note the Log line, that is giving me a string instead of an int in appointment_id (which is a BIGINT on MySql) if I just log this:

\Log::info($revisionList->get());

Now it gives me the correct data type. So basically the combination of union and apparently setting the value to null on $appointmentList is giving me this weird behaviour after I upgraded to laravel 6.7.2. I completely discard the PHP upgrade because my current DO production server is already using PHP 7.3, but it's still using 5.8 for Laravel. This is happening as of right now, on my local environment.

I want to know how to fix this honestly.

Thank you.

Activity icon

Started a new Conversation How To Change The Email Configuration For Laravel Notifications On The Fly?

I'm using Laravel email notifications to send my emails because that's enough for my needs.

Now, I need to use a new email configuration for a specific type of email I pretend to send, so the mailgun config I have on my .env file cannot be used, I've found guides but using mailable directly, I sill wanna keep using notifications for consistency.

This is basically the layout for each type of message I'm sending throughout my application:

namespace App\Notifications;

use Illuminate\Bus\Queueable;
use Illuminate\Notifications\Messages\MailMessage;
use Illuminate\Notifications\Notification;

class SmeClientMailContact extends Notification
{
    use Queueable;

    /**
     * Create a notification instance.
     *
     * @param  string  $message
     * @param  string  $email
     * @param  string  $phone
     * @param  string  $contactName
     * @return void
     */
    public function __construct($message, $email, $phone, $contactName)
    {
        $this->message = $message;
        $this->email = $email;
        $this->phone = $phone;
        $this->contactName = $contactName;
    }

    /**
     * Get the notification's delivery channels.
     *
     * @param  mixed  $notifiable
     * @return array
     */
    public function via($notifiable)
    {
        return ['mail'];
    }

    /**
     * Get the mail representation of the notification.
     *
     * @param  mixed  $notifiable
     * @return \Illuminate\Notifications\Messages\MailMessage
     */
    public function toMail($notifiable)
    {
        return (new MailMessage)
            ->from(config('app.contact_email'), config('app.contact_email_name'))
            ->subject('Su Médico Especialista - Mensaje de contacto de ' . $this->contactName)
            ->greeting('Mensaje de contacto de ' . $this->contactName)
            ->line('Este cliente acaba de enviar un correo de contacto a sumedicoespecialista.')
            ->line('Nombre: ' . $this->contactName)
            ->line('Correo electrónico: ' . $this->email)
            ->line('Teléfono: ' . $this->phone)
            ->line('Mensaje: ' . $this->message);
    }

    /**
     * Get the array representation of the notification.
     *
     * @param  mixed  $notifiable
     * @return array
     */
    public function toArray($notifiable)
    {
        return [
            //
        ];
    }
}

What's the way to manually set the mail driver, host, port, etc for this notification specifically for example.

Thanks in advance

Dec
03
5 months ago
Activity icon

Replied to Scalability On Demand?

Anyone have a possible answer? I honestly refuse to believe that the only way is setting the load balancers and such from minute 0 because that would be a good waste of money. I of course gave a look to vapor, but it requires laravel 6+ and it costs triple the Most basic plan on forge and double the one that allows multiple sites. Remember I'm making these questions with saving money in mind.

Thanks in advance

Dec
02
5 months ago
Activity icon

Replied to Scalability On Demand?

Uhh, my app is off the mark by 1 version (5.8) and why would I need to switch to Vapor when I can achieve the same with Forge, right?

Activity icon

Started a new Conversation Scalability On Demand?

I've been through multiple tutorials, where the scalability basically begins since the application is first deployed by configuring load balancers and some guides go as far as making a separate server for each individual function (database, redis, application, etc) which is excessive cost wise honestly.

What if I configure a DO server that is simply enough for a year or two, I have everything there, my application, database, Laravel websockets and then when the time comes I need to assign more resources, how do I proceed in that case? would I need to start from zero to decouple my sever into multiple instances each one doing something different or is there a more simpler approach? what if I just need to allocate more storage? are there any good tutorials explaining these situations?

Any help is really appreciated.