zefman

zefman

Developer at theunit.co.uk

Brighton, UK

Member Since 5 Years Ago

Experience Points 12,350
Experience
Level
Lessons Completed 70
Lessons
Completed
Best Reply Awards 7
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.

08 Oct
3 years ago

zefman left a reply on Broadcasting Event To Specific Client

@ukietech sweet will have a look. Interested to see how you have used JWTs. I had researched them for this purpose but never got round to trying anything out.

30 Sep
3 years ago

zefman left a reply on Broadcasting Event To Specific Client

Hi @ukietech sorry for the slow reply, been busy.

So in Laravel I do something like this:

    $redis = \RedisL5::connection();
        $redis->publish( 'messaging', json_encode( [
            'conversation_id' => $conversation->id,
            'participants'    => $participants,
            'message'         => $message
        ] ) );

Where participants is a list of user ids that I want the message to go to.

Then in node I do something like this:

// Subscribe to the relevant redis channels
redisClient.subscribe( 'messaging' );

// On recieving a message from one of the channels we subscribed too.
// Note 'message' is just redis's term for recieving something from a 
// subscribed channel. This is note a message sent by a user on bfc
redisClient.on( 'message', function( channel, data ) {

    data = JSON.parse( data );

    // Check to see whether this user should recieve this message
    if ( data.participants.indexOf( client.laravelSession[ userIdKey ] ) > -1 ) {

        // Check the message is not from the connected user
        if ( data.message.user_id != client.laravelSession[ userIdKey ] ) {
            client.emit( channel, data );
        }

    }

} );

Basically it looks to see if the connected client is in the participants lists, if they are it emits the message to them. Is that what you were after?

25 Sep
3 years ago

zefman left a reply on Broadcasting Event To Specific Client

@ukietech The code there doesn't do any of the relaying of websocket data. It just retrieves the session so you know which user you are dealing with. Because you then have the user id it is then easy to broadcast messages intended for one user to that user. You just need to send a userid along with the event you pass to redis

03 Jul
3 years ago

zefman left a reply on Pivot Table Problem

aasasd ada sdas dasdas dasd as dasd asdasd asd

26 Jun
3 years ago

zefman left a reply on Broadcasting Event To Specific Client

Great!!! Glad I could help, I had the eureka moment too the first time I got it to work!

zefman left a reply on Broadcasting Event To Specific Client

Hmm I'm not sure then I'm afraid. This setup is working for us. If it is the same domain as your main laravel app the session cookie should be sent with the initial request, there must be something else wrong.

zefman left a reply on Broadcasting Event To Specific Client

The port number shouldn't matter, you can leave that as what you had before. Its just the domain thats important. So if you visit your laravel site are you using the address socket.dev?

zefman left a reply on Broadcasting Event To Specific Client

yeah thats it. Any luck?

zefman left a reply on Broadcasting Event To Specific Client

Is your socket.io running at a different address/ip? It will only send the laravel cookie if you connect to it using the same domain. So if your site is example.com your node server will need to be at example.com: 8080 or whatever port it is you have it running on. If it is on the same domain it should send along the laravel cookie

24 Jun
3 years ago

zefman left a reply on Broadcasting Event To Specific Client

Hi sorry for the slow reply, been very busy. This is what we have:

var cookieKey = 'login_82e5d2c56bdd0811318f0cf078b78bfc';

// On websocket connections
io.listen( server ).on( 'connection', function( client ) {

    const redisClient = redis.createClient();
    // Select the correct redis db
    redisClient.select( process.env.REDIS_DB, function() {});
    logger.info( 'Connected and listening to redis db ' + process.env.REDIS_DB + '.....' );

    // Get the laravel cookie
    var cookies        = cookie.parse( client.handshake.headers.cookie );
    var laravelSession = cookies.laravel_session;
    var sessionId      = 'laravel:' + getSessionIdFromLaravelCookie( laravelSession );
    var userId;

    // Find the user id
    redisClient.get( sessionId, function( err, session ) {
        try {
            client.laravelSession = PHPUnserialize.unserialize( PHPUnserialize.unserialize( session ) );
            connectedUsers[ client.laravelSession[ cookieKey ] ] = client;
        }
        catch ( err ) {
            logger.info( 'Error unserializing session!', err );
        }

        if ( client.laravelSession[ cookieKey ] ) {
            logger.info( 'User connected: ' + client.laravelSession[ cookieKey ] );
            logger.info( 'Total connected: ' + _.keys( connectedUsers ).length );
            userId = client.laravelSession[ cookieKey ];
        }

    } );

} );
23 Jun
3 years ago

