ohffs

Experience

243,780

274 Best Reply Awards

  • Member Since 2 Years Ago
  • 897 Lessons Completed
  • 2 Favorites

5th May, 2018

ohffs left a reply on Getting The Json Data For An API Resource • 2 weeks ago

ah, so that's what API's are - I've always wondered.... o_O

ohffs left a reply on Getting The Json Data For An API Resource • 2 weeks ago

:: one-off bump :: :-)

3rd May, 2018

ohffs started a new conversation Getting The Json Data For An API Resource • 2 weeks ago

'Allo,

I've got a bit of code for an API that uses the Laravel API resources. I'd quite like to re-use the same logic/code in a different place for consistancy. But I can't see an obvious way of getting the resulting JSON data out of the Resource object.

So I have a resource a bit like :

return [
    'username' => $this->username,
    'surname' => $this->surname,
    'forenames' => $this->forenames,
    'email' => $this->email,
    'created' => $this->created_at->format('Y-m-d H:i'),
    'updated' => $this->updated_at->format('Y-m-d H:i'),
    'projects' => Project::collection($this->projects),
];

The only way I've found to do it and have it fully build the resource is to do :

json_decode(
    (new UserResource($user))->toResponse($this)->getContent()
)

Which is a bit ugly to say the least. I've tried the more obvious-sounding method :

(new UserResource($user))->jsonSerialize()

But that only transforms the 'top level' part, not the included related 'Project' collection. Anyone have any pointers? :-)

28th April, 2018

ohffs left a reply on Can Some Review My Code And See How I'm Doing - Users Adding Eachother In Laravel • 3 weeks ago

I'd just put it on the model for now :-) You just put the same login in there (well, replace $Tenancy with $this)- you're just giving it an easy to read name :-) But you wouldn't have the code to render the button in there - that can stay in the view. Eg, on your Tenancy mode :

public function hasPendingRequest()
{
    return $this->accepted == 0 && $this->request_sent == 1;
}

Then in your view you would just do the @if (...) <render the button> @endif.

To avoid having to check if the Tenancy is null, you can just pass a new one to your view too. Eg, in the create method you could do :

public function create($id){
    $user = User::where('id', $id)->first();
    $properties = PropertyAdvert::where('user_id', Auth::id())->get();
    $tenancy = new Tenancy;

    return view('/pages/account/tenancy/create', compact('user', 'properties', 'tenancy'));
}

Give it a try anyway and see if you think it looks/feels nicer :-)

ohffs left a reply on Can Some Review My Code And See How I'm Doing - Users Adding Eachother In Laravel • 3 weeks ago

One thing that leaps out at me that would be a quick 'win' would be to replace some of those long boolean conditionals in your view and give them helpful names. For instance

@if($Tenancy != null && $Tenancy->accepted == 0 && $Tenancy->request_sent == 1)

could be :

@if ($tenancy->hasPendingRequest())

That kind of thing anyway - it makes it easier on yourself when you come back to change the code in a year ;-)

You might also be better splitting your view (and likely controller) into two different versions - one for the tenant and one for the landlord - that way you have a lot less to worry about and check with 'if' statements.

Other than that - you seem to be mixing bits of code that I don't quite understand. For instance in your 'create' method you have :

    $user = User::where('id', $id)->first();
    $properties = PropertyAdvert::where('user_id', Auth::id())->get();

So you are getting the properties for the authenticated user, but the '$user' you are passing to the view could be someone else? I'm not sure if that's a feature of your site or just an accident :-)

Then in your accept/reject methods you are updating the database based on the 'accepted' and 'request_sent' flags, but not to a specific Tenancy id? So it looks like it would update potentially a lot of un-related rows in the table?

Anyway - hope some of that is helpful :-)

21st April, 2018

ohffs left a reply on Apache Monitor Tool (recommendations) • 1 month ago

