Roni

Roni

WINNIPEG, MANITOBA

Member Since 4 Years Ago

Experience Points 69,260
Experience
Level
Lessons Completed 786
Lessons
Completed
Best Reply Awards 4
Best Answer
Awards
  • Start Your Engines Achievement

    Start Your Engines

    Earned once you have completed your first Laracasts lesson.

  • First Thousand Achievement

    First Thousand

    Earned once you have earned your first 1000 experience points.

  • One Year Member Achievement

    One Year Member

    Earned when you have been with Laracasts for 1 year.

  • Two Year Member Achievement

    Two Year Member

    Earned when you have been with Laracasts for 2 years.

  • Three Year Member Achievement

    Three Year Member

    Earned when you have been with Laracasts for 3 years.

  • Four Year Member Achievement

    Four Year Member

    Earned when you have been with Laracasts for 4 years.

  • Five Year Member Achievement

    Five Year Member

    Earned when you have been with Laracasts for 5 years.

  • School In Session Achievement

    School In Session

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

  • Welcome To The Community Achievement

    Welcome To The Community

    Earned after your first post on the Laracasts forum.

  • Full Time Learner Achievement

    Full Time Learner

    Earned once 100 Laracasts lessons have been completed.

  • Pay It Forward Achievement

    Pay It Forward

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

  • Subscriber Achievement

    Subscriber

    Earned if you are a paying Laracasts subscriber.

  • Lifer Achievement

    Lifer

    Earned if you have a lifetime subscription to Laracasts.

  • Laracasts Evangelist Achievement

    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 Achievement

    Chatty Cathy

    Earned once you have achieved 500 forum replies.

  • Laracasts Veteran Achievement

    Laracasts Veteran

    Earned once your experience points passes 100,000.

  • Ten Thousand Strong Achievement

    Ten Thousand Strong

    Earned once your experience points hits 10,000.

  • Laracasts Master Achievement

    Laracasts Master

    Earned once 1000 Laracasts lessons have been completed.

  • Laracasts Tutor Achievement

    Laracasts Tutor

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

  • Laracasts Sensei Achievement

    Laracasts Sensei

    Earned once your experience points passes 1 million.

  • Top 50 Achievement

    Top 50

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

13 Nov
16 hours ago

Roni left a reply on Exists In A Table Validation Issue

@talinon you are the king, I must need yet another coffee.

Roni started a new conversation Exists In A Table Validation Issue

It's Tuesday morning and I'm under the weather, so my brain must be missing something jsut a validation request where my last rule is causing an issue. I need to validate that the incoming account_id is a valid id in the accounts table. I added them rest of the tests just to make sure that data was indeed coming in and in the end the two dumps showing that the ID in the Accounts table was there, and that the input matched the id ( I doubled that first test becuase my dump with a concat made the data look a bit funny and I didn't want to confuse anyone:


 public function rules()
    {
    dump(Account::all()->pluck('id'));
        dump('ACCOUNTS TABLE: '. Account::all()->pluck('id'));
        dump('INPUT ACCOUNT : '. $this->input('account_id'));

        return [
            'name' => 'required',
            'min_age' => 'required|numeric|min:3',
            'requires_group' => '',
            'public_visible' => '',
    // this line is the issue and it looks right to me !
            'account_id' => 'required|numeric|integer|min:1|exists:accounts, id',
        ];
    }


here is the test output


Testing started at 10:13 AM ...
/usr/local/bin/php /Users/roni/code/php/laravel/5.7/pie/vendor/phpunit/phpunit/phpunit --configuration /Users/roni/code/php/laravel/5.7/pie/phpunit.xml --filter "/(::a_valid_topic_can_be_created_in_the_database_by_an_authenticated_user)( .*)?$/" Tests\Feature\Topic\CreateTopicTest /Users/roni/code/php/laravel/5.7/pie/tests/Feature/Topic/CreateTopicTest.php --teamcity
PHPUnit 7.4.3 by Sebastian Bergmann and contributors.

Illuminate\Support\Collection {#1077
  #items: array:1 [
    0 => 1
  ]
}
"ACCOUNTS TABLE: [1]"
"INPUT ACCOUNT : 1"
"Tests\DomainTestCase\errorsArray([])"
"-------------------------------------------"
Illuminate\Support\MessageBag {#1092
  #messages: array:1 [
    "account_id" => array:1 [
      0 => "The selected account id is invalid."
    ]
  ]
  #format: ":message"
}

Process finished with exit code 1

Thanks for any assistance

12 Nov
1 day ago

Roni started a new conversation Visual Issue On Profile Section In Site

Hi @jeffrey_way, on the profile section where is lists your badges, unless your scree size is over xl, the mouse over descriptions on badges on the left and right sides bleed over the edge of the viewport. So on the far left and the far right, first 2-3 on each side the text and background box is cut off.

Clearly not a high priority, but thought I'd let you know.

08 Nov
5 days ago

Roni left a reply on Making Model Macroable

Well Damn Me! You can't the macroable trait because you are overwrittingt he macro's array! Because model IS macroable! I couldn't source dive find where it happens, but I removed everything and the macro's never stopped working.

I hope this saves you a few hours.

Cheers.

Roni started a new conversation Making Model Macroable

Hi, I've found it super helpful under certain circumstances to make model macroable. However I'm finding some drawbacks. I'm hoping someone might have a little deeper knowledge on this.

The only place I use it is in testing, and it's amazingly helpful. When faced with a nasty query, being able to throw the array, table, or collection into a console table printout has been a real go to. Taking what was a much longer process and shrinking it to a minute or two as the information pops out at you.

