connecteev

connecteev

Member Since 5 Years Ago

Experience Points
13,330
Total
Experience

1,670 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
97
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 3
13,330 XP
Sep
18
1 day ago
Activity icon

Replied to Laravel 8 Team::factory() Not Found

Same error here, and my use-case is a lot simpler with no circular reference.

<?php

namespace Database\Seeders;

use App\Role;
use App\User;
use Illuminate\Database\Seeder;
use Faker\Generator as Faker;

// Call using command: php artisan db:seed --class=AdminUsersTableSeeder
class AdminUsersTableSeeder extends Seeder
{
    public function run(Faker $faker)
    {
        $adminRole = Role::where([
            'title' => 'Admin',
        ])->firstOrFail();

        User::factory()->create([
            'id'                => 1,
            'email'             => env('ADMIN_EMAIL'),
            'username'          => env('ADMIN_USERNAME'),
            'password'          => Hash::make(env('ADMIN_PASSWORD')),
            'email_verified_at' => now(),
            'remember_token'    => Str::random(10),
            'created_at'        => now(),
            'updated_at'        => now(),
        ]);
    }
}

This is the output

$ php artisan db:seed --class=AdminUsersTableSeeder

   BadMethodCallException 

  Call to undefined method App\User::factory()

  at vendor/laravel/framework/src/Illuminate/Support/Traits/ForwardsCalls.php:50
     46▕      * @throws \BadMethodCallException
     47▕      */
     48▕     protected static function throwBadMethodCallException($method)
     49▕     {
  ➜  50▕         throw new BadMethodCallException(sprintf(
     51▕             'Call to undefined method %s::%s()', static::class, $method
     52▕         ));
     53▕     }
     54▕ }

  • Bad Method Call: Did you mean App\User::toArray() ? 

      +3 vendor frames 
  4   database/seeders/AdminUsersTableSeeder.php:20
      Illuminate\Database\Eloquent\Model::__callStatic("factory", [])

      +24 vendor frames 
  29  artisan:37
      Illuminate\Foundation\Console\Kernel::handle(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))

and it's driving me nuts. Anyone??

Sep
01
2 weeks ago
Activity icon

Replied to Cant Upgrade Php Version On MacOS Catalina

@rafaelmelope

/usr/local/bin/php is a logical link to /usr/local/Cellar/php/7.4.9/bin/php

so I think you meant this:

sudo ln -s /usr/local/Cellar/php/7.4.9/bin/php /usr/bin/php

Unfortunately Catalina's system integrity protection wont let me do that.

$ sudo ln -s /usr/local/Cellar/php/7.4.9/bin/php /usr/bin/php
Password:
ln: /usr/bin/php: Operation not permitted

Ready to hang in the towel on this one - was really hoping for a way to fix the php version in /usr/bin/php, but Apple makes it really difficult.

Aug
31
2 weeks ago
Activity icon

Replied to Cant Upgrade Php Version On MacOS Catalina

@bugsysha I want to use php locally (instead of homestead or valet) - i dont want to deal with VMs, port forwarding, and all that

@snapey @tykus good point yeah, and that works, but I'd like to just run "php" and not have to worry about version differences and being bitten by this issue again. Hope that makes sense.

@tisuchi I did try the approach at http://laravel-school.com/posts/macbook-update-php-version-globally-35 but it didnt work for me. My cron job still invokes /usr/bin/php which has version 7.3.

@tray2 that didnt work either.

Activity icon

Started a new Conversation Cant Upgrade Php Version On MacOS Catalina

I have a very annoying problem. I have 2 versions of PHP on MacOS Catalina, and no matter what I do, I cant seem to get rid of the old (php 7.3.x) version. I can't change anything in /usr/bin/ on my Mac, even though I'm an admin user.

The 2 versions of PHP are:

$ /usr/bin/php -v
PHP 7.3.11 (cli) (built: Apr 17 2020 19:14:14) ( NTS )
$ /usr/local/bin/php -v
PHP 7.4.9 (cli) (built: Aug  7 2020 19:23:06) ( NTS )

Even though which php and php -v use 7.4:

$ which php
/usr/local/bin/php
$ php -v
PHP 7.4.9 (cli) (built: Aug  7 2020 19:23:06) ( NTS )