Munin, Zabbix and Prometheus are quite popular. Depends what you're wanting to 'monitor' though - you could end up with something using logstash and kibana.

You're not short of options really depending how much insight & details you want and the scale of what you're doing :-)

20th April, 2018

ohffs left a reply on Upgrading Legacy Project V5.2.39 • 1 month ago

Exactly how much of a pain it will be depends a lot on the project. I seem to remember 5.2 -> 5.3 was a bit annoying, but after that it has been fairly painless for my own projects at least. A lot will depend on whether the code uses much in the way of 'undocumented' or 'out of the way' features - and also if you want to change the code to take advantage of new features in Laravel or just 'get it working'

If you have any kind of budget available maybe have a look at https://laravelshift.com/ which can automate a lot of the 'grunt work' :-)

9th April, 2018

ohffs left a reply on Introducing Laravel Fast Excel • 1 month ago

@jlrdw I've got a non-framework-specific basic excel wrapper at : https://github.com/ohnotnow/simple-spout that uses the same underlying 'spout' fast excel library - still uses composer though I'm afraid :-/ But if you install it via composer you should (I think!) just be able to do :

require_once('./vendor/autoload.php');
$data = (new \Ohffs\SimpleSpout\ExcelSheet)->import('/path/to/whatever.xlsx');

28th March, 2018

ohffs started a new conversation Gitlab/CI - Compling Assets • 1 month ago

'Allo,

I've used gitlab quite a lot for the testing side of things (ie, push to repo - gitlab spins up a test runner and tells me if it's broken). But I'd quite like to move to eventually deploying using gitlab/docker too.

One thing that's not very clear to me is where I could add some kind of stage/job that would run 'npm run production' to compile/optimise the projects js/css and have that as part of the deployment without having to have node/npm on the actual server. Once or twice we've had projects pushed out to production where someone has commited the js/css in development mode so it would be really nice to eliminate that manual 'remember to run npm run prod before you commit to master' step.

I think I might want to use the assets part of the gitlab setup, but I'm not entrely sure. Anyone else done this?

14th March, 2018

ohffs left a reply on Laravel Forces Use Of Constructer Like This '__construct'. Wondering Why? • 2 months ago

Just to re-iterate what @martinbean said - the old style constructors should be replaced with the new __construct ones. Pretty much all current PHP code will assume that is how things are done. In the next major release of PHP the old style constructors will be removed altogether - from the PHP docs :

Warning: Old style constructors are DEPRECATED in PHP 7.0, and will be removed in a future version. You should always use __construct() in new code.

So although if the code works for now in 'pure' PHP 5.x/7.x - things like laravel and some other projects will fail - and when you update to a newer PHP version your code will stop working full stop no matter if you are using Laravel or not.

9th March, 2018

ohffs left a reply on MySQL Database Backup As A Service • 2 months ago

I seem to remember ottomatik getting some praise from some Laravel people a while back. I've never tried it myself though.

8th March, 2018

ohffs left a reply on Is There A Way To Run Horizon With Systemd? • 2 months ago

Just add a systemd unit file to (afair) /lib/systemd/system/. So something like horizon.service :

[Unit]
Description=Laravel Horizon Queue Manager
After=network.target auditd.service

[Service]
ExecStart=/usr/bin/php /path/to/your/artisan horizon
Restart=always

[Install]
WantedBy=multi-user.target

Might do the tricky anyway. You'll need to run systemctl enable horizon.service and systemctl start horizon.service - see if it works :-)

7th March, 2018

ohffs left a reply on Do You Randomize Uploaded Images Names Or Tie Them To Meaningful IDs? • 2 months ago

I tend to try and split up files a bit. Mostly to save a single directory ending up with 1000's & thousands of files which can make things quite slow. But that's only a concern if you're letting people upload/change lots of file. But yeah - you need to be a bit careful tying to specific user/category/whatever id's. Maybe you could just do a basic separation like :