The main reason for doing this is to have access to the attributes array externally under test that you won't have access to in the actual app. It keeps the app code clean and the testing fast.

However, checking the rest of the test suite showed some conflicts with commands from the builder like "find" or "where", which is kind of a big deal. Has anyone properly implemented Macroable in a non conflicting way?

Here are the files for clarification with some examples, all are properly visible and working, it's not a composer autoload issue.

My Model


namespace App\Helpers;

use Illuminate\Database\Eloquent\Model as EloquentModel;
use Illuminate\Support\Traits\Macroable;


class Model extends EloquentModel
{

    use Macroable {
        __call as myMacroCall;
    }

    public function __call($method, $parameters)
    {
        if (static::hasMacro($method)) {
            return $this->myMacroCall($method, $parameters);
        }

        return parent::__call($method, $parameters);
    }

    protected $guarded = [];

}

I use it as follows for example Game.php :


namespace App;

use App\Helpers\Model;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\DB;

class Game extends Model
{

//rest of class

}

In my test class I've set up a macro:


Model::macro('tableHeaders', function(){
    return array_keys($this->attributes);
});


It works perfectly. But now, my test suite is throwing new errors like this:

  1. Tests\Unit\GameTest::a_game_has_many_turns BadMethodCallException: Method App\Game::find does not exist.

or

  1. Tests\Unit\GameTest::a_question_set_can_be_filtered_by_a_user BadMethodCallException: Method App\Turn::where does not exist.

These all vanish as soon as I comment out the use Macroable from the parent model class.

Thanks for any advice you might have.

07 Nov
6 days ago

Roni left a reply on What About New Look @laracast.com

Looks awesome, performing a bit slow, but more than likely because we are all here at the same time looking at the new site :)

06 Nov
1 week ago

Roni left a reply on Anyone Ever See M:N Sync Do Some Ordering?

I updated it with results for clarity:


public function setPlayers($players)
    {
        $shuffled = $players->shuffle()->pluck('id')->all();

        dump($shuffled);

        $this->players()->sync($shuffled);
        dd($this->players->pluck('id')->values()->all());
    }



//RESULTS

PHPUnit 7.4.3 by Sebastian Bergmann and contributors.

array:5 [
  0 => 5
  1 => 3
  2 => 2
  3 => 1
  4 => 4
]
array:5 [
  0 => 1
  1 => 2
  2 => 3
  3 => 4
  4 => 5
]

Process finished with exit code 1

Roni started a new conversation Anyone Ever See M:N Sync Do Some Ordering?

It's been a long day and maybe my brain is used up but running this test always gives me back ordered id's even though I'm attempting to randomize the order they are stored in.


public function setPlayers($players)
    {
    //players are in order here
        $shuffled = $players->shuffle()->pluck('id')->all();
    //dd($shuffled); //everything is nicely shuffled here

        $this->players()->sync($shuffled);
        dd($this->players); //everything is back in order here!!!

    //Mind => blown

    }

Roni left a reply on Validating An Array

I find this super confusing and perhaps I'm not testing this correctly,

this validation rule works perfectly in all cases that I've tested (again I've left in commented lines:

I hate using this even though it passes every test because I'm not exactly sure what is going on.

I'm missing where each item is pulled to compare. But I can tell you without any hesitation that it IS doing it.


    /**
     * Get the validation rules that apply to the request.
     *
     * @return array
     */
    public function rules()
    {
        return [
            'name' => 'required',
//            'players' => 'required|array|min:1',
            'players' => [
                'required',
                'array',
                'min:1',
                Rule::exists('players', 'id')->where('account_id', auth()->accountId())
            ]
//                'int',
//                Rule::exists('players')->where(function ($query) {
//                    $query->where('account_id', auth()->accountId());
//                }),
//            ]
        ];
    }

If anyone could shed some light it would be appreciated.

Here is the updated test lines broken out for easy commenting


 /** @test */
    public function a_valid_game_will_be_stored() {
        $this->accountSignIn();

        $validPlayer1 = create(Player::class, ['account_id'=>auth()->accountId()]);
        $validPlayer2 = create(Player::class, ['account_id'=>auth()->accountId()]);
        $invalidPlayer = create(Player::class);
        $this->withExceptionHandling()
            ->submitValidGame([
                'players'=>[
                    $validPlayer1->id,
                    $validPlayer2->id,
//                    $invalidPlayer->id
                ]
            ])
//        dd(session()->get('errors')->getBag('default'));
        ->assertOk();

        $this->assertDatabaseHas('games', [
            'name' => 'Valid Game Name']);
    }


Roni started a new conversation Validating An Array

Hi Guys,

I'm trying to figure out validating a single field that contains an array

the data for the field will be generated by a vue components that will produce an array of integers


[1, 2, 3]

I want to validate that the input is in fact an array, (that part is fine) AND that each item in the array is an integer and in in a table with a specific account_id

Here is my code, I've tried a number of variations on based on the docs, but I can't seem to find the right one.

I'm calling this from a unit test so that the backend is all hooked up before I setup the visuals, I can't see that making a difference, but in case it does, now you know.


 public function rules()
    {
        return [
            'name' => 'required',  //Works
            'players' => 'required|array|min:1', //Works
            'players.*' => [
                'required',
                'int',
                Rule::exists('players')->where(function ($query) {
                    $query->where('account_id', auth()->accountId());
                }),
            ]
        ];
    }

I'm calling it from this unit test, I've left some of my hackery in trying to dig into this one.


    /** @test */
    public function a_valid_game_will_be_stored() {
        $this->accountSignIn();
        $player = create(Player::class, ['account_id'=>auth()->accountId()]);
        $this//->withExceptionHandling()
            ->submitValidGame(['players'=>[$player->id]] );

//        dd(session()->get('errors')->getBag('default'));
        //->assertOk();

        $this->assertDatabaseHas('games', [
            'name' => 'Valid Game Name']);
    }

