timgavin

Member Since 5 Years Ago

West Palm

Web Developer at Freelance

Experience Points 21,900
Experience Level 5

3,100 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 221
Lessons
Completed
Best Reply Awards 2
Best Reply
Awards
  • start-engines Created with Sketch.

    Start Your Engines

    Earned once you have completed your first Laracasts lesson.

  • first-thousand Created with Sketch.

    First Thousand

    Earned once you have earned your first 1000 experience points.

  • 1-year Created with Sketch.

    One Year Member

    Earned when you have been with Laracasts for 1 year.

  • 2-years Created with Sketch.

    Two Year Member

    Earned when you have been with Laracasts for 2 years.

  • 3-years Created with Sketch.

    Three Year Member

    Earned when you have been with Laracasts for 3 years.

  • 4-years Created with Sketch.

    Four Year Member

    Earned when you have been with Laracasts for 4 years.

  • 5-years Created with Sketch.

    Five Year Member

    Earned when you have been with Laracasts for 5 years.

  • school-session Created with Sketch.

    School In Session

    Earned when at least one Laracasts series has been fully completed.

  • welcome-newcomer Created with Sketch.

    Welcome To The Community

    Earned after your first post on the Laracasts forum.

  • full-time-student Created with Sketch.

    Full Time Learner

    Earned once 100 Laracasts lessons have been completed.

  • pay-it-forward Created with Sketch.

    Pay It Forward

    Earned once you receive your first "Best Reply" award on the Laracasts forum.

  • subscriber-token Created with Sketch.

    Subscriber

    Earned if you are a paying Laracasts subscriber.

  • lifer-token Created with Sketch.

    Lifer

    Earned if you have a lifetime subscription to Laracasts.

  • lara-evanghelist Created with Sketch.

    Laracasts Evangelist

    Earned if you share a link to Laracasts on social media. Please email [email protected] with your username and post URL to be awarded this badge.

  • chatty-cathy Created with Sketch.

    Chatty Cathy

    Earned once you have achieved 500 forum replies.

  • lara-veteran Created with Sketch.

    Laracasts Veteran

    Earned once your experience points passes 100,000.

  • 10k-strong Created with Sketch.

    Ten Thousand Strong

    Earned once your experience points hits 10,000.

  • lara-master Created with Sketch.

    Laracasts Master

    Earned once 1000 Laracasts lessons have been completed.

  • laracasts-tutor Created with Sketch.

    Laracasts Tutor

    Earned once your "Best Reply" award count is 100 or more.

  • laracasts-sensei Created with Sketch.

    Laracasts Sensei

    Earned once your experience points passes 1 million.

  • top-50 Created with Sketch.

    Top 50

    Earned once your experience points ranks in the top 50 of all Laracasts users.

25 May
1 month ago

timgavin left a reply on Help With Booking System Timezone Offsets

@WILLJOHNATHAN - Yes, they will be in their timezone, but it has to show a user across the planet that that hour has been reserverd in THEIR timezone, which means it has to shift days. If someone in Asia schedules on a Monday, someone in the US will see that on a Tuesday. Not sure this is actually possible without using full dates...

timgavin left a reply on Help With Booking System Timezone Offsets

@EJDELMONICO - Yes, I already have that working. My problem is with international conversion, which I'm actually not sure is possible without a full date.

22 May
2 months ago

timgavin started a new conversation Help With Booking System Timezone Offsets

A client ordered a booking system: they wanted a seven day schedule (Mon-Sun) that would allow for people to book an hour on each day. This system is global, so it's based on UTC.

Basically, the user picks a day - let's say Monday - and a time (12:pm EST) and reserves that block. So we store it like so:

reserved_day = 1;
reserved_time = 5:00:00

Day 1 = Monday 5:00:00 = 12:pm EST UTC.

So this means if you're in the America/Los_Angeles time zone, you'd see this as 9:00 am Monday. It's working as it should.

Keep in mind this is not a calendar app; there are only 168 blocks of time available to book (24 hours in a day * 7 days), so Monday has 24 blocks, Tuesday has 24 blocks, etc.

