cameronscott137

cameronscott137

Member Since 4 Years Ago

Experience Points 9,375
Experience Level 2

625 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-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.

10 Jul
6 days ago

cameronscott137 started a new conversation Testing Mimetype Validation

In my Laravel app, I have a file upload that I validate using mimetypes. (We accept several kinds of graphics files, and using the actual mimetype was the only way to ensure we correctedly validated all possible variations of those files.)

I have a test that I want to cover this functionality:

$request = [
    'files' => [
        1 => [
            'artwork' => UploadedFile::fake()->image('mockup1.jpg'),
        ]
    ]
];
$response = $this->put(route('fileUpdate', $this->order), $request);
$response->assertStatus(302)
    ->assertSessionHasErrors([
        'files.*.artwork'
    ]);

The validation rule forbids .jpg files, so the test above expects a validation error. However, in the case above, the mimetype for the UploadedFile reads as "application/octet-stream", rather than "'image/jpeg".

For the purposes of testing, is there a way to set the mimetype of an UploadedFile fake?

10 Jun
1 month ago

cameronscott137 started a new conversation Handling Laravel Model Relationships Within Vue

In my Laravel/Vue applications, there are frequently scenarios where I need to build a component that functions both in the create/update contexts. For instance:

// Creating a new user
<user-form-component></user-form-component>

// Updating an existing user
<user-form-component :user="{{$user}}"></user-form-component>

In the component itself, I typically have to end up doing something like the following:

props: ['user'],
data() {
    return {
        userArray: this.user,
        userFollowers: (this.userArray === undefined ? [] : this.userArray.followers),
        userTopics: (this.userArray === undefined ? [] : this.userArray.topics)
    }
},

Where followers and topics are relations of the User object that I've eager-loaded. (This is just a simple example.)

This works, but using ternaries here looks ugly, ungraceful, and a bit difficult to understand at a glance.

How have you handled this scenario in the past? Can folks recommend another way to handle it?

29 May
1 month ago

cameronscott137 left a reply on Conditionally Set A URL To Redirect To After Authentication.

@jlrdw Thanks for the insight! You're correct, we could achieve the same result by turning the $redirectTo property into a protected function, as @snapey suggested.

