Corbin

Corbin

Member Since 5 Years Ago

Experience Points
35,730
Total
Experience

4,270 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
360
Lessons
Completed
Best Reply Awards
1
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 8
35,730 XP
Oct
19
1 week ago
Activity icon

Awarded Best Reply on How Do I Refresh Of Re-render A Component Through Vue Routes?

@rodrigo.pedra thanks for the help. I didn't see the notification and I figured out another way. Maybe you can tell me what way is better?

Here's what I did. On the navigation I created a click event that would see what the current route is. If on the current route I just reload the records, if not I go to the route:

Template

<v-list-item @click="pushRouteOrReloadRecords()">
    
    <div class="d-flex">Activity Feed</div>

</v-list-item>

Method

pushRouteOrReloadRecords(){
    if(this.$router.currentRoute.name == 'records'){
        this.$store.dispatch("getCounsellorFeed")
    } else {
        this.$router.push({ name: 'records' })
    }
}
Activity icon

Replied to How Do I Refresh Of Re-render A Component Through Vue Routes?

@rodrigo.pedra thanks for the help. I didn't see the notification and I figured out another way. Maybe you can tell me what way is better?

Here's what I did. On the navigation I created a click event that would see what the current route is. If on the current route I just reload the records, if not I go to the route:

Template

<v-list-item @click="pushRouteOrReloadRecords()">
    
    <div class="d-flex">Activity Feed</div>

</v-list-item>

Method

pushRouteOrReloadRecords(){
    if(this.$router.currentRoute.name == 'records'){
        this.$store.dispatch("getCounsellorFeed")
    } else {
        this.$router.push({ name: 'records' })
    }
}
Oct
18
1 week ago
Activity icon

Started a new Conversation How Do I Refresh Of Re-render A Component Through Vue Routes?

When I click on a list item I my navigation I go back to the main page:

Vue navigation

<v-list-item to="/">
    
    <div class="d-flex">Activity Feed</div>

</v-list-item>

Vue Route

{
    path: '/',
    name: '',
    get component() {
      if(store.state.user && store.state.user.is_counsellor === 1) {
        return CounsellorActivity
      } else {
        return Activity
      }
    },
    children: [
      { name: 'records', path: '', component: Records },
    ]
  },

In the Records component I load a bunch of records on mount based that's context is based on parameters assigned to the user:

mounted() {
    if(this.user.is_counsellor === 1){
        this.getCounsellorFeed()
    } else {
        this.getRecords()
    }
},

I have a bunch of ways that sort records in the component, and what I want to do is reload this.getCounsellorFeed() in the record component when <v-list-item to="/"> is clicked on on the same page slash route. I also don't want to reload the whole page. Just the record component.

Jul
17
3 months ago
Activity icon

Started a new Conversation SQLSTATE[HY000]: General Error: 1215 Cannot Add Foreign Key Constraint, In Dev Env, But Works Fine In Testing

I'm trying to migrate my messages/conversations/conversation_participants on a recently installed laravel project. The code works fine in testing, but doesn't work when I run php aritsan migrate

Error

SQLSTATE[HY000]: General error: 1215 Cannot add foreign key constraint (SQL: alter table messages add constraint messages_conversation_id_foreign foreign key (conversation_id) references conversations (id))

2020_07_13_000145_create_messages_table

Schema::create('messages', function (Blueprint $table) {
    $table->bigIncrements('id');
    $table->unsignedBigInteger('sender_id');
    $table->unsignedBigInteger('conversation_id');
    $table->text('body');
    $table->timestamps();

    $table->foreign('sender_id')->references('id')->on('users');
    $table->foreign('conversation_id')->references('id')->on('conversations');
});

2020_07_13_053229_create_conversations_table

Schema::create('conversations', function (Blueprint $table) {
    $table->bigIncrements('id');
    $table->string('hashed_id')->nullable();
    $table->unsignedInteger('has_reply')->unsigned()->default(0);
    $table->text('subject');
    $table->timestamps();
});

2020_07_14_045926_create_conversation_participants_table

Schema::create('conversation_participants', function (Blueprint $table) {
    $table->integer('user_id')->unsigned();
    $table->unsignedBigInteger('conversation_id');
    $table->tinyInteger('status')->default(0);
    $table->tinyInteger('is_sender')->default(0);

    $table->foreign('conversation_id')->references('id')->on('conversations')->onDelete('cascade');
    $table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
});
Jun
21
4 months ago
Activity icon

Started a new Conversation Custom Exception Handler For API Is Not Working

I'm having problems catching Exceptions in my Laravel/Sanctum/ SPA/API that uses Cahsier. I can catch Stripe exceptions in the handler method, but can't catch NotFoundHttpException.