here is the helper function submitValidGame


  protected function submitValidGame($overrides = [], $update = false)
    {
        return $this->post(route($update ? 'setup.update' : 'setup.store'),
            $this->validGameFields($overrides));
    }

    /**
     * @param $overrides
     * @return array
     */
    protected function validGameFields($overrides = []): array
    {
        try{
            return array_merge([
                'name' => 'Valid Game Name',
                'players'=> [1],
                'account_id' => auth()->accountId(),
            ], $overrides);
        }catch(\Exception $e){
            return [];
        }

    }

just in case, here is a snippet from the players migration

          
            $table->integer('account_id')->unsigned();
            $table->foreign('account_id')->references('id')->on('accounts')->onDelete('cascade');

and the relationship


    /**
     * Get the account that owns the Player.
     */
    public function account()
    {
        return $this->belongsTo(Account::class);
    }

the only thing I can't seem to make run is the players array specific item validation .

Thanks.

Roni left a reply on Add Custom Function To Auth Facade

@Edgar.Hauf , thanks!

I've noticed this won't work in a unit test


// WONT WORK in phpunit
auth()->user()->account

however this will work in a unit test and I think is very clear


SessionGuard::macro('account', function(){
    return auth()->user()->load('account')->account;
});


So you could use it like this in your unit tests


auth()->account()


Instead of the AppServiceProvider (I may add it there too for constancy) I jsut add it in my DomainTestCase file, setUp() method, just where I add macros that are specific to the project I'm working on, you could add it directly to TestCase and accomplish the same thing.

23 Oct
3 weeks ago

Roni left a reply on Additional Prepended Data Showing Up On My Cookie

@Borisu , @jlrdw Sometimes after too many coffees and too many hours, my brain turns to mush :) Thanks for pointing out the obvious ... and the video.

Roni left a reply on Use Function From Model In Notifications

I was looking at something unrelated when this popped up... This was what I was referring to before:

https://laracasts.com/discuss/channels/general-discussion/laravel-view-presenter

Roni left a reply on Sessions Seem To Always Be Empty And Regenerated

Ok, so to test a request with session data, you actually have to set the session in the request. Counter intuitive (for me at least)! Nice that this sessions and cookies don't seem to be covered in any testing course! Yes please show me how to mock mail for the hundredth time :/.

You probably don't need the local variable but I left it in for clarity.


 /** @test */
    public function a_guest_cart_is_reused_between_pages()
    {
        ObjectFactory::validInventoryProduct();

        $oldResponse = $this->get('/');
        $oldCart = session('cart');
        $oldCart->add(1);

        // Go back to the any page under the middleware and
        // the cart should be regenerated from the session.
        // set the session data needed for the request as
        // it will be purged on the new request.

        $session = session()->all(); //store session state
        $newResponse = $this->withSession($session)->get('/');

        // you can find more info about trait InteractsWithSessions
        // here: https://laravel.com/docs/5.7/http-tests#session-and-authentication 

        $newCart = session('cart');
        $newCart->add(1);

        $this->assertSame($oldCart, $newCart);
    }


Roni started a new conversation Sessions Seem To Always Be Empty And Regenerated

I've been playing with cookies on a laravel test app that I keep coming back to and just when I thought everything was working, I may have killed my sessions. Here are some unit tests on a middleware app to make sure it's working.

Otherwise this is in a regular laravel 5.7 application

middleware:


<?php

namespace App\Http\Middleware;

use App\Orders\Cart;
use Closure;
use Illuminate\Support\Facades\Cookie;

class SessionHasCart
{
    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */
    public function handle($request, Closure $next)
    {
        if(Cookie::has('cart') && ! session()->has('cart')) {

            $cart = Cart::restoreFromCookie();
            $this->dumpSession('cookie had cart');
        }elseif( session()->has('cart')){
            $this->dumpSession('cart existed in session');
        } elseif(! session()->has('cart')) {
            Cart::makeInMemory(session()->getId());
            $this->dumpSession('creating new cart');


        }

//        Cookie::queue('cart',session()->getId(),Cart::LIFETIME);

        $response = $next($request);
        return $response->withCookie(cookie()->make('cart', session()->getId(), Cart::LIFETIME));


    }

    private function dumpSession($title = '')
    {
        $sessionData = session()->all();

        dump('dumping session: '. $title);
        dump('-------------------------------------------------');
        dump('_token           : '. $sessionData['_token']);
        dump('cart: id         : '. (isset($sessionData['cart']) ? $sessionData['cart']['id']:''));
        dump('cart: session_id : '. (isset($sessionData['cart']) ? $sessionData['cart']['session_id']:''));
        dump('=================================================');
    }
}


unit test CartTest.php

/** @test */
    public function a_guest_cart_is_regenerated_from_cookie_when_there_is_no_session()
    {
        ObjectFactory::validInventoryProduct();
        $oldResponse = $this->get('/');
        $oldCart = session('cart');

        $oldResponse->assertCookie('cart');
        $oldSessionId = session()->getId();

        session()->invalidate();

        //NOTICE THIS, you can preset the cookie, but only if you use the "call" method, not the "get" shortcut
        $cookie = ['cart' => \Crypt::encrypt($oldSessionId)];
        $newResponse = $this->call('GET','/',[],$cookie);
        $newCart = session('cart');

        $newResponse->assertCookie('cart');
        $this->assertSame($oldCart->id, $newCart->id);

    }

