sustained

sustained

Member Since 8 Months Ago

Sheffield

Experience Points 31,640
Experience Level 7

3,360 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 274
Lessons
Completed
Best Reply Awards 5
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.

16 Jun
1 month ago

sustained left a reply on Auth Choices For SPA + Internal/closed API.

I mean, the "main" JWT library for Laravel has 398 open issues and 13 open pull requests. It just doesn't exactly inspire confidence in the hip and cool new JWT movement. Auth is important and should be done right.

It's the reason I went with default Laravel auth scaffolding until now - I trust them.

sustained started a new conversation Auth Choices For SPA + Internal/closed API.

It seems like there's a million different ways to implement auth and it can be a bit overwhelming.

There's Passport, there's JWTs, there's the token driver and probably more.

In the case that you have a Laravel app and that Laravel app serves a Vue SPA which wants to consume its own (the Laravel API), what should one use?

At this point in time, my API will be closed/internal/only for self-consumption.

Are JWTs the "correct" answer? But in the future I'll likely open up my API, so I want to be future-proof. Also I don't want to lock myself out of the possibility of having some good old-fashioned Laravel backed routes that still work with auth.

Up until now, I've had all my API routes in web.php in a group with an api prefix and an ajax middleware and have been using the default Axios setup (that sends CSRF tokens etc.) but now I'm at the stage where I'd like to move the login/register etc. stuff that comes with the Laravel auth scaffolding into the SPA itself.

But it seems like that default auth scaffolding just isn't designed to accommodate that use-case, correct? So now I will be forced to get my hands dirty and write some auth code, as opposed to using what Laravel provides?

I just really don't want to get auth wrong and I don't particularly trust these thousands of tutorials and guides that all do things in slightly different ways. I have no doubt many of them are flawed, security-wise and I've read about various security concerns with JWTs.

I wish that the Laravel docs had some comprehensive information on doing auth properly with a Vue SPA that self-consumes its own Laravel API, or that there was a course which covered this in detail. There is this series but so far it's only covering the use-case of an app on one domain consuming the API of a separate Laravel app on another domain which is not at all what I want.

Thanks for reading!

08 Jun
1 month ago

sustained started a new conversation And Tips/advice On Testing Scheduled Commands?

This is essentially a cross-post for this request.

Has anyone ever successfully applied TDD to the command scheduler? If so, I'd appreciate any information at all you can share on the process.

As I mentioned in the other thread, I don't see how one could possibly mock something like the scheduler cron job.

And you'd need to fake advances of system time within said process, but from the tests.

Is this even possible?

sustained started a new conversation Request For Lesson(s) On Testing Scheduled Tasks + Jobs/queues.

This requests subforum is for requesting videos on specific topics, right?

I'm working on an application that will rely heavily on jobs/queues and scheduled tasks. Them working properly, flawlessly even, will be vital and as such I think I need to apply TDD here.

There is some information available on testing jobs/queues but I can't even imagine how one begins to test scheduled tasks.

You'd have to somehow have the scheduler running in the context of the tests (I don't see how such a thing could be mocked) and you'd need to fake advances of system time and have the actual scheduler react to them.

I can't even begin to imagine how this would be accomplished.

Perhaps this would make for a good advanced lesson.

25 Dec
6 months ago

sustained left a reply on In Vue.js, Does It Make A Difference If I Call A Function With Parentheses?

Because with axios.get you want to give it a string and getUrl returns a string so you call the function whereas with .then it wants a callback and so you need to pass it a function, if you passed it the result of calling refresh then it would evaluate to undefined which isn't a callback.

sustained left a reply on Customizing The Message In Laravel's New Error Pages?

@THEBIGK - I was getting the same error at one point when my view was NOT in /resources/views/errors/ but when I moved it into that exact directory that error went away.

I never did find out what exactly was going on.

Laravel version? 5.7 or lower?

You can always as a temporary stopgap copy the layout file into the errors directory and use errors.layout instead, see here.

22 Dec
6 months ago