Now here's the rub: if someone books in Asia, where it's a day ahead, should the app be able to reflect that? So if someone in Bangkok registers on a Monday, should a person in Chicago see that as a reserved time on Tuesday? Or should they see it as reserved time on Monday?

If so, how is this accomplished? Carbon only seems to do the hours, not the days.

17 May
2 months ago

timgavin left a reply on How To Create Custom Email Verification Template | Laravel 5.7

For anyone in the future wondering how to do this.

<?php

namespace App\Providers;

use Carbon\Carbon;
use Illuminate\Auth\Notifications\VerifyEmail;
use Illuminate\Notifications\Messages\MailMessage;
use Illuminate\Support\Facades\URL;
use Illuminate\Support\ServiceProvider;

class AppServiceProvider extends ServiceProvider
{
    public function boot()
    {
        VerifyEmail::toMailUsing(function ($notifiable) {
            $verifyUrl = URL::temporarySignedRoute(
                'verification.verify', Carbon::now()->addMinutes(60), ['id' => $notifiable->getKey()]
            );

            return (new MailMessage)
                ->subject('Welcome!')
                ->markdown('emails.verify', ['url' => $verifyUrl]);
        });
    }

    public function register()
    {
        //
    }
}

Source: https://twitter.com/stefanbauerme/status/1037704501862559745/

18 Apr
3 months ago

timgavin left a reply on Trouble With Defining Relationships

@MKBAT - I found the problem. I was using Spatie's Laravel Tags and decided to create my own instead. I renamed the file from Tag.php to -Tag.php but forgot to rename the Class - so Laravel was using that one instead of mine! So i deleted -Tag.php and everything started working. Geesh.

Thanks again for your help!

timgavin left a reply on Trouble With Defining Relationships

Neither of these work

    $posts = Post::latest('created_at')->with('tags')->paginate(20);
    $posts = Post::latest('created_at')->with('tags')->paginate(20);

timgavin left a reply on Trouble With Defining Relationships

This is really strange. If I dd($posts) I see all posts with the tags relationship. However, if I do the following:

foreach($posts as $post) {
    dd($post->tags);
}

I get the following error

Column not found: 1054 Unknown column 'tag' in 'field list' (SQL: select `tag` from `tags` inner join `tags_posts` on `tags`.`id` = `tags_posts`.`tag_id` where `tags_posts`.`post_id` = 33) 

timgavin left a reply on Trouble With Defining Relationships

