mkrell

mkrell

Member Since 1 Year Ago

Experience Points 840
Experience Level 1

4,160 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 1
Best Reply
Awards
  • start-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-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-token Created with Sketch.

    Subscriber

    Earned if you are a paying Laracasts subscriber.

  • lifer-token Created with Sketch.

    Lifer

    Earned if you have a lifetime subscription to Laracasts.

  • lara-evanghelist 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.

29 May
3 months ago

mkrell left a reply on Laravel Queue Failure Does Not Trigger Failed() Method If There's An Exception, But RaiseFailedJobEvent() Works

@deepu07 I never figured out what exactly the problem was for OP, but what I did figure out is that I was not actually passing in a real job, because a Mailable isn't actually a job; it gets wrapped automatically in a job, and hence you can't call failed() on a Mailable.

29 Mar
5 months ago

mkrell started a new conversation Docker Instance's Nginx Config Doesn't Seem To Match Route

Hello. I have an nginx config that works perfectly fine when my site is deployed, but does not work in my docker container I use for local dev.

The site is deployed without docker on Forge, and works fine. The docker container's nginx, however, does not seem to match a particular location block.

We have three location blocks for the site, one for Laravel, one for an old PHP app that's integrated with the site, and one that is supposed to match three Code Ignitor routes. The CI routes are the ones not working in Docker.

Here is my nginx config:

server {
    listen 80 default_server;

    root /var/www/html/public;

    index index.html index.htm index.php;

    server_name _;

    charset utf-8;

    location = /favicon.ico { log_not_found off; access_log off; }
    location = /robots.txt  { log_not_found off; access_log off; }
    
    client_max_body_size 100M;


    # Code Ignitor - Not working
    location ~ /old/(statement|invoice|crosscheck)(/.*)? {
        try_files /old/index.php =404;
        fastcgi_split_path_info ^(.+\.php)(/.+)$;
        fastcgi_pass unix:/run/php/php5.6-fpm.sock;
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME $document_root/index.php;
        fastcgi_param SCRIPT_NAME /index.php;
        include fastcgi_params;

        # long for xdebug session
        fastcgi_read_timeout 3600;
    }

# Old PHP app - Works
    location ~ /old/.*\.php {
        try_files $uri /index.php?$query_string;

        # long for xdebug session
        fastcgi_read_timeout 3600;
    }

# Laravel - Works
    location / {
        try_files $uri $uri/ /index.php$is_args$args;
    }

    location ~ \.php$ {
        include snippets/fastcgi-php.conf;
        fastcgi_pass unix:/run/php/php5.6-fpm.sock;

        # long for xdebug session
        fastcgi_read_timeout 3600;
    }

    error_page 404 /index.php;

    location ~ /\.ht {
        deny all;
    }
}

When I try going to the CI routes on docker (say, /old/crosscheck), the app goes to my catch-all route in laravel. It never hits the /old/index.php like it's supposed to.

The Nginx config is the same on Forge and in Docker (except for the paths to PHP and such).

I've tried changing the regex on that block to /old/crosscheck to see if it would match, no dice.

I've looked at the access log and the error log, nothing helpful.

Any idea what's going on?

Thx, Matt

15 Feb
7 months ago

mkrell left a reply on Alternative To Using Command System

@TYKUS -

Define commands

Tell the application to do something more complicated than simple CRUD, usually to multiple resources.

Example: Send an email to a customer:

# api/customers/1/commands
{
    "data": {
        "attributes": {
            "command": "email",
            "payload": {
                "address":"[email protected]"
            }
        }
    }
}

send emails to customers with open invoices

# api/customers/commands
{
    "data": {
        "attributes": {
            "command": "email_statements",
            "payload": {
                "message":"your statement is here!",
        "statement_from_date":"2018-01-01"
            }
        }
    }
}

make employee vehicle assignments for a day according to a template (defined by other resources)

# api/schedule/8/commands
{
    "data": {
        "attributes": {
            "command": "assign_employees",
            "payload": {
                "template_id":"59"
            }
        }
    }
}

So side effects could be making several resources and sending an email at once, or updating multiple records that have X condition, etc.

You could just have separate endpoints for each command and post your data to it, but that feels messy to me. Plus, having a bunch of separate endpoints feels more like SOAP then REST.

mkrell started a new conversation Alternative To Using Command System

A colleague told me that Jeffrey has changed his mind about using a command system for complicated or large processes, for example like the Commander he made a few years back.

I can't find podcast / episode where he said this (if he said this!), but I'm inclined to agree; using DTOs and Command Handlers feels overly complicated.

I need the ability to issue commands to my application. I've got the request structure figured out, but what I'm wondering is what's the best way to organize the code without structuring it like he does in the above series? Maybe just a utility class that gets called in the controller?