/front/$random_filename
/side/$random_filename
/back/$random_filename

I guess it depends on how likely you think it is the category_id etc might change though (or any other random thing you might get asked to do down the line!). It's nice being able to do something like :

/front/2/3/image.jpg

Then from a filesystem level and your app level it's easy to know the file. Especially handy if a user says 'can I have yesterdays file back?' without needing to dig into the db as much to figure out filenames :-)

1st March, 2018

ohffs left a reply on Learning Testing - Using Classes With Dependency Injection • 2 months ago

Yay - glad it worked :-) Good luck with the rest of your testing! :-)

ohffs left a reply on Learning Testing - Using Classes With Dependency Injection • 2 months ago

If you replace new Cart(new SessionManager, new Dispatcher); with app(Cart::class) - does that help? That should ask laravel to recursively resolve all the dependencies if it can.

ohffs left a reply on MAC Addresses On LAN • 2 months ago

Ontop of what @crnkovic says, you could also run arpwatch on your server - then you can parse the file it logs (default is usually /var/lib/arpwatch/arp.dat) - saves doing a shell_exec :-)

28th February, 2018

ohffs left a reply on Design A Requirement Column For Course Table [Database] • 2 months ago

"It depends". You could just store it as text and print it out on the page, you could have a generic 'requirements' table and a pivot table like 'course_requirements' that joined it to the courses table or... other ways. 'It depends' :-)

ohffs left a reply on Download Large File From S3 *kind Of* Working • 2 months ago

No worries - glad you got it working :-)

ohffs left a reply on Download Large File From S3 *kind Of* Working • 2 months ago

If you remove the 'button' element altogether and put the class="btn btn-primary" on the <a> tag - does that help?

17th February, 2018

ohffs left a reply on Is There Anything Wrong With Calling Two Gates In Succession, Using ->authorize()? • 3 months ago

I don't think there's anything particularly wrong with it, personally. If you're having to do it in a few places maybe add an extra method/trait to the App\Http\Controllers\Controller so you could do :

$this->authorizes('is-coordinator', 'coordinators-can-deploy');

Maybe :-)

14th February, 2018

ohffs left a reply on RSA Encryption • 3 months ago

libsodium is now part of php 7.2 which gives you a whole lot of nice crypto stuff : https://secure.php.net/manual/en/book.sodium.php . You can hopefully just wrap some of that to do what you need?

ohffs left a reply on How To Reduce Model Data (eager Load) To One Field? • 3 months ago

Maybe have a look at the [pluck function)[https://laravel.com/docs/5.6/collections#method-pluck]?

9th February, 2018

ohffs left a reply on View Name Case Sensitive Problem Inside Sub-directory In Ubuntu 16.04 • 3 months ago

Rename the folder from Home to home?

8th February, 2018

ohffs left a reply on Queued Job - Best Way To Wait For An External Event • 3 months ago

@martinbean not really :-( it's being done by a regular torrent client (transmission) so I can only interact with it via it's http api. So I could theoretically have some kind of scheduled task which polled the torrent api - but it's much, much more 'expensive' to do that (circa 30seconds per run on the little rpi and ramps up it's CPU) and I'm still left running a scheduled task anyway.

I might look into extending the job class and see if there's a way I could do a '->releaseWithoutIncreasingTheRetryCount()' kinda thing as that's what I'm really after. I had kind of naively thought there must be a built in way to do a 'queue job, but only run on this condition' facility - but then again, I've never needed it until now so maybe it's not that common ;-)

ohffs started a new conversation Queued Job - Best Way To Wait For An External Event • 3 months ago

I've got a little (well, it was supposed to be little) home project to monitor torrent downloads and then let you copy them to another device. At the moment I just check in once in a while to see if a torrent has downloaded then I can click 'copy' and it kicks off a queued job which takes care of it in the background. All works fine.

But what I'd like to do is be able to think 'oh, that torrent is going to be a while' and click 'copy' and have it start copying when the torrent finishes downloading.

My first try was a simple check in the job itself to say 'if the torrent is still downloading, $this->release()' so the job would re-queue. But that fails quite a lot as the maximum retries can be hit very easily.

So I was wondering if there's a better way of doing it? The torrents are downloading via a 3rd-party program so I can't make that do much to help me.

My current hacky thought is to add (yet another!) flag onto the torrent entry in my apps db, so if I click 'copy' and it's still downloading then I set a 'auto_copy' flag to true - then there is a scheduled task that runs once in a while and it fires the background copy job off if the torrent has now downloaded. I don't always want the torrent to automatically copy btw, sometimes there isn't enough storage or it'll max out the raspberry pi I'm copying to.

But it feels like there should be a cleaner way than that - anyone run into this kind of situation?

ohffs left a reply on Collections 'where' And Pivot Values • 3 months ago

@bobbybouwmann pivot.choice was indeed the correct incantation :-) thank you :-D