zefman left a reply on Broadcasting Event To Specific Client

Oh i forgot you will need to install these dependencies of the node mycrypt library:

 apt-get install libmcrypt4 libmcrypt-dev

zefman left a reply on Broadcasting Event To Specific Client

Hi,

We successfully did this before the new event broadcasting stuff was added. You are on the right track. You need to decrypt their cookie and then use it to retrieve the user's session, this is quite easy if you also use redis for sessions.

We have this code, which I think I got from a blog post somewhere, unfortuanatrly i can't find it now!


/**
 * Helper function to return ASCII code of character
 * @param  [string] string
 * @return [ascii code]
 */
function ord( string ) {
    return string.charCodeAt( 0 );
}

/**
 * This function retrieves the laravel session stored in redis
 * from a cookie
 * @param  [cookie] cookie
 * @return session
 */
function getSessionIdFromLaravelCookie( cookie ) {

    var cookie = JSON.parse( new Buffer( cookie, 'base64' ) );

    var iv     = new Buffer( cookie.iv, 'base64' );
    var value  = new Buffer( cookie.value, 'base64' );
    var key    = 'dd4u1wm2rVi82s6eOI8sTRzaWomob58x'; // laravel app key

    var rijCbc = new MCrypt( 'rijndael-128', 'cbc' );
    rijCbc.open( key, iv ); // it's very important to pass iv argument!

    var decrypted = rijCbc.decrypt( value ).toString();

    var len = decrypted.length - 1;
    var pad = ord( decrypted.charAt( len ) );

    var sessionId = PHPUnserialize.unserialize( decrypted.substr( 0, decrypted.length - pad ) );

    return sessionId;
}

After you have done this you should be able to get their use id and it should be fairly straight forward from there.

11 May
3 years ago

zefman left a reply on Socket.io And Laravel Cant Connect To Socket

Try changing the line that starts the node server to this:

server.listen( port, '192.168.10.10' );

and then on your frontend

var socket = io('http://192.168.10.10:3000');

Then it should work if you start the node server on homestead

06 May
3 years ago

zefman left a reply on Forge/git Error When Trying To Commit

It seems as though you have edited files live on the server so git is worried you will overwrite them. Also for some reason your vendor folder is tracked it shouldn't be and should be added to your git ignore.

After adding the vendor folder to your git ignore, cd into your project directory then: ''' git rm --cached vendor ''' then commit the changes and push to your remote repository. This will stop tracking the vendor folder.

Now log into your server, cd into your project folder, and run: ''' git stash ''' This will temporarily clear those changes and you should be able to deploy again with forge.

09 Apr
3 years ago

zefman left a reply on Hoa\WebSocket With Laravel 5 Projects - Push Notifications

I implemented realtime messaging in a Laravel app recently using web sockets and found the best, way to interact between the socket server and the Laravel app was to use a shared redis database.

In my case I used node for the websocket server but it would work the same either way. In Laravel I do something like,

    $redis = \RedisL5::connection();
        $redis->publish( 'messaging', json_encode( [
            'conversation_id' => $conversation->id,
            'participants'    => $participants,
            'message'         => $message
        ] ) );

Then on websocket server you can subscribe to the redis channel, and push the messages, notifications or whatever you like on the clients. In node its something like this:

    // Subscribe to the redis messaging channel
        redisClient.subscribe( 'messaging', 'conversation' );

        redisClient.on( 'message', function( channel, data ) {

            data = JSON.parse( data );

        client.emit( channel, data );
    } );
19 Feb
3 years ago

zefman left a reply on Php Artisan Db:seed

try 'composer dump-autoload" and "php artisan clear-compiled"

14 Feb
3 years ago

zefman left a reply on Creating Push Notifications

I have just done this to enable realtime chat and notifications in a Laravel app. We have used socket.io for the web sockets, and then we have connected up laravel and nodes using a shared reds database. Its then super easy to push messages from laravel. We do something like this:

$redis = \Redis::connection();
$redis->publish(  'conversation',  json_encode( [
    'message' => 'Hello,
    'participants' => $participants
] ) );

Then in node we subscribe to reds for updates like so:

// Subscribe to the conversation channel
redisClient.subscribe( 'conversation' );

// Relay the message on the user
redisClient.on( 'message', function( channel, data ) {
    socket.emit( channel, data );
}

That is a simplified version obviously a lot of other things go on to but thats the basics.

We also use redis for sessions so found it useful to access these through node, this allowed us to authenticate and identify which user was connecting to each web socket as well.

06 Feb
3 years ago

zefman left a reply on Upgrading To L5 And Getting "Class Not Found" On Composer Update

I had this issue as well. I got around it by manually deleting the compiled files in storage>framework. The issue was the php artisan clear-compiled was failing before it could actually get rid of the files. It could be the same issue for you :)

03 Feb
3 years ago

zefman left a reply on Problems With Auth::user()

Thanks @pmall that was it! The correct user model was not set in config/auth.php.

Thanks for your help :)

zefman left a reply on Problems With Auth::user()

@pmall Thanks that was it, the correct user model wasn't set in config/auth.php

Thanks for your help!

zefman left a reply on Problems With Auth::user()

Thanks but as I said, this was working before running composer update, so I am pretty sure the relation is not the issue, and also if I load a user manually the relations work fine. This is how the comments relation is defined in my user model:

    /**
     * Get the users comments
     * @return Collection
     */
    public function comments()
    {
        return $this->hasMany('BigFanClub\Models\Comment');
    }

dd( Auth::user() ) results in this which looks ok to me:

User {#247 ▼
  #table: "users"
  #fillable: array:3 [▼
    0 => "name"
    1 => "email"
    2 => "password"
  ]
  #hidden: array:2 [▼
    0 => "password"
    1 => "remember_token"
  ]
  #connection: null
  #primaryKey: "id"
  #perPage: 15
  +incrementing: true
  +timestamps: true
  #attributes: array:8 [▼
    "id" => 680
    "email" => "protractor@protractor.com"
    "password" => "$2y$10$PbYYE20QNlUBlVHs1QR3FemqlH5D2WeYHYy1kTaDN.ZOplW6vrrO2"
    "confirmed" => 1
    "confirmation_code" => null
    "remember_token" => "7KraYlUdBX8qHO2umiRhxuolUV0XFIDzqv1KrcdS4WRK8bT0xc1JyyjgXiAt"
    "created_at" => "2015-01-15 10:46:42"
    "updated_at" => "2015-02-03 12:01:36"
  ]
  #original: array:8 [▼
    "id" => 680
    "email" => "protractor@protractor.com"
    "password" => "$2y$10$PbYYE20QNlUBlVHs1QR3FemqlH5D2WeYHYy1kTaDN.ZOplW6vrrO2"
    "confirmed" => 1
    "confirmation_code" => null
    "remember_token" => "7KraYlUdBX8qHO2umiRhxuolUV0XFIDzqv1KrcdS4WRK8bT0xc1JyyjgXiAt"
    "created_at" => "2015-01-15 10:46:42"
    "updated_at" => "2015-02-03 12:01:36"
  ]
  #relations: []
  #visible: []
  #appends: []
  #guarded: array:1 [▶]
  #dates: []
  #casts: []
  #touches: []
  #observables: []
  #with: []
  #morphClass: null
  +exists: true
}

Maybe a clear demonstration of the issue:

// Results in Call to undefined method Illuminate\Database\Query\Builder::profile()
$user = Auth::user()->load( 'profile );

// Works perfectly
$user = User::find(1)->load( 'profile );

zefman started a new conversation Problems With Auth::user()

Hello everyone.

So today I have ran composer update to bring a project up to the latest version of Laravel 5, almost everything is fine, but I am having issues with Auth::user() after updating.

In a number of places in the app I use Auth::user() to return the currently logged in user, the problem is, after this most recent update whenever I then go to try and load relations on the returned user object I get an error like:

Call to undefined method Illuminate\Database\Query\Builder::comments()

For example the following code causes this error:

$user = Auth:;user();
$user->load( 'profile.media', 'roles' );

likewise does this:

$user = \Auth::user();
$comments = $user->comments;

This was all working fine before so I am not sure whats wrong. Interestingly if I use the id from the user returned by Auth to again find the user like:

$user = User::find( Auth::user()->id );
$comments = $user->comments;

It works. Anyone got any ideas?

Cheers

21 Jan
3 years ago

zefman left a reply on Modal Relationships

No problem. You just surround it with ```

zefman left a reply on Modal Relationships

You could use the hasManyThrough relation in your company model:

public function contractors()
{
     return $this->hasManyThrough( 'Contractors', 'Projects' );
}

20 Jan
3 years ago

zefman left a reply on SSH Port Forwarding Failed

Hmm thats a strange one I have about 10 long running Forge servers running and have never seen this. A quick google has revealed that this can be caused by not closing ssh sessions correctly. Maybe that is what is happening.

zefman left a reply on Validator - Passing Through Parameter

In your Validator class add this:

protected $company_id;
function __construct()
{
    $this->company->id = Auth::user()->company->id;
}

protected $rules = [
    'name'      =>    'required|unique:inventory_items,name,NULL,id,company_id, ' . $this->company_id
];
16 Jan
3 years ago

zefman left a reply on Ionic & Laravel

No problem, yes you can still use CRSF filters although you have to do a little bit more work to get it to work. This answer on stackoverflow is a pretty good solution: http://stackoverflow.com/a/23760366

You are probably going to want an ssl certificate to make sure your api is secure. Just make good use of angular resource which makes consuming with apis super easy, and try and keep your json responses from laravel consistent.

15 Jan
3 years ago

zefman left a reply on Ionic & Laravel

Yes I have, only as an experiment though. Although it is looking likely that we will be developing a production app using ionic and laravel in the future.

We developed our api in laravel, and then hocked an ionic project into the api using angular resource or http. So they are essentially to separate projects, the ionic app just consumes the api.

zefman left a reply on Eloquent Performance Improvements -- Studly Caps

Ah ok interesting. I'm excited to see what performance difference this little change might make.

14 Jan
3 years ago

zefman left a reply on Eloquent Performance Improvements -- Studly Caps

@anzze I didn't notice that cache, strange its not being used here. Do you reckon its just an oversight? Yes I was thinking about a pull request, should be easy now that I can see that cache is already there.

@thepsion5 Yeah I would love to drop eloquent, but unfortunately there are quite a lot of relations going on. Until the performance becomes an issue I think the benefits outweigh the negatives.

zefman left a reply on Eloquent Performance Improvements -- Studly Caps

Yes I know Eloquent is not ideal in this situation. By data heavy I mean the app is aggregating a feed built up of a number of different models and their relations. Performance wise it is still ok at the even on a 5$ a month digital ocean testing server.

If I get chance I'll try with Doctrine too, will be interesting to compare.

zefman started a new conversation Eloquent Performance Improvements -- Studly Caps

Hello,

So I have recently been experimenting blackfire.io the profiling tool on a fairly data heavy app, and noticed that there were thousands of calls to Illuminate\Support\Str::studly which is converts a string into studly case. This is obviously pretty heavy due to the string transformations.

After a little digging I found this is used in an Eloquent Model's hasGetMutator, a function that is called whenever an attribute from a model is retrieved to check to see if you have created a mutator.

        /**
     * Determine if a get mutator exists for an attribute.
     *
     * @param  string  $key
     * @return bool
     */
    public function hasGetMutator($key)
    {
        return method_exists($this, 'get'.studly_case($key).'Attribute');
    }

In the app I'm profiling we never use get mutators ( all models pass through a dedicated transformer at some point ) so this is a complete waste. Solution extend the standard eloquent model and override the hasGetMutator method like so:

public function hasGetMutator($key)
{
    return false;
}

Doing just this has shaved about 400ms of my response times on the most data heavy parts of the app, sometime more.

Can anyone see any possible unexpected side effects from doing this? Maybe it would be a good idea to be able to set a flag on the eloquent model to enable and disable this feature.

09 Jan
3 years ago

zefman left a reply on L5 With Angularjs, Routing Problems

Great glad i could help :)

zefman left a reply on L5 With Angularjs, Routing Problems

No that is a controller function, but you could just do something like this in your routes file:

Route::any('{path?}', function()
{
    return view("index");
})->where("path", ".+");

zefman left a reply on L5 With Angularjs, Routing Problems

Basically I think his problem is that he wants angular to handle the routing of his application. To do this he needs requests to pass through laravel's router so requires a catch all route that just loads the main angular file.

zefman left a reply on L5 With Angularjs, Routing Problems

I was using this when annotations were still around in laravel 5:

        /**
     * Redirects any other unregistered routes back to the main
     * angular template so angular can deal with them
     *
     * @Get( "{path?}", as="catch.all" )
     * @Where({"path": ".+"})
     *
     * @return Response
     */
    public function catchOtherRoutes()
    {
        return view("index");
    }
05 Jan
3 years ago

zefman left a reply on Page Slugs And Nesting

I'de be interested in this too, its a tricky topic!

17 Dec
3 years ago

zefman left a reply on [Tip] Vagrant VM Manager (OS X/Win)

This is super handy :)

12 Dec
3 years ago

zefman left a reply on Modular Way To Structure Js Files

If you are using angular you should check out this: https://github.com/johnpapa/angularjs-styleguide

Even if you are not there are some great best practices that can be taken away for general js dev :)

11 Dec
3 years ago

zefman left a reply on File::isFile Returning False (but I Know It's There!!!)

Thats very strange the file inside appears to be the temporary file that php created when you upload a file. Have you dumped your filepath variable just before you do the move to check everyhting there looks ok?

zefman left a reply on How Can I Do Multiple Inserts In An API Store() And Not Abuse Single Responsibility

Are you using Laravel 5? if you are use a form request to check whether the email is unique. Thats moves the validation outside of your controller. Or if you want to just do it in the controller like @lonut suggested do this:

if( !empty( User::where('email', Input::get('email') )->first() ) )

Also are you storing the email twice? If a farmer belongs to a user there is no need to store the email on both tables.

10 Dec
3 years ago

zefman left a reply on Scaling With Laravel And Forge

@getstartify yes I was expecting a slight dip in average response times overall, but didn't really see this with a multi server set up on digital ocean. I was able to handle more requests, but not as many more as I was expecting.

I actually have the results of this testing in a rather messy spreadsheet here if you are interested: https://docs.google.com/spreadsheets/d/14vcovx322FeGwfW8i6G2CctMGaRoeiPiOc2Ya3rmt0w/edit?usp=sharing

I also had a quick play with hhvm and saw some very impressive increases in performance in some areas, but decreases in others.

Interestingly cpu was always the limiting factor.

zefman left a reply on Scaling With Laravel And Forge

Another +1 here. I have recently been experimenting on different multiple server setups using forge, and while I have found it relatively easy to split into multiple instances working off a shared db server, I haven't always seen the performance gains I would expect.

Would love to see something along these lines, and maybe app optimisation in general.

zefman left a reply on I Need Some Advices About Small Share Files Application

Not quite sure what you are asking but sounds like you would need a files table that holds info about each file, including the user who uploaded it, who can download it etc etc

zefman left a reply on Multiple Languages

Ok so I am just trying to understand what is happening here, in the foreach ( $language as $lang ) bit are you trying to output one input field for each language?

zefman left a reply on Extra Relation In Polymorphic Many To Many

Yeah unfortunately I don't think there is a way to do this with eloquent.

zefman left a reply on Multiple Languages

Could you maybe post some code to give us a better idea of what is going wrong?

zefman left a reply on Extra Relation In Polymorphic Many To Many

You can easily store the user_id on the pivot table, but I don't think retrieving it as an eloquent relation is possible.

Do you know how to store and retrieve extra attributes on the pivot table?

09 Dec
3 years ago

zefman left a reply on Deployment Scripts

You might also want to add "php artisan optimize" :)

zefman left a reply on Updating Different Parts Of View Using Ajax Calls ( Big Response Time )

Ah I see @Aktara the problem is that you are making lots of requests at once. 150ms with no db queries is pretty slow though, is this in vagrant, or on a production server? That sounds to me as though there is another problem.

Have you thought about trying to combine the ajax calls into one request?

@CrtlAltDylan we usually just try to keep it relatively simple and use the remember functionality like this:

$users = Cache::remember('users', 10, function()
{
    return User::with('profile')->get();
});

That looks for the 'users' entry in the cache, if it is there its returned, if not it will fill the cache using the database ready for next time.

We also make heavy use of events to flush the cache at certain points.