In my controller I'm deliberately setting a query parameter that I know will fail to test the exception:

Controller

public function processCheckout(Request $request)
{    
    
    $plan = Plan::findOrFail(100);
    $user = $user = auth()->user();
    
    //If user has no subscriptions subscribe them to new plan
    if($user->subscriptions->count() === 0){
        $user->newSubscription($plan->name, $plan->stripe_plan_id)->create($request->payment_method['id']);

        //return response([], 201);
    }
}

When I turn on: APP_DEBUG=true I get this response:

{
    "message": "No query results for model [App\Plan] 100",
    "exception": "Symfony\Component\HttpKernel\Exception\NotFoundHttpException",
    "file": "/Applications/MAMP/htdocs/saas-spa/vendor/laravel/framework/src/Illuminate/Foundation/Exceptions/Handler.php",
    "line": 222,
    "trace": [
        {
            "file": "/Applications/MAMP/htdocs/saas-spa/vendor/laravel/framework/src/Illuminate/Foundation/Exceptions/Handler.php",
            "line": 198,
            "function": "prepareException",
            "class": "Illuminate\Foundation\Exceptions\Handler",
            "type": "->"
        },
        {
            "file": "/Applications/MAMP/htdocs/saas-spa/app/Exceptions/Handler.php",
            "line": 85,
            "function": "render",
            "class": "Illuminate\Foundation\Exceptions\Handler",
            "type": "->"
        }, // and more
	]
}

When I turn APP_DEBUG=false I get nothing as a response.

app/Exceptions/Handler.php

public function render($request, Throwable $exception)
{
    if ($exception instanceof \Stripe\Exception\ApiErrorException) {
        return response()->json([
            'code' => $exception->getCode(),
            'message' => $exception->getMessage(),
        ]);
    }
    $response = $this->handleException($request, $exception);
    return $response;
}

public function handleException($request, Throwable $exception)
{

    if ($exception instanceof MethodNotAllowedHttpException) {
        return $this->errorResponse('The specified method for the request is invalid', 405);
    }

    if ($exception instanceof NotFoundHttpException) {
        return $this->errorResponse('The specified URL cannot be found', 404);
    }

    if ($exception instanceof HttpException) {
        return $this->errorResponse($exception->getMessage(), $exception->getStatusCode());
    }

    if (config('app.debug')) {
        return parent::render($request, $exception);            
    }
    return $this->errorResponse('Unexpected Exception. Try later', 500);

}

Why am I not able to output my custom error message?

Jun
17
4 months ago
Activity icon

Started a new Conversation Error Handling For Cashier Controller Methods While Building An API

Essentially I have a CheckoutController that handles the functionality for subscribing, unsubscribing, resuming a subscription, and changing a subscription. For example:

public function processCheckout(Request $request)
{
    
    try {
        $plan = Plan::findOrFail($request->billing_plan_id);
        $user = $user = auth()->user();
        
        //If user has no subscriptions subscribe them to new plan
        if($user->subscriptions->count() === 0){
            $user->newSubscription($plan->name, $plan->stripe_plan_id)->create($request->payment_method['id']);

            return response([], 201);
        }
    } catch (\Exception $e) {
        return response([], 500);
    }
}

What I don't understand is what type of errors I should output for the frontend to pick up if something goes wrong. Right now for all of my Checkout methods I just out put a 500 error, and on the front end I catch that error by outputting a message: "An error occurred. Please try again."

submitPaymentForm(paymentMethod){
        this.$http({
            method: 'POST',
            url: 'api/checkout',
            data: {
                billing_plan_id: this.planId,
                payment_method: paymentMethod
            }
        }).then(function (response) {
            this.$store.dispatch('getUser')
        }.bind(this))
        .catch(error => {
                this.serverErrorMessage = "An error occurred. Please try again.";
                console.log('submit payment'+error);
        });
    },
},

Now, I do understand that Stripe implements its own errors on the frontend, but I'm not sure what to do with my backend. I was hoping someone could help me out with this.

Here's my full gist of the functionality

Jun
02
4 months ago
Activity icon

Started a new Conversation Checking To See If User Has Subscriptions Causes Test To Fail Unexpectedly [Laravel Cashier]

I've created a method that processes user checkouts using cashier:

CheckoutController.php (working)

public function processCheckout(Request $request)
{
    $plan = Plan::findOrFail($request->billing_plan_id);

    try {
        $user = auth()->user()->newSubscription($plan->name, $plan->stripe_plan_id)->create($request->payment_method['id']);

        return response([], 201);
    } catch (\Exception $e) {
        return response([], 500);
    }
}

