consil

Experience

15,320

0 Best Reply Awards

  • Member Since 3 Years Ago
  • 133 Lessons Completed
  • 4 Favorites

1st August, 2018

consil left a reply on Laravel 5.6, Bootstrap 4 + Template, JQuery And Vue • 2 weeks ago

@Luka Did you every get an answer to your questions? One thing I am certain of, is that the node_modules directory does not get installed on your web server. It's a massive directory full of development stuff. The assets installed on the final server is what is in the public directory.

I'm looking for the same answers - how do I get from installing Laravel 5.6 to using bootstrap 4 classes in my views. There seems to be a lot of magic in the middle, and no one place where it is explained, because it involves so many moving parts from so many sources and with so much that can go wrong.

31st July, 2018

consil left a reply on Can Eloquent Lock A Whole Table? • 2 weeks ago

@Cronix I like that method. I wouldn't need the unlock if it's used in a transaction:

DB::transaction(function () {
    lockTable('table');

    // Do my stuff.
});

The lock would always be released when leaving the closure.

There is probably a way to extend the DB facade so DB::lockTable('table'); could be used.

consil left a reply on Can Eloquent Lock A Whole Table? • 2 weeks ago

@click that is essentially what I am trying to do, and have done something similar with queued jobs that have small sections that cannot run at the same time (oauth token refreshes are one example, where two jobs could be hitting the same expired oauth token, and end up with one overwriting the new token grabbed by the other).

The advantage of locking a row in the database instead, is that if the process dies, then the lock is released automatically. My initial thought was that since I was updating the table, then it makes sense to lock that table. But thinking about it more, it really does not matter what I lock in the database, so long as all jobs updating that table agree to lock (or attempt to lock) the same thing.

consil left a reply on Can Eloquent Lock A Whole Table? • 2 weeks ago

I can certainly find out which database type is being used by inspecting the PDO object.

It was worth a look, as PDO supports things like commit, rollback and starting transactions natively. It just doesn't have lock table.

I think I'm leaning towards a lockable row in a table set aside just for handling this. It may not even be an issue in the long run if the update job is running on a queue, and the queue only has one worker.

consil left a reply on Can Eloquent Lock A Whole Table? • 2 weeks ago

The transactions work, but solve a different problem. For a start, if two update processes ran at the same time (for whatever reason), and they started updating and inserting the same rows in the table, then they could easily get into a deadlock situation.

The locking of the whole table is to ensure no two jobs are updating the table at the same time, as a requirement to update the table will be to lock it.

consil left a reply on Can Eloquent Lock A Whole Table? • 2 weeks ago

I'm not sure what taking the site down is going solve!

Our application is going to be up 24/7, handling data through APIs, and we can't really afford to take it down on purpose. Handling the database updates are relatively trivial, but I was just wondering if locking whole tables is something that is handled by eloquent out of the box or not.

consil started a new conversation Can Eloquent Lock A Whole Table? • 2 weeks ago

That's the question :-)

I realise rows can be locked when selecting, by using the lockForUpdate() method in an eloquent query. But what about a whole table?

We have a table that gets updated from a CSV file at regular times, and simply want to lock the table while doing the updates, just in case multiple update processes get run at the same time. The locks will force them to line up and take their turn. The updates are done in a single transaction, so an update process will update the whole table, or none of the table.

Now, we will be deploying to both MySQL and Azure SQL databases. The transaction handling and row locks of eloquent work brilliantly on both databases - the whole process is abstracted so it just works.

But whole table locks? Can't find any documentation on that. Anyone done this?

11th June, 2018

consil left a reply on Supplying Views In Packages • 2 months ago

In fact, I think I have a better idea than just minimal HTML.

The problem I have often found with package views is that the package controllers send their output to a view to handle the controller's output. That view then needs to incorporate itself into a layout:

my consil package /views/auth/login.blade.php:

@extends('my-consil-package::layout')
@content 
    ...HTML for the login form...
@end

The problem here is that the package must provide a layout for the content to go in, and that layout will certainly NOT be usable in the end application. So to override the layout, you then have to override this whole view, which makes updates more difficult (the HTML content may be just fine to use without overriding).

So, the approach would be to use the view that the package controllers use just to join the detail views together. So the controller views will contain just and extends to a simple layout, and one or more include directives to pull in the views for the detail, such as a login form.

