trevorpan

trevorpan

Member Since 1 Year Ago

Experience Points
57,140
Total
Experience

2,860 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
492
Lessons
Completed
Best Reply Awards
2
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 12
57,140 XP
Jul
05
4 days ago
Activity icon

Replied to Maximum Execution Time Of 30 Seconds Exceeded. Spatie MediaLibrary

Awesome @guybrush_threepwood thank you for the boost!

the longer execution time of

max_execution_time = 120

max_input_time = 60

Seems to work on local. You mentioned queueing the conversions. The local env had sync so that definitely caused some issues locally (for anyone else who finds this)

// QUEUE_CONNECTION=sync
QUEUE_CONNECTION=redis // at least to test locally with horizon - drastically sped the feeling of the site site "working" -- UX

Took a bit to figure out how to edit that file policy.xml on the production server. While ssh'ing this command does the trick sudo nano /etc/ImageMagick-7/policy.xml

But I also wanted to do it locally and came across this post. The command I picked up is identify -list policy Super helpful as it shows you everything on the command line.

https://stackoverflow.com/questions/52703123/override-default-imagemagick-policy-xml

And this is also a helpful site with other recipes: https://forgerecipes.com/recipes/215

Activity icon

Replied to Maximum Execution Time Of 30 Seconds Exceeded. Spatie MediaLibrary

Hi @guybrush_threepwood

In your experience, do you think the max_execution_time should exceed 30 seconds? I was concerned that something is not setup right.

Just got this error and was about to dive into it:

ImagickException
attempt to perform an operation not allowed by the security policy `PDF' @ error/constitute.c/IsCoderAuthorized/408

this is where they are right now:

max_execution_time = 60

max_input_time = 60
Jul
03
6 days ago
Activity icon

Started a new Conversation Maximum Execution Time Of 30 Seconds Exceeded. Spatie MediaLibrary

$this->numberOfPages = $this->imagick->getNumberImages();

Has anyone run into this?

Have laravel medialibrary installed. It works fine for single page files. However a four page 8.5MB (and a smaller 2.5MB of the same file) pdf throws this:

Maximum execution time of 30 seconds exceeded or 502 Bad Gateway

Single page files do not throw the error.

spatie/laravel-medialibrary#1271 http://www.imagemagick.org/discourse-server/viewtopic.php?t=19087

Tried out a ton possible issues, but the error always comes back to a method in vendor/spatie/pdf-to-image/src/Pdf.php file.

Here's the versions I'm using:

"spatie/laravel-medialibrary": "^7",
"spatie/pdf-to-image": "2.0.1",

Laravel 7 GPL Ghostscript 9.50 (2019-10-15)

php.ini

upload_max_filesize = 32M
max_file_uploads = 20
post_max_size = 128M
memory_limit = 2048M
extension="redis.so"
extension="imagick.so"

Laravel Valet 2.11.0 Can verify valet uses [email protected] Have verified the server is using [email protected] laravel/valet#728 (comment) (this was a big pain, and a great find)

Have gone through all the possibilities I can find. Including this one: https://github.com/laravel/valet/issues/269#issuecomment-271928229 it adds:

fastcgi_buffers 16 16k;
fastcgi_buffer_size 32k;

to valet.conf but I'm not seeing an improvement. restart valet many times after these tweaks

Jun
30
1 week ago
Activity icon

Started a new Conversation A Guide To Deploying Production Artisan Commands

| php artisan  | Runs | Notes |

| scout:import |once| if rerun, existing records that were deleted will reappear |
| schedule:run |once?| commands will not run without it |

Would anyone like to contribute to this guide?

I want to have a place to reference these deploy scripts. Got stumped many times on deploy. e.g. scout:import was run on each update. After deleting a record in the index it would reappear; I left it in the database for the record but don't necessarily want it in the search index. After numerous support emails with algolia I finally figured it out. So, if algolia itself wasn't privy to this nuance it seems like this guide would be really useful.

On forge, I had a few support tickets about cron jobs not running and was told they should be running. But again without a guide it's hard to know that, as it's not the most obvious thing (at least to me).

(also, not sure how to get a table to show as markdown on laracasts)

Anyhow, if you have experience with a command please make a post and I'll fold it in here!

Jun
27
1 week ago
Activity icon

Replied to How Do You Set Up A Truth Test Console Command To Run A Task In Production?

@bugsysha thank you so much. I was at a complete loss as to why this was not going. Your return statement above was the most important. But I realized how badly everything else was setup.

Truth Test Steps:

  1. Make sure statement returns true or false, as shown above
  2. Depending on whether the console command sends emails make sure constructors are set properly, and args implemented
  3. If dispatching a huge number of things you may not need an arg as shown here:
    /**
    * Execute the console command.
    *
    */
    public function handle()
    {
    SendDeadlineExpiredEmails::dispatch();
    }

The above was really confusing, as the docs imply the use of args. But my case is a bit different as it loops through many jobs to email a bunch of users based on other conditions...

  1. In my case the queue job did not need type hints, as the handle() pulled special conditions and it was not an implied model like making a blog post or something.
  2. Make sure envoyer, or other deployment uses php artisan queue:restart
  3. AND most important be sure to include php artisan schedule:run

Wow, thank you. This was a really complicated setup.

Got the expected real emails on production server!!:

Your job has bidded: George Washington's Lumber Job (sample) We are very sorry to report that no one placed a bid on your job.

Activity icon

Replied to How Do You Set Up A Truth Test Console Command To Run A Task In Production?

Alright, your solution should have run but it has not. There are no logs @bugsysha .

class DeadlineHasPassed extends Command
{
    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'email:deadlineHasPassed {biddedJobs}'; // should this be model name?

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = 'Send deadline expired emails';

    /**
     * Create a new command instance.
     *
     * @return void
     */
    public function __construct()
    {
        parent::__construct();
    }

    /**
     * Execute the console command.
     * @param SlugJob $biddedJobs
     */
    public function handle(SlugJob $biddedJobs)
    {
        SendDeadlineExpiredEmails::dispatch($biddedJobs);
    }
}

Well, this has to be it. If the truth test tests whether a condition exists does the console command require arguments? If so, would the user be the argument or the model SlugJob? I've tried both. Something seems to be amiss.

I also verified the php artisan queue:restart is set in envoyer...

Activity icon

Replied to How Do You Set Up A Truth Test Console Command To Run A Task In Production?

aahh. Ok let me give that a go.

I had tried this but it did not work either.

        $schedule->command('email:deadlineHasPassed --force')
            ->everyMinute()
                ->withoutOverlapping()
                    ->when(function () {
                       $biddedJobs = DB::table('jobs')
                            ->where([
                                ['deadline', '<=', Carbon::now('America/Los_Angeles')->toDateTimeString()],
                                ['bidded', '=', 0]
                            ])
                            ->exists();
                        return $biddedJobs;
                    });
Activity icon

Replied to How Do You Set Up A Truth Test Console Command To Run A Task In Production?

@bugsysha yea, I had originally used the return. Here's the doc sample:

$schedule->command('emails:send')->daily()->when(function () {
    return true;
});

So my code was like:

protected function schedule(Schedule $schedule)
    {
       $schedule->command('email:deadlineHasPassed --force')
    ->everyMinute()
        ->when(function () {
            DB::table('jobs')
                ->where([
                    ['deadline', '<=', Carbon::now('America/Los_Angeles')
                        ->toDateTimeString()],
                    ['bidded', '=', 0]
                ])->get();
        })->withoutOverlapping();

return true;

I looked at that for a bit. It seemed like get() was the wrong call whereas exists() returns true or false. So it seems redundant to check for a truth and then explicitly return true as this could falsely return true.

Am I wrong?

Activity icon

Started a new Conversation How Do You Set Up A Truth Test Console Command To Run A Task In Production?

Recently, I made a post and was successfully able to write a test for this condition: https://laracasts.com/discuss/channels/testing/the-expected-notification-was-not-sent-using-cron-scheduled-command-phpunit

However, now that it's in production the scheduler does not run when a job deadline passes. I've tried with --force and without.

The docs mention a routes/console.php is needed for a closure. This truth test appears to be a closure, however in the docs https://laravel.com/docs/7.x/scheduling#schedule-frequency-options under Truth Test Constraints it makes no mention of the routes/console.php file???

class Kernel extends ConsoleKernel
{
    /**
     * The Artisan commands provided by your application.
     *
     * @var array
     */
    protected $commands = [
        Commands\DeadlineHasPassed::class,
        Commands\GenerateSitemap::class
    ];

    /**
     * Define the application's command schedule.
     *
     * @param  \Illuminate\Console\Scheduling\Schedule  $schedule
     * @return void
     */
    protected function schedule(Schedule $schedule)
    {
       $schedule->command('email:deadlineHasPassed --force')
            ->everyMinute()->when(function () {
            DB::table('jobs')
                ->where([
                    ['deadline', '<=', Carbon::now('America/Los_Angeles')
                        ->toDateTimeString()],
                    ['bidded', '=', 0]
                ])->exists();
        })->withoutOverlapping();
Jun
26
1 week ago
Activity icon

Replied to Phpunit: AssertArrayHasKey() - Undefined Index: Errors

@fuhrn

I appreciate your comment! So, I reworked the test:

    /** @test */
    public function an_order_is_not_created_if_payment_fails()
    {
        $this->withoutExceptionHandling();
        $joe = factory(User::class)->create();
        $job = factory(SlugJob::class)->create();

        $this->actingAs($joe)
                ->payBidReserve($job, [
                    'price' => 500,
                    'quantity' => 1,
                    'stripeToken' => 'not-a-token',
                ]);


        $this->response->assertStatus(422);
        $this->response->assertJsonValidationErrors(['stripeToken']); // this returns: Invalid JSON was returned from the route.

        $this->assertFalse($joe->hasOrderFor($joe->id));
    }

I made some searches and found the answer from the man himself!

https://github.com/laravel/framework/pull/28595#issuecomment-495251983

The line $this->response->assertJsonValidationErrors(['stripeToken']); is redundant and not needed as 422 is asserted.

Thank you - without your post I wouldn't have discovered this`

Activity icon

Replied to Phpunit: AssertArrayHasKey() - Undefined Index: Errors

HI @fuhrn - let me give that a go tonight and I'll let you know! Thank you