@snapey, you're correct, as well—in most cases, this would be the default behavior when using Laravel's `au middleware.

That wasn't an option for me here, though. Some posts are public, and some are private, and I don't know which is which until I hit the controller.

Utilizing the auth middleware would keep those public posts from being accessible, so I had to watch for private posts, and manually re-create that same functionality using @bobbybouwmann's suggestion:

         if ($post->isPrivate()) {
            $request->session()->setPreviousUrl($request->path());
            return redirect()->guest('login');
        }   

Thanks, all!

28 May
1 month ago

cameronscott137 left a reply on Conditionally Set A URL To Redirect To After Authentication.

@bobbybouwmann, thank you! That put me on the right path.

For anyone else looking, here's my final code:

Middleware:

    public function handle($request, Closure $next)
    {

        if (auth()->check()) {
            return $next($request);
        }

        $post = $request->route('post');
        if ($post->isPrivate()) {
            $request->session()->setPreviousUrl($request->path());
            return redirect()->guest('login');
        }

        return $next($request);
    }

LoginController:

    protected function authenticated(Request $request, $user)
    {
        if ($request->session()->has('url.intended')) {
            return redirect($request->session()->get('url.intended'));
        }
    }

cameronscott137 started a new conversation Conditionally Set A URL To Redirect To After Authentication.

In my app, a post author can set an otherwise public post to private. If an unauthenticated user tries to visit that post, they will be prompted to login.

After they authenticate, I want to redirect them back to the original post URL, so they can read that private post.

This behavior is normally handled by Laravel's default auth middleware. However, because the posts are often public, I can't use that in this case.

Here's my current, non-functioning middleware:

    public function handle($request, Closure $next)
    {
        $post = $request->route('post');
        if ($post->isPrivate()) {
            $request->session()->setPreviousUrl($request->url());
            return redirect()->guest('login');
        }
        return $next($request);
    }

My hope is that I can set a custom URL to redirect to (/posts/{id}). However, when I try to login, I'm redirected to my default $redirectTo property (/dashboard).

Is this something that's feasible? Am I even thinking about this in the correct way?

18 Apr
2 months ago

cameronscott137 started a new conversation Filter By A Non-Null Value In Laravel Nova

I'm trying to implement a basic filter using Laravel Nova. The filter looks at the field "onboarded_at," which is a datetime field. If the attribute has a timestamp, they're onboarded, and if not, they aren't.

Here's my filter:

    public function apply(Request $request, $query, $value)
    {
        return $query->where('onboarded_at', $value);
    }

    public function options(Request $request)
    {
        return [
            'Onboarded' => !NULL, // How would I indicate a non-null value here?
            'Not Onboarded' => NULL,
        ];
    }

How would I indicate a non-null value in the options function?

04 Dec
7 months ago

cameronscott137 started a new conversation Smooth Vue Translation Transition Between Two Elements

I'm working on a Vue animation where:

  • Button #1 slides out to the left.
  • Button #2 slides in to the right.

And vice-versa.

However, when I initiate the transition, Button #2 in inserted into the DOM, and immediately pushes Button #1 to the right, where #1 then begins its transition.

Here's my component:

<transition name="detail">
    <div class="u-align-center" v-if="showShare">
        <button class="btn btn-wide u-ml-20 u-mr-40 u-align-center u-text-blue">
            Sample Button
        </button>
    </div>
</transition>
<transition name="detail">
    <div class="u-align-center u-ml-20 u-mr-40" v-if="!showShare">
        <button class="btn btn-blue u-mr-20 u-align-center" @click="showDetail = !showDetail" v-if="!showDetail">
            See List
        </button>
        <button class="btn btn-blue u-align-center u-mr-20" @click="showShare = !showShare" v-if="!showShare">
            Take With You
        </button>
    </div>
</transition>

And here's my CSS:


.detail-enter {
    transform: translateX(-2500px);
}

.detail-enter-to {
    transform: translateX(0px);
}

.detail-leave {
    transform: translateX(0px);
}

.detail-leave-to {
    transform: translateX(-2500px);
}

.detail-leave-active {
    transition: all 1s cubic-bezier(.42,0,.58,1);
}

.detail-enter-active {
    transition: all 1s cubic-bezier(.42,0,.58,1);
    transition-delay: .75s;
}

Here's a GIF of exactly what I'm experiencing:

https://www.dropbox.com/s/9vg7c9mrvxt5pyr/gif.gif?dl=0

Is there a way to accomplish this with Vue Transitions? I've read about transition modes, which seem to do exactly what I need, but I can't get them to behave in this context.

15 Aug
11 months ago

cameronscott137 started a new conversation Using Laravel Accessors In A Vue Layout

In my Laravel app, I have some pieces of a model that constitute PII, and need to be encrypted. To achieve this, I have an Encryptable trait (via a suggestion from @martinbean on this very website.

public function getAttribute($key)
{
    $value = parent::getAttribute($key);
    if (in_array($key, $this->encryptable)) {
        $value = Crypt::decrypt($value);
    }
    return $value;
}

public function setAttribute($key, $value)
{
    if (in_array($key, $this->encryptable)) {
        $value = Crypt::encrypt($value);
    }

    return parent::setAttribute($key, $value);
}

This works fantastically in most scenarios. However, I have one part of my app that leverages a Vue-based UI. Here's the controller that supplies that view:

public function show(Order $order)
{
    $model = $model->load(['user', 'user.company');
    return view('orders.workspace.show', compact('order'));
}

And then, in the view:

<component :order="{{ $order }}"></component>

The getter and setter in my trait only fire when a specific attribute is accessed (e.g. $model->first_name). So, when I pass the whole object to a Vue component and render it out there, it bypasses that trait, and displays the encrypted values.

Is there a way to adjust my getter and setter so that I can accommodate my Vue-based layout?

23 Jan
1 year ago

cameronscott137 started a new conversation Customizing The Name Of An Uploaded .zip File

My app accepts user-submitted .zip files, which I temporarily store in local storage:

Storage::disk('local')->put('exports', $request->custom_report_url);

The challenge is that this creates a file with what I assume is some kind of hash:

'app/storage/exports/U44SEhM1wycNgMU0bV6qieSRiGJwMPvkDpBDgkyo.zip'

This makes that zip file a pain to find later in the process.

Is there a way that I can define a custom name for that zip file? Ideally, I'd like to do something like:

Storage::disk('local')->put('exports/export_' . $export-id . '.zip', $request->custom_report_url);

However, when I run that code, it creates the following filepath:

'app/storage/exports/export_1.zip/U44SEhM1wycNgMU0bV6qieSRiGJwMPvkDpBDgkyo.zip'

Close, but not what I need. Any ideas?

22 Jan
1 year ago

cameronscott137 started a new conversation Using Spatie's Browsershot/Headless Chrome To Capture Extremely Long Screenshots

I periodically run into scenarios where I need to use Spatie's Browsershot to capture extremely tall web pages. However, when I do this, the resultant screenshot repeats every 16,384 pixels. (You can see an example of the repetition here: https://github.com/GoogleChrome/puppeteer/issues/1576)

This is a known limitation of Puppeteer (documented here). The recommended workaround for now seems to be taking several screenshots, and using clip() to offset the screenshot by increments of 16,384px. You can see an example of this approach using Node.JS here.

Now, on the client side, that approach seems to work well enough, but that doesn't really help us in the context of the Browsershot library. As far as I know, there's no viable way to get the height of a page within PHP; can anyone think of any potential workarounds on the server side to hack an extremely long screenshot?

I know this isn't really the intended use of the library, and at the end of the day, it's not even the library's limitation, but I thought I'd throw it out there regardless.

16 Jan
1 year ago

cameronscott137 left a reply on Redirect If Usertype Is Invalid | Laravel 5.5

@NoneNameDeveloper, okay, so that means either a) your user isn't logged in, or b) more likely, the app doesn't have access to session data at that particular method.

Within your controller, add:

/**
     * Create a new controller instance.
     *
     * @return void
     */
    public function __construct()
    {
        $this->middleware(['userProfile', 'auth'])->only('single_user');
    }

Then hit your dd() and let me know if a user doesn't pop up.

cameronscott137 left a reply on Redirect If Usertype Is Invalid | Laravel 5.5

@NoneNameDeveloper, $request->user() will return the authenticated user, so it looks like we don't have that user.

Is your single_user() function behind Laravel's auth middleware? If so, you should be able to drop a dd() in and see our authenticated user object:

/**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */
    public function handle($request, Closure $next)
    {
        dd($request->user());
    }

Can you do that and let me know what you see?

cameronscott137 left a reply on Retrieve Duplicates From WhereIn

Take a look at @rodrigo.pedra's answer here:

https://laracasts.com/discuss/channels/general-discussion/finding-duplicate-data

I've taken similar approaches before, and his answer should work like a charm for you.

cameronscott137 left a reply on Create Or Save Products With Category

Is $request->cats an array of Cat IDs? sync() wants to accept an array of model ids that you want to associate:

// if $request->cats equals something like [1,3,4]
$product->cats()->sync($request->cats);

cameronscott137 left a reply on Blade Templating

@lravel, could you post the contents of formPersonne and formBagage? The code you posted looks correct, but as @topvillas said, there might be something in the partials themselves that's causing the issue.

cameronscott137 left a reply on Redirect If Usertype Is Invalid | Laravel 5.5

@NoneNameDeveloper, this looks like it might be a good opportunity for a (middleware)[https://laravel.com/docs/5.5/middleware], which will allow you to redirect as necessary, and keep your controller clean and concise.

Using middleware, you could do something like this:

class canAccessUserProfile
{
    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */
    public function handle($request, Closure $next)
    {
        if ($request->user()->userType == "user") { // If user is regular user, and non-admin
            return $next($request); // return the next request
        }
    flash()->error('OOPS! We did not found any user, Search valid user!');
    return redirect('/'); // Redirect all other users wherever you want.
    }
}

After registering the middleware in your kernal.php file, you can then enable it on specific actions within your controller:

    /**
     * Create a new controller instance.
     *
     * @return void
     */
    public function __construct()
    {
        $this->middleware(['userProfile'])->only('single_user');
    }
15 Jan
1 year ago

cameronscott137 started a new conversation Processing Resource-Intensive Jobs With Laravel

I have a project coming up that's going to involve some very resource-intensive functions—PDF generation, external API calls, email notifications, etc.

In some cases, these processes might be heavy enough that I risk timing out even a well-resourced server if I were to handle them synchronously.

My best thought on approach here is to create a separate Redis server, install Horizon, and manage those processes as queued, chained jobs, with each job sending a notification back to the user on success or failure.

Are there any other methods or strategies out there that folks have used in production before? Any gotchas to be aware of? I took a look around Laracasts for any videos that address this particular use case, but didn't see anything that looked relevant.

23 Dec
1 year ago

cameronscott137 left a reply on Incrementing A Formatted Timer

Solved it. The answer was actually to use a local filter within my component:

filters: {
    formattedTime: function (value) {
        var sec_num = parseInt(value, 10);
        var hours   = Math.floor(sec_num / 3600);
        var minutes = Math.floor((sec_num - (hours * 3600)) / 60);
        var seconds = sec_num - (hours * 3600) - (minutes * 60);

        //if (hours   < 10) {hours   = "0"+hours;}
        if (minutes < 10) {minutes = "0"+minutes;}
        if (seconds < 10) {seconds = "0"+seconds;}
        return +minutes+':'+seconds;
    }
},

And then apply that filter to my time variable: {{ time | formattedTime }}.

22 Dec
1 year ago

cameronscott137 started a new conversation Incrementing A Formatted Timer

I'm building a basic Timer Vue component. The timer increments by seconds, and the user can play and pause the timer on click. Here's the component:

<template>
    <div v-bind:class="{workspaceTimer: isRunning}">
        <a class="u-link-white" href="#" @click="toggleTimer">
            {{ time }}
            <span v-if="isRunning">
                Pause
            </span>
            <span v-else>
                Play
            </span>
        </a>
    </div>
</template>

<script>
    export default {
        props: ['order'],
        data() {
            return {
                time: this.order.time_to_complete,
                isRunning: false,
                interval: null,
            }
        },
        watch: {
            time: function (newTime) {
                this.saveTime(6000)
            }
        },
        methods: {
            toggleTimer() {
                if (this.isRunning) {
                    clearInterval(this.interval);
                } else {
                    this.interval = setInterval(this.incrementTime, 1000);
                }
                this.isRunning = !this.isRunning;
            },
            incrementTime() {
                this.time = parseInt(this.time) + 1;
            },
            formattedTime() {
                var sec_integer = parseInt(this.time, 10);
                var hours   = Math.floor(sec_integer / 3600);
                var minutes = Math.floor((sec_integer - (hours * 3600)) / 60);
                var seconds = sec_integer - (hours * 3600) - (minutes * 60);

                if (minutes < 10) {minutes = "0"+minutes;}
                if (seconds < 10) {seconds = "0"+seconds;}
                this.time = +minutes+':'+seconds;
            },
            saveTime: _.debounce(
                function () {
                    var self = this;
                    axios.put(location.pathname, {time_to_complete: self.time})
                    .then(function (response) {
                        console.log('timer: ' + response.data.time_to_complete);
                    })
                    .catch(function (error) {
                         console.log('Error: ' + error);
                    })
                },
                1000
            )
        
    }
</script>

I'm storying the second count as an integer, but would like to display that second count as a mm:ss, and have that formatted value increment, e.g. 00:59 increments to 1:00.

I can easily format my second value using a method or computed property, but I'm unsure of how to approach incrementing that string, and then formatting that incremented string. Do I need to watch for changes to that string, and then format the updated string?

16 Jul
2 years ago

cameronscott137 started a new conversation Organizing Custom Blade Directives

I was recently inspired by a tweet from David Hemphill to begin exploring custom Blade directives to clean up my views.

I've got close to a dozen in my AppServiceProvider::boot(), and the file is starting to get a little unwieldy. Has anyone experimented with different methods of organizing custom directives? Even extracting the directives out to a separate file (if possible) would feel cleaner than what I've got going on right now.

05 Jun
2 years ago

cameronscott137 started a new conversation Restricting Access To Passport's Password Grant Tokens

I'm using Laravel Passport's password grant tokens to manage access to an iOS app. The iOS app has its own, dedicated token, which it uses to authenticate users via email address and password.

Right now, the iOS app services users with role type A (there are only so many hours in the day). Is there a way that I can prevent users with role type B from authenticating themselves?

21 Mar
2 years ago

cameronscott137 started a new conversation Using Laravel Passport With A Load Balancer

In my Laravel app, I'm using Passport's Password Grant to give API access to an iOS application.

In my production environment, I'm also using one load balancer to distribute requests to two servers. All have been created in forge.

I can use the Password Grant token to authenticate a user via iOS, and have the API return the bearer access_token. However, the load balancer then ships the next request to the other server, which seems not to recognize the access_token, and so throws a 401.

Question #1: Does anyone have experience using Passport with a load-balanced environment? If so, did you run into this issue?

Question #2: Where is the access_token stored? I see it referenced within my database via an ID, but the token itself isn't stored there. Without, I'm not sure how to persist from server to server.

15 Mar
2 years ago

cameronscott137 started a new conversation POST Request Works With Postman, But Not With Guzzle

In my Laravel application, I periodically need to POST data to an API using Guzzle 6.0.

The API users a bearer token to authenticate, and requests and accepts raw json. To test, I accessed the API using Postman, and everything worked wonderfully.

Postman Headers:

```
Accept:application/json
Authorization:Bearer [token]
Content-Type:application/json
```

And Postman Body:

```
{
    "request1" : "123456789",
    "request2" : "2468",
    "request3" : "987654321",
    "name" : "John Doe"
}
```

Postman returns a 200, and a JSON object as a response.

Now, when I try the same with Guzzle, I get a 200 status code, but no JSON object gets returned. Here's my Guzzle implementation:

    public function getClient($token)
    {
        return new Client([
            'base_uri' => env('API_HOST'),
            'Accept' => 'application/json',
            'Authorization' => 'Bearer ' . $token,
            'Content-Type' => 'application/json'
        ]);
    }

    $post = $client->request('POST', '/path/to/api', [
        'json' => [
            'request1' => 123456789,
            'request2' => 2468,
            'request3' => 987654321,
            'name' => 'John Doe',
        ]
    ]);

Is there some trick to POSTing JSON with Guzzle? If not, is there a way to debug what's going on under the hood?

I cannot, for the life of me, understand what the difference is between the Postman POST and the Guzzle POST.

02 Mar
2 years ago

cameronscott137 started a new conversation Empty Repeatable Fields In Laravel 5

In my Laravel 5 app, I have a set of repeatable field groups, each with a name field and a price field.

Here's the HTML on page load:

    <div id="js-new-line-items" style="display: none">
        <div class="repeatable-fields">
        </div>
    </div>
    <a class="btn__add-field u-text-right" href="#" id="js-show-line-item-form">
        Or add a new line item
    </a>

Here's the Javascript:

    // Add new line items
    var x = 0;
    $( "#js-show-line-item-form" ).click(function(e) {
        e.preventDefault();
        $('#js-new-line-items').show();
        x++; //text box increment
        $(".repeatable-fields").append('<div class="field__repeatable"><input class="js-new-line-item-field js-new-line-item-name" placeholder="Enter New Line Item Name" name="new_lineItem['+x+'][name]" data-name-id="'+x+'" type="text"><input class="js-new-line-item-field js-new-line-item-price" placeholder="Enter Price" name="new_lineItem['+x+'][price]" data-price-id="'+x+'" type="text"></div>');
            // Display Line item preview in bill
          $('#js-display-custom-lineItem').append('<div class="bill-section__body-row"><span class="bill-section__body-row-item" id="js-new-display-line-item-name-'+x+'"></span><span class="bill-section__body-row-item" id="js-new-display-line-item-price-'+x+'"></span></div>');
    });

And for legibility, here's the unpacked HTML that function appends:

    <div class="field__repeatable">
        <input class="js-new-line-item-field js-new-line-item-name" placeholder="Enter New Line Item Name" name="new_lineItem['+x+'][name]" data-name-id="'+x+'" type="text">
        <input class="js-new-line-item-field js-new-line-item-price" placeholder="Enter Price" name="new_lineItem['+x+'][price]" data-price-id="'+x+'" type="text">
    </div>

Now, this all works well. I can add as many field groups as I need, and the input names increment correctly.

However, when I submit the form, this is my request object:

    array:8 [▼
        "_token" => "dKnCstu3pbQoXnH3bM5QTVDrHAZfwiKc7gPdAcDM"
        "description" => "test"
        "new_lineItem" => array:2 [▼
            1 => array:2 [▼
                "name" => ""
                "price" => ""
            ]
            2 => array:2 [▼
                "name" => ""
                "price" => ""
            ]
        ]
    ]

My name and price values are empty. I cannot, for the life of me, figure out why this is happening. Can anyone spot any errors with this implementation?

30 Jan
2 years ago

cameronscott137 left a reply on Flattening A Collection

@samfrjn11, that does help, thank you, but the next step in my method takes me right back to the same problem.

Ultimately, I need to group the results by business_category so the result is:

'business_category' => ['name' => 'name', 'id' => 'id']

I need to format this into a Select2 dropdown with option groups.

Again, I would normally achieve this using groupBy, but the end result is:

Collection {#532 ▼
  #items: array:7 [▼
    "Maintenance" => Collection {#144 ▼
      #items: array:2 [▼
        0 => {#494 ▼
          +"id": 1
          +"name": "Auto Detailing"
          +"business_category": "Maintenance"
        }
        1 => {#496 ▶}
      ]
    }
    "Home and Office" => Collection {#526 ▶}
    "Personal Care" => Collection {#527 ▶}
    "Sports and Fitness" => Collection {#528 ▶}
    "Training and Education" => Collection {#529 ▶}
    "Transportation" => Collection {#530 ▶}
    "Other" => Collection {#531 ▶}
  ]
}

That extra index is still there, preventing me from formatting the data into that Select2 menu.

cameronscott137 started a new conversation Flattening A Collection

Super basic collections question:

So, say I have a query:

$collect = DB::table('codes')->get();

This returns a collection that is structured like so:

Collection {#488 ▼
  #items: array:31 [▼
    0 => {#494 ▼
      +"id": 1
      +"business_category": "Maintenance"
      +"name": "Auto Detailing"
      +"naics_category": "Automotive detailing services"
      +"naics_code": 811192
    }
    1 => {#496 ▶}
    2 => {#497 ▶}
...

Now, ultimately I want to return some of those attributes using the only method. The challenge is, because those attributes appear to be nested within that index, I can't get access them. Performing something like $collect->except('naics_category', 'naics_code') just returns the same collection.

In addition, using flatten doesn't impact the collection, either.

How would I need to approach the collection above to access those individual attributes?

cameronscott137 left a reply on Applying A User's Timezone To A Model Attribute In Laravel

Collections to the rescue. I was able to use map to modify the attribute in question, and then return a collection of bills with that modified attribute. Also reduced the number of queries I was making, too.

    $bills = DB::table('bills')
        ->where('provider_id', Auth::user()->company()->first()->id)
        ->where('status', 'paid')
        ->get();

    $adjustedBills = $bills->map(function ($bill, $key) {
        $bill->date_paid = Carbon::parse($bill->date_paid)->timezone('America/New_York')->toDateTimeString();
        return $bill;
    });

    return $dates->map(function ($item, $key) use ($interval, $adjustedBills) {
        return $adjustedBills->filter(function ($date, $key) use ($item, $interval) {
            return $date->date_paid >= $item && $date->date_paid <= $this->returnRangeFromInterval($item, $interval);
        })->pluck('amount_due')->sum();
    })->flatten();
26 Jan
2 years ago

cameronscott137 left a reply on Applying A User's Timezone To A Model Attribute In Laravel

@rch, yup, I can use Carbon elsewhere, but I can't apply it to the database column I'm referencing in the collection above.

How would you handle it? Create a new accessor on the Bill model, and then reference that?

cameronscott137 started a new conversation Applying A User's Timezone To A Model Attribute In Laravel

In Laravel 5.3, I've written a collection designed to cycle through a user's bills and determine whether they were paid within a given time frame.

    return $dates->map(function ($item, $key) use ($interval) {
        $bills = DB::table('bills')
        ->where('provider_id', Auth::user()->company()->first()->id)
        ->whereBetween(
            'date_paid', [$item, $this->returnRangeFromInterval($item, $interval)]
        )
        ->where('status', 'paid')
        ->get();
        return $bills->pluck('amount_due')->sum();
    });

That date_paid attribute is stored as UTC, but to return an accurate sum, I need to shift that date to a user's timezone—which I have stored on the `Us object. How could I accomplish this in the collection above?