3rd February, 2018

ohffs left a reply on Am I Refactoring The Right Way ? • 3 months ago

You could look into using Laravels authorization facilities too. Then you could end up with code that looked like :

public function destroy(Quote $quote)
{
  if (auth()->user()->cannot('delete', $quote) {
    // redirect with error message
  }
  $quote->delete();
  // return redirect... with success message
}

Or if you can be a little more 'brutal' (in the case the user should only ever get the option to delete something if it's theirs already, for instance - so this is a user deliberately doing something bad)

public function destroy(Quote $quote)
{
  $this->authorize('delete', $quote);  // that will return with a 403 if they are forbidden
  $quote->delete();
  // return redirect with success message
}

Using the authorization facilities can be nice as you can re-use them elsewhere. For instance in your blade template you can do :

@can('delete', $quote)
  <button>Delete</button>
@endcan

2nd February, 2018

ohffs left a reply on Collections 'where' And Pivot Values • 3 months ago

@bobbybouwmann ahhhh - that rings a bell now! Sadly I left work and didn't push that bit of code up to git (yes, I'm bad...) so I can't pull it down now to check - but I'll give it a try next week and mark this as correct if it works :-) Now that I see it written down it looks like what I was thinking before I did the 'pivot_choice' then sat thinking 'hrm, that's right, .... isn't it?' ;-) Thanks! Hope you have a good weekend :-)

ohffs started a new conversation Collections 'where' And Pivot Values • 3 months ago

I'm sure I've done this before, but it's reached that stage of a Friday afternoon where my brain has given up and google isn't helping much...

I've got a couple of many-to-many relations and a pivot table with some extra attributes. I'm including those in the relations using ->withPivot(...) as per - all works fine. But in another section of the code I need check based on the pivot table 'choice' column to do something like :

if ($projects->where('pivot_choice', 1)->isNotEmpty()) {
...

Which I'm sure used to work. but doesn't ;-) The curious thing is when I dd() the $projects to check they had the 'pivot_choice' field I can see :

#original: array:13 [
        "id" => "2"
        "title" => "Optio."
        "staff_id" => "3"
        "pre_req" => "Omnis voluptatibus ut facere."
        "description" => "Et est perspiciatis autem."
        "max_students" => "4"
        "created_at" => "2018-02-02 14:53:34"
        "updated_at" => "2018-02-02 14:53:34"
        "pivot_student_id" => "5"
        "pivot_project_id" => "2"
        "pivot_choice" => "2"
        "pivot_is_accepted" => "0"
      ]

#attributes: array:9 [
        "id" => "2"
        "title" => "Optio."
        "staff_id" => "3"
        "pre_req" => "Omnis voluptatibus ut facere."
        "description" => "Et est perspiciatis autem."
        "max_students" => "4"
        "created_at" => "2018-02-02 14:53:34"
        "updated_at" => "2018-02-02 14:53:34"
      ]