The problem is that when my cron job runs, it uses /usr/bin/php (version 7.3.x), making my cron job fail (turns out some Laravel package code - specifically Mailcoach - is not compiant with php 7.3.* and NEEDS php v 7.4 or above.

This is what my PATH variable looks like:

$ echo $PATH
/usr/local/bin/php:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:./vendor/bin:/usr/local/sbin:/Users/kunalpunjabi/.composer/vendor/bin:/usr/local/mysql/bin:/usr/local/bin/mysql

If you've encountered this before or know how to fix it, please help!

Aug
11
1 month ago
Activity icon

Replied to Package Or Repo For Email Drip Campaign Functionality? (not Drip.com)

Thanks @bobbybouwmann just looking for a good starting point

Activity icon

Started a new Conversation Package Or Repo For Email Drip Campaign Functionality? (not Drip.com)

I am looking for a Laravel Package or Repo that implements email Drip campaigns (NOT using Drip.com), on top of ANY email provider (whether custom or using a provider like Mailgun). I am using Laravel Mailcoach for my emails and they dont have Drip functionality yet - but this is something I urgently need. I intend to build a layer in my app that uses Mailcoach underneath....really need a good starting point.

Any pointers to code snippets or repos that do the Drip portion (adding / editing / deleting / scheduling Drip campaigns) would be helpful.

Jul
31
1 month ago
Activity icon

Started a new Conversation Nuxt Subdomain Routing

I'm trying to implement subdomain routing in Nuxt. This is what I need to do:

/pages/username/index.vue:
username1.mydomain.com (this page should display "hello, i am username1")
username2.mydomain.com (this page should display "hello, i am username2")
username3.mydomain.com (this page should display "hello, i am username3")
username4.mydomain.com (this page should display "hello, i am username4")
and so on

/pages/username/content.vue
username1.mydomain.com/content (this page should display "content by username1")
username2.mydomain.com/content (this page should display "content by username2")
username3.mydomain.com/content (this page should display "content by username3")
username4.mydomain.com/content (this page should display "content by username4")
and so on

I found this link (have yet to make it work) but it uses @Nuxtjs/router to (i think) override vue-router - wondering if there's a better way, I really like nuxt's ability to "create a page and you dont need to define the route" approach. Is there a way to do this in nuxt, ideally without vue-router, keeping the nuxt default page / routing behavior?

Jun
09
3 months ago
Activity icon

Replied to How To Test Social Login In Laravel?

@uxweb did you figure this out? Perhaps you could share your solution with the community

May
31
3 months ago
Activity icon

Replied to How To Create A Tailwind.css File From A Config File

@bobbybouwmann yes - thats right. My use case: I am trying to submit a PR to this repo: https://github.com/kiliman/tailwindui-crawler But it requires you to have a pre-built tailwind.css file (or pull from the CDN), it doesn't work with a tailwind.config.js file. I'm looking to take the config file and create the tailwind.css file from it programmatically with a shell command.

May
30
3 months ago
Activity icon

Replied to How To Create A Tailwind.css File From A Config File

That's right @bobbybouwmann @hjortur17 I would appreciate your thoughts - I need a (short) script to do this build / conversion for me.

@bobbybouwmann pointed me to the scripts, like the build script

but I dont know how to trigger it without an input file. Someone created a PR for this today, but it's not been tested / accepted into the tailwind repo yet, so I am stuck https://github.com/tailwindcss/tailwindcss/pull/1861

I need another way that doesnt rely on changing tailwindcss (there have to be other ways - all the frameworks have tailwindcss integration from the CLI...I just need a minimal one that "just works").

Activity icon

Replied to How To Create A Tailwind.css File From A Config File

@bobbybouwmann thanks for the response, but that looks quite complicated. I'm a newbie when it comes to javascript and builds...I have noidea how to start with this.

Activity icon

Started a new Conversation How To Create A Tailwind.css File From A Config File

I have a tailwind.config.js file.I am looking for a command to generate a tailwind.css file, using the config. I need to do this in a programmatic way.

There has to be a way - I'm sure tailwind is doing it themselves in their build chain. So are frameworks like react and nuxt when you create a react / nuxt app from the command line and configure tailwindcss. The question is how?

May
24
3 months ago
Activity icon

Replied to Seeing Puzzling And Inconsistent Results With Unit Test

@talinon Very interesting, thanks so much for the explanation! I have been breaking my head on this for hours on end.

Just curious, why would this work, then, without a refresh?

        $response = $this->actingAs($user, 'api')->json('POST', '/api/v1/me/payments/updateDefaultPaymentMethod', [
            'paymentMethodId' => $paymentMethod['id']
        ]);

In the API call, updateDefaultPaymentMethod did this:

    public function updateDefaultPaymentMethod(Request $request)
    {
            $loggedinUser = auth()->user();
            $paymentMethodId = $request->get('paymentMethodId');
            if ($loggedinUser->stripe_id == null) {
                $loggedinUser->createAsStripeCustomer();
            }

            // Accepts a Stripe payment method identifier and will assign the new payment method
            // as the default billing payment method
            $loggedinUser->updateDefaultPaymentMethod($paymentMethodId);

            return response([
                "success" => true,
            ], Response::HTTP_OK);
    }

Then getting the default payment method returned the correct result:

            $stripeCustomer = $user->asStripeCustomer();
            $defaultPaymentMethodId = ($stripeCustomer && $stripeCustomer->invoice_settings) ? $stripeCustomer->invoice_settings->default_payment_method : null;

Maybe a refresh() wasn't needed because I was accessing the $user model directly?

Activity icon

Replied to Seeing Puzzling And Inconsistent Results With Unit Test

@talinon whoa, that worked. I'm really puzzled as to why?

From my debugging, I put this in Laravel\Cashier\Concerns\ManagesSubscriptions::subscribed()

print_r($this->subscriptions);
  • With Method 1 (direct call), $this->subscriptions was an array with 1 entry, subsequently calling subscribed() on the user object returned TRUE.
  • With Method 2 (API call), $this->subscriptions was an empty array, subsequently calling subscribed() on the user object returned FALSE.
  • With Method 2 (API call, using refresh()), $this->subscriptions was an array with 1 entry, subsequently calling subscribed() on the user object returned TRUE.

I have so many questions: What does the refresh() method do? I did find Illuminate\Database\Eloquent\Model::refresh() whose comment says:

    /**
     * Reload the current model instance with fresh attributes from the database.
     *
     * @return $this
     */
    public function refresh()
    {
...

But I am not sure I have the right function.

Why is refresh() necessary? Is it a symptom that my unit test is not well-written, or is it really necessary?

Thank you!

Activity icon

Replied to Seeing Puzzling And Inconsistent Results With Unit Test

@talinon thank you, I will use config() instead of env() as much as possible going forward.

Shouldn't your endpoint be using $loggedInUser and not $user? No, because in Method 1, the endpoint is being called by my front-end (vuejs). In Method 2, I need to call it from my unit test.

Other API calls from my unit test seem to work fine...for example:

        // update the default Stripe payment method for the user
        $response = $this->actingAs($user, 'api')->json('POST', '/api/v1/me/payments/updateDefaultPaymentMethod', [
            'paymentMethodId' => $paymentMethod['id']
        ]);

I just can't figure out why this one doesn't work.

Activity icon

Replied to Seeing Puzzling And Inconsistent Results With Unit Test

Update: In case you're curious, the env variables are accessible from the unit test. I'm not sure why there's this inconsistency or how to fix this. Any ideas?

Activity icon

Started a new Conversation Seeing Puzzling And Inconsistent Results With Unit Test

Method 1: directly call Laravel Cashier's API to create a new subscription

$user->newSubscription(env('STRIPE_SUBSCRIPTION_PRODUCT_NAME'), env('STRIPE_ID_PLAN_1'))->create($paymentMethodId);

$isUserSubscribed = $user->subscribed(env('STRIPE_SUBSCRIPTION_PRODUCT_NAME'));

This returns $isUserSubscribed = TRUE.

Method 2: My unit test makes an API call to my API endpoint at /api/v1/me/payments/createOrUpdateSubscription:

        $response = $this->actingAs($user, 'api')->json('PUT', '/api/v1/me/payments/createOrUpdateSubscription', [
            'stripePlanId' => env('STRIPE_ID_PLAN_1'),
            'paymentMethodId' => $paymentMethodId
        ]);

The API endpoint does this (which is exactly the same as what method #1 does directly)

        $loggedinUser = auth()->user();
        $loggedinUser->newSubscription(env('STRIPE_SUBSCRIPTION_PRODUCT_NAME'), $stripePlanId)->create($paymentMethodId);

$isUserSubscribed = $user->subscribed(env('STRIPE_SUBSCRIPTION_PRODUCT_NAME'));

This returns $isUserSubscribed = FALSE.

Whyy??

May
19
4 months ago
Activity icon

Started a new Conversation Calling Stripe's Javascript APIs From PHPUnit?

This may come off as a strange question, is there a way to call a javascript API from phpunit or laravel dusk? I need to call Stripe's Javascript API: https://stripe.com/docs/js/setup_intents/confirm_card_setup and I don't see a "php" or backend way of doing it

I have a value for this.stripePublicKey and intentToken available in phpunit, I now need to do this:

      this.stripe = Stripe(this.stripePublicKey);
      this.elements = this.stripe.elements();
      this.card = this.elements.create('card', {style: this.stripeOptions.style});
      this.card.mount('#card-element');

      this.stripe.confirmCardSetup(
        this.intentToken.client_secret, {
          payment_method: {
            card: this.card,
            billing_details: {
              name: this.name
            }
          }
        }
      ).then(function(result) {
          console.log("Your card has been added to your account, but you have not yet been charged");
          this.savePaymentMethod(result.setupIntent.payment_method);
      }.bind(this));

Activity icon

Replied to Factory Error On Calling $user->roles()->sync(1) From Unit Test

Not very elegant but this seems to work: https://stackoverflow.com/a/17727695/11491070

No idea what triggers the error though!

Activity icon

Started a new Conversation Factory Error On Calling $user->roles()->sync(1) From Unit Test

I'm seeing a weird error when I try to create my first unit test to create a user and call sync()

class PaymentsAndSubscriptionsTest extends TestCase
{
    // use RefreshDatabase; // cleans out the entire database

    public function setUp(): void
    {
        parent::setUp();
    }

    public function tearDown(): void
    {
        // parent::tearDown();
    }

    /**
     * Can do something
     * @test
     */
    public function can_do_something2()
    {
        $user = $this->create('User', [], false);
        $user->roles()->sync(1); // make sure the new user created has their 'role' set, otherwise we'll get a 403 unauthorized response
    }

Error:

phpunit
PHPUnit 8.5.3 by Sebastian Bergmann and contributors.

....S..EPHP Fatal error:  Cannot redeclare createUnique() (previously declared in /kb_backend_apis_laravel/database/factories/ReactionFactory.php:41) in /kb_backend_apis_laravel/database/factories/ReactionFactory.php on line 41
PHP Fatal error:  Uncaught Illuminate\Contracts\Container\BindingResolutionException: Target [Illuminate\Contracts\Debug\ExceptionHandler] is not instantiable. in /kb_backend_apis_laravel/vendor/laravel/framework/src/Illuminate/Container/Container.php:1011

this is the factory where it's coming from, except I'm not calling it from my unit test...

$factory->state(Reaction::class, 'to_posts', function (Faker $faker) {
    return createUnique($faker, "Post");
});

$factory->state(Reaction::class, 'to_comments', function (Faker $faker) {
    return createUnique($faker, "Comment");
});

// $entityType: Post | Comment
function createUnique(Faker $faker, $entityType)
{
...
}

Any ideas?

May
17
4 months ago
Activity icon

Replied to Finding A Unique Record (based On A Composite Key) In Eloquent

@spyworld thanks but my User table or Reaction table isn't empty, so this doesnt solve my problem. I basically need an eloquent query that does this:

Find the first (or a random) row in the reactions table for which the combination of reactable_id + user_id does NOT exist.

Activity icon

Replied to Access 2 Values From .env In Phpunit.xml (without A New .env.testing File)

@click thanks for the tips, appreciate you responding. The maintenance burden comes from updating the .env.testing file for local, dev, staging, production with every addition of an env variable... I have these .env files for these environments and it's already starting to get unweildy..

Activity icon

Started a new Conversation Finding A Unique Record (based On A Composite Key) In Eloquent

I have 3 tables: users, posts, reactions...they're self-explanatory. A user can react to (like) a post, so the reactions table contains: id, user_id, post_id. I have a unique DB constraint for: user_id, post_id, ie a specific user can only react to a given post ONCE.

I am trying to create a seeder (using factories) to generate 1000 random reactions using a factory. Here's my old code, which doesn't work.

$factory->define(Reaction::class, function (Faker $faker) {
    $isRemoved = $faker->boolean(10); // parameter = chance of being true
    return [
        'is_archived' => $isRemoved,
        'deleted_at' => $isRemoved ? now() : NULL,
    ];
});

$factory->state(Reaction::class, 'to_posts', function (Faker $faker) {
    $randomPost = Post::inRandomOrder()->first();
    $reactableId = $randomPost['id'];
    $reactableType = 'App\Post';
    $randomUserId = getUniqueUserId($reactableType, $reactableId); 
    return [
        'user_id' => $randomUserId,
        'reactable_type' => $reactableType, // type of entity this reaction was made to
        'reactable_id' => $reactableId, // id of entity this reaction was made to
        'created_at' => null,
        'updated_at' =>  null,
    ];
});


// Get a random User ID, to avoid the unique constraints on the reactions table
// The combination of user_id, reactable_type, reactable_id have to be unique
function getUniqueUserId($reactableType, $reactableId)
{
    $usersThatHaveReactedToThis =
        Reaction::where([
            ['reactable_type', '=', $reactableType],
            ['reactable_id', '=', $reactableId],
        ])
        ->pluck('user_id')
        ->toArray();

    $randomUser =
        User::whereNotIn('id', $usersThatHaveReactedToThis)
        ->inRandomOrder()
        ->first();

    if (!$randomUser) {
        echo "Exiting Seeder: No random User could be found in the DB\n";
        exit;
    }

    $user_id = $randomUser->id;
    return $user_id;
}

Schema:

CREATE TABLE `reactions` (
  `id` int unsigned NOT NULL AUTO_INCREMENT,
  `is_archived` tinyint(1) DEFAULT '0',
  `created_at` timestamp NULL DEFAULT NULL,
  `updated_at` timestamp NULL DEFAULT NULL,
  `deleted_at` timestamp NULL DEFAULT NULL,
  `user_id` int unsigned NOT NULL,
  `reactable_type` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
  `reactable_id` int unsigned NOT NULL,
  PRIMARY KEY (`id`),
  KEY `user_fk_1390101` (`user_id`),
  CONSTRAINT `user_fk_1390101` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=401 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

As you can see, it first tries to get a random post, then it tries to find a user that has not reacted to the post. which is not the same logic as what I am trying to do now. This sucks because it's doing it serially like this, it cannot find UNIQUE values (I have a unique DB constraint for: user_id, post_id, ie a specific user can only react to a given post ONCE, which makes sense) With this, my seeder dies because of "conflicts".

Seeding: ReactionsFakeDataSeeder
Seeding Reactions... 
Exiting Seeder: No random User could be found in the DB

So, it couldnt find a random user that has not reacted to this post - doesnt mean that another random user that has not reacted to a different post does not exist.

My logic above is flawed. A better way would be to write an eloquent query to get any random user than has NOT reacted to any post. What is the best way to go about doing this?

Activity icon

Replied to Access 2 Values From .env In Phpunit.xml (without A New .env.testing File)

@michaloravec it's an interesting idea, but it doesn't quite work..

config/database.php:

        'testing' => [
            'driver' => env('DB_DRIVER_PHPUNIT'),
            'url' => env('DATABASE_URL'),
            'host' => env('DB_HOST', '127.0.0.1'),
            'port' => env('DB_PORT', '3306'),
            'database' => env('DB_DATABASE_PHPUNIT'),
            'username' => env('DB_USERNAME_PHPUNIT'),
            'password' => env('DB_PASSWORD_PHPUNIT'),
        ],

.env file:


DB_CONNECTION_PHPUNIT=testing
DB_DRIVER_PHPUNIT=mysql
DB_DATABASE_PHPUNIT=my_laravel_testing_db
DB_USERNAME_PHPUNIT=root
DB_PASSWORD_PHPUNIT=root

phpunit.xml:


    <php>
        <server name="APP_ENV" value="testing"/>
        <server name="BCRYPT_ROUNDS" value="4"/>
        <server name="CACHE_DRIVER" value="array"/>
        <server name="DB_CONNECTION" value="testing"/>
        <server name="MAIL_MAILER" value="array"/>
        <server name="QUEUE_CONNECTION" value="sync"/>
        <server name="SESSION_DRIVER" value="array"/>
    </php>

This is what I have in my Feature/Api/PostsApiTest.php:


<?php
// See more sample TDD / Unit Test code in /Users/kunalpunjabi/Code/KEENBRAIN_NUXT/TDD/devlob_apis_in_laravel_using_tdd/tests/Feature/Http/Controllers/

namespace Tests\Feature\Api;

use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Foundation\Testing\WithFaker;

use Tests\TestCase;
use App\User;
use Symfony\Component\HttpFoundation\Response;

class PostsApiTest extends TestCase
{
    use RefreshDatabase; // cleans out the entire database

    public function setUp(): void
    {
        // parent::setUp();
        // $this->artisan('passport:install');
    }

    public function tearDown(): void
    {
        // parent::tearDown();
    }


    /**
     * Can do something
     * @test
     */
    public function can_do_something()
    {
        $user = \App\User::find(['id' => 1]);
        $this->assertTrue($user->email == "[email protected]");
    }

This is the error I see on running phpunit:

There was 1 error:

1) Tests\Feature\Api\PostsApiTest::can_do_something
Error: Call to a member function connection() on null


Activity icon

Replied to Access 2 Values From .env In Phpunit.xml (without A New .env.testing File)

@click I dont think you're understanding the question.

<server name="DB_DATABASE" value="abc" />

works fine.

I am trying to get 'value' of DB_DATABASE from a DIFFERENT .env variable that I have defined in my .env file, called DB_DATABASE_PHPUNIT.

The idea is that I can't have different versions of my phpunit.xml file on dev/staging/production. So I am trying to read from my .env file - is this possible? I really would like to avoid a new .env.testing file - it becomes a maintenance burden.

Activity icon

Started a new Conversation Access 2 Values From .env In Phpunit.xml (without A New .env.testing File)

I am trying to ** read ** values from my .env file and access them in phpunit.xml Is there a way to do this? I do not want to define a new .env.testing file and have to maintain it separately, I just want to override 2 variables in my .env file.

I have tried:

        <server name="DB_CONNECTION" value="config('DB_CONNECTION_PHPUNIT')"/>
        <server name="DB_CONNECTION" value="env('DB_CONNECTION_PHPUNIT')"/>

phpunit errors out with:

4) Tests\Feature\Api\PostsApiTest::non_authenticated_users_cannot_access_the_following_endpoints_for_the_posts_api
InvalidArgumentException: Database connection [env('DB_CONNECTION_PHPUNIT')] not configured.

Any way to do this?

Activity icon

Replied to Phpunit.xml Not Being Read, Using Variables From .env

I am trying to ** read ** values from my .env file and access them in phpunit.xml Is there a way to do this? I do not want to define a new .env.testing file and have to maintain it separately, I just want to override 2 variables in my .env file.

I have tried:

        <server name="DB_CONNECTION" value="config('DB_CONNECTION_PHPUNIT')"/>
        <server name="DB_CONNECTION" value="env('DB_CONNECTION_PHPUNIT')"/>

phpunit errors out with:

4) Tests\Feature\Api\PostsApiTest::non_authenticated_users_cannot_access_the_following_endpoints_for_the_posts_api
InvalidArgumentException: Database connection [env('DB_CONNECTION_PHPUNIT')] not configured.

Any way to do this?

May
16
4 months ago
Activity icon

Commented on Automatically Resolve Dependencies

Not sure if this is the right place to ask, but the topic seems appropriate.

Deployingmy laravel app to ubuntu and I'm really stumped why it wont work. The logs show something that might be related to the service container:

2020/05/16 00:26:07 [error] 2056#2056: *5023 FastCGI sent in stderr: "PHP message: PHP Fatal error:  Uncaught ReflectionException: Class translator does not exist in /home/domains/apistaging.mydomain.com/public/current/vendor/laravel/framework/src/Illuminate/Container/Container.php:805
Stack trace:
#0 /home/domains/apistaging.mydomain.com/public/current/vendor/laravel/framework/src/Illuminate/Container/Container.php(805): ReflectionClass->__construct('translator')
#1 /home/domains/apistaging.mydomain.com/public/current/vendor/laravel/framework/src/Illuminate/Container/Container.php(687): Illuminate\Container\Container->build('translator')
#2 /home/domains/apistaging.mydomain.com/public/current/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(796): Illuminate\Container\Container->resolve('translator', Array, true)
#3 /home/domains/apistaging.mydomain.com/public/current/vendor/laravel/framework/src/Illuminate/Container/Container.php(633): Illuminate\Foundation\Application->resolve('translator', Array)
#4 /home/domains/apistaging.mydomain.com/pu...PHP message: PHP Fatal error:  Uncaught ReflectionException: Class translator does not exist in /home/domains/apistaging.mydomain.com/public/current/vendor$

Anyone seen this? This tip didnt help either https://stackoverflow.com/questions/45506239/reflectionexception-class-translator-does-not-exists

Activity icon

Awarded Best Reply on Nginx Config Causes "Primary Script Unknown"

Turns out the fix for this was simple. I had pm2 running, causing a conflicting port

For future reference, if anyone encounters this same issue, run:

pm2 stop all

sudo fuser -k 443/tcp (finds processes using files or socket (in this case TCP port 443) and KILLS them using the -k attribute)

and try a restart again:
sudo service nginx restart
Activity icon

Replied to Nginx Config Causes "Primary Script Unknown"

Turns out the fix for this was simple. I had pm2 running, causing a conflicting port

For future reference, if anyone encounters this same issue, run:

pm2 stop all

sudo fuser -k 443/tcp (finds processes using files or socket (in this case TCP port 443) and KILLS them using the -k attribute)

and try a restart again:
sudo service nginx restart
Activity icon

Started a new Conversation Nginx Config Causes "Primary Script Unknown"

I am having a really puzzling issue with my nginx config. I keep seeing this error:

FastCGI sent in stderr: "Primary script unknown" while reading response header from upstream
client: 76.14.172.29, server: apistaging.mydomain.com, request: 
"GET / HTTP/2.0", upstream: "fastcgi://unix:/var/run/php/php7.4-fpm.sock:", host: "apistaging.mydomain.com"

I did try the suggestions in this question and also this one but nothing has worked. I am asking as a separate question in the hope that someone can help me out (after 2 days stuck on this).

This is my nginx/sites/available/apistaging.mydomain.com.conf file:

server {
        server_name apistaging.mydomain.com;

        # make sure you point to a laravel or wordpress public directory containing an index.php file
        root /home/domains/apistaging.mydomain.com/public/current/public;

        # From https://www.linode.com/docs/web-servers/nginx/slightly-more-advanced-configurations-for-nginx/#host-multiple-websites
        # This link may be outdated. adding 'main' and 'error' makes nginx crap out
        #access_log   /home/domains/apistaging.mydomain.com/log/apistaging.mydomain.access.log;
        error_log   /home/domains/apistaging.mydomain.com/log/apistaging.mydomain.error.log;

        # from https://www.linode.com/docs/web-servers/nginx/slightly-more-advanced-configurations-for-nginx/#limit-or-disable-content-embedding
        add_header X-Frame-Options "SAMEORIGIN";

        # from https://www.linode.com/docs/web-servers/nginx/slightly-more-advanced-configurations-for-nginx/#cross-site-scripting-xss-filter
        add_header X-XSS-Protection "1; mode=block";

        # from https://www.linode.com/docs/web-servers/nginx/slightly-more-advanced-configurations-for-nginx/#disable-content-sniffing
        add_header X-Content-Type-Options "nosniff";

        index index.html index.htm index.php;

        charset utf-8;

        location / {
                try_files $uri $uri/ /index.php?$query_string;
        }

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

        #error_page 404 /index.php;
        # create a custom 404 nginx page, from https://www.digitalocean.com/community/tutorials/how-to-configure-nginx-to-use-custom-error-pages-on-ubuntu-14-04
        error_page 404 /custom_404.html;
        location = /custom_404.html {
            root /etc/nginx/sites-available/custom_nginx_error_pages;
            internal;
        }

        location ~ \.php$ {
                # After installation of php-fpm, check in /var/run/php/ for a fpm sock file like: /var/run/php/php7.3-fpm.sock
                fastcgi_pass unix:/var/run/php/php7.3-fpm.sock;
                fastcgi_index index.php;
                fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
                include fastcgi_params;
        }

        location ~ /\.(?!well-known).* {
                deny all;
        }

        # From https://www.linode.com/docs/web-servers/nginx/nginx-installation-and-basic-setup/#static-content-compression
        # Note that gzip has security vulnerabilities and it used to be off by default in the base nginx.conf file (oddly it is set to on by default now)
        # Make sure that gzip is set / enabled only in server{} blocks for individual site configs, not globally in nginx.conf.
        # Though gzip directives can go in the http block if you want it to apply to all sites served by NGINX, it’s safer to use it only inside server blocks for individual sites and content types
        gzip on;
        gzip_types text/plain text/css image/* application/json application/javascript text/xml application/xml application/xml+rss text/javascript;

        #listen 443 ssl http2 ipv6only=on; # managed by Certbot (not sure if we support ipv6 yet)
        listen 443 ssl http2; # managed by Certbot, modified to add http2

        #Install SSL certificates and configure https:// on a per-domain-basis by running:
        #sudo certbot --nginx
        #(when prompted, be sure to select the option to set up redirects from http to https and effectively "disable" http)

        include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
        include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
        ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
    ssl_certificate /etc/letsencrypt/live/apistaging.mydomain.com-0002/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/apistaging.mydomain.com-0002/privkey.pem; # managed by Certbot

}

server {
    server_name apistaging.mydomain.com;

    if ($host = apistaging.mydomain.com) {
        return 301 https://$host$request_uri;
    } # managed by Certbot

    listen 80;
    return 404; # managed by Certbot
}

Any help is appreciated.

Activity icon

Replied to Configuring PHPUnit To Connect With A Test DB

@imre08 yes, that works.

What is a good way to fill the DB tables before phpunit runs, and clear them after?

May
15
4 months ago
Activity icon

Replied to Configuring PHPUnit To Connect With A Test DB

@tray2 I cant use sqlite, my DB is way too complex and I need to perform complex operations in the tests.

I also need to use .env.testing, but it looks like the phpunit.xml file takes precedence.

Activity icon

Started a new Conversation Configuring PHPUnit To Connect With A Test DB

Here's what I'd like to do..

  • have a test DB in MySQL (backend_apis_laravel_testing) that gets used for all PhpUnit tests. I do not want to use Sqlite (because I don't know how to view the database and tables in sqlite)
  • clear any cache (if needed) before PHPUnit runs
  • migrate the DB (and seeds) before PHPUnit runs, and cleanup after
  • ignore all settings in phpunit.xml, and only use the .env.testing file (not sure what takes precedence - the .env.testing file, or the settings in phpunit.xml. I would like my .env.testing file to override the phpunit.xml - for reasons that will take too long to explain, I am not allowed to change the phpunit.xml file.

These are the .env.testing settings I would like to use:

APP_NAME=KB
APP_ENV=testing
APP_KEY=base64:SjuP4OPbjmKHASkC22SFF3HbU+p6K22Pi+YkPsxIIwU=
APP_DEBUG=true
APP_URL=http://localhost:8000
FRONTEND_CLIENT_URL=http://localhost:3000

LOG_CHANNEL=stack

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=backend_apis_laravel_testing
DB_USERNAME=root
DB_PASSWORD=root

And yet, running phpunit keeps using phpunit.xml's settings (and connecting to sqlite, which I don't want). I also don't know how to do the DB migration setup / teardown (and cache clearing) in Laravel 7. Tips appreciated.

May
14
4 months ago
Activity icon

Started a new Conversation Laravel Cashier's Invoices(), UpcomingInvoice() And InvoicesIncludingPending() Return No Data

Even though $loggedinUser is a Billable model and belongs to a user with an active (monthly) subscription plan (subscribed() returns true and I can access this customer's subscription), calling invoicesIncludingPending(), upcomingInvoice() or invoices() on it returns no data.

            $loggedinUser = auth()->user();
            $upcomingInvoice = $loggedinUser->invoicesIncludingPending();
            $upcomingInvoice = $loggedinUser->upcomingInvoice();
            $upcomingInvoice = $loggedinUser->invoices();
            return response([
                "upcoming_invoice" => $upcomingInvoice,
            ], Response::HTTP_OK);

This is what I get back:

{
    "upcoming_invoice": [
        {}
    ]
}

Note that on the Stripe dashboard I do see an upcoming invoice 1 month from now: https://www.webpagescreenshot.info/#v2=572v2l6nG

Are any of you seeing this? Is this a bug in Cashier?

What I am trying to do is get the amount the user will be charged at the next billing cycle (note that this may NOT be the same as the subscription plan's price the user is on - they may have a credit applied to their account, etc)

FYI..

  • Cashier Version: 11
  • Laravel Version: 7.x
  • PHP Version: 7.4.5
  • Database Driver & Version: MySQL 8
Activity icon

Replied to Proper Way To Handle Exceptions

@bugsysha thanks for the help

May
13
4 months ago
Activity icon

Awarded Best Reply on Proper Way To Handle Exceptions

Figured it out, basically the signatures weren't matching:

In the controller:

    private function getDefaultPaymentMethodId(User $user)
    {
        try {
            $stripeCustomer = $user->asStripeCustomer();
            $defaultPaymentMethodId = $stripeCustomer->invoice_settings->default_payment_method;
            return $defaultPaymentMethodId;

        } catch (\Exception $e) {
            \Log::emergency('throw MyStripeException');
            throw new \App\Exceptions\MyStripeException($e);
        }
    }

In app\Exceptions\MyStripeException.php:


<?php

namespace App\Exceptions;

use Throwable;
use Exception;
use App\Exceptions\Handler;

class MyStripeException extends Exception
{
    public $exception;

    public function __construct(Exception $e)
    {
        $this->exception = $e;
        parent::__construct($e->getError()->message, $e->getCode(), null);
    }

    /**
     * Report or log an exception.
     *
     * @param  \Throwable  $exception
     * @return void
     *
     * @throws \Exception
     */
    public function report()
    {
        $e = $this->exception;
        \Log::emergency('In MyStripeException::report(): ' .
            ' Exception Message is:' . $e->getMessage() .
            ' Status is:' . $e->getHttpStatus() .
            ' Type is:' . $e->getError()->type .
            ' Code is:' . $e->getError()->code .
            ' Param is:' . $e->getError()->param .
            ' Message is:' . $e->getError()->message
        );

        if ($e instanceof \Stripe\Exception\CardException) {
            // Since it's a decline, \Stripe\Exception\CardException will be caught
            \Log::emergency("Since it's a decline, \Stripe\Exception\CardException will be caught");

        } else if ($e instanceof \Stripe\Exception\RateLimitException) {
            // Too many requests made to the API too quickly
            \Log::emergency("Too many requests made to the API too quickly");
        } else if ($e instanceof \Stripe\Exception\InvalidRequestException) {
            // Invalid parameters were supplied to Stripe's API
            \Log::emergency("Invalid parameters were supplied to Stripe's API");
        } else if ($e instanceof \Stripe\Exception\AuthenticationException) {
            // Authentication with Stripe's API failed
            // (maybe you changed API keys recently)
            \Log::emergency("Authentication with Stripe's API failed (maybe you changed API keys recently)");
        } else if ($e instanceof \Stripe\Exception\ApiConnectionException) {
            // Network communication with Stripe failed
            \Log::emergency("Network communication with Stripe failed");
        } else if ($e instanceof \Stripe\Exception\ApiErrorException) {
            // Display a very generic error to the user, and maybe send
            // yourself an email
            \Log::emergency("Display a very generic error to the user, and maybe send yourself an email");

        } else {
            // Something else happened, completely unrelated to Stripe
            \Log::emergency("Something else happened, completely unrelated to Stripe");
            parent::report($e);
        }
    }
}

Activity icon

Replied to Proper Way To Handle Exceptions

Figured it out, basically the signatures weren't matching:

In the controller:

    private function getDefaultPaymentMethodId(User $user)
    {
        try {
            $stripeCustomer = $user->asStripeCustomer();
            $defaultPaymentMethodId = $stripeCustomer->invoice_settings->default_payment_method;
            return $defaultPaymentMethodId;

        } catch (\Exception $e) {
            \Log::emergency('throw MyStripeException');
            throw new \App\Exceptions\MyStripeException($e);
        }
    }

In app\Exceptions\MyStripeException.php:


<?php

namespace App\Exceptions;

use Throwable;
use Exception;
use App\Exceptions\Handler;

class MyStripeException extends Exception
{
    public $exception;

    public function __construct(Exception $e)
    {
        $this->exception = $e;
        parent::__construct($e->getError()->message, $e->getCode(), null);
    }

    /**
     * Report or log an exception.
     *
     * @param  \Throwable  $exception
     * @return void
     *
     * @throws \Exception
     */
    public function report()
    {
        $e = $this->exception;
        \Log::emergency('In MyStripeException::report(): ' .
            ' Exception Message is:' . $e->getMessage() .
            ' Status is:' . $e->getHttpStatus() .
            ' Type is:' . $e->getError()->type .
            ' Code is:' . $e->getError()->code .
            ' Param is:' . $e->getError()->param .
            ' Message is:' . $e->getError()->message
        );

        if ($e instanceof \Stripe\Exception\CardException) {
            // Since it's a decline, \Stripe\Exception\CardException will be caught
            \Log::emergency("Since it's a decline, \Stripe\Exception\CardException will be caught");

        } else if ($e instanceof \Stripe\Exception\RateLimitException) {
            // Too many requests made to the API too quickly
            \Log::emergency("Too many requests made to the API too quickly");
        } else if ($e instanceof \Stripe\Exception\InvalidRequestException) {
            // Invalid parameters were supplied to Stripe's API
            \Log::emergency("Invalid parameters were supplied to Stripe's API");
        } else if ($e instanceof \Stripe\Exception\AuthenticationException) {
            // Authentication with Stripe's API failed
            // (maybe you changed API keys recently)
            \Log::emergency("Authentication with Stripe's API failed (maybe you changed API keys recently)");
        } else if ($e instanceof \Stripe\Exception\ApiConnectionException) {
            // Network communication with Stripe failed
            \Log::emergency("Network communication with Stripe failed");
        } else if ($e instanceof \Stripe\Exception\ApiErrorException) {
            // Display a very generic error to the user, and maybe send
            // yourself an email
            \Log::emergency("Display a very generic error to the user, and maybe send yourself an email");

        } else {
            // Something else happened, completely unrelated to Stripe
            \Log::emergency("Something else happened, completely unrelated to Stripe");
            parent::report($e);
        }
    }
}

Activity icon

Replied to Proper Way To Handle Exceptions

@bugsysha I need the exception data because I need to act on it differently, depending on what the exception thrown by Stripe is. I am trying to centralize all the Stripe exception handling, and Stripe can throw one of many exeptions, like \Stripe\Exception\RateLimitException, \Stripe\Exception\CardException, etc.

I did try using $this and it didn't work:

        try {
            $stripeCustomer = $user->asStripeCustomer();
            $defaultPaymentMethodId = $stripeCustomer->invoice_settings->default_payment_method;
            return $defaultPaymentMethodId;

        } catch (\Exception $e) {
            \Log::emergency('throw MyStripeException');
            throw new \App\Exceptions\MyStripeException(
                "{$e->getError()->message}", $e->getCode(), null
            );
        }

In class MyStripeException:

namespace App\Exceptions;

use Throwable;
use Exception;
use App\Exceptions\Handler;

class MyStripeException extends Exception
{
    // see vendor/laravel//cashier/src/Exceptions/IncompletePayment.php
    public function __construct($message = '', $code = 0, Throwable $previous = null)
    {
        parent::__construct($message, $code, $previous);
    }
    public function report()
    {
        // $e = Handler::prepareException($this);
        // $e = $this;
        \Log::emergency('In MyStripeException::report(): ' .
            $this->getMessage()
            // 'Status is:' . $e->getHttpStatus() .
            // 'Type is:' . $e->getError()->type .
            // 'Code is:' . $e->getError()->code .
            // 'Param is:' . $e->getError()->param .
            // 'Message is:' . $e->getError()->message
        );
   }

This is what I see in the logs:

[2020-05-13 15:12:58] local.EMERGENCY: throw MyStripeException  
[2020-05-13 15:12:58] local.EMERGENCY: In MyStripeException::report(): dude No such customer: dss  
[2020-05-13 15:12:58] local.EMERGENCY: Something else happened, completely unrelated to Stripe  
[2020-05-13 15:12:58] local.ERROR: Call to undefined method Exception::report() {"userId":1,"exception":"[object] (Error(code: 0): Call to undefined method Exception::report() at /app/Exceptions/MyStripeException.php:63)
[stacktrace]
Activity icon

Replied to Proper Way To Handle Exceptions

I also tried


    public function report()
    {
        $e = $this;
...

but had no luck either

Activity icon

Replied to Proper Way To Handle Exceptions

@bugsysha I tried that, here's the problem, I don't know how to access the $exception object in the render() function (so that I can then call $e->getError() etc, and the docs dont give an example how to do it.

Here's what I've tried:


<?php

namespace App\Exceptions;

use Throwable;
use Exception;
use App\Exceptions\Handler;

class MyStripeException extends Exception
{
    public function __construct($message = '', $code = 0, Throwable $previous = null)
    {
        parent::__construct($message, $code, $previous);
    }


    public function report(Exception $e)
    {
        // $e = $this;
        \Log::emergency('In MyStripeException::report(): ' .
            // 'Status is:' . $e->getHttpStatus() .
            'Type is:' . $e->getError()->type .
            'Code is:' . $e->getError()->code .
            'Param is:' . $e->getError()->param .
            'Message is:' . $e->getError()->message
        );

This is what I see in the logs:

[2020-05-13 14:27:34] local.EMERGENCY: throw MyStripeException  
[2020-05-13 14:27:34] local.ERROR: Unresolvable dependency resolving [Parameter #0 [ <optional> $message ]] in class Exception {"userId":1,"exception":"[object] (Illuminate\Contracts\Container\BindingResolutionException(code: 0): Unresolvable dependency resolving [Parameter #0 [ <optional> $message ]] in class Exception at /app/vendor/laravel/framework/src/Illuminate/Container/Container.php:1026)
[stacktrace]
#0 /app/vendor/laravel/framework/src/Illuminate/Container/Container.php(939): Illuminate\Container\Container->unresolvablePrimitive(Object(ReflectionParameter))
#1 /app/vendor/laravel/framework/src/Illuminate/Container/Container.php(874): Illuminate\Container\Container->resolvePrimitive(Object(ReflectionParameter))
#2 /app/vendor/laravel/framework/src/Illuminate/Container/Container.php(836): Illuminate\Container\Container->resolveDependencies(Array)
#3 /app/vendor/laravel/framework/src/Illuminate/Container/Container.php(687): Illuminate\Container\Container->build('Exception')
Activity icon

Started a new Conversation Proper Way To Handle Exceptions

What I am trying to do is build a Stripe-specific exception class to handle any Stripe-related exception:

        try {
            $stripeCustomer = $user->asStripeCustomer();
            $defaultPaymentMethodId = $stripeCustomer->invoice_settings->default_payment_method;
            return $defaultPaymentMethodId;

        } catch(\Stripe\Exception\CardException $e) {
            // Since it's a decline, \Stripe\Exception\CardException will be caught
            echo 'Status is:' . $e->getHttpStatus() . '\n';
            echo 'Type is:' . $e->getError()->type . '\n';
            echo 'Code is:' . $e->getError()->code . '\n';
            // param is '' in this case
            echo 'Param is:' . $e->getError()->param . '\n';
            echo 'Message is:' . $e->getError()->message . '\n';
        } catch (\Stripe\Exception\RateLimitException $e) {
            // Too many requests made to the API too quickly
        } catch (\Stripe\Exception\InvalidRequestException $e) {
            // Invalid parameters were supplied to Stripe's API
        } catch (\Stripe\Exception\AuthenticationException $e) {
            // Authentication with Stripe's API failed
            // (maybe you changed API keys recently)
        } catch (\Stripe\Exception\ApiConnectionException $e) {
            // Network communication with Stripe failed
        } catch (\Stripe\Exception\ApiErrorException $e) {
            // Display a very generic error to the user, and maybe send
            // yourself an email
        } catch (\Exception $e) {
            // Something else happened, completely unrelated to Stripe
            return [false, '$e->getError()->message', null];
        }

I would like to move all this exception logic (for Stripe) from my Controller above into an exception class.

What is the correct (Laravel) way to handle exceptions? How would you do it?

Some context:

When Laravel 7.x came out, according to the upgrade guide I believe there was a symfony-related update on how exceptions were handled.

Not sure if the php artisan make:exception command has been updated, but running php artisan make:exception MyStripeException generates a file like this

<?php

namespace App\Exceptions;

use Exception;

class MyStripeException extends Exception
{
    //
}

However, if you look at app\Exceptions\Handler.php it looks more like this


<?php

namespace App\Exceptions;

use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
use Throwable;

class Handler extends ExceptionHandler
{
    /**
     * A list of the exception types that are not reported.
     *
     * @var array
     */
    protected $dontReport = [
        //
    ];

    /**
     * A list of the inputs that are never flashed for validation exceptions.
     *
     * @var array
     */
    protected $dontFlash = [
        'password',
        'password_confirmation',
    ];

    /**
     * Report or log an exception.
     *
     * @param  \Throwable  $exception
     * @return void
     *
     * @throws \Exception
     */
    public function report(Throwable $exception)
    {
        parent::report($exception);
    }

    /**
     * Render an exception into an HTTP response.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Throwable  $exception
     * @return \Symfony\Component\HttpFoundation\Response
     *
     * @throws \Throwable
     */
    public function render($request, Throwable $exception)
    {
        return parent::render($request, $exception);
    }
}

Confused how to proceed - how would you build the exception class for Stripe?

May
12
4 months ago
Activity icon

Replied to Implementing A "Forever" Plan In Stripe (like Laracasts)

@bobbybouwmann thanks for sharing your thoughts...all of that makes sense.

Prorating when you upgrade from monthly -> forever: Stripe does support prorations, and Cashier does it by default, too. I plan on doing this.

Re: Downgrading and Canceling:

  • Can you downgrade from Yearly to Monthly? Stripe gives you a "credit" back, but you dont get your money back....you "spend" the credit every month. The balance will decrease the amount due on the customer's next invoice.

  • Can you cancel a Yearly plan? What happens? Stripe doesnt offer refunds, and any money you've paid is "lost" (unless you resume your subscription)

  • Can you cancel a Forever plan? What happens? You can't give a prorated credit back here - because you were being billed "forever". Can't see what Stripe does here because it doesn't offer a "forever" subscription plan. You are suggesting not allowing it at all, which may be the most logical thing to do. I'd like to know...Does Laracasts allow you to downgrade from Forever to Monthly / Yearly?

Thanks..

Activity icon

Started a new Conversation Implementing A "Forever" Plan In Stripe (like Laracasts)

Just like Laracasts, I am trying to implement a "Forever" Subscription plan in Stripe.

I have 2 questions:

  1. This is for anyone with knowledge about plan upgrades, downgrades and prorations. How would this work, if you were upgrading / downgrading from a monthly plan to the "forever" plan? I know Stripe takes care of prorations for you, but should downgrading from the "forever" plan be allowed? If so, how would the charges work?

  2. For anyone that has a "forever" subscription plan, does Laracasts allow you to downgrade (if you try)? I'm not trying to trick you into downgrading - I'm genuinely curious.

Activity icon

Started a new Conversation Fixing The Timezone For Datetime Fields

When I add a new record to MySQL, the created_at and updated_at fields are always 7 hours ahead of my current timezone (I am on PST or Pacific time).

I did try a SELECT NOW() in MySQL and it returns my current time (PST), however anytime my Laravel application adds a record, the created_at and updated_at fields (or any other dates) end up being 7 hours ahead.

What gives??