It looks as though I can use a MYSQL method called convert_tz] if absolutely necessary, but I'm interested first and foremost in the "Laravel Way".

12 Jan
2 years ago

cameronscott137 started a new conversation Using Javascript With Lumen

I'm building a small API using Lumen. The workflow will be:

  1. The API accepts a user-inputted zip code.
  2. The API uses leaflet.js to geo-encode that zip into latitude and longitude, and place it within a set of custom geoJSON polygons
  3. The API returns data based on the results of that placement

However, I'm unsure how to proceed with Step 2. I need a small piece of Javascript to manage that geo-encoding process, but I'm not sure where that fits in with how Lumen wants to work.

The rest of the API is so simple that it seems silly to spin up an entire Laravel application just to support it, but I'm not sure how to incorporate that script into the Lumen workflow.

Has anyone come up against this problem before?

27 Oct
2 years ago

cameronscott137 left a reply on Isolate Key/Value Pair From Laravel Model Relationship

@Shig, you're right, it's not, which is why nothing I was trying was working. I wasn't thinking it through properly.

For future devs: the pluck() method takes two arguments: the value you want to pluck, and a second value that gets assigned to the key. Using the scenario above, I was able to write:

$result = $poll->options()->pluck('responses', 'option_text'); //Value and corresponding key