That test finally works it first hits the creating new cart segment in middleware and then hit's the restoring from cookie section.

As, I then went on to make sure the session segment was working, and it always restores from cookie! Yikes! Here is the test for that and results,


    /** @test */
    public function a_guest_cart_is_reused_between_pages()
    {
        ObjectFactory::validInventoryProduct();

        $oldResponse = $this->get('/');
        $oldCart = session('cart');
        $oldCart->add(1);

        //Go back to the any page under the middleware and the cart should be regenerated from the session. 
        
        $newResponse = $this->get('/');
        $newCart = session('cart');
        $newCart->add(1);

        $this->assertSame($oldCart, $newCart);
    }

// __________________________________
// RESULTS
// __________________________________

"dumping session: creating new cart"
"-------------------------------------------------"
"_token           : 3iZ6HcwK5Lno8Uc7pFIwrMjy3Wkb2EFYMEWDP5yv"
"cart: id         : 1"
"cart: session_id : bII3wpaBqeTHOSotraVLrl7onGjArpdCZ5zpKvt3"
"================================================="
"dumping session: before restoring cookie"
"-------------------------------------------------"
"_token           : elGVNleQwPNaTKnjt0vzmYZlTUO7NxYQTJVgVVpl"
"cart: id         : "
"cart: session_id : "
"================================================="
"dumping session: cookie had cart"
"-------------------------------------------------"
"_token           : elGVNleQwPNaTKnjt0vzmYZlTUO7NxYQTJVgVVpl"
"cart: id         : 1"
"cart: session_id : giBdIW4aFBVcrn7ptmWZM7V88s9iVDpDqfLK5vOq"
"================================================="

Time: 452 ms, Memory: 28.00MB

OK (1 test, 3 assertions)

Process finished with exit code 0

notice that it's using the cookie even though the session should in fact be set. Also the session is empty before restoring the cookie.

Here is the cart setting and restoring functions


 const LIFETIME = 60 * 24 * 30;

    public static function makeInMemory($sessionId)
    {


        $cart = self::create([
            'session_id' => $sessionId,
        ]);

        \Cookie('cart', $sessionId,self::LIFETIME);

        session()->put('cart', $cart);
        return $cart;

    }


    protected static function cleanCookieSession($value)
    {
        $sections = explode('"', $value);
        if(count($sections) == 3 )
            return $sections[1];
        return $value;
    }

    protected static function saveCurrentState($cart)
    {
        $cart->session_id = session()->getId();
        $cart->save();

        session()->put('cart', $cart);

        \Cookie('cart', session()->getId(),self::LIFETIME);
    }


    public static function findBySessionId($sessionId)
    {

        return self::where('session_id', self::cleanCookieSession($sessionId))->first();


    }
    public static function restoreFromCookie()
    {

//        dd('here:' . request()->cookie('cart'));
//        dump('searching for this cart: '.Cookie::get('cart'));
        $cart =  self::findBySessionId(Cookie::get('cart'));
        self::saveCurrentState($cart);

//        dd(session()->all());
        return $cart;

    }

Any insights would be helpful

22 Oct
3 weeks ago

Roni started a new conversation Additional Prepended Data Showing Up On My Cookie

I'm setting a cookie in middleware, and in the DB / session everything looks good when it is set, however, when I try to retrieve it from a cookie I get a prepended type attached to it.

Here are multiple way of setting it they all have the identical effect:


\Cookie('cart', $sessionId,self::LIFETIME);

Cookie::queue('cart',session()->getId(),Cart::LIFETIME);

$response = $next($request);

return $response->withCookie(cookie()->make('cart', session()->getId(), Cart::LIFETIME));


When I try to retrieve it from the cookie I end up with the prepended type, in my case a 40 character string:


dump(request()->cookie('cart'));
dump(Cookie::get('cart'));

They all give out the same data


"s:40:"8QdA0CymbSRllnttonOCvtYj90TErujQ4EmvecKQ";"

// when what the variable should actually get is simply

8QdA0CymbSRllnttonOCvtYj90TErujQ4EmvecKQ



$tmp = json_decode($sessionId, true);
dd($tmp);

// seems to just yield a blank. any advice welcome on the proper way.


Roni left a reply on Use Function From Model In Notifications

ok, I'm missing the "connective tissue" where are you creating the notification. In notify_comment.blade.php what is the $notification? How are you passing it to the view? Please share that or (and worse in my opinion)

move the following function to the comment class.

// remember you'll have to reset what
// $this->author is in the new class.
// and import PrivacySetting


public function displayAuthorName(){


       if( auth()->id() == $this->author->id ||
            in_array($this->author->privacy, PrivacySetting::CAN_SEE_USERNAME)||
            $this->author->isFollowed()) {
    
           return $this->author->username;

       }
       return 'AC';
     
   }



then you should be able to access it here


{{ $notification->data['comment']->displayAuthorName() }}

I'm not against using a base model to detail how its data should be look, however, I think it should be on some middle ground area. I used to use view models (I'm reaching into the past for terminology there, I think I forgot what they were called) there are lots of lessons here on laracasts. But I look at that spatie package. Consider some helper classes that do all your formatting.

If I have a ton of UI options like that I will always defer to a helper class, all you have to really do is pass in your relevant model or models, and then make your logical functions with all the ugly display logic.

I have a couple of HUGE projects (for me that is) and the thought of going back through all the forms and making UX changes in 100+ places would make me cry.

When people advise deferring that to a wrapper function it's not just giving you an opinion of meaningless A vs meaningless B is better. It's the horrible pain of correcting the mistake that they wish someone had passed on to them before they got into the mess.