So in summary, split those views up into more structural parts. This is probably obvious, but I seldom see it done.

consil left a reply on Supplying Views In Packages • 2 months ago

I thought that would probably be the case (it always has been). I was hoping there would be more of a consensus these days to make packages more easily integrated. But I guess the driver here are views, and view are HTML, and HTML has to fit into some kind of framework the package knows nothing about.

I'll stick to minimal HTML that works but does not make any assumptions about the framework. Then people can publish those views and add their own wrapper and classes, while being able to see the wood for the trees.

consil started a new conversation Supplying Views In Packages • 2 months ago

So, if I have a package that provides some views for use in a site the package is going to be used in, and that package is going to be published for use in a number of sites, how is it best to provide the view content?

For example, supposing I have an authentication package, and it comes with a login form, what would that login form look like? Should I put the absolute minimal HTML in it, so people can override it, copy that HTML, and wrap it in their own theme? Should there be multiple examples - for bootstrap, Vue, etc. perhaps?

Many packages seem to supply full bootstrap views and layouts, which is great to evaluate and looks pretty, but then pulling the guts of those views out to use in my own overall layout/theme can be a real pain. Is there a better way, maybe a more oppinioated way, or an approach that is more generic?

10th June, 2018

consil started a new conversation Do I Need A Guard For Each User Provider? • 2 months ago

I have a system that needs "multi-auth". There are two distinct sets of users (both remotely defined), authenticated in different ways, and which have access to different parts of the site.

The "admin" users will have access to everything under /admin. They are authenticated using an API and have a custom user provider defined for them. Authentication in the /admin area is controlled by the admin guard.

The "users" users have access to the rest of the site, and they will be authenticated through a different API. A different user provider have been defined for them.

Now, the guard. I'm using the session driver for both the admin and user guards. What I don't understand, is whether the session driver can only look after one guard at a time. For example, can a user be logged into the admin area, then also be logged into the non-admin areas as a different non-admin user? Or to do this, do I need separate guard drivers (session-admin and session-user, for example)? I'm just not sure if these guards fall over each other when sharing a driver.

consil left a reply on Adding A Custom Guard • 2 months ago

This is a really really tough problem, that does not seem to be explained fully anywhere. The problem is that it involves at least a dozen different parts that need to come together, and aliases all other the place, with similar or identical names but very different meanings. And most of the stuff joins together within magic middleware that is very hard to debug. Struggling with this myself, and no tutorial or article gives the complete picture.

@crowsed on one question you have - how the guard knows how to access the remove system, I don't believe it does. It is the user provider that does that. The user provider knows where the user is (at the end of an API), how to fetch a user (from that API), and how to check the credentials of a user.

The provider used by the guard comes in two parts: the driver and the model. The driver, which is aliased and registered yet somewhere else (not in the auth config, even though it is only used for auth) is the class that does the actual API communications and populates the model. However, if you are allowing the user details to be updated, then the user model may need to contain the actual communications with the API. For example, when using an eloquent user model, you can change the user's name, then hit $user->save() to save it back to the database. However, your user model won't be an eloquent model if it is entirely remote. However, you may mirror the user locally and update it each time the user logs in - it depends if you need to store anything locally against the user.

I'd love to see all this drawn out in a diagram, because it is crazy complex to picture.

7th June, 2018

consil left a reply on Using A String Primary Key • 2 months ago

@click Yes, I can cast the values before using them to find a record. I was just hoping this was a well-known problem with a solution already in place and just hiding from me. I guess not, and I just need to be careful instead.

consil left a reply on Using A String Primary Key • 2 months ago

Luckily I'm not having to generate them, as I'm just reading from an external system. I'm using the eloquent models with global scope closures ("global", but locally defined) to pull in data from relationships and related tables, which abstracts the external database structure out of sight very nicely. So the convenience of using eloquent for the models here is a big benefit.

consil left a reply on Using A String Primary Key • 2 months ago

Firstly, I have tried the $incrementing thing, and that only tells Laravel not to try to add an incrementing value when creating an record, I'm not creating anything here - these are read-only (a great package michaelachrisco/readonly makes that dead easy).

Secondly, this cannot be a PHP thing. This is an eloquent model. What gets selected from the database is what the query in the database returns. It is not as though ALL records are selected then sifted out by PHP.

If I run this query through MySQL Workbench:

select id, first_name from users where id = 18;
// Brings back: 18af8e5b-97ce-b26d-9037-xxxxxxxxxxxx    Albe

then it will return a row with the id `'18123'. MySQL is (incorrectly IMO) casting the IDs it is querying over to a number before doing the comparison, and getting the same result as PHP. Maybe there is a database option I can set to turn it off.

Other people have found this too: https://stackoverflow.com/questions/33543671/mysql-automatic-string-to-integer-casting-in-where-clause and it looks like it has been around for a long time. If I cannot turn off this feature in MySQL, then eloquent needs to protect the database by always passing in a number to the id field, if only I could somehow tell it to.

consil started a new conversation Using A String Primary Key • 2 months ago

I am selecting model instances from a table that uses UUIDs as primary keys. That works fine when I pass a string into find() to fetch the model instance.

MyModel::find('18af8e5b-97ce-b26d-9037-4e6e0fb82f20');
// Returns my instance.

MyModel::find('18');
// Rightly returns null.

MyModel::find(18);
// Returns my model instance again. Yikes!

It seems that eloquent is passing the data type provided into the query, and MySQL is doing some casting (a-la-PHP!) to return a row that it should not return.

How can I set up the model to make sure find() will always do a string search on the primary key, regardless of what has been passed in.

As a bonus, this returns the first row it finds:

MyModel::find(0);

No, eloquent, naughty! How do I whip it into shape? None of the following on the model work:

public $incrementing = false;
protected $casts = [
    'id' => 'string',
];
protected $keyType = 'string';

So is my only option to override static find()?

24th May, 2018

consil left a reply on JWT Authentication, Authorisation And Session, Without A User Table/model • 2 months ago

What a brilliant set of slides (you can tell Luís personally ;-)

Almost didn't need the presentation, but it helps: https://www.youtube.com/watch?v=p2tItlr_3QI

23rd May, 2018

consil left a reply on JWT Authentication, Authorisation And Session, Without A User Table/model • 2 months ago

Hi @bobbybouwmann thanks for the tips.

The JWT token will contain an ID for some resources the [human] user will interact with. Those resources will have been pushed into the application via API from another system - the system that sent the user there in the first place, armed with the JWT.

What that user does will not be linked to any user account on the application. It's kind of like they get a temporary access to a locker in a locker room, and can leave stuff in it, take stuff out, and eat any snacks they find in it. Once they close the locker door, or the key self-destructs after 30 minutes, the locker is taken away and the user cannot see or do anything there again. So yes, the user does store state - they change stuff, authorise actions etc.

All the locker knows, is that the person with their browser has a key that is valid and working right now, so they have the authority to do what they like with the contents.

From what you are saying, it seems that tymon/jwt-auth is probably overkill for what I need, and I probably just need the underlying lcobucci/jwt and perhaps some certificate support, and a relatively simple guard that just checks the JWT validity on every page access (and provides details of the resource authorisation). Unraveling the bits of tymon/jwt-auth I don't need may turn out to be more involved. Would that be a fair assessment?

Do you know of any examples that show how a JWT would be used in a non-one page application? I'm guessing the token could just go into a cookie as the easiest way to handle it.

22nd May, 2018

consil started a new conversation JWT Authentication, Authorisation And Session, Without A User Table/model • 2 months ago

As usual, I can't find a channel that seems relevant to my question, so hopefully this channel is okay.

Now, I need to build a simple application, without users, but supporting JWT authentication and authorisation. There will be some simple GUI actions the user can perform, linked to some details in the JWT payment.

SInce the application has no users, it also has no login pages. The JWT will be generated by an external application and the user thrown over to this application with the token to do their stuff. I guess the session will also need to be based on the JWT too - I can't see a need for a second way to handle the user sessions while the JWT is available, with all the details the application needs to give the user access to carry out a few tasks.

Are there any packages that can handle this at a high enough level to just be configurable? Or do I need to build my own gates/auth classes to do this, based on low-level JWT packages? The tymon/jwt-auth package all seems to focus around users logging in, but then I'm not sure what it actually handles after that, so I'm not sure if it fits this use-case or not.

26th April, 2018

consil left a reply on Laravel Does Not Validate Queue Data • 3 months ago

Just a note about Azure queues, and I'm not sure if this is how other queuing systems work:

It looks like when you take a message from an Azure queue, it gets marked as locked, and is invisible to other workers. You then process the message, and when you have finished, you tell Azure whether you want that message permanently removed or not. The idea is that if a job fails for an unexpected reason while "holding the message" then that message is not lost. If the job dies, then Azure will put the message back onto the queue withing 30 minutes, assuming it still needs to be processed. That is reasonable, and puts the queue messages at the heart of the system - each message is assumed to be very important and cannot be lost.

Now, the Laravel Azure queue driver tells Azure that it has processed the queue message when it finishes. It does not matter whether the job "failed" and has been put on the failed table, or finished successfully - the point is that the queue worker has taken ownership for that message and moved it on to the next place of rest.

The big problem comes when the queue worker (artisan queue:work) dies unexpectedly. That's not the job itself, but the worker that listens to the queue and runs the jobs. That is where exceptions are not being handled. If that worker fails, unexpectedly, its end events are never run and the jobs are left in an intermediate state. Sometimes the queue message is left hanging, only to be put back on by Azure in half an hour. Sometimes it's put back on immediately, but the job failed count is not incremented, so it loops retrying forever, and very rapidly.

consil started a new conversation Laravel Does Not Validate Queue Data • 3 months ago

I'm not sure where to post this, and not quite sure what to do about it.. The bottom line is that Laravel takes data from the queues and handles it as though those queue messages are valid, correctly structured, contain job objects that can be unserialized without errors, and basically does a poor job of handling any kind of invalid data that may end up on the queue.

I am using Azure queues, and occasionally Azure will put its own message onto the queue, or it looks that way. I suspect it is the Microsoft library that acts like a message has been put onto the queue when connections time out, but the end result is that the MS Azure Queue Storage library tells Laravel, "here is a message". That message contains some timeout error details and a bit of XML. Laravel cannot cope with that, and ends up throwing all sorts of exceptions, instead of just failing the job and throwing it onto the failed heap.

I had a job put onto the queue for a job class that does not exist (it was another Laravel instance that put it onto the wrong queue). Again, Laravel tries unserializing that job payload, which throws an exception that is not handled in any sensible way. The job exits, but does not call its failed() method, so the queue worker does not know it has ended, the queue message remains locked in Azure for the half an hour that Azure will allow a process to lock it, then the message gets dumped back onto the queue by Azure and the process starts again - an error every half an hour, no completed jobs in that time, no failed jobs registered either, and messages checked out of the Azure queue and so not even visible through other means for debugging.

Then I thought, what if I just throw "xxx" onto the queue. Surely that will be handled correctly? On no, it throws Laravel into an endless loop, trying to process the "xxx" job about 50 times a second, failing each time, and retrying immediately. Again, it is not handled as a failed job, and so no retry count is kept.

So, IMO Laravel queue handling needs some serious fixes here. It is just the points at which it assumes the job details it has been given by an outside source (Azure, memory-based queues, Aamazon SQS etc.) are correctly formatted, valid, safe, and complete. Just one byte out and a production system can go into an overdrive endless loop, or just lose jobs completely.

Is this a common problem? Are there any issues that anyone here is aware of that covers these types of problems that I can add to? This is out-of-the-box Laravel 5.6 behaviour, and it's leaving me a bit nervous. When queues work, they are great, but when something goes wrong, they seem to be able to bring the system down.

20th April, 2018

consil left a reply on How Do I Add A Message To The List Detecting A Closed Database Connection? • 3 months ago

I've added the two "connection lost" messages I've seen to a PR, so hopefully that will go through at some point (hopefully to laravel 5.6).

I also found some strange connection issues with the Azure queue, and that does not have an auto-reconnect facility built in. When the connection to that drops (which happens apparently randomly) it sends an XML message to the Azure Queue library, which then passes it on to the queue worker as though it were a queued message (doh!). This starts a job with that data (doh!) which promptly dies as it attempts to JSON decode the message (doh!) and Laravel does not know it has died since it does not do so cleanly (doh!). The artisan queue worker then just hangs around for ten minutes, blocking doing nothing but waiting for the child process to finish (a child process that is already dead), before issuing an error telling me the job took too long, and then tries to read the next message from the queue - which is a DEAD LINK. DOH!

The result is, I'm telling the queue worker to restart every ten minutes (artisan queue:restart). Hopefully that will keep things up and running.

So, all around - bugs in Laravel, bugs in the MS queue handling composer package, bugs in the Azure network that is up and down like a yoyo. What a fun week :-(

18th April, 2018

consil left a reply on How Do I Add A Message To The List Detecting A Closed Database Connection? • 4 months ago

Yeah, I tried it, but it's using the core trait and not mine. Issue raised on the framework here, which I'll link to the PR:

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

Thanks for the tips.

consil left a reply on How Do I Add A Message To The List Detecting A Closed Database Connection? • 4 months ago

I've never dived into the ioc container like that before. The Illuminate\Database\Connections class is very specific about needing this trait, and I would have thought the composer autoloader would just load the original every time. Or does the ioc extend the autoloader so that scripts can be overridden?

consil left a reply on How Do I Add A Message To The List Detecting A Closed Database Connection? • 4 months ago

Oh, and does this mean Laravel only auto-reconnects database connections in English locales? Is everyone outside US/UK just hacking a workaround of some sort?

consil started a new conversation How Do I Add A Message To The List Detecting A Closed Database Connection? • 4 months ago

So, I'm using long-running queue workers and an Azure SQL Server database. On the whole it works great, except for when the workers have not processed a job in some time.

What happens is the database connection drops after some time unused, as you would expect, but Laravel does not detect this. Instead it blindly keeps trying to use the dead database connection for every new job that is dispatched.

Azure SQL Server PDO returns this error when the connection times out:

ERROR: SQLSTATE[08S02]: [Microsoft][ODBC Driver 13 for SQL Server]SMux Provider: Physical connection is not usable [xFFFFFFFF].

It seems that Laravel detects a database connection has been lost by comparing this message with a list of messages (all in English!) that it holds here in Illuminate\Database\DetectsLostConnections:

https://github.com/illuminate/database/blob/71f75f4d1d7ffaa33da4bde0da6f246ed7741479/DetectsLostConnections.php#L10

So here is my quandary: how do I fix this? If I add the Azure message "Physical connection is not usable" to this list, then my long-running jobs have a happy time. I can submit this as a PR, so other people's long-running jobs can be in the happy place too. But what do I do in the meantime? What do I need to configure/inject/extend/whatever to get more messages into this array? Overriding that one script in the autoloader is one way, but it's not very update-safe.

Thanks.

11th April, 2018

consil left a reply on Simple Homestead Without Messing With Vagrant? • 4 months ago

It doesn't like symbolic links - "protocol error" :-( I think this is because the filesystem is on the host machine (Windows) and shared with the VM. If the filesystem were on VM and shared with the host machine, this would not be a problem.

But I guess Homestead is configured with the idea that the host OS is always the true owner of the source code and not the VM, which can be destroyed and rebuild at any time. That's fine when the host machine happens to run a form of Unix, but not if it is running Windows.

I use symbolic links a lot when editing a composer package in an application. Well, composer sets up the symbolic links for me when I point the "path repository" for a package at the git clone for the package. Maybe there are other ways to develop a package withing an application that I could explore.

consil left a reply on Simple Homestead Without Messages With Vagrant? • 4 months ago

Okay, thanks for the explanation, I'll give it a go. It will be interesting to see how symbolic links work on Windows and then across the share when I'm editing a package.

consil left a reply on Simple Homestead Without Messages With Vagrant? • 4 months ago

I think it's about the source code being on my local machine. I'm not sure why it would be there. I'd like the code to be managed in the VM, with Linux properties, permissions, symbolic links, git command line in bash etc. That's kind of where I'm coming from.

consil started a new conversation Simple Homestead Without Messages With Vagrant? • 4 months ago

This is my understanding, so correct me if I am wrong: the Homestead VM can be built from scratch using Vagrant. This means your host machine must have Vagrant installed and stack of other stuff to support it.

What I am looking for, is a VM image that I can run in VirtualBox (on Windows 7) that contains the Homestead "stuff", and that does not involve messing around with Vagrant. Is there such a VM image available anywhere?

If there is no VM for this, then do I need to install (headless) Debian in the VirtualBox from an ISO then run some kind of Homestead provisioning in it to give me the VM I need? I have other server tools to install on top of that.

Is this a sensible thing to do, or is every VM install these days built locally using Vagrant, and something I cannot really avoid? I've just been going back and forth all day between incredibly complex sets of instructions. It feels like I want to buy a car, but have to set up a rubber and glass factory to manufacture windows and wheels before I can get my hands on a car. I just want the car :-)

10th April, 2018

consil left a reply on Can I Monitor Supervisord From Within Laravel? • 4 months ago

I'll explore this a little more over the weekend, and post back here with what I'm going to do about it. If it's a new wrapper package, then it will be open for additions/suggestions. I think all the pieces are there, some maybe needing a fresh coat of paint, but otherwise solid.

consil left a reply on Can I Monitor Supervisord From Within Laravel? • 4 months ago

@Helmchen horizon is pretty much just for redis at the moment. I'm using azure to service the queues, so redis isn't even in the picture here.

php artisan queue:restart is preferable to just killing the process, since it signals the process to die as soon as it has finished its current job. Ideally you don't want to kill a worker while it is in the middle of a job.

I've found a package that talks to supervisord really well (it worked for me straight away without any effort) so I might just create a Laravel wrapper for that (to handle the service provider and config settings) assuming it has not already been done. It uses XML-RPC to talk to supervisord, and get statuses, logs, process IDs, tell it to restart or signal processes etc.

Remember, this is just the supervisor. It sits there doing nothing for 99.999% of the time, just keeping an eye on the artisan processes, restarting them if they die. I could tell it to restart a process at any time, and would need to do that if any new code is released. However, I probably don't want to do that, as it will involve the jobs being killed. Instead I want to send the artisan worker(s) an event (something this package supports) to tell the artisan worker to die when it is good and ready. Then supervisord will kick in after noticing it gone and restart it.

Monitoring what is happening on the queues is another level, and there are good laravel packages to help with that. I've not worked out how to throw a failed job back on its original queue via the web interface though (it kind of works, then ends up trying to run a CLI command by invoking the full php executable path, which is protected since it is outside the permitted web root. But that's another problem for another day.

consil left a reply on Can I Monitor Suporvisprd From Within Laravel? • 4 months ago

Just found this:

https://github.com/yzalis/Supervisor

Works like a dream, though has a big stack of zend dependencies. It probably needs a little expansion to cover some of the functions it does not cover yet (e.g. it can restart all processes, but not restart an individual process).

consil left a reply on Can I Monitor Suporvisprd From Within Laravel? • 4 months ago

Just found this standalone application written in PHP, which shows me it can be done:

https://github.com/mlazarov/supervisord-monitor

I guess the guts of that application need to be ripped out into a separate package, so the communication with supervisord and the front end can be separated.

consil started a new conversation Can I Monitor Suporvisprd From Within Laravel? • 4 months ago

supervisord comes with a simple process monitor that serves pages on port 9100 from the server. Processes can be viewed, restarted, reloaded, logs read and tailed etc. from there, which is handy.

Does it also serve this underlying data and services through an API of some sort? Is there a library that Laravel can use to access the supervisord status, maybe view config and logs, and perhaps allow processes to be restarted?

I've not found anything to fit this requirement, but also not found anyone else asking for this. So I guess it's up in lights and I can't see it, or everyone is happy with the admin page that supervisord serves up now.

Anyone know of any way to do this?

27th March, 2018

consil left a reply on Any Examples Of A Custom Log Handler/driver/channel For Laravel 5.6? • 4 months ago

Thanks Martin, that certainly looks promising.

I wasn't going to write the log in a queue, as the log message links to multiple models too. With the models created in transactions (with the messages) I couldn't be sure the model instances exist in the queue worker database session by the time it runs. The queue worker would fail as it tries to unserialize the models. Your point about the timestamps is a good one to remember if I do end up going down that route.

I'm not logging everything through this channel, just some key blocks of processing, where I can log my database logger with contextual links, and to the standard file logger (as a backup because transactions). I'm hoping that using a channel means I can change my mind later about how it works without revisiting code all over the place.

consil started a new conversation Any Examples Of A Custom Log Handler/driver/channel For Laravel 5.6? • 4 months ago

I would like to add a logging channel that can log messages to a completely custom channel (it's in the database, and links the message to model instances in the $context array).

I'm unsure just where I need to hook into Laravel to do this. I would like as much of the code as possible to go into a package, though appreciate at least an entry in config/logging.php is needed.

What I don't understand is what else needs to be created, and how to tell Laravel about it. I guess I need a channel. Then that channel would need a driver. Is that a monolog driver? Or a custom driver? If it is a monolog driver, then do I create something else that hooks into monolog, some kind of handler? Or a writer? Or something else?

Any pointers would be appreciated.

19th March, 2018

consil left a reply on Update Child Records • 5 months ago

@phildawson from what I can see, and from some experimentation, this updates the child records directly in the database.

However, this does not update via the eloquent models, and that means observer events will not fire. If that is important in your application (and it is to me), then the technique that OP provided is the way to go. Another way to handle it is to hand the looping over to the collection:

$user->renewRecords->each(function ($rr) {
    $rr->foo = 'bar';
    $rr->save();
 });

I'm adding this, because the two approaches listed in this thread above are not equivalent, but depending on your needs, either approach may work for you, or may not.

14th March, 2018

consil started a new conversation A Job Choosing Its Default Queue • 5 months ago

I would like to set some jobs to dispatch to specific queues. Rather than spread the queue names around the various places where the jobs are dispatched, I would like the jobs to control the queue they are dispatched to for themselves.

From what I can see, a dispatchable job will have a $queue property, and the queue can be hard-coded there:

class MtJob implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
    
    protected $queue = 'my-queue-name';
    ....
}

If the queue name is handled dynamically, such as in a config file, then this can be set in the constructor of the job:

public function __construct(Thing $thingToProcessInJob)
{
    ...
    $this->onQueue(config('config.path.to.my.queue.name'));
}

This seems to work, and I can dispatch the job without having to specify a queue. If i do specify a queue when dispatching, then that default queue will be over-ridden.

So, does this seem right? I've not found this technique documented, or anyone else asking how to set a default queue for a job, so I'm unsure whether I'm missing something.

What's more, examples like this are in the docs: ProcessPodcast::dispatch($podcast); and ProcessPodcast::dispatch($podcast)->onQueue('some-queue');. I don't understand how that works. If dispatch dispatches, then surely the onQueue() afterwards is too late, because it is already dispatched and in the queue? Unless this is some kind of "dispatch promise" that does not actually added to the queue until later in the request? I'm curious about how that works.

12th March, 2018

consil left a reply on Having Trouble To Set Up Auto-discovery For A Facade • 5 months ago

I tried this to reset the cached aliases that I changed in a package I was developing. It kept on picking up the old alias name, no matter what I did, and even when there was no trace of the old alias name in any PHP or JSON file in the application.

Turned it out it was an artisan queue:work process that was holding onto the old settings. This is on PHP 7.2, which does some fancy inter-process cacheing of data automatically. I can not see how that process could have affected the composer update otherwise. Once I stopped that queue worker, the clear+update worked a treat.

Just adding this in case anyone else is sat there scratching their head for an hour over why changes aren't being recognised.

8th March, 2018

consil left a reply on Does Anyone Have Examples Of Bootstrap Popover With Laravel Blade • 5 months ago

The answer to my previous question was that popover is built into jQuery. It wasn't working for me, and the reason was that I was using it in dynamic content, in a dataTable. To fix this, instead of binding the popover to each item on the page (items which may then be added dynamically to the pager later, and miss their chance to bind) it is bound to the body instead (or some other wrapping element if you want to contain it to a specific region of the page). The selector option then listens out for hover triggers against matching selectors:

    <script>
        $('body').popover({
            html: true,
            placement: 'auto left',
            trigger: 'hover',
            selector: '[data-toggle="popover"]'
        });
    </script>

The data-trigger attribute on the hover-over elements seems a little redundant, as it is also in the javascript options. So I think there is some other subtle setting that I'm missing.

consil left a reply on Does Anyone Have Examples Of Bootstrap Popover With Laravel Blade • 5 months ago

Just for context, where does this "popover" come from? Is it a jQuery plugin that needs installing? Built into jQuery perhaps?

2nd March, 2018

consil left a reply on Using Views For Columns In Datatables • 5 months ago

Just to follow up on the answer from @Voyowsky, this answer works very well and it pretty neat. It is not documented very well (like much of the Laravel DataTables package) but this will call up the view. It includes package-based views, such as 'MyPackage::view.path.in.package'.

The parameters passed to the view will be the columns selected in the query, so an App\User query would include {{ $id }} and {{ $name }} variables, for example.

26th February, 2018

consil left a reply on Which Laravel Admin Panel Should I Use? • 5 months ago

@royduin how did you get on with the z-song admin? I've narrowed down to https://github.com/z-song/laravel-admin and http://labs.infyom.com/laravelgenerator/ - both look very well written, well documented and well thought out. They both install as packages, [can be configured to] keep themselves in their own areas rather than blatting all over your application space.

The infyom labs version has an edge on reverse-engineering existing models and offering additional features as plugins, while the z-song admin seems overall a lot smoother to use.

Do I toss a die?

19th February, 2018

consil left a reply on Log Rotate • 6 months ago

I'm late here, but there is no reason why a symbolic link could not be used to point laravel.log to the latest named log file when it gets created. That should involve minimum effort for a handy feature.

18th February, 2018

consil left a reply on Where Is The Best Place To Put Queued Job Dispatching? • 6 months ago

Here is how I am handling this for now.

In my application I have a core package (my application is written almost entirely as a bunch of packages). The core package contains all the dependencies on other packages in the application, so it knows all the models it needs to observe are present.

That core package has an Observers directory with an observer class for each model I want to observe. The observer classes are all registered in the boot() method of my core package provider.

use Vendor\Core\Observers\ModelAObserver;
use Vendor\Core\Observers\ModelBObserver;

use Vendor\NonCoreA\ModelA;
use Vendor\NonCoreB\ModelB;

class CoreServiceProvider extends ServiceProvider
{
    public function boot()
    {
        ModelA::observe(ModelAObserver::class);
        ModelB::observe(ModelBObserver::class);
    }
}

These observers fire off jobs to the queues when they see changes they are interested in. The observer classes are all in one place, and NOT in the framework (they are in a package, which should make upgrades much easier later on), so easy to find and manage. I still wonder whether I need an "observer of the observers" to monitor each time they are triggered by an event, but I can work on that later.

consil started a new conversation Where Is The Best Place To Put Queued Job Dispatching? • 6 months ago

I have an application that processes data in a fairly complex way, with data coming in from a number of sources, and being updated from various triggers.

I have a bunch of jobs that should be despatched on certain triggers, such as creation of a model instance, or changing of a status in a model instance.

What I'm not sure, is the nest place to put the code to handle this dispatching. It could go into the eloquent models, and be scattered around the application that way, This would make it more difficult to see where all the despatching is.

It could go in some central place, where it monitors all events for all eloquent models, and makes decisions on what jobs need to be dispatched. This feels a little messy.

This feels to me like it is a workflow thing. Is this the kind of problem that a Laravel workflow package would handle? Are there any recommendations I could look into? I like the idea of being able to monitor all the triggers and what gets dispatched in one place, so I can see what is happening, and defining these rules through data feels like a good way to do it.

Any oher tips?

15th February, 2018

consil left a reply on How Properly Use The LockForUpdate() Method? • 6 months ago

It makes sense to wrap the lock in a transaction, since I assume you are locking a record to do several operations related to it, so they would be in the same transaction. It may work the same if the lock is done immediately before the transaction is started, but any other statements that follow it will (by default) auto-commit and your lock will be lost.

14th February, 2018

consil left a reply on Refresh And Locka A Model • 6 months ago

I think my solution will be to fetch a completely new instance $modelDummy, locking in the process. Ignore that instance from that point on. Its only purpose is to grab the lock.

Then fresh() the original $model, knowing that will then be refreshed from the database against a locked row that I know won't be changed until the transaction is released.

consil started a new conversation Refresh And Locka A Model • 6 months ago

I would like to refresh a model and lock it for updates at the same time. The reason is to make sure we have the latest model data in memory, and that nothing else can update it while we are working with it in the transaction.

The clincher is that I would like to avoid creating a new instance of the model, so that when we come out of the transaction, the model is up-to-date.

This will refresh a model and lock it by loading a new instance:

$model = $model->lockForUpdate()->find($model->id);

This will refresh a model without creating a new instance:

$model->fresh();

What I can't seem to see, is a way to mix the two together. I had hoped this would work, but it doesn't:

$model->lockForUpdate()->fresh();

I'm using this in a transaction like this:

echo $model->status; // NEW

DB::transaction(function () use ($model) {
    $model = $model->lockForUpdate()->find($model->id);
    
    // Do some transactional stuff here.
    
    $model->status = 'SUCCESS';
    $model->save();
});

echo $model->status; // NEW - we get the old model still

I would like at the end for $model to have the new status, but that status change was in a different instance. Any clues how I can fix that first line in the transaction?

Edit Your Profile
Update

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