trevorg

Experience

9,565

3 Best Reply Awards

  • Member Since 4 Years Ago
  • 76 Lessons Completed
  • 8 Favorites

1st June, 2018

trevorg left a reply on Jobs: RetryUntil() And $tries Not Taking Effect • 4 months ago

What I typically do in these situations is manually release the job with a delay:

$this->release(60)

That command will release the job back to the queue, with a delay of 1 minute.

30th January, 2018

trevorg left a reply on Preventing Duplicate Entries While Using Soft Deletes • 8 months ago

You can use transactions and lock the table. But, I think this is actually a better solution, as it relies on the DB unique constraints:

https://tech.endeepak.com/blog/2015/10/19/soft-delete-and-unique-constraint/

9th August, 2017

trevorg left a reply on Passport Json Response • 1 year ago

Also curious about this. I'll come back if I find an easy way to do this.

19th February, 2017

trevorg left a reply on Laravel Intermittently Does Not Pull From Environment Variables Correctly • 1 year ago

@leolam2005 Sorry for the late reply.

Not sure about Lumen, but for your second question, you will want to add whatever variable you need from your .env file into your /config/app.php file as "secret_key" => env("SECRET_KEY") and then call `config('app.secret_key') in your application.

Of course, it won't solve the issue unless you are caching the config files with the artisan config:cache command.

trevorg left a reply on Laravel Shift, Upgrade To 5.2 - Use Config() Instead Of Env() • 1 year ago

I'll chime in here as well because I haven't seen anyone else mention it.

As @nztim mentioned, the config files are cached so anytime you call config(...) you're reading from a cached array. So there is a speed benefit.

But it's more than that. If you use env(...) outside of these cached config files, you will be reading directly from your .env file every time you call this function, which will almost certainly cause issues when you have a rapid succession of requests in your application, where the .env file can't be read (due to file locking issues, IIRC). I ran into this issue myself.

Read more here: https://laracasts.com/discuss/channels/general-discussion/laravel-intermittently-does-not-pull-from-environment-variables-correctly

Basically, the only place you ever use the getenv() or env() functions are in your config files (present in the /config/ directory). Then, you run the command php artisan config:cache which caches all those files. Then, you are only pulling your ENV variables once, upon deployment, and you won't have this issue anymore where there is a problem reading ENV variables (which is a complex issue involving more than just Laravel).

5th May, 2016

trevorg left a reply on Passing Custom Parameters For SparkPost API Call • 2 years ago

Yeah I'm wonder the same thing myself. I need to pass the transaction = true flag to the API call to prevent the "Unsubscribe" link from showing up, but I don't think there is a way to do it...

24th April, 2016

trevorg left a reply on Log Monitoring & Alerting • 2 years ago

@wiedem Thanks -- great information! Bugsnap looks like a good bet all around.

trevorg left a reply on Log Monitoring & Alerting • 2 years ago

@EmilMoe certainly, but for anything larger than a simple project some kind of log analysis and error manager is preferable, in my opinion.

trevorg left a reply on Log Monitoring & Alerting • 2 years ago

That looks great, and cheaper than the other options as well!

23rd April, 2016

trevorg left a reply on Handling Beanstalkd Crashes • 2 years ago

@pentium10 Are you using Supervisord to monitor beanstalkd itself, or just the worker processes?

trevorg started a new conversation Log Monitoring & Alerting • 2 years ago

What does everyone use for keeping track of log files? I'd like to be able to both dig deep into log files (some kind of GUI would be nice), as well as be notified immediately if there are any Exceptions added to the log files.

I'm looking at logentries.com and papertrailapp.com but wasn't sure if there were others that people found useful.

22nd April, 2016

trevorg left a reply on Making Controller Not Repeating Same Code • 2 years ago

@APPLE199 It's just a generic class that I create to handle creating objects. For instance, I may have a UserService that handles creating a user. It may have several methods like createFromRequest() or createFromApiRequest(), both of which may perform some complex checks, format the inputs and then call a private create() method.

trevorg left a reply on Making Controller Not Repeating Same Code • 2 years ago

Typically the controllers is where it gets messy. What I do is separate concerns:

For an incoming request:

  1. Middleware: authorizing, trim input fields
  2. Form Request: validate input fields
  3. Controller: Pass request off to Service for processing
  4. Service: Process request, return result to Controller
  5. Controller: Return appropriate view w/ success/failure message

This way, everything is separated out nicely, and it helps my controllers not become bloated. But no one is perfect. I still have some controllers that are too large, but it takes time to refactor everything out nicely. Every app is a work-in-progress.

trevorg left a reply on Lazy People Piss Me Off • 2 years ago

Yeah just focus on solid questions. This forum is a huge resource to people. The better we can do at submitting quality questions and getting quality answers, the more Laravel will continue to grow.

trevorg left a reply on XML Parsing • 2 years ago

This is what I use. Pretty simple:

libxml_use_internal_errors(true);
$string = '<?xml version="1.0" encoding="UTF-8"?>
<message id="12345">
<user id="47" />
<text>This is some text.</text>
</message>';
$object = simplexml_load_string($string);

This will load the XML string into an object that can be utilized as such:

$message_id = (int) $object['id'];
$user_id = (int) $object->user['id'];
$text = (string) $object->text;

21st April, 2016

trevorg started a new conversation Handling Beanstalkd Crashes • 2 years ago

I know it's not likely that beanstalkd will crash, but it may happen. Is there a way to make sure that it is restarted automatically if it does crash?

18th April, 2016

trevorg left a reply on Why Queue Worker Is Terribly Slow While Running With Supervisord? • 2 years ago

I would love to see someone's Upstart configuration so I can forgo using Supervisor to monitor queues.

16th April, 2016

trevorg left a reply on Daemon Workers Reset With Envoyer • 2 years ago

I would love to get more information on this, especially for those of us not using Forge and only using Envoyer.

trevorg left a reply on Boostrap/cache Permissions Require Custom Hook • 2 years ago

I also added a hook like this to CHMOD the cache directory. I think whether this is necessary depends on the specifics of your installation.

However, you shouldn't need 777. In my case I use 775. I created a user envoyer in the www-data group, so that all the files Envoyer creates have the ownership of envoyer:www-data and the webserver then can read and execute everything (since it's in the www-data group). Then my hook makes it so the group www-data can also write to the cache directory, which it needs to do.

The only other thing I did ahead of time was give the same permissions to the storage directory.

I'm not 100% sure this is the best way to do it, but I think it's safer than the alternatives. I would be happy to know what others are doing.

trevorg left a reply on Laravel Intermittently Does Not Pull From Environment Variables Correctly • 2 years ago

Yes, I did. This is an issue, but the solution is pretty simple. Basically, the only place you ever use the getenv() or env() functions are in your config files (present in the /config/ directory). Then, you run the command php artisan config:cache which caches all those files. Then, you are only pulling your ENV variables once, upon deployment, and you won't have this issue anymore where there is a problem reading ENV variables (which is a complex issue involving more than just Laravel).

31st March, 2016

trevorg left a reply on Confusion About Queue Timeouts • 2 years ago

It does seem odd that there is both a --timeout flag as well as an expire variable for the database queue driver. What is the purpose of the expire variable? It seems redundant, and can lead to unexpected situations if not properly configured.

If in queue.php I specify the following:

'database' => [
            'driver' => 'database',
            'table' => 'jobs',
            'queue' => 'default',
            'expire' => 3600,
        ],

And then I run two workers with this command: php artisan queue:listen --timeout=30

What happens is the job goes to the first worker, and after 30 seconds it throws the ProcessTimedOutException and quits. HOWEVER, the other worker does not pick it up to retry it, since it respects the expire value in the config.

So it seems like you must utilize the both the expire config setting, as well as the --timeout flag if you are using the database driver. If the expire is set to less than the timeout, you can have unexpected results.

trevorg left a reply on Caching Less Than 1 Minute • 2 years ago

@JeffreyWay I would definitely recommend Laravel consider allowing for caching for any amount of time. There are certainly scenarios where Laravel is used to power apps that accept hundreds of requests/sec. A 5 second cache would yield considerable performance improvements without sacrificing much in terms of live data presentation.

Microcaching is a caching technique whereby content is cached for a very short period of time, perhaps as little as 1 second.

https://www.nginx.com/blog/benefits-of-microcaching-nginx/

21st March, 2016

trevorg left a reply on Disabling Laravel Utilities For RESTFUL API • 2 years ago

@bdsoha My guess is that one of your routes is trying to return a view. Look through your routes.php file and all your controllers to make sure that isn't the case.

18th March, 2016

trevorg left a reply on Question Regarding Timezone For Carbon Objects Returned By Models • 2 years ago

Ah, timezones. So much fun.

What is your mysql connection timezone set to? There are a couple places this could be set. When retrieving TIMESTAMP columns, mysql will automatically convert it from UTC to your connection timezone. Remember that. It's important (and annoying, in my opinion). See here: http://www.mysqltutorial.org/mysql-timestamp.aspx

Personally, this stuff drove me crazy, and I ended up doing the following:

  • Set timezone in PHP.ini to UTC
  • Set mysql timezone to UTC
  • Set application timezone to UTC
  • Make sure every Carbon() instance is set to UTC before inserting into database
  • When displaying dates on the frontend, convert to the user's timezone at the last step

I also started using DATETIME instead of TIMESTAMP columns, for various reasons. But that's just a personal preference. Most people disagree with me on that.

trevorg left a reply on Disabling Laravel Utilities For RESTFUL API • 2 years ago

I'm fairly certain you can just comment it out in your config/app.php. It looks like you are already doing that successfully for most items. I'm not sure why you wouldn't be able to remove the ViewServiceProvider specifically. Can you paste the error you get when you try to do that? It could be due to some of the boilerplate stuff that ships with Laravel.

trevorg left a reply on Preventing Duplicate Entries While Using Soft Deletes • 2 years ago

@jekinney This isn't a real solution, I'm afraid.

Firstly, Laravel uses its own session handler, not PHP's native one. And the file-locking that Laravel's file session driver does is (unfortunately) not the same as PHP's native one (this causes other, unrelated issues).

More importantly, this does nothing to mitigate the potential of duplicate data reaching the database when either (a) different users with different sessions request with the same data or (b) a duplicate API request is made that does not utilize sessions. The latter is much more likely, and needs to be addressed using either constraints or locking, as far as I can tell.

trevorg left a reply on Preventing Duplicate Entries While Using Soft Deletes • 2 years ago

Yeah, @premsaurav is correct. The protection needs to be at the database level, either by a constraint or locking. Think about a scenario where two requests are received at the exact same time. Both requests would pass validation, and both would try to insert a row into the database.

trevorg left a reply on Preventing Duplicate Entries While Using Soft Deletes • 2 years ago

Actually my solution won't work, since MySQL does not treat null value columns as the same. Here's a thread discussing this, and they end up doing basically what I suggest, by adding a deleted_token with a non-null default value (http://tech.endeepak.com/blog/2015/10/19/soft-delete-and-unique-constraint/)

trevorg left a reply on Preventing Duplicate Entries While Using Soft Deletes • 2 years ago

Yeah that's what I'm leaning towards doing. The only other option I was considering was creating a UNIQUE constraint that stretched across multiple columns, like this: UNIQUE(email,deleted_at). I'm trying to think of a scenario where this wouldn't work... of course this adds another index onto the table.

My guess it that most Laravel applications that use soft deletes are not protected against this potentiality. Can't find much about this discussed anywhere.

trevorg left a reply on Best Way Of Inserting 100k+ Entries In MySQL • 2 years ago

I've had the joy of transferring about 2 million rows recently. Takes about 30 minutes, but that's because large number of foreign keys, indexes, etc.

Transactions, storing database files on an SSD, are what worked for me. Still looking for a better way, but it's beyond my expertise at this point.

trevorg started a new conversation Preventing Duplicate Entries While Using Soft Deletes • 2 years ago

So here's an interesting issue that I'm occasionally seeing.

Sometimes, especially with API requests, due to network connections I see the same request received twice, at basically the same time. Normally, Laravel's validation will prevent duplicate entries using the unique validation rule, however, this does not work if both requests are received at the same time, since they both pass validation at the same moment, and then continue to insert data into the database.

Now typically, I can prevent duplicate entries at the database level by setting a UNIQUE constraint in MySQL on the requisite column, so even if the request makes it past the validation rules it won't sully the database. However, since I'm using soft deletes, there can exists multiple columns with the same data (if they have been deleted and the deleted_at column is not null). So a UNIQUE constraint won't work.

So I'm wondering, what is the best methodology for preventing duplicate entries in this scenario? I thought about using table locking with transactions, but that seems like a worst-case situation, but maybe it is necessary.

15th March, 2016

trevorg left a reply on Dispatch A Job From Event Listener • 2 years ago

There is a global function dispatch() that you can use.

3rd February, 2016

trevorg left a reply on Better Place For Validations? Controller Or Model? • 2 years ago

I always handle validation either within a controller, or a Form Request.

However, I store universal validation rules on the model, like this:

public static $rules = [
 'name' => ['min:1','max:191'],
 'email' => ['email']
];

Then I am keeping those rules in a single place, rather than in several separate Form Requests or controllers.

24th January, 2016

trevorg left a reply on Pulling Job Workers Out Of Laravel So Use Lumen Or Symfony? • 2 years ago

I too am curious about using Lumen for processing queues, but honestly I haven't found much guidance out there. I'm probably just going to stick with Laravel.

I believe the best way to run the worker(s) is by using the command line and then something like systemd or supervisord to monitor/restart them if necessary. Forge/Envoyer are good for this. You can also run them in daemon mode so they load the Laravel framework only once, which will make it faster (but also use more memory).

trevorg left a reply on Laravel Relationships With Repositories • 2 years ago

And I agree with @kfirba on both points.

Definitely keep using the related user model to lookup posts for that user, as it is both secure and simple that way. I do it that way for almost everything.

And injecting the authenticated user into a root class is also a great idea, to avoid duplicating code. Personally, I inject the user into my root controller, rather than a root repository.

// Controller.php
protected $user;
public function __construct() {
   $this->user = Auth::guard('web')->user();
}
/// PostsController.php
protected $postsRepository;
public function __construct(PostsRepository $postsRepository) {
   $this->postsRepository = $postsRepository;
   parent::__construct();
}

trevorg left a reply on Laravel Relationships With Repositories • 2 years ago

Here's my list of my own "best practices" for this scenario, for what it's worth:

#1 - Store the logged in user in the controller in a protected variable.

// PostsController.php
protected $user
public function __construct() {
   $this->user = Auth::user();
}

#2 - Create a method on your PostsRepository class to find a given post for a given user.

// PostsRepository.php
public function findforUser(User $user, $id) {
    return $user->posts()->findOrFail($id);
}

#3 - Inside your controller, call the PostsRepository and pass the currently authenticated user and the id.

public function show($id) {
   $post = $this->postsRepository->findForUser($this->user, $id);
   ...
}

The only other advice I would give is this: Don't feel like you HAVE to use repositories for every model lookup. I found that I was basically undoing all of the flexibility that Laravel provides by doing that. For instance, I wouldn't necessarily bother with a repository for the lookup you're describing. At this stage, I use repositories for more complex lookup queries that I don't want to be duplicating around my application. For simple ones, I don't bother with a repository.

Just my opinion.

23rd January, 2016

trevorg left a reply on [Laravel 5] Modify Input Before Validation • 2 years ago

Yes @ricardovigatti is right. I think that's the best way to handle input manipulation prior to validation.

I would also extract certain aspects, such as trim, to a middleware, if you want that done on every request.

trevorg left a reply on Lets Talk Frameworks! • 2 years ago

Honestly, I love PHPStorm and use it for everything. It's a great IDE to use with Laravel/Vue/Gulp.

10th January, 2016

trevorg started a new conversation Lumen / Laravel With Shared Models • 2 years ago

Let's say we have an app that has both a web frontend and API access, which I think is fairly common.

If I wanted to use Lumen for the API and Laravel for the frontend, what is the best way to go about this? I'd love to see a Laracasts series that goes into details of setting this up (and include aspects such as events, queues, shared database, etc.)

28th December, 2015

trevorg started a new conversation How To Check How Many Jobs Are Currently Running • 2 years ago

Let's say I have a queue with 5 workers. Each worker takes a job and hits an API (like Twitter) to send/receive some data. A single job may require 100-1,000 separate API calls.

The issue is, the application as a whole must stay within Twitter's API limits. So, each worker must know how many other workers are hitting the API at any given moment so as to not go over the limit.

Previously, I had used file-locking so that each worker was aware when another worker was running. But I'm wondering if there is a better way to do this.

Is there a way for Laravel queue workers to be aware of each other?

15th December, 2015

trevorg left a reply on Loading HTML Via Ajax • 2 years ago

If you want to use Vue for a table, I'd recommend using Vue for drawing the entire (or ). I switched from using Jquery and Datatables to this and it actually wasn't that difficult. But I did initially attempt some combination of Vue & Datatables and it was too cumbersome.

But yes, you'll have to write computed properties in Vue to replace those HTML helpers, which are very easy to do. Alternatively, you can just include those links in the JSON that your API returns for Vue to consume.

11th December, 2015

trevorg left a reply on Make A Return Date React Like Carbon Diffforhuman Method In Vue • 2 years ago

Just in case anyone else finds this, here is what I did:

1 - Return database field as Carbon object, accessible via API, in UTC. 2 - Create a filter in Vue to manipulate the date to display in user's timezone.

Vue.filter('moment', function(value, format) {
            return moment.utc(value).local().format(format);
        });

3 - Then in your template:

{{ comment.created_at | moment 'ddd, MMM D, h:mma' }}

In your case, you want to use moment's fromNow() method:

Vue.filter('timeago', function(value) {
            return moment.utc(value).local().fromNow();
        });
{{ comment.created_at | timeago }}

10th December, 2015

trevorg left a reply on Vue.js + Laravel Pagination • 2 years ago

I also really need a pagination component that will nicely integrate with Laravel.

18th November, 2015

trevorg started a new conversation Is There A Way To Add UNIX Epoch Time To Carbon JSON Serialization? • 2 years ago

Currently if I return a Carbon instance in a JSON response, it is automatically serialized into:

{
"date": "2015-11-19 02:35:22.000000",
"timezone_type": 3,
"timezone": "UTC"
}

This is great, however, I'd like to add epoch time to this array, because it's often useful to have it for apps that are consuming an API. Is there an easy/universal way to do this?

1st November, 2015

trevorg left a reply on Is It Better Caching SQL Queries Or Decreasing Number Of Requests? • 2 years ago

Simplest thing to do is put a delay on the AJAX search, after 300ms or so of no changes to the search value. That way if they type a 10-character word you could potentially only do 1-2 AJAX calls, instead of 10.

27th October, 2015

trevorg left a reply on Boolean Casting & Default Value Issues • 2 years ago

Perfect @thomaskim. That should fix it. And yes, the default value is set to 0 in the database. The issue was that line where I used $request->get('is_admin') and it returned a null value.

And I checked and indeed casting does not work if the value is null:

Model.php

   protected function castAttribute($key, $value)
    {
        if (is_null($value)) {
            return $value;
        }
...

trevorg left a reply on Boolean Casting & Default Value Issues • 2 years ago

Okay, it turns out the issue was actually with the assignment I was using in creating the model:

$user->is_admin = $request->get('is_admin');

This didn't work because the is_admin value was from a checkbox: <input type="checkbox" name="is_admin" value="1" />. And if the checkbox wasn't passed in the form, then I guess the $request->get('is_admin') returns null, which makes sense.

However, I assumed the model would still cast that value to boolean before saving, but apparently that is not the case. Am I missing something?

trevorg started a new conversation Boolean Casting & Default Value Issues • 2 years ago

So I have a model like this:

class User extends Model
{
protected $attributes = [
   'is_admin' => 0
];
protected $casts = [
   'is_admin' => 'boolean'
];
}

In my MySQL database, the is_admin column is a TINYINT(1) that does not allow NULL values. (Value should always either be 0 or 1.)

When creating a new model and saving it, I run into this issue:

SQLSTATE[23000]: Integrity constraint violation: 1048 Column 'is_admin' cannot be null (SQL: insert into `user` (`name`,`is_admin`, `updated_at`, `created_at`) values (Bob,,2015-10-27 20:58:03, 2015-10-27 20:58:03))

So it looks like Laravel is passing an empty string rather than a 0. So, am I storing boolean values incorrectly in the database? Or is something else going on?

28th September, 2015

trevorg left a reply on Laravel 5 Validation Request, How To Handle Validation On Update? • 3 years ago

Saving this thread. Great stuff.

Edit Your Profile
Update

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