Here's an example of the POST data structure (I'm using the JSON-API format for my api)

{
    "data": {
        "attributes": {
            "command": "email",
            "payload": {
                "address":"[email protected]"
            }
        }
    }
}

Thoughts? Apologies if this is the wrong channel to post this in :)

Matt

mkrell left a reply on VS Code Formatting

There is an HTML formatter I noticed, that might work for Blade. I haven't used it, though.

I've been using this for better formatting in PHP, but I'm waiting Prettier to finish their PHP extension.

mkrell left a reply on Syncronous Queue Not Running Failed() Method, Or Adding To Failed_jobs

@BOBBYBOUWMANN - OK, I'm pretty sure I know what's the issue.

Short answer:

A Mailable class is not a queueable job. When Mail::queue() is called, Mail constructs the Mailable, makes a new job, then queues that job.

Long answer:

I had put my failed() method in the Mailable itself. It won't be run on a failed job because it's not in that API. It's not a job.

Example:


class EmailStatement extends Mailable
{
    use InteractsWithQueue, Queueable, SerializesModels;
    
    public function __construct()
    {
        //
    }


    /**
     * Build the message.
     *
     * @return $this
     */
    public function build()
    {
        //  
    }


    // doesn't run
    public function failed(\Exception $exception)
    {
        \Log::critical('Failed happened');  
    }
}

What Mail actually does is construct the Mailable and puts it in an Illuminate\Mail\SendQueuedMailable instance.

# Mailable.php

    public function queue(Queue $queue)
    {
        $connection = property_exists($this, 'connection') ? $this->connection : null;

        $queueName = property_exists($this, 'queue') ? $this->queue : null;

        return $queue->connection($connection)->pushOn(
            $queueName ?: null, new SendQueuedMailable($this)
        );
    }

Since I'm not pushing my own job on the queue (I'm just doing Mail::queue()), Laravel is pushing it's own job onto the queue with the Mailable inside. As such, it won't ever run my failed method because it isn't on the associated job.

So what's the best way to handle updating a database record if an email fails? I suppose I could just make my own job and push that onto the queue, or use the failures() method on Mailer to figure it out.

mkrell left a reply on Laravel Queue Failure Does Not Trigger Failed() Method If There's An Exception, But RaiseFailedJobEvent() Works

Yeah I would like to know how to resolve this too. I'm trying to test a failed send on a Mailable and my failed() isn't running either. I'm running Laravel 5.4. Maybe this gets solved in a later version?

mkrell left a reply on Syncronous Queue Not Running Failed() Method, Or Adding To Failed_jobs

@BOBBYBOUWMANN - Switching to the database driver made the failed_jobs table start getting populated. No dice on my code being run, though.

Here's my failed() code:

public function failed(\Exception $exception)
{
    file_put_contents('duh.txt');
    $log             = \Acme\ActivityLog::find(1);
    $log->successful = false;
    $log->message    = "Failed to send statement email to $this->address. Message: $exception->getMessage()";
    $log->save();
}

I can confirm that the activity_log resource is indeed there, but nothing's happening. Plus the file_put_contents('duh.txt.') isn't doing anything either.

13 Feb
7 months ago

mkrell started a new conversation Syncronous Queue Not Running Failed() Method, Or Adding To Failed_jobs

I can't seem to get a failed() method on a queueable email job to run, nor does anything appear on the failed_queues table populate on the fail. I'm using the sync driver.

The way I'm attempting to trigger the fail is by turning off my laptops wifi. Since the mail configuration on my local environment goes to mailtrap.io, I figure the easiest way to force a fail is just to cut the connection to mailtraps SMTP server and try to send it. My failed() code doesn't run. I've also tried throwing an exception in the Mailable's build(), still doesn't run the failed().

On top of this, the failed job doesn't get populated into the failed_jobs table. I'm pretty sure I have that configured correctly.

The failed() method is supposed to update a record on my database. To confirm that the method was not actually running, I did a file_put_contents() to a random file and checked if the file appeared after the tasked errored out.

Does anything happen to a failed job if your driver is sync?

I have not tested this using redis or beanstalk.

Laravel version: 5.4 Server: Custom Docker image.

I'm not sure what configuration / code I could show that would be helpful.

Thanks, Matt

21 Sep
11 months ago

mkrell left a reply on Laravel Passport: 401 Unauthenticated, But Encryption Keys Are The Same

Well, bad code doesn't pay.

What I didn't mention was that the site I'm trying to deploy is an attempt to move a domain over to a new server. Both the broken site and it's active sister site have the same domain name. This is the code that posts to my own domains /oauth/token endpoint:

$username = Input::json('username');
$password = Input::json('password');

$page = Input::get('page');

$client = Client::find(2);

$http = new GuzzleHttp\Client();