SubscriptionsTest

use RefreshDatabase;

protected $monthlyPlan;
protected $yearlyPlan;

protected function setUp(): void
{
    parent::setUp();

    $this->monthlyPlan = factory('App\Plan')->create(['name' => 'Monthly', 'stripe_plan_id' => 'plan_thing']); 
    $this->yearlyPlan = factory('App\Plan')->create(['name' => 'Yearly', 'stripe_plan_id' => 'plan_thing2']);      
}

/** @test */
public function a_user_can_subscribe_to_a_plan()
{
    $this->withoutExceptionHandling();

    $this->actingAs($user = factory('App\User')->create());

    \Stripe\Stripe::setApiKey(\Config::get('services.stripe.secret'));
    $payment_method = \Stripe\PaymentMethod::create([
        'type' => 'card',
        'card' => [
            'number' => '4242424242424242',
            'exp_month' => 5,
            'exp_year' => 2021,
            'cvc' => '314',
        ],
    ]);

    $response = $this->json('POST', '/api/checkout', ['billing_plan_id'=> 1, 'payment_method' => $payment_method ] )
        ->assertStatus(201);

    $this->assertTrue($user->subscribed('Monthly'));
}

Everything works great until I need to check to see if a user is already subscribed, and if they aren't create a subscription auth()->user()->newSubscription(). This is to prevent duplicate subscriptions.

CheckoutController (Not working)

public function processCheckout(Request $request)
{
    
    try {
        $plan = Plan::findOrFail($request->billing_plan_id);
        $user = $user = auth()->user();
        
        //If user has no subscriptions subscribe them to new plan
        if($user->subscriptions->count() === 0){

            $user->newSubscription($plan->name, $plan->stripe_plan_id)->create($request->payment_method['id']);

            //dd($user->subscribed('Monthly'));

            return response([], 201);
        }
    } catch (\Exception $e) {
        return response([], 500);
    }
}

Test:

Tests\Feature\SubscriptionsPlansTest::a_user_can_subscribe_to_a_plan Failed asserting that false is true.

As you can see I've //dd($user->subscribed('Monthly')); in the controller method. This returns false. dd($user->subscriptions->toArray()); also returns an empty array.

I'm unsure what is going on here and why dd($user->subscribed('Monthly')); is returning false. I'm pretty sure this works because the front end is working. What's going on?

May
28
4 months ago
Activity icon

Replied to Cookie::queue() Not Creating A Cookie For API Login

@bugsysha I had no idea it existed. Is there the possibility for two factor authentication?

Activity icon

Started a new Conversation Cookie::queue() Not Creating A Cookie For API Login

I'm using passport with Laravel 7 to login in and store a refresh token in a cookie:

class AuthController extends Controller
{
    const REFRESH_TOKEN = 'refreshToken';

    public function login(Request $request)
    {

        $request->validate([
            'username' => 'required|email',
            'password' => 'required',
        ]);

        return $this->proxy('password', [
            'username' => $request->username,
            'password' => $request->password,
        ]);

    }

    public function refresh(Request $request)
    {
        $refreshToken = $this->request->cookie(self::REFRESH_TOKEN);

        return $this->proxy('refresh_token', [
            'refresh_token' => $refreshToken
        ]);
    }

    public function proxy($grantType, array $data = [])
    {
        $data = array_merge($data, [
            'client_id'     => config('services.passport.client_id'),
            'client_secret' => config('services.passport.client_secret'),
            'grant_type'    => $grantType
        ]);

        $response = Request::create(route('passport.token'), 'POST', $data);

        $handleResponse = app()->handle($response);

        $data = json_decode($handleResponse->getContent());

        // Create a refresh token cookie
        Cookie::queue(
            self::REFRESH_TOKEN,
            $data->refresh_token,
            864000, // 10 days
            null,
            null,
            false,
            true // HttpOnly
        );

        return response('hello world')->withCookie(cookie(self::REFRESH_TOKEN));
        return [
            'access_token' => $data->access_token,
            'expires_in' => $data->expires_in
        ];
    }

}

Cookie::queue() in my proxy() method aren't storing a cookie.

It tried the solution from this stack overflow question

Cookie queuing is not enabled for api requests, this is the reason why it didn't work.

Open file App/Http/Kernel.php add the line \Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class, in protected $middleware array as displayed in above code snippet and test again it should work now.

This solution didn't work for me.

I don't know how to implement the second solution:

In case anyone fond their way here by Google, one way for cookie inclusion to silently fail is if you're explicitly defining your domain variable in its creation, and forgot to remove the "http://" from the beginning of it first. That's not the case with OP, but it was what brought me here. ;)