sustained left a reply on Forge Support?

@_STEFANZWEIFEL - Aye, as I figured out myself eventually it was my ad blocker!

17 Dec
7 months ago

sustained left a reply on Forge Support?

@MDECOOMAN - I can't find any form of support widget or link to a support section or anything anywhere on their site. Seriously thinking of cancelling my subscription because of it.

sustained left a reply on Flash Session After Sending Verification Email

Can you add some kind of logging to the registered method to make sure it's getting called? Perhaps a dd or something?

sustained left a reply on Auth In Browser / Vue App

I too am taking the API routes in web.php route for now and plan to look into Passport etc. later on. Apparently a lot of people do this, from what I've read and heard.

It's important to understand that the api.php file is for STATELESS APIs only... but cookies and sessions are, of course, stateful data.

sustained left a reply on Customizing The Message In Laravel's New Error Pages?

The abort helper raises an exception which will then be caught by the exception handler, which will decide which view to render. As such, aborting and the rendering of error pages is tied to the status code.

You can see what the views look like by navigating to the vendor/laravel/framework/src/Illuminate/Foundation/Exceptions/views/ directory, they are rather simple.

You are free to override them on a status code-by-status code basis by creating a file in your resources/views/errors directory as you have found out.

You are also free to copy the built-in layout, and just display your own message.

Some of the error pages, like the 403 page, do actually allow you to display the message because of this line of code in the view:

@section(
    'message',
    __($exception->getMessage() ?: 'Sorry, you are forbidden from accessing this page.')
)

As you can see, if there is a message it will be displayed. Try it yourself with abort(403, 'my message');.

Others like the 404 page instead have something like this:

@section('message', __('Sorry, the page you are looking for could not be found.'))

You are free to override the entire template for any HTTP error, as I mentioned before above, and use $exception->getMessage() just like the 403 error page does.

16 Dec
7 months ago

sustained left a reply on Auth In Browser / Vue App

The easiest option is to put your API routes in web.php, thereby giving you access to cookies and session stat and such. Another option is probably to use Passport and access tokens and such, see here.

13 Dec
7 months ago

sustained left a reply on How Inportant Is Xcode For Us As PHP And Javascript Developers?

I personally just use VS Code for all development on all OSes.

sustained left a reply on Manage Multiple Servers

You can host multiple servers on one DigitalOcean droplet. I have three on my Forge server.

You can then upgrade at a future time if and when the single server can no longer manage your traffic.

11 Dec
7 months ago

sustained left a reply on Can't Get Run Laravel Telescope

What is the actual error in the log file, or printed to the console (if using php artisan serve)...

sustained left a reply on Learn It All Wrong First?

Kids learn to stumble and fall constantly before you learn to walk. Kids learn to throw broken sentences together before you learn to speak a language.

It's a perfectly natural method of learning, for adults too.

So my question is - why not?

sustained left a reply on Is There One Artisan Command That Clears All Caches?

You could add an entry to your package.json?

{
    ...
    "scripts": {
        ....
        "clear-cache": "cache::clear && config::clear && route::clear && view clear"
    }
}

Then run npm run clear-cache?

10 Dec
7 months ago

sustained left a reply on Register Dynamic Model Events From Static Trait Boot Method.

Apparently I'm far too used to JavaScript closures.

It works fine if I add a use statement:

    protected static function bootRecordsActivity()
    {
        foreach (static::$activities as $eventName) {
            static::$eventName(function ($model) use($eventName) {
                $model->record($eventName);
            });
        }
    }

sustained left a reply on Javascript Push Removing Previous Item From Array

Please create a minimal "working" example with some actual example data using a tool like JSFiddle or CodePen.

This will help people to help you.

sustained started a new conversation Register Dynamic Model Events From Static Trait Boot Method.

In episode 25 of Let's Build a Forum with TDD we start working on adding an activity feed.

After we get our tests passing, we extract the code to a trait which we can use in all of our models.

The trait looks something like this:

<?php

namespace App;