Sorry I'm on my phone watching a kids tae kwon-do class so I got talkative.

So find whats driving that notification, it's not the NotifyComment Object or you would already have had access to it. Then look at your blade flies and pull out those conditionals.

if you get stuck you can always try a dd(get_class($notification)); Next year when you upgrade, you'll be thankful you did.

And post that route controller where you are actually passing around the data please if either of those refactors won't work.

18 Oct
3 weeks ago

Roni left a reply on Use Function From Model In Notifications

ok @slickness I'm trying to help as much as I can but you aren't giving me a whole lot to help you with. Do you want to post it to a public repo? Can you tell me the steps you actually took?

Where exactly you put what? It's probably an easy fix, but I can't address it other than in generalities because all I can see is the comments and not the code.

That error tells me you put the function somewhere, and it's not where it needed to be. So... either I don't understand your file structure.

When you make a notification, the content of the notification class that is public to the class can be accessed by the mail or view. you can move that function to the comment class itself if you like, and then call it directly from the class.

You still need to know oop php scope resolution to know where you have visibility and where you don't. I don't have time to guess at it. If its a private repo, then good luck or post actual files with explanations.

If it's a public repo link it here, and I'll clone it and check it.

Good luck either way.

Roni left a reply on How To Get Sum Score When Checked The Checkboxess?

@Cronix just trying to pay it forward. I'm sure my questions are often confusing too. And yet you still take the time to answer them :)

17 Oct
3 weeks ago

Roni left a reply on How To Get Sum Score When Checked The Checkboxess?

It's really unclear what exactly you are asking... Can you clarify what you are looking for? What JS are you using? Vue, Vanilla, React etc... Do you need to calculate it in javascript? Or do you want some sort of API endpoint in your laravel backend. What models/tables are involved? Etc... As it reads now it's pretty hard to identify what you are doing now, and what you can't figure out.

Roni left a reply on Use Function From Model In Notifications

@slickness, a suggestion. You look like you are coming from a procedural style background (me too) where you first look at blade and thing awesome and hack it apart with heavy logic.

My first suggestion is actually to read up a bit on what @D9705996 mentioned.

But if you want to go this route of heavy logic in a blade file, maybe turn your Notification into a view model of sorts, and abstract this behavior behind a semantic function.

1. Add some constants to create a more readable request


//these are made up guesses 

//maybe in \App\Privacy

const PUBLIC_VISIBLE = 1;
const GROUP_VISIBLE = 2;
...

const CAN_SEE_USERNAME = [
    self::PUBLIC_VISIBLE,
    self::GROUP_VISIBLE
];


// etc...

then in your notify comment




use App\Privacy; // import constants


//change your constructor

protected $comment;
protected $author; //only to clarify your understanding a bit

    /**
     * Create a new notification instance.
     *
     * @return void
     */
    public function __construct($comment)
    {
        $this->comment = $comment;
    $this->author =-$comment->user(); //you probably have that relationship on your model
    
    // actually you should name it better
    $this->author = $comment->author(); //much more clear
    }


public function displayAuthorName(){


    if( auth()->id() == $this->author->id ||
         in_array($this->author->privacy, Privacy::CAN_SEE_USERNAME)||
         $this->author->isFollowed()) {
    
        return $this->author->username;

    }
    return 'AC';
     
}

Then maybe in your view just render it instead of that whole pile of stuff


{{ $notification->displayAuthorName() }}


Please consider separation of concerns as you grow as a developer. You want your designers designing, and your backend easily upgradable. Look at spatie view models here is a link when you for when you bloat your models and controllers.

https://github.com/spatie/laravel-view-models

in fact look at spatie everything.

Cheers -Roni

Roni left a reply on Regenerating Cart From A Cookie

Hours and a ton of googling later, here is the half way mark...

/** @test */
public function a_guest_cart_is_regenerated_from_cookie_when_there_is_no_session()
    {
        ObjectFactory::validInventoryProduct();
        $oldResponse = $this->get('/');

        $oldCart = session('cart');
        $oldCart->add(1);

        $oldResponse->assertCookie('cart');
        $oldSessionId = session()->getId();

        dump('old session id: '. $oldSessionId);
        dump($oldCart);

        session()->invalidate();

        //NOTICE THIS, you can preset the cookie, but only if you use the "call" method, not the "get" shortcut
        $cookie = ['cart' => \Crypt::encrypt($oldSessionId)];
        $newResponse = $this->call('GET','/',[],$cookie);

        $newCart = session('cart');

        $newResponse->assertCookie('cart');
        $newSessionId = session()->getId();

        dump('new session id: '. $newSessionId);
        dump($newCart);

    }

There are no assertions yet because I can see from the output the second cart is never restored from the session. I can't currently figure out how to restore the old session from the cookie... yet.

Here is the handler now