try {
    $response = $http->post(url('oauth/token'), [   # <-- see the problem?
        'form_params' => [
            'grant_type'    => 'password',
            'client_id'     => '2',
            'client_secret' => $client->secret,
            'username'      => $username,
            'password'      => $password,
            'scope'         => '',
        ],
    ]);

#...

The problem is rather hilarious. Since the DNS hasn't switched for the site yet, the requests to my own site are going to the old site, not this one. Hence I'm getting back Unauthenticated. Because I'm not.

The solution was to edit the /etc/hosts file on the server to point the domain to itself. That way, any calls to its own api will actually go its own api. Problem solved.

So, moral of the story: if you need to post to your own api, make sure your /etc/hosts file will direct your calls back to yourself.

mkrell started a new conversation Laravel Passport: 401 Unauthenticated, But Encryption Keys Are The Same

Hello. I have weird problem with Passport authentication deploying my application to a new site, in spite of the fact that I haven't had a problem with this before.

I'm using Passport's password grant feature to log in to the application (Laravel 5.4). This happens by the user posting his username / password as json to the site, and from there it posts those credentials to oauth/token to get the api key for the site. This has worked fine in the past, and my oauth keys are committed to the repository.

The other day I managed to deploy the site to a new server (with the same oauth keys), regenerated (I think) the app key, loaded my data that has the encrypted passwords, and authentication worked fine. Today, however, I did the same thing on a different branch and now logging in returns 401 Unauthorized.

I've done nearly every permutation I could think of: delete the oauth keys, regenerate app key, reinstall passport, and yet the app refuses to log in. I don't believe it has anything to do with the source code because no changes I made on this branch would affect the login system.

I even tried copying the working site's app key and oauth keys to the broken site, still doesn't work.

What makes this even more puzzling to me is that I have another site with a different app key, different oauth keys, but the same data, and the login system works fine.

I don't understand the league/oauth package enough to understand why this isn't working. What am I missing?

Thanks, Matt

25 Apr
1 year ago

mkrell left a reply on Laravel Passport Invalid Credentials Grant_type - Password

Are you using an alternative column for your username field? (I.E. using username instead of default email)? If that's the case put this in your User model:

    public static function findForPassport($username)
    {
        return User::where('username', $username)->first();
    }

According to this, the UserRepository in Passport is assuming the default field, email. You have to override the appropriate method in UserRepository if you do.

The culprit code block:

        if (method_exists($model, 'findForPassport')) {
            $user = (new $model)->findForPassport($username);
        } else {
            $user = (new $model)->where('email', $username)->first();
        }
20 Sep
1 year ago

mkrell started a new conversation Migrate Command Hanging In Artisan Script

Hello. I have an artisan command db:sync that syncs my local database from a live database my company runs. This command used to work before; now, once it reaches the migrate command it hangs for an eternity. When I run the steps myself within the terminal directly, it works fine.

I've tried restarting my computer and valet, does not seem to fix it.

Here's my handle function (redacted, of course)

public function handle()
    {
        // (SCP live server file, database.sql)

        $this->clearDatabase();

        $script =
            'mysql' .
            ' -u ' . getenv('DB_USERNAME') .
            ' -h ' . getenv('DB_HOST');

        if (getenv('DB_PASSWORD') != '') {
            $script .= ' -p' . getenv('DB_PASSWORD');
        }

        $script .=
            ' ' . getenv('DB_DATABASE') .
            ' < ' . escapeshellarg(base_path()) . '/database.sql';

        $output = shell_exec($script);

        $output = empty($output) ? 'Sync complete.' : $output;
        $this->info($output);

        $force = '';
        if ($this->option('force')) {
            $force = '--force';
        }
        $this->info('Migrating data');

    // begins to hang right here
        $output = shell_exec('php ' . escapeshellarg(base_path()) . '/artisan migrate ' . $force);
        $output = empty($output) ? 'Database migrated.' : $output;
        $this->info($output);

        // ... 
    }

the clearDatabase() function:

protected function clearDatabase()
    {
        $columnName = 'Tables_in_' . env('DB_DATABASE');

        $tables = DB::select('SHOW TABLES');

        if (empty($tables)) {
            return;
        }

        foreach($tables as $table) {
            $dropList[] = $table->$columnName;
        }

        $dropList = implode(',', $dropList);

        DB::beginTransaction();

        // Turn off referential integrity
        DB::statement('SET FOREIGN_KEY_CHECKS = 0');

        DB::statement("DROP TABLE $dropList");

        // Turn referential integrity back on
        DB::statement('SET FOREIGN_KEY_CHECKS = 1');

        DB::commit();
    }

I'm running Laravel 5.4.15, Valet 2.0.3. I'm using MariaDB for my database.

Any help would be appreciated.

Thanks, Matt