This results in something like:

Collection {#386 ▼
  #items: array:6 [▼
    "Never" => 54
    "Occasionally" => 21
    "2–3 times a week" => 80
    "4–5 times per week" => 33
    "Daily" => 11
  ]
}

Which ultimately did what I need it to do.

cameronscott137 left a reply on Best Solution To Work On A Hosting Service

@kidrobin, that's a tough hand to be dealt—I'm sorry you're there.

Sounds like when your user submits a post, an email is fired. Is that email fired in real time? Or are you using a queue to send those emails asynchronously?

cameronscott137 left a reply on Isolate Key/Value Pair From Laravel Model Relationship

@InaniELHoussain, thanks for the reply. I gave that a shot, too, thinking maybe it was similar to eager loading syntax. Still returns an empty collection, though:

$options = Poll::find(1)->options()->get();
$responses1 = $options->only('responses'); // original
$responses2 = $options->only('PollOption.responses'); // proposed
dd($responses1, $responses2);

Returns:

Collection {#400 ▼
  #items: []
}
Collection {#402 ▼
  #items: []
}

cameronscott137 left a reply on Isolate Key/Value Pair From Laravel Model Relationship

Thanks, @tomi. That bracketed value still returns an empty collection, though:

$options = Poll::find(1)->options()->get();
$responses1 = $options->only('responses'); // original
$responses2 = $options->only(['responses']); // proposed solution
dd($responses1, $responses2);