trait RecordsActivity
{
    protected static function bootRecordsActivity()
    {
        static::created(function ($model) {
            $model->record('created');
        });
    }

    public function activities()
    {
        return $this->morphMany(Activity::class, 'subject');
    }

    public function record($eventName)
    {
        $this->activities()->create([
            'action' => $eventName,
            'user_id' => auth()->id(),
            'subject_id' => $this->id,
            'subject_type' => get_class($this)
        ]);
    }
}

Now I figured I could take this slightly further so first I added this to my Thread model:

    protected static $activities = [
        'created'
    ];

Next I modify bootRecordsActivity:

    protected static function bootRecordsActivity()
    {
        foreach (static::$activities as $eventName) {
            static::$eventName(function ($thread) {
                $thread->record($eventName);
            });
        }
    }

But this doesn't work as expected.

It's looking for a static::$eventName property in the Thread model but I instead want to call a static method (static::created) dynamically.

Is there a clean way to achieve this? I tried googling and attempted some stuff with get_called_class and such but didn't have any luck.

Thanks!

08 Dec
7 months ago

sustained left a reply on Register/Login An API Session To My Site From Within Another Website

As far as I understand, the generally accepted way to allow other websites to do anything along these lines is by making use of OAuth2.

Have you taken a look at Passport?

sustained left a reply on Not Able To Deploy

Odd. Personally I'd first try just destroying and recreating the app and/or server.

sustained left a reply on ES6 Class Does Not Work In Compiled Js

Perhaps this...

if (typeof window === 'undefined')
    export default Point;
else
    window.Point = Point;

No idea what best practice is though regarding this.

Since the stuff I import/require in my app/main JS file are only being used in the browser personally I just do stuff like window.Blah = require('blah'); or import Blah from 'blah'; window.blah = Blah;.

sustained left a reply on Automatic DB Seeding For Tests.

Nah, I never seed the DB in migrations.

I'll take a look at the packages and versions between both versions.

07 Dec
7 months ago

sustained left a reply on No Queries Being Exected With Route-model Binding?!

I generally always do. I just don't sit on the Laracasts forum all day.

sustained left a reply on No Queries Being Exected With Route-model Binding?!

@CRONIX - Huh, I feel like I've already learned this... my memory seems to be leaking. :/

sustained started a new conversation Automatic DB Seeding For Tests.

On one of my projects I don't need to call $this->seed() or $this->artisan('db:seed') at all and seeding just works by default.

On another project I just started, I have to call those in setUp otherwise the DB is blank.

Both are using SQlite and :inmemory:, same version of PHP+Laravel+SQlite, same machine even.

Both are using the same base TestCase:

abstract class TestCase extends BaseTestCase
{
    use CreatesApplication;
    use RefreshDatabase;
    use DatabaseMigrations;
}

I don't understand.

sustained started a new conversation No Queries Being Exected With Route-model Binding?!

Why is implicit route-model binding not working for me? I have this route in api.php:

Route::get('guild/{discord_id}', '[email protected]');

And this model:

class Guild extends Model
{
    public function getRouteKeyName()
    {
        return 'discord_id';
    }
}

And this controller:

class GuildController extends Controller
{
    public function show(Request $request, Guild $guild)
    {
        return $guild;
    }
}

I have removed use statements etc. for clarity.

If I setup the binding explicitly in RouteServiceProvider.php then it works?

06 Dec
7 months ago

sustained left a reply on Ajax POST MethodNotAllowedHttpException

It happens to us all.

sustained left a reply on Disable Updated_at Time Of Insert

@SOUVIKBHATTACHARYAS - I too will be waiting to see what other suggestions show up, out of curiosity.

Just mark me as the best answer, if you decide to go with my solution/nothing better comes along though? :D

sustained started a new conversation Very Strange Behaviour When Using ::class In Routes File.

This doesn't make any sense?

use App\Http\Controllers\ReplyController;

Route::resource('threads', ThreadController::class);
Route::post('/threads/{thread}/replies', [ReplyController::class, 'store']);