So the 'original' section has the pivot_ keys, but not the 'attributes' section - which is why I guess it doesn't match in the where() collection clause (doing a 'where' on anything in the attributes section seems to work as expected).

Anyway - my brain has possibly melted and I'm doing something really, really dim ;-) Anyone care to point at my glaring mistake and laugh? ;-)

1st February, 2018

ohffs left a reply on Need Some Advice Regarding Laravel Server Usage • 3 months ago

I think ~50 queries per-user-per-page is going to hurt most websites. Is there anything you can do to cache some of that data? Or is it all changing all the time? A sticking-plaster solution might be to put something like varnish in front of some routes?

Do you know what's causing the system load to spike? Is it the sql server, php itself, something else? There are some tools you can install like htop and 'iotop' that can help narrow things down

ohffs left a reply on Analytics But Not From Google Analytics. Anyone? • 3 months ago

goaccess is quite nice these days - it parses your web-server logs so you don't need to worry about people blocking cookies/js etc. It's got a built-in live dashboard too.

26th January, 2018

ohffs left a reply on Best Practice Controller Methods • 3 months ago

A little aside, but I think sometimes the idea that you have lots of controllers that only have CRUD methods can get taken a bit far. I've seen some really tortuous controllers appear in projects that actually make things harder to understand than just having an extra non-cruddy method on an existing one. '[email protected]' ;-) It's possibly this years 'command bus all the things' ;-)

But if it makes sense it works really well :-) In your specific case maybe a 'League\MembershipRequestController' would be a good place to put that logic for instance. It kind of makes cruddy sense to 'create a membership request', 'delete a membership request' etc?

You could also create a MembershipRequest model that mapped to the 'league_users' table then your code might read quite clearly too - like $membershipRequest->approve().

Anyway - I haven't had my morning coffee yet, so that's possibly all nonsense ;-) But hope it helps a little ;-)

24th January, 2018

ohffs left a reply on Create Laravel Ready To Run Package • 3 months ago

Why not write a little php or bash script that does what you need? Or have a look at something like Deployer

ohffs left a reply on Test For Message After Redirect. • 3 months ago

Then there's something in your doSomething() method that's returning it - or there's something the object is inheriting/etc (or using a middleware - whatever) that's doing a redirect. Try putting dd's into the doSomething() method to see where the code is going.

ohffs left a reply on Test For Message After Redirect. • 3 months ago

Maybe dd() the view you get back - it'll give you the object type then you can see what is available on it? That's how I end up figuring some of this out... :-)

20th January, 2018

ohffs started a new conversation Reporting (and DB Design) • 4 months ago

Hi Jeffrey,

I was watching your first Office Hours stream and you mentioned doing a series about database design.

It's something that I have to deal with a lot in regards to reporting - which I don't think gets very much coverage, possibly because it's seen as a bit, you know, boring ;-) There's very little SRP, hexagonal architecture, web-scale about it I guess to get the twitter & reddit hordes fired up ;-)

But it's what takes up a huge amount of time and delivers a whole lot of business value. So I was just wondering if you would be able to tie in DB design with reporting logic - indexes, joins, raw queries vs. eloquent, queued/scheduled jobs vs. live, exporting to Excel/pdf - all the humdrum stuff that we have to deal with rather than doing the WebGL spinning raytraced Zelda-in-a-browser that we'd all like to do ;-)

Anyway - just a thought :-)

Cheers!

ohffs left a reply on Maybe Add A Default Markup For A New Discussion • 4 months ago

I think expecting users to read any guidance before they post is a hopeless task - though maybe I'm just ground down & cynical after too many years on the internet ;-)

But maybe a little link just before the textarea where you type your question like 'Click here for some help on asking questions and formatting your post' that opened a brief simple example markdown of a short formatted question (and showing you how it would look once posted) would be worth a shot. I think linking to anything longer or more complex will end up being tldr.