Returns :

Collection {#400 ▼
  #items: []
}
Collection {#402 ▼
  #items: []
}

cameronscott137 left a reply on Best Solution To Work On A Hosting Service

Ooof, you mean like a $9.95/mo shared hosting service? That's tough. Couple of questions:

  1. You're definitely stuck using that hosting system? There's no way you can set up a subdomain and point it to a solution better suited to your app?

  2. When you say it makes the app really slow, you're talking about the speed with which that action is performed? For example, I click a button that says "send email," and the response time is super slow? Or is the app slow even for non-intensive actions (logging in/out, clicking to different views, etc.)?

cameronscott137 started a new conversation Isolate Key/Value Pair From Laravel Model Relationship

In my Laravel App, a poll has many poll options. I can create a collection of those options by simply running:

$result = Poll::find(1)->options()->get();

This query returns:

Collection {#387 ▼
    #items: array:6 [▼
        0 => PollOption {#388 ▼
          #table: "poll_options"
          #connection: null
          #primaryKey: "id"
          #keyType: "int"
          #perPage: 15
          +incrementing: true
          +timestamps: true
          #attributes: array:8 [▼
            "id" => 1
            "poll_id" => 1
            "option_text" => "Never"
            "responses" => 54
            "is_public" => 0
            "created_at" => null
            "updated_at" => null
            "deleted_at" => null
          ]
          #original: array:8 [▶]
          #relations: []
          #hidden: []
          #visible: []
          #appends: []
          #fillable: []
          #guarded: array:1 [▶]
          #dates: []
          #dateFormat: null
          #casts: []
          #touches: []
          #observables: []
          #with: []
          #morphClass: null
          +exists: true
          +wasRecentlyCreated: false
        }
        1 => PollOption {#389 ▶}
        2 => PollOption {#390 ▶}
        3 => PollOption {#391 ▶}
    ]
}

Within my poll option, there is a column called responses, which returns an integer. I need to take the collection above and isolate the responses key/value pair.

Collection {#385 ▼
  #items: array:6 [▼
    "responses" => 54
    "responses" => 20
    "responses" => 10
    "responses" => 123
    "responses" => 33
    "responses" => 11
  ]
}