`` `

16 Oct
4 weeks ago

Roni left a reply on Use Function From Model In Notifications

there's alot missing to answer this question, however,


return $this->followers()
                ->where('follower_id', auth()->id())->exists();

is returning a boolean based on if the data exists in the DB.

  1. from the code shown above, isFollowed doesn't take a parameter. And if you are only using this function for the authorized user, it doesn't need to so don't add it in your call.

  2. guessing only from the view that


$notification->data['user']['id']

is an integer, it's the user's id not the user object. Is notification->data a collection of users? An array?

If for example it was a collection or array of user objects you could instead use"


foreach (notification->data['user'] as $user) {
    //then do something with the user
    <div>$user->isFollowed()</div> 
}


//you could extract the specific user stuff to a to a view partial or use some functional helpers

$notification->data->pluck('user')->map( function ($user) {
    @include('path.to.user.display')
}


Hope that helps.

Roni started a new conversation Regenerating Cart From A Cookie

Hey, I keep circling back to testing Cookies. I haven't had to use them since I started using TDD, and I feel like I'm missing something.

Right now, I'm trying to perform this test on a middleware that should for guests force a cart on the session.

Using this criteria...

  1. If there is a cart on the session, simply update the expiry of the cookie so it's lifetime is reset.
  2. if there isn't a cart on the session, but there is a session_id stored on the cookie in the cart key, then restore that session (or restore the cart portion of the session, right now . I'm just doing the whole thing, but if you know how to do both options please let me know).
  3. if neither is present (first time on the site) set the session and the cookie.

here is the failing unit test: lots of dumps for clarity, the output will fail and show two different cart objects


   /** @test */

    public function a_guest_cart_is_regenerated_when_they_come_back_to_the_site() {
        $response = $this->get('/');
        $oldCart = session('cart');
        dump($oldCart);
        dump(Cookie::get('cart'));
        session()->invalidate();
        $response = $this->get('/');
        $newCart = session('cart');
        dump($newCart);
        $this->assertInstanceOf(Cart::class, session('cart'));

        $this->assertSame($oldCart, $newCart);
    }

Here is the middleware, which is working, for the no session or cookie phase. Middleware is firing correctly (registered) and routes are properly enclosed in a middleware group. I left all my hacking in there commented out


<?php

namespace App\Http\Middleware;

use App\Orders\Cart;
use Closure;
use Illuminate\Support\Facades\Cookie;

class SessionHasCart
{
    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */
    public function handle($request, Closure $next)
    {

        if(Cookie::has('cart') && ! session()->has('cart')) {
            session()->setId(Cookie::get('cart'));
            session()->start();
        } elseif(! session()->has('cart')) {
            session()->put('cart', new Cart());
        }

//        $cookie = Cookie::make('cart',session()->getId(),Cart::LIFETIME);
//        dd($cookie);

        return $next($request); //->cookie('cart',session()->getId(),Cart::LIFETIME));
    }
}


Any advice appreciated

09 Oct
1 month ago

Roni left a reply on TDD Cookies

Thanks, very helpful, I should have checked there first.

Roni started a new conversation TDD Cookies

Hi, never had a use for a cookie before, but I never really work on shopping sites. Right now, I have a specialized cart for a series of products that can only be put in by staff, and that is all implemented, but I now need to add in a section of products that can be simply ordered online. So presumably a guest can select items and add them to a cart with no registration. I was thinking about just implementing something simple in a session or in the DB when the user is logged in.

However it seems like a good use case for cookies. So possibly just adding an "cart" key to the site cookie, and putting the value of a cart DTO that looked something like


cookie: { 
    id: session_id,
    cart: {
        products: {
            id: product_id,
            qty: product_id
            price: price
        }
    }

and just setting it either in the controller or on an event listener each time the cart was changed.


Cookie::queue(Cookie::make('cart', $cart, Cart::MINUTES_PER_MONTH));

I haven't implemented it yet, however, I'm not sure how to tdd testing if a cookie is present, or not present. Does anyone know how to test that?

I know response has assertCookie($cookie) and assertCookie expired. Is there a Cookie::fake()?

Any doc references or tutorials appreciated.

29 Sep
1 month ago

Roni started a new conversation Add A Macro To Arrays For Test Assertions

Hey, just a quick question on array assertions. Does anyone know if I can wrap a test in a method/macro that runs on an array?

Right now, I'm using assertTrue(in_array($needs, $responseArray)), but I'd much rather macro it and add something like $responseArray->assertContains($data) and $responseArray->assertDoesNotContain($data);

Is there a way to accomplish that?

Using laravel 5.7

Thanks

Roni left a reply on Routing Action Syntax Vs Array Syntax And Route File Splitting

Just an update, I was unit testing in that framework, and I switched from method tests to class tests and everything except the first test was failing. After some source diving you can't use require once in a routes file, because if you are executing a class or non filtered unit test it will have to rebuild your world several times. So ever subsequent test will fire an error that can't find whatever route you are trying to hit unless it's in routes.php because you've told the process to it can only require it once.

So just change your require_once to require and the problem is solved.

reference

https://github.com/laravel/framework/issues/2836

27 Sep
1 month ago

Roni left a reply on Very Slow PHPUnit Tests Using PHP7.2 Or PHP7.1.

@tykus,Thanks for the link, I'm going to add it to my base class tomorrow and see what happens. However, I took compsci / engineering 20 years ago so my c++/Java is significantly dated (haven't used it for 14 years for almost anything, but I do remember the same thing happening in Java years ago.

If you left garbage collection up to the virtual machine it may not choose optimal times to run. Or that was the case a LONG time ago. Now, if you implemented your own garbage collection, an anti-pattern back then it could in some situations make a pretty drastic difference.

I'd imagine under the hood in some situations, especially where you might be resource constrained in some fashion, active garbage collection might free up some ram or high speed cache at some threshold which previously had you starting to use a low speed resource.

Just old dude ramblings but I'd be curios to find out more. Some of my test suites are make a cup of coffee actions, and I'd love to cut those down.

25 Sep
1 month ago

Roni left a reply on Namespaceing Convention

I know this is a year old and closed, but a laracasts lesson on this would be super helpful. I find myself dumping everything in app, and then refactoring (painfully) classes into products inventory and everything you can imagine, and with polymorphic relations it gets uglier,



App\Products\ProductContract
App\Products\Product
App\Products\special\ProductA
App\Products\special\ProductB

etc...

Is there a good name spacing pattern as projects get too big to live in app easily? What do you do with the table names for 10 product types?

Roni left a reply on Need Laravel Expert

Have you set permissions on those folders to make them readable to the process or to whatever is scanning them so the cron can read them? Is the cron a Laravel command or just a php script?

What errors are showing up in your logs?

Better question, what EXACTLY is your job title, are you someone who can answer the questions? Have you phoned emailed etc... the original author?

Roni left a reply on Need Laravel Expert

And what kind of traffic are you serving? I'm serving thousands of pages a day on a 1 CPU droplet, and it's barely breaking a sweat.

Roni left a reply on Need Laravel Expert

Can you be more clear about what is and isn't working? Is the database running? Can you show some errors? I'm running a bunch of unrelated client sites, although I never allow myself to host on cpanel any more, maybe I or others could help you more if you posted more information.

20 Sep
1 month ago

Roni left a reply on Routing Action Syntax Vs Array Syntax And Route File Splitting

@cronix if I could award you twice I would

everything just feels so much faster! I'm just looking at exactly what I need. I may have gone overboard and I'll feel it out in a day or so but wow. it was at 450 and constant scrolling and now little slices of heaven.

And each one of those only has between 10-60 routes. Just so much quick to find what I need. Thank again.


<?php

if( app()->environment() !== 'production'){
    require_once ('sections/test.php');
}

require_once ('sections/static.php');
require_once ('sections/products.php');
require_once ('sections/blog.php');
require_once ('sections/staff.php');
require_once ('sections/pdf.php');
require_once ('sections/home.php');

Auth::routes();
Route::get('/users/logout', 'Auth\[email protected]')->name('user.logout');


Roni left a reply on Routing Action Syntax Vs Array Syntax And Route File Splitting

Thanks @Cronix, I should have tried that one before I posted.

Roni started a new conversation Routing Action Syntax Vs Array Syntax And Route File Splitting

while looking at a large routes file, 300+ routes and growing, I frequently find myself annoyed that I can't command click on a route and go to the file or method. If there is a plug in for that on phpstorm any reference would be appreciated. Searching through that large file for your one line seems to be a mentally draining.

But while diving laravel I noticed the action() helper takes both:


 action('[email protected]') 


and


action( [FooController::class, 'index'] 


and playing with this idea in the routes file works fine too


Route::get('/Foo', [ FooController, 'index'])->name('foo.index'); 


you seem to have to import the controller at the top of routes.php which makes Route::namespace() fail or not work as expected.

Other than the namespace issue not working (you could use a fully Qualified route in it's place, is there a downside to this method I'm missing?Do all the use statements at the top add a massive additional overhead? As it would essentially use every controller.

Another option might be to sort routes into smaller more manageable files anyone separate the web routes into multiple files? Is there an operational cost to this?

Any advice would be appreciated.

15 Sep
1 month ago

Roni left a reply on Very Slow PHPUnit Tests Using PHP7.2 Or PHP7.1.

What I prefer to do is add another group for example @needsPHPINI and test it separately. the -n flag removes the php_ini add ons and though you can enable them selectively, it can slow you down.

Then for my TDD cycles I just exclude the groups, unless i'm working directly on that item, and then i typically run only the one test or one class to keep it clean and fast.

I don't have my coding laptop with me but I realized I didn't leave an annotation example

here is a link from a quick google search on stack exchange

https://stackoverflow.com/questions/22180186/testing-levels-groups-in-phpunit

but basically


/** @test @needsPHPINI */
public function a_special_test() {
        // presumably doing something that has some special ini file need   
        $this->get('/')
            ->assertOk();

    }

14 Sep
1 month ago

Roni left a reply on Very Slow PHPUnit Tests Using PHP7.2 Or PHP7.1.

Don't remove x-debug if you need it, thats nuts, just disable it and any other extraneous php_ini add-ons while in unit test. add -n to your flags

here are some aliases to help out from my .bash_profile if you run your commands in the terminal.

alias c='clear'

#TESTING PHPUNIT
alias phpspec='c;vendor/bin/phpspec'
alias phpunit='c;vendor/bin/phpunit'
alias p='c;php -n vendor/bin/phpunit --exclude-group external'
alias pf='c;php -n vendor/bin/phpunit --exclude-group external --filter '
alias pext='c;php -n vendor/bin/phpunit'
alias pextf='c;php -n vendor/bin/phpunit --filter '


Use the advice above, I extend DBTestCase a file with RefreshDatabases Trait and a bunch of other macros and hacks I need for testing features, for unit tests just extent regular test case so you don't run migrations when you don't need to.

Add an annotation like @external to tests that can't be rushed, like talking to an external payment gateway when you aren't mocking one out or any external service you can't rush like a fax server etc.. Once you have those running, test them when you need but not when you are doing TDD.

p or pf will run 3-5x faster that phpunit.

if you are using phpstorm, in your Debug Configuration under command line / Interpreter Options: add your -n there too and it should fly again.

HTH Cheers

Roni left a reply on Test If A View Partial Is Loaded In A Phpunit Test

@click BOOM! Love it! I think this will play a major role in speeding up rapid my development, but the major benefit is going to really shine in change update request and task delegation!

Roni left a reply on Test If A View Partial Is Loaded In A Phpunit Test

Actully the exists has another sneaky caveat, it will give you a false positive, it's only chekcing for view existance, not restricting it to your open views :(

Roni left a reply on Test If A View Partial Is Loaded In A Phpunit Test

A+ for effort! You are awesome! However I can't make this work, in your case it's the main view not the view partial that you are checking. like using something from @include('some.partial');

For the main view an easier method is assertViewIs('auth.login'); It's a pre-baked assertion in laravel 5.7 and probably earlier, as the name is available as the last key in the view response.

The thing thats killing me is all the other blade segments or partials are stored there too. I just can't touch them because I can't find an accessor or a way to intercept the data.

I was hopeful on getFactory()->getFinder() they are all stored right there in $views, but there is no way to sneak them out.

Roni left a reply on Test If A View Partial Is Loaded In A Phpunit Test

@click, thats actually just a buried part of the response object, basically I can find it, I just dont know how to find it :)

meaning for example in a unit test I'm not sure where to hook into it for example


$this->assertContains('some.blade.partial', $response->original->whatGoesHere());

I've been source diving for a couple of hours going through illuminate\Foundation\Response Object and it's symfony http-foundation set. But I can't figure out how to call it.

Roni left a reply on Test If A View Partial Is Loaded In A Phpunit Test

@Tray2, I use that when I'm the designer, and the developer, but sometimes I've noticed during design updates where I'm not always on point that trying to semantically test on html is breaking, even if the code is fine. But the unit test lost what it was looking for. However, normally no one will change the blade or blade partial names. so I thought this would be a nicer solution.

@click thanks for the pointer, trying it now!

Roni started a new conversation Test If A View Partial Is Loaded In A Phpunit Test

Is there a way to access a segment of a View response object? I'm trying to test if a view partial has been loaded in a less brittle way than just using see.

when I dd the response object I can find the view list

 #finder: Illuminate\View\FileViewFinder {#120
          #files: Illuminate\Filesystem\Filesystem {#121}
          #paths: array:1 [
            0 => "/Users/roni/code/php/laravel/5.7/munroe/resources/views"
          ]
          #views: array:13 [
            "static.new-front" => "/Users/roni/code/php/laravel/5.7/munroe/resources/views/static/new-front.blade.php"
            "segments.front.v2.events.upcomming-conferences" => "/Users/roni/code/php/laravel/5.7/munroe/resources/views/segments/front/v2/events/upcomming-conferences.blade.php"
            "segments.front.v2.weight-management" => "/Users/roni/code/php/laravel/5.7/munroe/resources/views/segments/front/v2/weight-management.blade.php"
            "segments.front.v2.notifications.sale-free-registration" => "/Users/roni/code/php/laravel/5.7/munroe/resources/views/segments/front/v2/notifications/sale-free-registration.php"
            "segments.front.v2.compression-therapy" => "/Users/roni/code/php/laravel/5.7/munroe/resources/views/segments/front/v2/compression-therapy.blade.php"
            "layouts.new-front-with-nav" => "/Users/roni/code/php/laravel/5.7/munroe/resources/views/layouts/new-front-with-nav.blade.php"
            "segments.front.v2.navbar" => "/Users/roni/code/php/laravel/5.7/munroe/resources/views/segments/front/v2/navbar.blade.php"
            "segments.front.v2.reviews.div" => "/Users/roni/code/php/laravel/5.7/munroe/resources/views/segments/front/v2/reviews/div.blade.php"
            "segments.front.v2.newsletter" => "/Users/roni/code/php/laravel/5.7/munroe/resources/views/segments/front/v2/newsletter.blade.php"
            "segments.front.map" => "/Users/roni/code/php/laravel/5.7/munroe/resources/views/segments/front/map.blade.php"
            "segments.front.v2.footer" => "/Users/roni/code/php/laravel/5.7/munroe/resources/views/segments/front/v2/footer.blade.php"
            "segments.scripts.front.v2.navbar" => "/Users/roni/code/php/laravel/5.7/munroe/resources/views/segments/scripts/front/v2/navbar.blade.php"
            "segments.scripts.front.v2.newsletter" => "/Users/roni/code/php/laravel/5.7/munroe/resources/views/segments/scripts/front/v2/newsletter.blade.php"
          ]
          #hints: array:2 [
            "notifications" => array:1 [
              0 => "/Users/roni/code/php/laravel/5.7/munroe/vendor/laravel/framework/src/Illuminate/Notifications/resources/views"
            ]
            "pagination" => array:1 [
              0 => "/Users/roni/code/php/laravel/5.7/munroe/vendor/laravel/framework/src/Illuminate/Pagination/resources/views"
            ]
          ]

but I can't figure out how to isolate that portion of the view object and test against it. Any advice is welcome.

13 Sep
2 months ago

Roni left a reply on Out Of Order Migrations With GIT

thanks for the quick response, I have an update to push and I was worried about making a crazy amount of extra work coordinating that change.

Roni started a new conversation Out Of Order Migrations With GIT

As my workflow changes, I notice, I'm using git a bit more often, and more selectively then what I used to "git add ." As I work on feature requests, I can find myself deeply into one branch when a hotfix is required urgently. This has to be a common scenario, but until now, it hasn't had any impact.

If I have migrations on my feature branch that are dated before my hotfix branch, do I need to go and "re-date" all my feature migrations to a date after my hotfix migration to merge it? Or will laravel pick up on migrations that haven't been run and just run them. In this case, they are not dependant on each other.

07 Sep
2 months ago

Roni left a reply on Best Practises

Thanks @Cronix

06 Sep
2 months ago

Roni started a new conversation Best Practises

As applications grow, is there a best practise on Model and Controller naming and namespacing? Is it bad to end up with 2 of the same model name or controller names in different name spaces?

25 Jul
3 months ago

Roni left a reply on SourceMaps Problem With Laravel Mix

@debiprasad, I'm not sure, I've been battling this all morning, as of laravel 5.6 with mix 2.1.11 sourcemaps are not showing up with dev or watch. but the webpack config did the trick.