Possibly also a little reminder when you post saying something like 'Remember to say thanks if someone helps!' - that would go some way to keeping the place friendly :-)

19th January, 2018

ohffs left a reply on New Application With 100's Of Form Fields • 4 months ago

@gator your point 2) is strictly correct, but in practice there are all sorts of other mysql limits that have an effect on the columns and what you can store in them. It also varies from version to version and changes depending on the column types :-/ I've been there and watched an application blow up unexpectedly because of them ;-)

ohffs left a reply on New Application With 100's Of Form Fields • 4 months ago

I feel your pain :-) I've got some forms like that too - just typing the html out is dreadful enough, never mind the back-end ;-)

If I was you I'd maybe split the data into separate tables if you can - mysql does have some really strange column limits (as I found out when doing my own huge forms!) that you will run into in very hard to debug ways :-/ It's been a while, but I seem to remember there was a limit on the number of columns but it also depended how long the data was inside them - something really weird anyway :-/

Have you thought about using mysql's (or postgres) JSON column to store info? Might be easier if you are not already using mongodb and keeps your data in one place.

18th January, 2018

ohffs left a reply on 2018- Best Hosting (subjective) • 4 months ago

I've heard some nice comments about https://www.scaleway.com/ too - haven't tried it yet, but considering moving some test sites over to see how it goes :-) I'll be interested to see how the ARM boxes perform.

ohffs left a reply on Local Filesystem On Load Balanced Servers • 4 months ago

No worries - glad to help :-)

ohffs left a reply on Local Filesystem On Load Balanced Servers • 4 months ago

Yep - that's the kind of thing :-) It's pretty easy to set up - just a bit of fiddling about depending if you're wanting to use (or the OS defaults to) NFSv4 rather than NFSv3 :-)

ohffs left a reply on Local Filesystem On Load Balanced Servers • 4 months ago

You could make 'server Z' export the filesystem to A & B using NFS? The config is pretty easy - but annoyinly slightly different between Linux distro's :-/

ohffs left a reply on Am I On Good Way Or I Should Refactor ? • 4 months ago

One way you could maybe make things easier would be to add some helpers to your user or profile model. Then in your view - instead of all those checks in the controller and view - you could do something like :

<li>{{ $user->getCountry() }}</li>
<li>{{ $user->getRelationshipStatus() }}</li>
...

and on your model (or a helper class) do something like :

public function getCountry()
{
  if ($this->show_country) {
    return $this->countries()->first();
  }
  return '';
}

Something along those lines anyway. There are lots of ways to tidy things up a bit, but that's the first one that came to mind without knowing more about the rest of the system :-)

17th January, 2018

ohffs left a reply on How To Make Assertions On A Laravel Mailable • 4 months ago

@haakym ah - don't worry about it :-) just glad to help - I had to do exactly the same thing recently so it was in my head :-)

ohffs left a reply on How To Make Assertions On A Laravel Mailable • 4 months ago

Inside the assertSent block, if you do a $mail->build(); before doing your checks - does that work?

ohffs left a reply on Monitoring Failed Jobs • 4 months ago

I've done it this way in the past : https://laravel.com/docs/5.5/queues#failed-job-events

11th January, 2018

ohffs left a reply on Cannot Display Image From Local Storage • 4 months ago

Have a look at the storage:link artisan command. Hopefully that should help :-)

8th January, 2018

ohffs left a reply on Can You Use Notifications Without A Model? • 4 months ago

I send exception alerts to slack just using the 'on demand notifications'. That might cover what you need - just set the route to 'slack' and use it like you would a regular notification.

5th January, 2018

ohffs left a reply on Debugging Jobs • 4 months ago

Calling \\Log::info('whatever') works ok for me inside of jobs - can you show your code?

Edit Your Profile
Update

Want to change your profile photo? We pull from gravatar.com.