The only() collection method does exactly what I need, but I can't figure out how to structure the query when working with Eloquent models:

$options = Poll::find(1)->options()->get();
$responses = $options->only('responses');
dd($responses->all());

Returns an empty collection because the responses value is nested within the PollOption object.

I've also tried flatten(), but that seems to have no effect in this scenario.

Is there an easier way to return a single key/value pair within an Eloquent model collection?

18 Jul
2 years ago

cameronscott137 left a reply on Adding Custom Field To Registration

I don't remember the exact issue, but it was something obvious—forgetting to make the attribute mass assignable or similar.

To solve it, though, I do remember checking my laravel.log file in my storage directory. That file contains all the detail you'd come to expect from a typical Laravel error message, so take the steps to recreate your error again, and then check that file. That was enough for me to uncover the root issue.

30 Jun
3 years ago

cameronscott137 left a reply on CSV Export In Controller

Old question, but for the record, I've also had a great experience with: https://github.com/Maatwebsite/Laravel-Excel

21 Jun
3 years ago

cameronscott137 started a new conversation Adding Custom Field To Registration

I've been following the official Spark docs to try and add a custom field to my registration form:

In register-common-form.blade.php:

    <!-- Age -->
    <div class="form-group" :class="{'has-error': registerForm.errors.has('age')}">
        <label class="col-md-4 control-label">Age</label>

        <div class="col-md-6">
            <input type="text" class="form-control" name="age" v-model="registerForm.age">

            <span class="help-block" v-show="registerForm.errors.has('age')">
                @{{ registerForm.errors.get('age') }}
            </span>
        </div>
    </div>