// ^ All routes work (?!):
Route::resource('threads', ThreadController::class);
Route::post('/threads/{thread}/replies', [ReplyController::class, 'store']);

// ^ Only the routes on the threads resource work, otherwise:
// ReflectionException, Function () does not exist
use App\Http\Controllers\ThreadController;
use App\Http\Controllers\ReplyController;

Route::resource('threads', ThreadController::class);
Route::post('/threads/{thread}/replies', [ReplyController::class, 'store']);

// ^ Only the store reply route works, otherwise:
// App\Http\Controllers\App\Http\Controllers\ThreadController does not exist
use App\Http\Controllers\ThreadController;

Route::resource('threads', ThreadController::class);
Route::post('/threads/{thread}/replies', [ReplyController::class, 'store']);

// ^ None of the routes work:
// App\Http\Controllers\App\Http\Controllers\ThreadController does not exist

sustained left a reply on Disable Updated_at Time Of Insert

Extend the model class and use eloquent events e.g.

<?php
use Illuminate\Database\Eloquent\Model;

class CustomModel extends Model
{
    public static function boot()
    {
        parent::boot();

        static::creating(function ($model) {
            $model->timestamps = false;
            $model->created_at = now();
        });
    }
}

Code is untested.

Disclaimer: I'm a Laravel newb so this might not work or might be really bad code etc.

sustained left a reply on How Can I Add A New Repo From An Existing Project And Connect It To Github Or Gitlab

Just create a new completely empty repository on Gitlab and then scroll down and read the "command line instructions" section.

sustained left a reply on Ajax POST MethodNotAllowedHttpException

Change Route::get to Route::post.

sustained left a reply on Testing Environment Is Not Set When Running Phpunit?

CONFIG CACHING STRIKES AGAIN, ANOTHER VICTIM CLAIMED!

sustained started a new conversation Testing Environment Is Not Set When Running Phpunit?

At around 8:25 in episode 4, Jeff mentions a gotcha with Laravel testing in that sending a request that doesn't have a route/endpoint doesn't trigger an error like you'd expect.

He mentions a walkaround wherein one can edit the render method within app/Exceptions/Handler.php and throw the exception if the app environment is testing i.e.:

public function render($request, Exception $exception)
{
    if (app()->environment() === 'testing') throw $exception;
}

But if I try to apply the workaround, it doesn't work as expected.

If I do a \Log::debug(app()->environment()) within that method, I can see that it returns local when I run vendor/bin/phpunit.

Is this a bug? Is there a new/different workaround for this issue for Laravel 5.7?

05 Dec
7 months ago

sustained left a reply on Laravel And Gzip... How To?

But that is for compressing some specific file, like a report that you've generated in that case.

If you want to compress all of your public assets then it's best to do it at the webserver level?

sustained left a reply on Laravel And Gzip... How To?

I believe gzip is something that happens at the webserver level, so you need to google for how to enable gzip with Apache or Nginx or whatever webserver you're using.

sustained left a reply on Proper Queue Usage?

Another approach could be to batch them so that the first job is responsible for sending say 20 Slack messages and the second job for the next 20 and so on.

This way, if one of the jobs fails only a small number of messages fail to send and the number of people affected is minimal.

sustained left a reply on Flash Session After Sending Verification Email

I believe you can add a method called registered to your Auth\RegisterController.

This method will be fired immediately after logging in the user (after registration) and immediately before redirecting the user.

The code in question that calls this method is in vendor/laravel/framework/src/Illuminate/Foundation/Auth/RegistersUsers and looks like this:

        return $this->registered($request, $user)
                        ?: redirect($this->redirectPath());

So if the return value of registers is truthy then it returns that, otherwise if it is non-truthy (which is the default because by default it does nothing) then it redirects based on the redirectPath.

And the definition of redirectPath looks like this:

    public function redirectPath()
    {
        if (method_exists($this, 'redirectTo')) {
            return $this->redirectTo();
        }

        return property_exists($this, 'redirectTo') ? $this->redirectTo : '/home';
    }

