MikeMacDowell

MikeMacDowell

Head of Business Systems at Anthony Best Dynamics Ltd

Member Since 4 Years Ago

Bristol

Experience Points
116,670
Total
Experience

3,330 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
1001
Lessons
Completed
Best Reply Awards
27
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.

Level 24
116,670 XP
Feb
17
5 days ago
Activity icon

Awarded Best Reply on Hijack Password Reset

If you want to replicate what you've done here, I'd suggest overriding the sendResetResponse method in PasswordController

    /**
     * Get the response for a successful password reset.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  string  $response
     * @return \Illuminate\Http\RedirectResponse|\Illuminate\Http\JsonResponse
     */
    protected function sendResetResponse(Request $request, $response)
    {
    $user = $this->guard()->user();

    session(['api_token' => $user->api_token]);
        session(['season' => Season::where('active', 1)->first()]);
        session(['centres' => Centre::where('active', 1)->get()]);
        session(['centre' => Centre::findOrFail(auth()->user()->centre_id)]);
        session(['user' => $user]);

        return redirect()->route('home') ;
    }

Or just override the resetPassword method so the user isn't logged in and is required to then authenticate and your method gets hit then?

Feb
15
1 week ago
Activity icon

Awarded Best Reply on Every Page Load Calls A Method That Is Supposed To Only Run Once

Okay, I understand more about what you're asking now - you can't use Javascript to protect the endpoint being hit more than once total - because if 100 people have the same page open, it's going to countdown to zero on each of their pages and you'll get 100 requests sent to the server. This will cause your job to get dispatched multiple times, even if you're checking for a completion status (as this is a race hazard https://en.wikipedia.org/wiki/Race_condition)

You'd be better to have the time countdown on your server and the Event be executed at the point your server wants. This does mean that the timer on your front-end is independent of the server time, but you can run a request on an infrequent basis to re-sync it to the server

Feb
14
1 week ago
Activity icon

Replied to Every Page Load Calls A Method That Is Supposed To Only Run Once

Okay, I understand more about what you're asking now - you can't use Javascript to protect the endpoint being hit more than once total - because if 100 people have the same page open, it's going to countdown to zero on each of their pages and you'll get 100 requests sent to the server. This will cause your job to get dispatched multiple times, even if you're checking for a completion status (as this is a race hazard https://en.wikipedia.org/wiki/Race_condition)

You'd be better to have the time countdown on your server and the Event be executed at the point your server wants. This does mean that the timer on your front-end is independent of the server time, but you can run a request on an infrequent basis to re-sync it to the server

Activity icon

Replied to Hijack Password Reset

If you want to replicate what you've done here, I'd suggest overriding the sendResetResponse method in PasswordController

    /**
     * Get the response for a successful password reset.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  string  $response
     * @return \Illuminate\Http\RedirectResponse|\Illuminate\Http\JsonResponse
     */
    protected function sendResetResponse(Request $request, $response)
    {
    $user = $this->guard()->user();

    session(['api_token' => $user->api_token]);
        session(['season' => Season::where('active', 1)->first()]);
        session(['centres' => Centre::where('active', 1)->get()]);
        session(['centre' => Centre::findOrFail(auth()->user()->centre_id)]);
        session(['user' => $user]);

        return redirect()->route('home') ;
    }

Or just override the resetPassword method so the user isn't logged in and is required to then authenticate and your method gets hit then?

Activity icon

Replied to Every Page Load Calls A Method That Is Supposed To Only Run Once

There's nothing wrong with your Vue component (I copied and compiled it up myself), so are you sure that the endpoint is being hit by this component?

Maybe add a query string to the uri and check for it in the controller as a debug tool?

Is this controller method being called anywhere else in your code?

Activity icon

Awarded Best Reply on How Can I Load A Relationship On Illuminate\Support\Collection

Load the relationships before the pluck. All of the collection methods return the Illuminate\Support\Collection class because they are defined on that class.

This should work:

$this->groups->load('thread.tags')->pluck('thread.*.tags.*.name');
Activity icon

Replied to How Can I Load A Relationship On Illuminate\Support\Collection

Load the relationships before the pluck. All of the collection methods return the Illuminate\Support\Collection class because they are defined on that class.

This should work:

$this->groups->load('thread.tags')->pluck('thread.*.tags.*.name');
Jan
15
1 month ago
Activity icon

Replied to Laravel Joining Issue With Two Tables

This is Eloquent 101 - you can watch a series on Relationships here https://laracasts.com/series/eloquent-relationships

To do it in this case you'd do:

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class branchname extends Model
{

    public function course()
    {
        return $this->belongsTo(coursename::class, 'course_id');
    }

}
Activity icon

Replied to Laravel Orderby Uses

Not from the database, but if you have a collection of users you can use the collection method sortBy

$sorted = $collection->sortBy(function ($user, $key) {
    return $user->fullName();
});
Activity icon

Replied to Replicate Magento's Layered Navigation

If you don't know how many attributes you're going to be giving on any given request, the only way I can think of is this:

web.php