In resources/assets/app.js:

require('spark-bootstrap');

require('./components/bootstrap');

Spark.forms.register = {
    age: ''
};

var app = new Vue({
    mixins: [require('spark')]
});

In SparkServiceProvider.php:

Spark::validateUsersWith(function () {
            return [
                'name' => 'required|max:255',
                'age' => 'required|integer|min:1',
                'email' => 'required|email|max:255|unique:users',
                'password' => 'required|confirmed|min:6',
                'vat_id' => 'max:50|vat_id',
                'terms' => 'required|accepted',
            ];
        });

        Spark::createUsersWith(function ($request) {
            $user = Spark::user();

            $data = $request->all();

            $user->forceFill([
                'name' => $data['name'],
                'email' => $data['email'],
                'age' => $data['age'],
                'password' => bcrypt($data['password']),
                'last_read_announcements_at' => Carbon::now(),
                'trial_ends_at' => Carbon::now()->addDays(Spark::trialDays()),
            ])->save();
            return $user;
        });

That is the exact code from the Spark docs. However, when I fill out my registration form, I receive an error "Something went wrong. Please try again or contact customer support." In the console, I get a 500 error.

Two questions:

  • Is there an obvious mistake in the code above that would cause those errors?
  • Is there an obvious process to begin debugging errors like this? I'm also new to Vue, and my typical Laravel debugging tactics aren't that applicable.
04 May
3 years ago

cameronscott137 started a new conversation Build A Blog With Post Categories And User Preferences

I'm building a blog for fun. In my blog, I have users, posts, and a fixed list of predefined categories.

  1. Posts belong to many categories.
  2. Users can specify category preferences, and therefore belong to many categories.

I have this set up as a series of many-to-many relationships:

In User.php:

/**
     * A user belongs to many categories
     */
    public function categoryPreferences()
    {
        return $this->belongsToMany('App\Category');
    }

In Post.php:

    /**
     * A Post Can Have Many Likes
     *
     * @return \Illuminiate\Database\Eloquent\Relations\belongsToMany
     */

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

And the inverse of each in Category.php:

    /**
     * A category belongs to many users
     */
    public function users()
    {
        return $this->belongsToMany('App\User');
    }

    /**
     * A category belongs to many posts.
     *
     * @return \Illuminiate\Database\Eloquent\Relations\belongsToMany
     */

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

I have corresponding category_post and category_user join tables to support each relationship. However, I may be thinking about this incorrectly.

I would like to display a loop of posts that belong to categories that users have specified, but can't work through how to do that. I can easily collect a user's category preferences with:

$categories = $user->categoryPreferences->pluck('id');

And can do the same for posts:

$categories = $post->categories->pluck('id')

However, I'm unsure how to merge the two collections together. I've looked into polymorphism, but that doesn't seem quite right. Can someone point me toward the correct concept?

25 Mar
3 years ago

cameronscott137 left a reply on Show Form Fields Conditionally Based On User Input

D'uh—easy fix. Need to toggle `disabl as well:

    $('.js-siteSelect').removeClass('js-show').prop('disabled', true);
    $('.select-us').addClass('js-show').prop('disabled', false);

cameronscott137 started a new conversation Show Form Fields Conditionally Based On User Input

In my Laravel app, I have a select form field that lists a set of countries:

    <select id="js-countrySiteSelect">
        <option>Select Your Country</option>
        <option>United States</option>
        <option>Australia</option>
        <option>Germany</option>
        <option>Switzerland</option>
        <option>United Kingdom</option>
    </select>

Beneath that, I also have a series of select form fields. Each select shows a series of locations within that country.

    {!! Form::select('site_id', $australia, null, ['class' => 'js-siteSelect select-australia', null => 'Select a user...']) !!}
    {!! Form::select('site_id', $germany, null, ['class' => 'js-siteSelect select-germany']) !!}
    {!! Form::select('site_id', $switzerland, null, ['class' => 'js-siteSelect select-switzerland']) !!}
    {!! Form::select('site_id', $us, null, ['class' => 'js-siteSelect select-us']) !!}
    {!! Form::select('site_id', $uk, null, ['class' => 'js-siteSelect select-uk']) !!}