So you can probably create the registered method as I said and make it look something like this:

<?php
class RegisterController extends Controller
{
    use RegistersUsers;

    protected $redirectTo = '/home';

    protected function registered(Request $request, $user)
    {
        $request->session()->flash('foo', 'bar');
        // Any other logic needed.
    }
}

And if you want it to redirect after then make sure that you return false/null/nothing.

Sorry if this is not super clear or if I'm incorrect or if there are easier/better ways to achieve this or whatever, I'm brand new to Laravel.

sustained left a reply on Consuming Jobs From Laravel Queues With Node

I just ended up creating a NodeJob model and basically creating my own custom implementation.

sustained left a reply on Laravel Custom Url Set

It's very easy to conditionally redirect the user with any framework, including Laravel.

sustained left a reply on Laravel Websockets

I saw this on the Laravel subreddit the other day, looks interesting!

sustained left a reply on Dynamic Routes

Originally I was trying to do this, which I thought would work just fine but it doesn't (hence the above solution):

Route::get('/dynamic/{params?}', function ($method, $params = null) {
    return App::call('\App\Http\Controllers\[email protected]', explode('/', $params));
})->where('params', '.+');

And this controller:

<?php
namespace App\Http\Controllers;

use Illuminate\Http\Request;

class DynamicController extends Controller
{
    public function handle(Request $request, $one = null, $two = null, $three = null)
    {
        dd([$one, $two, $three);
    }
}

Those params are ALWAYS null for me instead of just defaulting to null which I don't understand.

Does anyone know why?

If you change it to e.g. handle(Request $request, $one, $two) and pass exactly two params it works just fine?

sustained left a reply on Dynamic Routes

You could have this route:

Route::get('/dynamic/{params?}', function ($method, $params = null) {
    return App::call('\App\Http\Controllers\[email protected]');
})->where('params', '.+');

And this controller:

<?php
namespace App\Http\Controllers;

use Illuminate\Http\Request;

class DynamicController extends Controller
{
    public function handle(Request $request)
    {
        $params = array_slice($request->segments(), 1);
        dd($params);
    }
}

04 Dec
7 months ago

sustained started a new conversation Consuming Jobs From Laravel Queues With Node

Does anyone have any experience with this or any ideas/input? Or perhaps an alternative method of communicating with my node program from Laravel?

My current setup is thus:

  1. I have one server running a long-running Node process (let's call it node) as well as a Laravel app that acts as a purely private API (let's call it papi. The server as a whole, let's call node/papi.
  2. I also have a second server which is also a Laravel app but this one is publicly accessible (via the web), let's call this server web.

Note that web is also able to communicate with papi.

So, the web server is going to be powering a relatively complex web application and so I will be using jobs/queues for various things, most likely. And most of these I'll want to consume from PHP/Laravel code.

But now and again, I'll need a job triggered from web to be ultimately processed by node.

I'm thinking that I can just have a second job queue setup on papi which is solely for node-specific jobs.

Then I can presumably just not run any queue worker at all on the node/papi server and instead consume those jobs from Node/JS.

But this all feels a little clunky. Any input appreciated.

03 Dec
7 months ago

sustained left a reply on Redirect

Question: If you're using Laravel then why not do it server-side?

You could check document.referrer to see where the user came from and you can use window.location = 'url to redirect to'; to redirect the user?

If you still can't get it working, post example code?

sustained left a reply on How To Install Vuex

Try this:

  1. Install Vue CLI 3 - npm i @vue/cli -g.
  2. Create a new project - vue create myproject (you may need to close and reopen the terminal window first, after step 1).
  3. When prompted to select a preset, choose "manually select features".
  4. Use arrow key down, until you hit Vuex, then hit space.
  5. Select whatever you want for linter, lint features, config location etc. (the default is fine - just hit return).
  6. You should have a working Vue project with VueX boilerplate and Babel compilation etc.