Route::get('category-name/{parameters?}', '[email protected]')->where('parameters', '.*');

Controller

    public function test(Request $request, $parameters)
    {
        return explode('/', $parameters);
    }

This gives you the parameters in an array which you could then use for filtering. It's messy because you'd need to put a name and a value in each parameter unless you want to only filter one attribute if another has already been filtered by.

Activity icon

Commented on Database Notifications

@JeffreyWay using ->markAsRead() on the DatabaseNotificationCollection still causes the N+1 issue as it's a collection method that just runs a database query for each Notification. Unless there's something I'm missing?

It would probably be better to write a mass update query?

Oct
04
4 months ago
Activity icon

Replied to How To Custom Resources Controller With Specific Middleware

I think the only way you can specify for particular actions is in the controller with Controller Middleware

https://laravel.com/docs/5.8/controllers#controller-middleware

Alternatively you can just set up the routes twice?

Route::resource('api/tasks', 'TaskController', [
    'only' => ['update', 'destroy']
])->middleware(['tasks_view']);    

Route::resource('api/tasks', 'TaskController', [
    'only' => ['index', 'show', 'store']
]);
Activity icon

Replied to Sanity Check My Eager Loading + Filtering?

You could also do this as part of the query building when you're populating the model/collection of Audit using wherePivot.

Alternatively you can set up a new relationship on your Audit model which means you always would have access to the "Good" checks

// Audit.php
public function goodChecks()
{
    return $this->belongsToMany(Check::class)->wherePivot('result', 'Good');
}

Lastly, and this may be off base, but I'm wondering why you have a Many-to-Many relationship? Obviously without knowing the business logic behind your code structure I'm guessing, but it seems strange that an Audit can have many Checks and each Check can have many Audits.

Unless the model you are calling "Check" is actually the type of check? In that case I would restructure your models as I believe it would end up being simpler.

You'd have:

/* Audit.php */

public function checks()
{
    return $this->hasMany(Check::class);
}


/* Check.php */
// This is new, it's a first class citizen model as I believe this is what's important to you
// This would contain the status of the check and any other information that is relevant about the check
// Storing it not on a pivot table makes it easier to access everything and you can form relationships on the model too

public function audit()
{
    return $this->belongsTo(Audit::class);
}

public function type()
{
    return $this->belongsTo(CheckType::class);
}


/* CheckType.php */
// this is what you're currently calling Check

public function checks()
{
    return $this->hasMany(Check::class);
}

Just my two cents, but this is a pattern I see repeated a lot where people try to use Many-to-Many relationships when what they're really interested in is information about the join itself

Oct
01
4 months ago
Activity icon

Replied to Combination Of Two Column Must Unique

You can check this in validation using the "different" validation rule (if what you want is the column values to always be different, making each entry unique in the table is a different check)

https://laravel.com/docs/5.8/validation#rule-different

Activity icon

Replied to Hash:: Facade And Hash() Helper Differences?

Look at the Laravel documentation for Hashing

https://laravel.com/docs/5.8/hashing

Activity icon

Replied to How To Show Only 3 First Words Of A Text Variable ?

I wouldn't do it with regex, I'd just use split() and join() in the filter

Activity icon

Replied to Validating Unique Via Pivot Table

I think this should do it


'role' => [
    'required', 
    Rule::unique('role_user', 'role_id')->where(function ($query) {
        return $query->where('user_id', $this->user_id); 
// assuming you're sending 'user_id' in the request
    }),
]

However, if you're using sync() on the ManyToMany relationship, you don't need to check this as it will only be added once into the table anyway

Activity icon

Replied to How To Show Only 3 First Words Of A Text Variable ?

You can use split() and join() to do this

<h5 class="modal-title" id="deleteTaskModalLabel">
{{ modalTitle.split(" ", 3).join(" ") + modalTitle.split(" ").length > 3 ? "..." : "" }}
</h5>

You probably want to move this to its own function though

Activity icon

Replied to Add Dynamic Prefix In Laravel Routes Web.php

Like my previous reply, with a wildcard as a route prefix which you then check in a middleware if a valid Customer exists (or load a tenant based upon the prefix).

Route::group([
    'prefix'     => '/{customer_name}',
    'middleware' => \App\Http\Middleware\IdentifyCustomer::class,
    'as'         => 'customer:',
], function () {
    // routes here
});

Check out the link I posted for how you'd do this and load only the information for that customer on every other database request.

Sep
30
4 months ago
Activity icon

Replied to Add Dynamic Prefix In Laravel Routes Web.php

That's a multi-tenanted application if you're then segmenting all the data for each company based upon the URL.

IF you still want to just pre-generate all the URLs, you can do it like this, but be warned, for each company you add to the database you're duplicating all your routes again for that extra company, so if you have 100 routes, and 10 companies then you'll have 1000 routes.

Company::all()->each(function($company) {

    Route::group([
        'prefix' => $company->name, 
        'name' => $companyName . '.',
    ], function() {
    // routes go here
    });

});


Activity icon

Replied to Add Dynamic Prefix In Laravel Routes Web.php

Are you trying to create a multi-tenanted application?