@MKBAT - Can I not do something like `Post::latest('created_at)->with('tags')->get();? I'm receiving errors when trying this.

timgavin left a reply on Trouble With Defining Relationships

@MKBAT - Thank you! While I was tinkering around I was entering the column names as the second parameter instead of the table; That's where I was going wrong! :/

timgavin started a new conversation Trouble With Defining Relationships

I'm having a hard time figuring out the relationships between my tags and posts.

I created a tagging system that would store tags in one table (tags) and the posts that use them in another (tags_posts).

What I want to do is get the tags when getting the posts by doing this: $post = Post::with('tags')->find(1); instead of something like this: $post = Post::with('tags.tags')->find(1);

So far all I've been able to do is get the tag IDs from the TagPost relationship and scratch my head a lot.

I tried a hasManyThrough relationship but that didn't work out too well. I'm kind of stuck here...

Schema::create('tags', function (Blueprint $table) {
    $table->increments('id');
    $table->string('slug')->unique();
    $table->string('name')->unique();
    $table->unsignedInteger('count')->default(0)->index();
    $table->timestamps();
});

Schema::create('tags_posts', function (Blueprint $table) {
    $table->unsignedInteger('tag_id')->index();
    $table->unsignedInteger('post_id')->index();
    $table->unique(['tag_id', 'post_id']);
});

###Post.php

public function tags()
{
    return $this->hasMany(TagPost::class, 'post_id');
}

// tried this with no success
public function tags()
{
    return $this->hasManyThrough('App\Tag', 'App\TagPost', 'post_id', 'tag_id);
}

###TagPost.php

public function tags()
{
    return $this->belongsToMany('App\Tag');
}

Hopefully this makes sense!

17 Apr
3 months ago

timgavin started a new conversation Incrementing A Count Field In Another Table

I'm creating a simple Categories system to assign categories to posts. Basically a tagging system.

As you can see by my migrations I have two tables: one for categories and one for the Posts to which each category is attached.

Schema::create('categories', function (Blueprint $table) {
    $table->increments('id');
    $table->string('slug')->unique();
    $table->string('name')->unique();
    $table->unsignedInteger('count')->default(0)->index();
    $table->timestamps();
});

Schema::create('categories_posts', function (Blueprint $table) {
    $table->unsignedInteger('category_id')->index();
    $table->unsignedInteger('post_id')->index();
    $table->unique(['category_id', 'post_id']);
    $table->timestamps();
});

When a category is attached to a Post I want to increment a count field in the categories table, to show how many posts are using that category.

Here's how I'm currently doing it...

$post = Post::create(['title' => 'My First Post']);
$post->addCategory([1,2,3]); // <-- the category IDs from a dropdown
// App\Post.php

public function addCategory($array)
{
    $data = $ids = [];
    
    foreach ($array as $category_id) {
        $arr['post_id'] = $this->id;
        $arr['category_id'] = $category_id;
        array_push($data, $arr);
        array_push($ids, $category_id);
    }

    \App\CategoryPost::insert($data);

    foreach($ids as $id) {
        \App\Category::where('id', $id)->increment('count');
    }
}

Is there a more elegant way of doing this? is there a way to update the count field in CategoryPost without resorting to foreach? Or a way to cascade the increment, such as with foreign keys?

13 Apr
3 months ago

timgavin left a reply on Redirect To Custom Page After Registration

@NEEONLINE - Thanks for your help. This is only set at user registration, and redirects the user to answer different questions based on their choice, which will then be persisted. :)

timgavin left a reply on Redirect To Custom Page After Registration

Got it.

protected function redirectTo()
{
    if(\Request::get('usertype') == 'foo') {
        return '/foo';
    }

    return '/bar';
}
12 Apr
3 months ago

timgavin started a new conversation Redirect To Custom Page After Registration

My registration page has two buttons, one with the value foo and one with bar. I want to send the new user to a dynamic page after registration; users who clicked the foo button will go to /foo and users who clicked the bar button will go to /bar

protected function redirectTo(Request $request)
    {
        
        if($request->usertype == 'foo') {
            return '/foo';
        }

        return '/bar';
    }

Should be straightforward, but it's not working. I'm either getting a message Too few arguments to function App\Http\Controllers\Auth\RegisterController::redirectTo(), 0 passed

I tried passing $data from my validators method, but that doesn't work either.

What am I doing wrong?

07 Apr
3 months ago

timgavin left a reply on Converting Query To Eloquent

Got it.

$query = \App\Referrals::selectRaw('username, SUM(total) AS points_total')
    ->leftJoin('users', 'users.id', '=', 'referrals.user_id')
    ->where('referrals.referred_by', 3)
    ->groupBy('user_id')
    ->get();

timgavin started a new conversation Converting Query To Eloquent

A site user can refer another site user.

The referred site user (user_id in the query) can do things on the site which will give the referring user (referred_by in the query) points, as a way of rewarding them for the referral.

I want to get the total number of reward points (total) from each column and display it.

The following query works, but I'm having a hard time converting it to Eloquent. Any suggestions?

select username, sum(total) as points_total
from referrals
join users on users.id = referrals.user_id
where referrals.referred_by = 3
group by referrals.user_id
05 Apr
3 months ago

timgavin left a reply on Insert Or Update With Increments

@MIRONMG - Thanks. It's definitely cleaner, however, clicks aren't being recorded on a create.

04 Apr
3 months ago

timgavin started a new conversation Insert Or Update With Increments

I'm looking to persist search terms and record how many times they've been searched with an incrementing value.

In the following example I'm recording a username search. If the record isn't found, create a new one. If it is found, update it. Simple enough.

There's got to be a cleaner way of doing this though, right?

$search = Search::where('term', $request->username)->first();

if($search) {
    $search->increment('clicks', 1);
    $search->save();
} else {
    Search::create([
        'term' => $request->username,
        'clicks' => 1
    ]);
}

timgavin left a reply on Policy Method Not Working As Expected

@NAKOV - Good catch, thank you. :)

timgavin started a new conversation Policy Method Not Working As Expected

I'm working on a policy that will only allow users with the role of creator to create posts. However, this isn't working as expected, as any user with the role of creator is being denied.

What am I doing wrong?

PostPolicy.php

public function create(User $user)
{
    if ($user->role == 'creator') {
        return true;
    }
}

PostController.php

public function create()
{        
    $this->authorize('create');
    
    return view('posts.create');
}

timgavin left a reply on Cleaning Up A Controller

@TYKUS - Thank you for that explanation! I've been using route model binding but just couldn't figure out how to do it in this manner - using the boot() method; the docs aren't that great for someone who doesn't fully understand the ins and outs of Laravel just yet.

Unfortunately, I'm receiving the following error

"Cannot make static method Illuminate\Database\Eloquent\Model::boot() non static in class App\Post"

timgavin started a new conversation Cleaning Up A Controller

I'm using hash IDs to display a Post ID publicly so I have to decode that ID every time I want to find a Post, which is getting messy. Is there a way to automatically decode the hash ID for each one of my controller methods?

Here's an example of what I'm currently using.

public function destroy($id)
{
    // Is there a way to decode the hash ID globally in the controller so I can get rid of the following line?
    $id = Post::decodeHashId($id);

    $delete = Post::findOrFail($id)->delete();
    
    if($delete) {
        return response()->json(['success' => 'success'], 204);
    }

    return response()->json(['success' => 'error'], 500);
}
01 Apr
3 months ago

timgavin left a reply on Envoyer Deployment Not Showing

Turns out restarting PHP fixed it; the new changes are showing.

This is weird though, as I'm using Forge and Envoyer. Isn't Envoyer supposed to restart PHP FPM automatically? Plus, I didn't enable OPcache in Forge yet...

31 Mar
3 months ago

timgavin left a reply on Envoyer Deployment Not Showing

Maybe, but I doubt it as I've been making several deployments in the last week and every one of them worked.

timgavin left a reply on Change Timezone From US/Eastern To UTC

Thanks, figured it would be something like that. :)

timgavin started a new conversation Envoyer Deployment Not Showing

I just deployed using Envoyer; it was successful. However, I don't see any of the changes in my browser. I SSH'd into the server and ran php artisan cache:clear and it didn't make a difference; I still see the old files. I SFTP'd into the server as well, and sure enough the files are there...

I've done hundreds of deployment and never encountered this before. How do I fix this?

timgavin left a reply on Count(): Parameter Must Be An Array Or An Object That Implements Countable

I apologize for wasting your time. i was reading the BugSnag log incorrectly and thought it was telling me the issue was in the controller, when it was actually in a blade file.

For some reason to following was throwing an error

if(count($users)) {
    ....
}

So I tried

if(! $users->isEmpty()) {
    ...
}

which also threw an error, so I just settled on

if($users) {
    ...
}

and it worked. Weird....

timgavin started a new conversation Count(): Parameter Must Be An Array Or An Object That Implements Countable

I'm using Laravel 5.7 and PHP 7.3.3, both in production and locally using Valet. However, in production I'm receiving the error count(): Parameter must be an array or an object that implements Countable

Here's my query.

$users = \App\User::whereDate('created_at', \Carbon\Carbon::today())->count();

I've read that this was an issue in PHP 7.2, and that the solution was to upgrade to Laravel 5.6. I'm past that; why am I receiving this error and how do I fix it?

timgavin started a new conversation Change Timezone From US/Eastern To UTC

I screwed up.

When I built my app I had no idea what I was doing (I still don't) and set up the timezone in config/app.php to be 'timezone' => 'US/Eastern',

I just realized this mistake after doing a Shift and now I'd like to change it back to UTC. Unfortunately, the app has been online for over a year, so... yeah, lot's of records already...

Can I change it to UTC?

If so, how?

24 Mar
3 months ago

timgavin left a reply on Trying To Get Property Of Non-object In Blade @if()

Figured it out. Stupid error: a user was deleted in the database and that was causing recipient to be null in one of the results. ?‍♂️

timgavin started a new conversation Trying To Get Property Of Non-object In Blade @if()

I just upgraded my Laravel app to 5.7 and began testing. I encountered the Trying to get property of non-object error on a page that has been working just fine since the app was built, which was Laravel 5.2.

The line on which the error appears:

@if($thread->recipient->username != auth()->user()->username)

Now here's the weird thing, if I do the following, it actually prints the username!

{{ dd($thread->recipient->username) }}
@if($thread->recipient->username != auth()->user()->username)

I have no idea why this is happening or how to go about fixing it, as it works outside of the @if statement. Is it a bug in Blade?

17 Mar
4 months ago

timgavin left a reply on Redirect To Same Page With Cookie

@CRONIX - Thank you!

I started using this and it's so bulky!

$response = new \Illuminate\Http\Response(view('cart.index'));
$response->withCookie(cookie()->forever('cart', $cookie));
return $response;

timgavin started a new conversation Redirect To Same Page With Cookie

  1. I have a shopping cart page located at /cart, which shows the user their cart contents.
  2. The cart contents are stored in a cookie.
  3. The Route is set up as Resource::get('/cart', '[email protected]');
  4. A user can add items to their cart if they are not logged in, but in order to make a purchase they have to login.

Now, in [email protected] I check if the user is logged in, and if so check their purchase history to see if they've ordered this item before. If they have, I remove the item from the cart cookie.

My problem is that when returning from the index method, I have to use return view('cart.index') because if I use return redirect('/cart') I'm stuck in an infinite loop.

However, if I dont' use redirect the cookie doesn't update.

How can I update the cookie and send them to the /cart page?

16 Mar
4 months ago

timgavin left a reply on Get The 15th Of The Month With Carbon

@CORYS8646 - That's funny, because before I posted this question I was trying startOfMonth() and it didn't work. firstOfMonth() did. :)

15 Mar
4 months ago

timgavin started a new conversation Get The 15th Of The Month With Carbon

I'm configuring pay periods, which are on the 15 of the month and the last day of the month.

I want to grab sales that happened between those days, so I need to find sales that happened between the 1st and the 15th, and the 16th and the end of the month.

The first part is easy. The second, not so hard, but a little on the messy side.

$month = Carbon::now()->format('m');
$year = Carbon::now()->format('y');
$day = $year.'-'.$month.'-15';

$startDate = Carbon::parse($day)->format('Y-m-d');
$endDate = Carbon::now()->endOfMonth()->format('Y-m-d');

Is there a cleaner way of doing this?

19 Feb
5 months ago

timgavin left a reply on Replace String With Function

@CRONIX - Sweet, thanks!

timgavin left a reply on Replace String With Function

I think I just figured it out. If I change [image1], [image2] and [image3] to just [image] I can do this...

@foreach(explode('[image]', $article->body) as $part)
    <p>{{ $part }}</p>
    @if($loop->iteration == 1)
        {{ $article->getFirstMedia('image1') }}
    @endif
    @if($loop->iteration == 2)
        {{ $article->getFirstMedia('image2') }}
    @endif
    @if($loop->iteration == 3)
        {{ $article->getFirstMedia('image3') }}
    @endif
@endforeach

So far it's working well.

timgavin started a new conversation Replace String With Function

I'm using Laravel Media Library and would like to be able to add responsive images inside of my news articles, so I thought about using short codes as placeholders for each image, something like

Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.

[image1]

Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

This would require searching through the text body, finding the string [image1] and replacing it with $article->getFirstMedia('images')

Or to put it another way:

str_replace('[image1]', $article->getFirstMedia('images'), $article->body)

I'm just not having luck figuring this out. Any suggestions?

10 Feb
5 months ago

timgavin started a new conversation Looking For Opinions/advice On Scaffolding An Admin CP

I'm trying to keep my controllers from getting out of hand, both in the number of controllers I create, and in the number of methods within each controller; I'm trying to keep the methods to the basic 7 per controller.

I'm working on a new app, which means I need to be able to administer pages, a blog, a photo gallery, etc.

So I create a BlogController and create the resource methods. Now comes my question: what do you do if you want an Admin to be able to update the blog too, from within an admin control panel?

Do you create a separate Controller, such as AdminController and put those methods in there? This is what I normally do, but it gets loaded with methods. I mean LOTS of methods, and I don't like this approach because now I'm doing blog methods from outside the BlogController. Wouldn't it be better to keep it all on the BlogController?

How do you handle this situation?

timgavin left a reply on Relationship On Same Table Not Working

Turns out I had a column on the users table named referrer that was causing an issue. I changed the relationship's method name from referrer() to referredBy() and it worked. *eyeroll*

timgavin started a new conversation Relationship On Same Table Not Working

I have a relationship that's acting weird. If I get the results and dd(), it has the correct data. However, if I run the collection through a foreach loop it's like the relationship disappears.

The users table has a field called referred_by, which stores the user ID of the person who referred the user. In my instance I'm looking for all the new users who were referred by the user with the ID of 3.

Here's the relationship in User.php

public function referrer()
{
    return $this->belongsTo(User::class, 'referred_by');
}

Here's the code which is returning funky results

$users = User::where('referred_by', 3)
    ->with('referrer')
    ->get();

// doing dd() here returns a collection with full referrer relationship;
// the returned data is as expected

dd($users);

foreach($users as $user)
{
    // dd($user) here returns the relationship, as it should

    // dd($user->referrer) here returns null, like the relationship doesn't exist
}
09 Feb
5 months ago

timgavin left a reply on First() And Update() Row In One Query

@BOBBYBOUWMANN - increment() was perfect. Thanks! :)

timgavin left a reply on First() And Update() Row In One Query

@BOBBYBOUWMANN - That was one of the first things I tried, but got an Undefined variable: account error

timgavin started a new conversation First() And Update() Row In One Query

How can I do this in one line?

$account = Account::where('user_id', $user->id)->first();
$account->update(['balance' => $account->balance + 25]);
08 Feb
5 months ago

timgavin left a reply on Overriding Auth\LoginController

@SNAPEY - Ok, thanks. Turns out the problem was that I was using Spatie's Larvel Permission middleware on the route, and when I removed that and added auth middleware to the constructer on my controller the intended behavior started working as expected.

timgavin started a new conversation Overriding Auth\LoginController

I've overridden Laravel's default authentication by adding some of my own methods. However, I'm not sure the way I went about it is right.

Basically I added methods - such as the ones below - inside of App\Http\Controllers\Auth\LoginController

// allow login using either email or username
protected function credentials(Request $request)
{
    $usernameInput = trim($request->{$this->username()});
    $usernameColumn = filter_var($usernameInput, FILTER_VALIDATE_EMAIL) ? 'email' : $this->username();

    return [$usernameColumn => $usernameInput, 'password' => $request->password];
}

public function logout(Request $request)
{
    if (\Cookie::get('impersonate') === 'true') {
        \Cookie::queue(\Cookie::forget('impersonate'));
    }

    \Auth::logout();

    return redirect('/');
}

Was this the correct way of doing it? I'm not so sure because the Laravel docs say I should create a LoginController at App\Http\Controllers\LoginController

I'm now trying to implement an intended login, to redirect the user back to a page after login, and every scenario I try is not working, the user is just directed to $redirectTo = '/home'.

Do I need to move my override methods into App\Http\Controllers\LoginController and return App\Http\Controllers\Auth\LoginController back to its default state?

What's the correct way of doing this?

31 Jan
5 months ago

timgavin left a reply on Combining Multiple Less Files

@CRONIX - Thank you!!!!

timgavin started a new conversation Combining Multiple Less Files

What's the proper way to combine multiple Less files into one? The following doesn't work...

mix.less([
   'resources/assets/less/theme/core.less',
   'resources/assets/less/theme/components.less',
   'resources/assets/less/theme/pages.less',
   'resources/assets/less/theme/menu.less',
   'resources/assets/less/theme/responsive.less',
   'resources/assets/less/app.less'
],'public/css/app.css');
30 Jan
5 months ago

timgavin left a reply on Running Console Command From Subfolder

@TYKUS - You're right. I just commented them out and they still work. Thanks again!

timgavin left a reply on Running Console Command From Subfolder

@TYKUS - smacks forehead

Good catch. I totally forgot about that. ?

@billriess was right. Thank you.