Maybe that's it? Any help would be awesome

May
04
5 months ago
Activity icon

Started a new Conversation Can You Guys Make Sure There Isn't A Problem With My Code Before I Reopen An Old Cashier Issue?

I'm having the same issue as this cashier git issue: Changing plans does not change the local subscription name

As the issue you implies:

$this->user->subscription('basic')->swap('premium');

Needs to be changed to this to be functional:

SubscriptionsTest.php

$this->user->subscription('basic')->swap('premium')->update(['name' => 'premium']);

It looks like there was a pull request made and it was merged to fix the bug. So maybe it's just my code:

protected $monthlyPlan;
protected $yearlyPlan;

protected function setUp(): void
{
    parent::setUp();

    $this->monthlyPlan = factory('App\Plan')->create(['name' => 'Monthly', 'stripe_plan_id' => 'plan_number_monthly']); 
    $this->yearlyPlan = factory('App\Plan')->create(['name' => 'Yearly', 'stripe_plan_id' => 'plan_number']);      
}

    /** @test */
public function a_user_can_change_their_subscription()
{
    $this->withoutExceptionHandling();

    Passport::actingAs($user = factory(User::class)->create());

    \Stripe\Stripe::setApiKey(\Config::get('services.stripe.secret'));
    $payment_method = \Stripe\PaymentMethod::create([
        'type' => 'card',
        'card' => [
            'number' => '4242424242424242',
            'exp_month' => 5,
            'exp_year' => 2021,
            'cvc' => '314',
        ],
    ]);

    $user->newSubscription($this->monthlyPlan->name, $this->monthlyPlan->stripe_plan_id)->create($payment_method['id']);

    

    $response = $this->json('POST', '/api/change-subscription', ['old_plan_id'=> $this->monthlyPlan->id, 'new_plan_id' => $this->yearlyPlan->id] )
        ->assertStatus(201);
    
    $this->assertTrue($user->subscribed('Yearly'));
}

api.php

Route::group(['middleware' => 'auth:api'], function() {
    Route::post('change-subscription', 'Api\[email protected]')->name('checkout.process');
});

CheckoutController.php

public function updateSubscription(Request $request)
{
    $newPlan = Plan::findOrFail($request->new_plan_id);
    $oldPlan = Plan::findOrFail($request->old_plan_id);


    try {
        $user = auth()->user();
        
        $user->subscription($oldPlan->name)->swap($newPlan->stripe_plan_id)->update(['name' => $newPlan->name]);

        return response([], 201);
    } catch (\Exception $e) {
        return response([], 500);
    }
}

As you can see, just like the git issues I had to add ->update(['name' => $newPlan->name]); to the end of $user->subscription($oldPlan->name)->swap($newPlan->stripe_plan_id)

I figure I'd just run it by you guys first before reopening the issue. Thanks for any help

Apr
28
5 months ago
Activity icon

Started a new Conversation Can Migrate DB, But On Insert Get: Access Denied For User 'root'@'localhost'

I'm using postman to try and make an API post request:

http://127.0.0.1:8000/api/auth/register?name=corbin&[email protected]&password=password

There must be a database connecting because I can migrate my db just fine. However when I try and create a record I get this:

Illuminate\Database\QueryException: SQLSTATE[HY000] [1045] Access denied for user 'root'@'localhost' (using password: NO) (SQL: insert into users (name, email, password, updated_at, created_at) values (corbin, [email protected], $2y$10$QfVSBr67zOJldKrxqjVVsO9pZ5QV9qOkvoCH./FPRZfSRVo1A4GqC, 2020-04-28 08:53:51, 2020-04-28 08:53:51)) in file /Applications/MAMP/htdocs/laravel-vue-spa/vendor/laravel/framework/src/Illuminate/Database/Connection.php on line 671

Here's my AuthController:

public function register(Request $request)
    {
       
        
        /*$request->validate([
            'name' => 'required|string|max:255',
            'email' => 'required|string|email|max:255|',
            'password' => 'required|string|min:6|confirmed'
        ]);*/

        $user = new User();
        $user->name = $request->name;
        $user->email = $request->email;
        $user->password = bcrypt($request->password);

        $user->save();

        /*if($user->save()){
            return response()->json([
                'message' => 'User was successfully created.',
                'status_code' => 201
            ], 201);
        } else {
            return response()->json([
                'message' => 'An error occured. Please try again.',
                'status_code' => 500
            ], 500);
        } */
    }

.env

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=laravel_spa
DB_USERNAME=root
DB_PASSWORD=password

I also tried switching DB_HOST=localhost