Functionally doing what you ask is pretty simple, but I'm not sure you actually want to do this as what you're asking for is to create a pre-defined set of routes for every company_name, which is just going to duplicate the entire routes file across however many companies in your database (which means that the routes can't be cached etc...)

I think what you instead want, is for all routes to require a company_name as a wildcard which then triggers a tenant to be loaded for that request?

You'd do that like this:

Route::group([
    'prefix'     => '/{tenant}',
    'middleware' => \App\Http\Middleware\IdentifyTenant::class,
    'as'         => 'tenant:',
], function () {
    // Tenant routes here
});

Taken from https://ollieread.com/articles/laravel-multi-tenancy-avoiding-over-engineering which I've used to implement multi-tenancy on an application previously

Activity icon

Replied to Carbon AddDays

Carbon::now()->lastOfMonth()->addDays(37)->toDateString();

https://carbon.nesbot.com/docs/#api-addsub

Activity icon

Replied to Prevent Reactivity Of Data Once Pushed To An Array.

Can you post more of your child component? Specifically how you're setting selectedProduct and emitting it to the parent?

Sep
17
5 months ago
Activity icon

Replied to Is Mass Assignment Dangerous ?

I think you might have misunderstood some of the comments,

Laravel automatically protects you against SQL Injection Attacks because it uses PDO binding when you use Eloquent to do database transactions - this happens automatically and you don't have to worry about it as long as you're not using the DB facade or directly creating database queries.

Mass Assignment Attacks are not SQL Injection and are where you've left mistakes in your code logic to allow an attacker to exploit them by setting database fields in a way they should not be able to. The examples everyone has given are the dangers of mass assignment attacks. Typically you'd be adding an extra field into the request data on a Mass Assignment Attack, like

{is_admin = 1}

SQL Injection is where the request allows a user to enter extra SQL information into a database query to take extra actions, this usually involves pushing malformed or "clever" text into an already existing request field to take action on the database like

{name = "bob' ; drop table users;"}
Sep
16
5 months ago
Activity icon

Replied to Is Mass Assignment Dangerous ?

Laravel protects you from SQL injection if you use Eloquent.

Mass assignment is fine as long as you understand the potential issues and protect against them with validation or by using the $fillable array on a model.

It's good practice to validate the input from the user and only use the validated array to mass assign https://laravel.com/docs/6.x/validation#quick-writing-the-validation-logic

Activity icon

Replied to Vue V-for

Why don't you group your collection in your controller before returning it to the front-end. That way PHP is doing the heavy lifting on your dataset.

$data = Model::all()
    ->groupBy('carMake');

This will give you a collection like:

[
"Fólksbíll" : [
      0: {id: 1, carMake: "Fólksbíll", …},
      1: {id: 2, carMake: "Fólksbíll", …}
   ],
"Jepplingur" : [
      2: {id: 3, carMake: "Jepplingur", …}
      3: {id: 4, carMake: "Jepplingur", …},
   ],
"Jeppi" : [
      4: {id: 3, carMake: "Jeppi", …}
      5: {id: 4, carMake: "Jeppi", …}
   ]
]

Then you can loop through this collection and then each of the sub-collections if you wish

Sep
03
5 months ago
Activity icon

Replied to Is There Such Method In Collection?

You won't make that map function any simpler without PHP 7.4 where you can use short closure syntax.

There's no built in Laravel Collection method for you to do this, but you could make your own Macro.

Collection::macro('keyItems', function ($key) {
    return $this->map(function ($value) use ($key) {
        return [$key => $value];
    });
});

$animals = collect(['dog', 'cat', 'tiger']);

$columnized = $animals->keyItems('animal');

Put your Macro definition in a Service Provider and it will be available globally.

Aug
23
5 months ago
Activity icon

Replied to Self Join Query Is Too Slow

Do you have Models set up? This could be achieved using Eloquent without having to do a massive SQL join (which is probably what's taking the time, but without a similar recordset I can't tell you for sure).

What are you trying to achieve? Some background of the business logic you're trying to implement will help with understanding possible solutions.

Activity icon

Replied to More Than One Listener On Events

Can you post the whole Listener class? Makes it easier to look at and try to see the problem

Aug
22
6 months ago
Activity icon

Replied to More Than One Listener On Events

@orion in reference to your second paragraph, surely that defeats the object of having events - if you're just going to essentially call a method which dispatches different jobs, you can call that method from wherever you're dispatching the event (obviously excepting that you can fire an event from anywhere).

The way shown here is a framework recommended way of handling multiple required outcomes of an event - especially if those outcomes are dependant upon each other in some way, you can stop the event propagating to further listeners. Even if they are not dependent upon each other, you're isolating single responsibilities in response to an event to a given listener, and then you can couple the same listener to another event or events.

By putting all your jobs in a single listener it's no longer reusable and you're just using events as a tool to essentially call a single method?

Happy to discover and learn your reasonings behind your approach.

Activity icon

Replied to More Than One Listener On Events

Nothing looks incorrect in your EventServiceProvider.

Can you post your first listener class?