Based on which country the user selects, I want to show or hide the corresponding form fields:

    $('#js-countrySiteSelect').change(function(e) {
      e.preventDefault();
      $('.js-siteSelectLabel').addClass('js-show');
      if ( $(this).val() == 'United States' ) {
        $('.js-siteSelect').removeClass('js-show');
        $('.select-us').addClass('js-show');
      } else if ( $(this).val() == 'Australia' ) {
        $('.js-siteSelect').removeClass('js-show');
        $('.select-australia').addClass('js-show');
      } else if ( $(this).val() == 'Germany' ) {
        $('.js-siteSelect').removeClass('js-show');
        $('.select-germany').addClass('js-show');
      } else if ( $(this).val() == 'Switzerland' ) {
        $('.js-siteSelect').removeClass('js-show');
        $('.select-switzerland').addClass('js-show');
      } else if ( $(this).val() == 'United Kingdom' ) {
        $('.js-siteSelect').removeClass('js-show');
        $('.select-uk').addClass('js-show');
      }
    });

However, since each location dropdown is still loaded into the DOM, the form always submits the first option of the last select—in this example, the UK dropdown.

How can I refactor this so that only the visible select element submits data?

20 Mar
3 years ago

cameronscott137 started a new conversation Accessing Nested HasMany Eloquent Relationships In Laravel

In my Laravel app, a user has many helpers, and a user has many needs.

I can access a user's helpers and a user's needs with simple Eloquent relationships:

    /**
     * An user can own many needs.
     *
     * @return \Illuminiate\Database\Eloquent\Relations\hasMany
     */

    public function needs()
    {
        return $this->hasMany('App\Need', 'creator_id');
    }

    /**
     * An user helps many other users
     *
     * @return \Illuminiate\Database\Eloquent\Relations\belongstoMany
     */

    function helpers()
    {
      return $this->belongsToMany('App\User', 'user_helper', 'user_id', 'helper_id');
    }

However, I also want to display a user's helper's helper's needs, eg. find a user's helpers; for each helper, get their list of helpers; for each of those helpers, get their list of needs. The goal is to for a user to see a list of their helper's needs, but also the needs of those users who are one degree removed.

In my need table, I use the creator_id column to log the creating user's ID.

I've written this method in my Need.php model:

    public static function helpersHelpersNeeds()
    {
        return Need::where('creator_id', Auth::user()->id)
            ->orWhere(function($query){
                // Get all helpers of current user
                foreach(Auth::user()->helpers as $helper){
                    $helpersHelpers = $helper->helpers()->get();
                    // Get all helpers of each helper
                    foreach ($helpersHelpers as $helpersHelper){
                        $query->orWhere('creator_id', $helpersHelper->id);
                    }
                }
            })
            ->distinct()
            ->get();
    }

Then, I can call this method in my controller like so:

$upcoming_needs = Need::helpersHelpersNeeds();

And loop through them in my view. This does work, but running nested foreach loops in a model seems super inefficient, and not at all "the Laravel way." Is there a cleaner way to achieve data that is one degree removed, so to speak?

cameronscott137 started a new conversation Determining Whether An ID Is Part Of An Laravel Eloq Uent Collection

In my Laravel app, a user has many helpers, and a user has many needs.

I can access a user's helpers and a user's needs with simple Eloquent relationships:

`/**

  • An user can own many needs.
  • @return \Illuminiate\Database\Eloquent\Relations\hasMany */

public function needs() { return $this->hasMany('App\Need', 'creator_id'); }

/**

  • An user helps many other users
  • @return \Illuminiate\Database\Eloquent\Relations\belongstoMany */

function helpers() { return $this->belongsToMany('App\User', 'user_helper', 'user_id', 'helper_id'); }`

In one controller, I call a loop of needs that include needs that user's helpers have created, and needs that other uses in the system have created. However, I need to display each need differently, depending on whether it was created by a helper or not.

In my needs table, I log the ID of the user that created the need in a column called creator_id. I believe I need to check that creator ID against a list of the current user's helper IDs.

The result would be something like:

@foreach ($upcoming_needs as $need) <div {{ $need->creator_id != Auth::user()->helpers()->pluck(id) ? "class=bg-gray" : ""}}> <p>{{$need->description}}</p> </div> @endforeach

However, that isn't doing it. Is there another collection method that I could use in this scenario?

28 Jul
3 years ago

cameronscott137 left a reply on Passing Multiple Parameters To Controller In Laravel 5

Thanks for the response! I'd tried that prior, but it throws the following error:

Undefined variable: eventid (View: /Applications/MAMP/htdocs/littlehelper/resources/views/events/_inviteHelpers.blade.php)

cameronscott137 started a new conversation Passing Multiple Parameters To Controller In Laravel 5

In my application, a user has the ability to remind another user about an event invitation. To do that, I need to pass both the IDs of the event, and of the user to be invited.

In my view, I have:

{!!link_to_route('remindHelper', 'Remind User', $parameters = array($eventid = $event->id, $userid = $invitee->id) )!!}

In my controller, I have:

public function remindHelper($eventid, $userid) { $event = Events::findOrFail($eventid); $user = User::findOrFail($userid); $invitees = $this->user->friendsOfMine; $invited = $event->helpers; $groups = $this->user->groupOwner()->get(); return view('events.invite_groups', compact('event', 'invitees', 'invited', 'groups')); }

However, when I hit that route, I receive the following error:

Missing argument 2 for App\Http\Controllers\EventsController::remindHelper()

I'm sure I have a formatting error in my view, but I've been unable to diagnose it. Is there a more efficient way to pass multiple parameters to a controller?