Jun
21
2 weeks ago
Activity icon

Awarded Best Reply on Package:discover --ansi Handling The Post-autoload-dump Event Returned With Error Code 1

Well, I've made a lot of rookie mistakes.

Somehow telescope was added to production on an earlier commit. So, I added a gate to telescope and to production. Got past this error.

The gate feature is pretty slick so I guess I'll work with it. Does anyone else use this in production?

Activity icon

Replied to Package:discover --ansi Handling The Post-autoload-dump Event Returned With Error Code 1

Well, I've made a lot of rookie mistakes.

Somehow telescope was added to production on an earlier commit. So, I added a gate to telescope and to production. Got past this error.

The gate feature is pretty slick so I guess I'll work with it. Does anyone else use this in production?

Activity icon

Replied to Package:discover --ansi Handling The Post-autoload-dump Event Returned With Error Code 1

I take that back. There is a log related. I didn't think the time matched earlier. Tried a new deploy and got this:

production.ERROR: Class 'Laravel\Telescope\TelescopeApplicationServiceProvider' not found {"exception":"[object] (Error(code: 0):

Telescope is only in the "require-dev" section of composer.json. It doesn't make sense that it's being called in the package:discover script on deploy....

Is this the correct use?

    "extra": {
        "laravel": {
            "dont-discover": [
                "TelescopeServiceProvider"
            ]
        }
    },
Activity icon

Started a new Conversation Package:discover --ansi Handling The Post-autoload-dump Event Returned With Error Code 1

Writing lock file
Generating optimized autoload files
> Illuminate\Foundation\ComposerScripts::postAutoloadDump
> @php artisan package:discover --ansi
Script @php artisan package:discover --ansi handling the post-autoload-dump event returned with error code 1

Any ideas of what is happening in envoyer on deploy?

I checked the logs - there's nothing related to this...

May
24
1 month ago
Activity icon

Awarded Best Reply on Envoyer Has Deployed Forge Has Not (roles / Permissions Tables & AuthServiceProvider)

So, this was a bit tough for a first-timer.

In order to get the roles/permissions tables in so the AuthServiceProvider wouldn't throw errors I ssh'd into the server and then booted up mysql and manually installed the tables with a insert statement. That took care of the roles/permissions issues. (probably a cleaner way, but this worked)

But I found I had to refresh the server in envoyer a few times, and be sure to update env variables with server address. In the end it wasn't too bad, but the first time through it was rough.

The other issue was paths - making sure current/public is the forge path (what envoyer deploys too). There were a few hangups. Hope that helps.

Activity icon

Replied to Envoyer Has Deployed Forge Has Not (roles / Permissions Tables & AuthServiceProvider)

So, this was a bit tough for a first-timer.

In order to get the roles/permissions tables in so the AuthServiceProvider wouldn't throw errors I ssh'd into the server and then booted up mysql and manually installed the tables with a insert statement. That took care of the roles/permissions issues. (probably a cleaner way, but this worked)

But I found I had to refresh the server in envoyer a few times, and be sure to update env variables with server address. In the end it wasn't too bad, but the first time through it was rough.

The other issue was paths - making sure current/public is the forge path (what envoyer deploys too). There were a few hangups. Hope that helps.

Activity icon

Awarded Best Reply on Enabling Imagick.so With Envoyer And Forge

Was on a slack channel and was able to get this to work.

For anyone a little confused like me, use recipes for things like extensions and deployment hooks for artisan commands. (generally)

#!/bin/bash

if [ "$EUID" -ne 0 ]
  then echo "Please run as root"
  exit
fi


apt-get -y install gcc make autoconf libc-dev pkg-config
apt-get -y install libmagickwand-dev
yes '' | sudo pecl install imagick

bash -c "echo extension=imagick.so > /etc/php/7.3/mods-available/imagick.ini"
ln -s /etc/php/7.3/mods-available/imagick.ini /etc/php/7.3/cli/conf.d/20-imagick.ini
ln -s /etc/php/7.3/mods-available/imagick.ini /etc/php/7.3/fpm/conf.d/20-imagick.ini
service php7.3-fpm restart

This code was able to implement the extension.

Activity icon

Replied to Enabling Imagick.so With Envoyer And Forge

Was on a slack channel and was able to get this to work.

For anyone a little confused like me, use recipes for things like extensions and deployment hooks for artisan commands. (generally)

#!/bin/bash

if [ "$EUID" -ne 0 ]
  then echo "Please run as root"
  exit
fi


apt-get -y install gcc make autoconf libc-dev pkg-config
apt-get -y install libmagickwand-dev
yes '' | sudo pecl install imagick

bash -c "echo extension=imagick.so > /etc/php/7.3/mods-available/imagick.ini"
ln -s /etc/php/7.3/mods-available/imagick.ini /etc/php/7.3/cli/conf.d/20-imagick.ini
ln -s /etc/php/7.3/mods-available/imagick.ini /etc/php/7.3/fpm/conf.d/20-imagick.ini
service php7.3-fpm restart

This code was able to implement the extension.

Activity icon

Started a new Conversation Envoyer Has Deployed Forge Has Not (roles / Permissions Tables & AuthServiceProvider)

I know this sounds super basic but I'm trying to figure out how these services work together. I've watched both series on forge and envoyer - they've really helped alot.

Wish there was a bridge video series that shows how to use them both. Envoyer is now at all green lights which is great (just fantastic).

Do we have to install the git repository on Forge? Or is it Envoyer that pushes this? (this is where the lines of which service does what is not clear to me)

I've run into this issue when trying to install the repo on Forge:

  SQLSTATE[HY000] [1045] Access denied for user 'forge'@'localhost' (using password: NO) (SQL: select * from information_schema.tables where table_schema = forge and table_name = permissions and table_type = 'BASE TABLE')

What's strange is the .env in Envoyer should deploy the variables. The server status shows green and when refreshed stays that way. This seems like all public keys, etc are in good working condition...

In order to get this to work in CI I used these scripts:

mysql $DB_DATABASE < database/insert_roles.sql
mysql $DB_DATABASE < database/insert_permissions.sql
mysql $DB_DATABASE < database/insert_permission_role.sql
mysql $DB_DATABASE < database/insert_role_user.sql

Should these be a recipe on Forge or a Deployment Hook on Envoyer?

Or is there some other reason the code deployed from Envoyer has not made it to the server?

Thank you `

May
23
1 month ago
Activity icon

Started a new Conversation Enabling Imagick.so With Envoyer And Forge

So close to launching...

If I understand this correctly. When using both Forge and Envoyer Forge should provision the server & we should not place the recipes in Forge's dashboard. We should use the deployment hooks in Envoyer, right?

If that's so, I found a great site for Forge https://forgerecipes.com/recipes/215

It seems like that same recipe could be used as a deployment hook here:

cd {{release}}
#!/bin/bash

if [ "$EUID" -ne 0 ]
  then echo "Please run as root"
  exit
fi


apt-get -y install gcc make autoconf libc-dev pkg-config
apt-get -y install libmagickwand-dev
yes '' | sudo pecl install imagick

bash -c "echo extension=imagick.so > /etc/php/7.3/mods-available/imagick.ini"
ln -s /etc/php/7.3/mods-available/imagick.ini /etc/php/7.3/cli/conf.d/20-imagick.ini
ln -s /etc/php/7.3/mods-available/imagick.ini /etc/php/7.3/fpm/conf.d/20-imagick.ini
service php7.3-fpm restart

But this gives this error:

E: Could not open lock file /var/lib/dpkg/lock-frontend - open (13: Permission denied)

I have ssh'd into the server to try to edit the php.ini file but get: [ File '/etc/php/7.3/cli/php.ini' is unwritable ] I have also enabled the php.ini file in Forge under files with extension=imagick.co but it does not seem to have any effect when deploying from Envoyer.

This article helped out quite a bit, but did not address pecl stuff. https://medium.com/@ted.nugent/laravel-forge-envoyer-cloudforge-ssl-and-you-cc0cc51db945

Any ideas?

Thank you much`

May
19
1 month ago
Activity icon

Replied to How To Get Optional() Functionality Without Using Optional() ? ? ?

@tykus you know so much stuff. For almost every post I make you've answered 5 in my searches!

Ok, so, first thank you!

Alright, I've got that reconfigured as you say:

        $userCompany = auth()->user()
            ->companies()
            ->latest()
            ->first(); //changed from get

        $companyUsers = optional($userCompany)->users ?? collect(); // this I had tried and tried using an if, but could not get the $userCompany = [];
// Your tip ?? collect(); is the ticket.

        $companyAdmin = $companyUsers->filter(function ($user, $role) {
            return $user->hasRole('company_administrator');
        });

Then I changed the blade to this:

  @if ($companyAdmin->isEmpty())
... forms, @can directives, etc.

Now it worksssssss!

Activity icon

Replied to How To Get Optional() Functionality Without Using Optional() ? ? ?

omg, is it really that easy?

I had tried first() before but it said trying to get user on null or something like that. Let me give it a go!

Activity icon

Started a new Conversation How To Get Optional() Functionality Without Using Optional() ? ? ?

Hello, have a strange issue that just popped up. Wasn't triggering before but it now seems unavoidable.

 $userCompany = auth()->user()
            ->companies()
            ->latest()
            ->get();

// $userCompany returns empty array for fresh user (intentional)

                $companyUsers = optional($userCompany->users()->get());
// ->get() returns Eloquent\Collection::users does not exist. 

                $companyAdmin = $companyUsers->filter(function ($user, $role) {
                    return $user->hasRole('company_administrator');
});
 

I've got Roles, Permissions and Company.

  1. When a fresh user arrives at dashboard, no company exists, no admin exists for a company.
  2. Show Roles/Permissions form based on: @if ($companyAdmin == false) in blade.
  3. Can't use optional as the blade directive controls authorization.

If you have any tips I'd really appreciate it `

May
18
1 month ago
Activity icon

Awarded Best Reply on Test Code Or Tested Code Did Not (only) Close Its Own Output Buffers & ActingAs()

Well after two days of trying to track this error down I found the issue.

https://github.com/sebastianbergmann/phpunit-documentation/issues/403

An open @endslot That's the one. I had made a custom email text template and there it was with squiggly lines in php-storm! what . a . pain .

I had kept combing the blade files and combing the blade files. Anyhow I really hope this helps someone out!

Activity icon

Replied to Test Code Or Tested Code Did Not (only) Close Its Own Output Buffers & ActingAs()

Well after two days of trying to track this error down I found the issue.

https://github.com/sebastianbergmann/phpunit-documentation/issues/403

An open @endslot That's the one. I had made a custom email text template and there it was with squiggly lines in php-storm! what . a . pain .

I had kept combing the blade files and combing the blade files. Anyhow I really hope this helps someone out!

Activity icon

Started a new Conversation Test Code Or Tested Code Did Not (only) Close Its Own Output Buffers & ActingAs()

https://laracasts.com/discuss/channels/testing/php-unit-risky-test-whats-the-cause-of-it-and-how-to-avoid

Have an unusual error here. It seems to be related to a brew update, but I'm not certain. At any rate I went through the blade views on the risky tests as the above post mentions. That does not seem to have fixed the error.

I am concerned it may be a session issue as the failing tests all have this method.

Recently updated the auth scaffolding... Any thoughts would be amazing!

May
17
1 month ago
Activity icon

Replied to CSRF Token Mismatch. ($this->withoutExceptionHandling() Not Doing Its Job)

https://medium.com/p/d9c00fbef263/responses/show

This article really helped. What started as the csrf token mismatch exception became expected 200 but got 419 errors.

It's still confusing how the docs in laravel https://laravel.com/docs/7.x/configuration#environment-configuration advocate for a .env.testing file.

https://laravel.com/docs/7.x/testing#environment advocates for .env.testing file.

Dusk https://laravel.com/docs/7.x/dusk#environment-handling has .env.dusk.local It also uses another config file: phpunit.dusk.local

    /**
     * Determine if the application is running unit tests.
     *
     * @return bool
     */
    public function runningUnitTests()
    {
        return $this['env'] === 'testing';
    }

Yet, the .env that ships with laravel uses the local ENV.

Here the appserviceprovider:

    /**
     * Register any application services.
     *
     * @return void
     */
    public function register()
    {
        //
        if ($this->app->isLocal()) {
            $this->app->register(TelescopeServiceProvider::class);
            $this->app->register(DuskServiceProvider::class);
        }

requires local env.

I'm still having a hard time understanding what takes precedence. It seems like one .env file should be able to configure everything instead we have about 4 or 5 if you include production.

May
16
1 month ago
Activity icon

Replied to CSRF Token Mismatch. ($this->withoutExceptionHandling() Not Doing Its Job)

\Session\TokenMismatchException: CSRF token mismatch.

Does anyone know why this would trigger in a phpunit test?

Activity icon

Replied to CSRF Token Mismatch. ($this->withoutExceptionHandling() Not Doing Its Job)

Looking at this more closely I may have found the issue - but not certain.

The InvitationsController posts the invitation in an email form on the dashboard. The dashboard displays the form. The dashboard has auth, verified middleware applied.

I'm thinking the show method needs to be broken off the InvitationsController to the InvitationsShowController (or something like that).

Have you faced a similar situation?

Activity icon

Started a new Conversation CSRF Token Mismatch. ($this->withoutExceptionHandling() Not Doing Its Job)

Hey there,

The test suite passes sometimes but not others. I'm at a loss as to why this occurs randomly.

Using sqlite, :memory: local env.

/** @test
     *
     * @throws Illuminate\Session\TokenMismatchException
     */
    public function registering_with_a_valid_invitation_code()
    {
        $this->withoutExceptionHandling();
//        dd(env('APP_ENV'));
        $shelley = factory(User::class)->create([
                    'firstname' => 'Shelley',
                    'email' => '[email protected]',
        ]);
        $this->assertEquals(1, User::count());
        $invitation = factory(Invitation::class)->create([
            'inviter_user_id' => $shelley->id,
            'invitation_code' => 'TESTCODE1234',
        ]);

        $this->assertDatabaseHas('users', [
            'email' => '[email protected]',
        ]);

        $response = $this->from('/invitations/TESTCODE1234')->post('/invitations/register', [
            'firstname' => 'John',
            'lastname' => 'Smith',
            'email' => '[email protected]',
            'password' => 'secretsecret',
            'password_confirmation' => 'secretsecret',
            'invitation_code' => 'TESTCODE1234',
        ]);

        $response->assertRedirect('/email/verify');

        $this->assertEquals(2, User::count());
        $inviterShelley = User::first();
        $john = User::find(2);

        $this->actingAs($john);
        $this->assertEquals('[email protected]', $inviterShelley->email);
        $this->assertEquals('[email protected]', $john->email);
        $this->assertTrue(Hash::check('secretsecret', $john->password));

//        dd($invitation);
//        dd($invitation->fresh()->invitedUser);
        $this->assertTrue($invitation->fresh()->invitedUser->is($john));

        $this->assertDatabaseHas('users', [
            'email' => '[email protected]',
        ]);

        $this->assertDatabaseHas('invitations', [
            'user_id' => $john->id,
        ]);

    }
May
10
1 month ago
Activity icon

Replied to RenderForConsole($output, Throwable $exception) Upgrade Guide Differs From Api

@bobbybouwmann

Well - for sure this new tool I picked up Larastan is causing me to look more at this level of detail. Just an excellent leveling up - still think I'll need another year or so to really get it.

As always thank you!

Where's my laravel secrets? You know I'm waiting for that to become available!!

May
09
2 months ago
Activity icon

Replied to Using Larastan And Making Sense Of The Suggestions

@punksolid Thank you so much.

The last day I've been letting Larastan take the chainsaw to my doc blocks `

Going to have stay close to that tool for while. Just so much to know. It seems like Laravel is pretty forgiving though - which is pretty amazing. Like below would still retrieve the view - but with the response()prefixing the view seems like it'll be more bullet proof when real users actually use the site.

Alot of these type of controller issues:

 * @return \Illuminate\Http\Response

return view('good.view', compact('pizza'));

turned into

 * @return \Illuminate\Http\Response

return response()->view('good.view', compact('pizza'));

referencing: https://laravel.com/docs/7.x/responses#view-responses

Appreciate your help!

Activity icon

Replied to RenderForConsole($output, Throwable $exception) Upgrade Guide Differs From Api

Ok, so the doc block essentially visually "cleans up" the method in the () but calls the same interface?

In my particular file there are no doc blocks and they are not suggested by phpstorm for some reason.

Just trying to understand why the docs say public function renderForConsole($output, Throwable $exception); exception is fully spelled out but the api states $e or does it even matter?

Not that you would - but could it be Throwable $z and still work?

Activity icon

Started a new Conversation RenderForConsole($output, Throwable $exception) Upgrade Guide Differs From Api

https://laravel.com/docs/7.x/upgrade#symfony-5-related-upgrades

use Throwable;

public function renderForConsole($output, Throwable $exception);

https://laravel.com/api/7.x/Illuminate/Contracts/Debug/ExceptionHandler.html#method_renderForConsole

void renderForConsole(OutputInterface $output, Throwable $e)

I'm trying to make a custom console exception work and noticed the docs don't fully line up. When I tried making the renderForConsole(OutputInterface $output, Throwable $e) like the api, phpstorm gave an error: method must be compatible with ExceptionHandler->renderForConsole etc.

Is it common for these to not exactly match? Or is the OutputInterface used by Throwable? I searched that file but could not see a reference.

May
08
2 months ago
Activity icon

Replied to Using Larastan And Making Sense Of The Suggestions

Thank you. I just don't know enough yet. Still don't quite get :void.

on the return statement is missing. I noticed phpstorm doing that on a different situation, but when I added return SendDeadlineExpiredEmails::dispatch(); the phpunit tests all failed.

Does return include the doc block? So, it does not require literally the word return before (in this case below) a dispatch?

The below version does not fail the phpunit tests anymore.

    /**
     * Execute the console command.
     *
     * @return mixed
     */
    public function handle()
    {
        SendDeadlineExpiredEmails::dispatch();
    }
Activity icon

Started a new Conversation Using Larastan And Making Sense Of The Suggestions

Hi, I decided to give larastan a shot to improve my code but there's a bunch of comments that I'd like to see what more experienced people have to say about it:

54     Method App\Http\Controllers\BidInvitationsController::store() should return Illuminate\Http\Response but returns Illuminate\Http\RedirectResponse. 

return back(); is all it's doing. Filling out an email to invite someone and then staying on the page.

Almost every controller has these types of issues. I'm concerned they may mess up the Laravel framework, as I'm staying as close to out of the box as possible.

This one is the out of the box auth login controller:

  53     Method App\Http\Controllers\Auth\LoginController::authenticate() should return App\Http\Controllers\Auth\Response but return statement is missing. 
56     Method App\Http\Controllers\Auth\LoginController::authenticate() should return App\Http\Controllers\Auth\Response but returns Illuminate\Http\RedirectResponse. 

Here's the method:

     /**
     * Handle an authentication attempt.
     *
     * @param  \Illuminate\Http\Request $request
     *
     * @return Response
     */
    public function authenticate(Request $request)
    {
        $credentials = $request->only('email', 'password');

        if (Auth::attempt($credentials)) {
            // Authentication passed...
            return redirect()->intended('/dashboard');
        }
    }
May
06
2 months ago
Activity icon

Replied to Database Connection [testing.sqlite] Not Configured.

one more whack-a-mole shot seems to have found the database!!

I still think it's worth talking about.

        'sqlite' => [
            'driver' => 'sqlite',
            'database' => database_path('testing.sqlite'),
	    // 'database' => database_path('database.sqlite'), // this one was setup prior and did not fix issue
            'prefix' => '',
        ],

//         'sqlite_testing' => [
//            'driver' => 'sqlite',
//            'database' => env('DB_DATABASE', database_path('testing.sqlite')),
//            'prefix' => '',
//        ],

I saw a post on laracasts that said use the env('DB_DATABASE env variable. However, in the sqlite above it did not allow the database to be found. That post said you can remove the variable from the env.dusk.local file.

The other issue I may have found on accident, I thought it would be good to use a sqlite_testing connection. However, does the env.dusk.local or phpunit.dusk.xml stop at the first sqlite?

I'm wondering if the suffix of _testing is never read?

If you can share and make sense of all this that would be great.

Activity icon

Replied to Testing

I've hit that before, you may need to import the model use App\Media; file at the top of the test.

If that import exists in the test file you can create a factory using php artisan make:factory MediaFactory and fill in those factory details. Probably one of those items. The re-run the test.

Activity icon

Started a new Conversation Database Connection [testing.sqlite] Not Configured.

https://laracasts.com/discuss/channels/testing/database-does-not-exist-when-trying-to-use-mysql-for-phpunit-tests

https://medium.com/@james_fairhurst/issues-i-ran-into-when-testing-in-laravel-5-with-sqlite-7ef79de29a94

I've spent the last few hours trying to setup a sqlite database.

What is the order of php artisan dusk reading the

env.dusk.local
phpunit.dusk.xml
database.php

It seems like I try one file, then a database not specified in any of the above files is used. Or the database migrations trait dumps the local mysql dev database.

Is it necessary to run php artisan serve and put that APP_URL=http://127.0.0.1:8000 in the env.dusk.local or is Laravel Valet just fine?

Thank you `

May
02
2 months ago
Activity icon

Awarded Best Reply on What Triggers `Serialization Of 'Closure' Is Not Allowed` When Using Queue?

@nakov really appreciate your taking a stab at this. It helped me think about other possibilities. In the end, at least it appears, the InvitationsController was using the out of the box Laravel register method. I mistakenly believed I could reuse it.

From what I can see the route cannot be used twice.

The error message is not sufficiently descriptive - possibly worth doing a PR on github and try to improve the message.

So, in the InvitationsController I omitted the protected function validator(array $data) and condensed it to:

/**
     * Create a new user instance after a valid registration.
     *
     * @param Request $data //changed from array $data
     * @return User
     */
    protected function create(Request $data) //changed from array $data
    {
        $invitation = Invitation::findByInvitationCode(request('invitation_code'));
        abort_if($invitation->hasBeenUsed(), 404);

        request()->validate([
            'firstname' => 'required|string|max:255',
            'lastname' => 'required|string|max:255',
            'email' => 'required|string|email|max:255|unique:users',
            'password' => 'required|string|min:12|confirmed',
        ]);

        $user = User::create([
            'firstname' => $data['firstname'],
            'lastname' => $data['lastname'],
            'email' => $data['email'],
            'password' => Hash::make($data['password']),
        ]);

        event(new Registered($user)); // a key addition

        $invitation->update([
            'user_id' => $user->id,
        ]);

        return view('auth.verify');
    }
Activity icon

Replied to What Triggers `Serialization Of 'Closure' Is Not Allowed` When Using Queue?

@nakov really appreciate your taking a stab at this. It helped me think about other possibilities. In the end, at least it appears, the InvitationsController was using the out of the box Laravel register method. I mistakenly believed I could reuse it.

From what I can see the route cannot be used twice.

The error message is not sufficiently descriptive - possibly worth doing a PR on github and try to improve the message.

So, in the InvitationsController I omitted the protected function validator(array $data) and condensed it to:

/**
     * Create a new user instance after a valid registration.
     *
     * @param Request $data //changed from array $data
     * @return User
     */
    protected function create(Request $data) //changed from array $data
    {
        $invitation = Invitation::findByInvitationCode(request('invitation_code'));
        abort_if($invitation->hasBeenUsed(), 404);

        request()->validate([
            'firstname' => 'required|string|max:255',
            'lastname' => 'required|string|max:255',
            'email' => 'required|string|email|max:255|unique:users',
            'password' => 'required|string|min:12|confirmed',
        ]);

        $user = User::create([
            'firstname' => $data['firstname'],
            'lastname' => $data['lastname'],
            'email' => $data['email'],
            'password' => Hash::make($data['password']),
        ]);

        event(new Registered($user)); // a key addition

        $invitation->update([
            'user_id' => $user->id,
        ]);

        return view('auth.verify');
    }
Activity icon

Replied to What Triggers `Serialization Of 'Closure' Is Not Allowed` When Using Queue?

possibly this explains it?

https://laracasts.com/discuss/channels/laravel/troubleshooting-serialization-of-closure-is-not-allowed-issue-when-caching-routes

Would re-using the register method on the RegistersUsers trait cause this?

Route::post('/invitations/register', 'Auth\[email protected]');
Activity icon

Replied to What Triggers `Serialization Of 'Closure' Is Not Allowed` When Using Queue?

ok @nakov , thank you for sharing some ideas.

well this is what I've got for phpunit.xml <env name="QUEUE_CONNECTION" value="sync"/>

and in the config/queue.php

 'default' => env('QUEUE_CONNECTION', 'redis'),
...
 'connections' => [
        'redis' => [
            'driver' => 'redis',
            'connection' => 'default',
            'queue' => 'default',
            'retry_after' => 90,
            'block_for' => 5,
        ],

Pretty standard ... not sure.

// user.php
class User extends AuthUser implements Authenticatable, MustVerifyEmail
{
    use  Notifiable, HasRoles;
...

The only other thing that I'm thinking could be the routes.web: Route::middleware(['verified'])->group(function () {...

Could the route group cause this?

May
01
2 months ago
Activity icon

Replied to What Triggers `Serialization Of 'Closure' Is Not Allowed` When Using Queue?

@nakov So what you asked hit me this afternoon.

I need to implement a job.

I've started a class InvitedUserRegisteredEmail implements ShouldQueue job but I'm wondering how would that work?

The Registered event fires: SendEmailVerificationNotification::class,. Not sure where or if something like SendEmailVerificationNotification::dispatch(); is a reasonable thing to do as the listener is already picking up on the event.

Have you created anything like this before that might cause the error Serialization of 'Closure' is not allowed?

Activity icon

Replied to What Triggers `Serialization Of 'Closure' Is Not Allowed` When Using Queue?

Hi good morning @nakov

Well, interestingly I noticed the listener did not have a queue setup on it by default - I added that. Could not find a job in the vendor directory as it does not appear to ship with a laravel implementation.

Is the registered email something that should not be queued? The out of the box registered event has a use Illuminate\Queue\SerializesModels; statement.

I'm in the weeds here with familiarity.

<?php

namespace Illuminate\Auth\Listeners;

use Illuminate\Auth\Events\Registered;
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Contracts\Queue\ShouldQueue;

class SendEmailVerificationNotification implements ShouldQueue
{
    /**
     * Handle the event.
     *
     * @param  \Illuminate\Auth\Events\Registered  $event
     * @return void
     */
    public function handle(Registered $event)
    {
        if ($event->user instanceof MustVerifyEmail && ! $event->user->hasVerifiedEmail()) {
            $event->user->sendEmailVerificationNotification();
        }
    }
}
Apr
30
2 months ago
Activity icon

Awarded Best Reply on SQLSTATE[23000]: Integrity Constraint Violation: 19 NOT NULL Constraint Failed: Articles.article

I've run across this and usually fix it in your migration, in your case it looks like class CreateArticlesTable extends Migration

try adding:

        Schema::create('articles', function (Blueprint $table) {
            $table->bigIncrements('id');
            $table->text('article'); // this is the line you're likely missing - it's possible you've named 'text' in the migration but reference 'article' in a blade view, e.g. if that's the case you can rename 'text' to 'article'
... other columns, 

Give that a go ...

Activity icon

Replied to SQLSTATE[23000]: Integrity Constraint Violation: 19 NOT NULL Constraint Failed: Articles.article

I've run across this and usually fix it in your migration, in your case it looks like class CreateArticlesTable extends Migration

try adding:

        Schema::create('articles', function (Blueprint $table) {
            $table->bigIncrements('id');
            $table->text('article'); // this is the line you're likely missing - it's possible you've named 'text' in the migration but reference 'article' in a blade view, e.g. if that's the case you can rename 'text' to 'article'
... other columns, 

Give that a go ...

Activity icon

Started a new Conversation What Triggers `Serialization Of 'Closure' Is Not Allowed` When Using Queue?

This is from abstract class Queue

    /**
     * Create a payload for an object-based queue handler.
     *
     * @param  object  $job
     * @param  string  $queue
     * @return array
     */
    protected function createObjectPayload($job, $queue)
    {
        $payload = $this->withCreatePayloadHooks($queue, [
            'displayName' => $this->getDisplayName($job),
            'job' => 'Illuminate\Queue\[email protected]',
            'maxTries' => $job->tries ?? null,
            'delay' => $this->getJobRetryDelay($job),
            'timeout' => $job->timeout ?? null,
            'timeoutAt' => $this->getJobExpiration($job),
            'data' => [
                'commandName' => $job,
                'command' => $job,
            ],
        ]);

        return array_merge($payload, [
            'data' => [
                'commandName' => get_class($job),
                'command' => serialize(clone $job), // this line is where the exception is thrown
            ],
        ]);
    }

In my particular case I have an InvitationsRegisterController that has an invitation code.

    /**
     * Get a validator for an incoming registration request.
     *
     * @param array $data
     * @return \Illuminate\Contracts\Validation\Validator
     */
    protected function validator(array $data)
    {
        $invitation = Invitation::findByInvitationCode(request('invitation_code'));

        abort_if($invitation->hasBeenUsed(), 404);

        return Validator::make($data, [
            'firstname' => 'required|string|max:255',
            'lastname' => 'required|string|max:255',
            'email' => 'required|string|email|max:255|unique:users',
            'password' => 'required|string|min:12|confirmed',
        ]);
    }

    /**
     * Create a new user instance after a valid registration.
     *
     * @param array $data
     * @return User
     */
    protected function create(array $data)
    {
        $invitation = Invitation::findByInvitationCode(request('invitation_code'));

        $user = User::create([
            'firstname' => $data['firstname'],
            'lastname' => $data['lastname'],
            'email' => $data['email'],
            'password' => Hash::make($data['password']),
        ]);

        $invitation->update([
            'user_id' => $user->id,
        ]);

        return redirect('/email/verify');
    }
Apr
25
2 months ago
Activity icon

Replied to 'verified' Middleware Acting Buggy On Login

ok not currently using that so I commented out.

But just so I understand:

// from `routes/api.php`
Route::middleware('auth:api')->get('/user', function (Request $request) {
    return $request->user();
});

Gives that error because it uses the (Request $request)?

Whereas, this does not give that error because it's an anonymous function with the Route::get...?

Route::middleware(['verified'])->group(function () {
	Route::get('/', '[email protected]')->name('home');
...