I'm developing an application in Cake that heavily interacts with the filesystem. The basic idea is to monitor and index a folder and it's subfolders and files and save meta data for each file in the database. It's working fine so far, but now I got kind of a problem in understanding the MVC mechanics.
I got this heavy FilesController with a lot of functions checking if a file is up-to-date or if it has moved, updating the database entries and so on... Now I want to call some of this actions from a shell/cronjob and I want to call them in the browser too.
I've heard a lot of people complaining about importing controllers in shells and I think I got the idea why this is a bad idea. But now I want to use the same code that interacts with the FileModel directly in a shell and in a controller. Where to put it? What is best practice in this situation? In a component, loading the model? In the controller, importing it in the shell?
Thanks for your help in advance <3
I got this heavy FilesController with a lot of functions checking if a file is up-to-date or if it has moved,
Wrong place, heavy controllers are definitely wrong. You want fat models, skinny controllers. If there is logic that extracts meta data I probably would put it into app/Utility/FileMetaData or app/Lib/FileMetaData.php and make it a new class. Depending on what it does you might extend the core class Folder or File.
The processing logic for the meta data and reading the folder should go into a model. The model can be used from the shell like in a controller by using the $uses property with an array of models.
To instanitate that class I would use a helper method (I don't mean a view helper by this!) in the model like getMetaDataReader() that returns the instance. The reason for this is to be able to mock the result of that method call in an unit test. Also, if you ever change the class or constructor args you'll have to change only a single place.
Controllers are clearly wrong in shells. There is no request to deal with. Sure technically you can do the stunt and instantiate them there but it is just wrong and doesn't make any sense. If you think you have to or "need" to do so, something is wrong with your application architecture.
You might want to take a look at my FileStorage plugin as well. You can implement an event listener there and when storing a file have the listener automatically process the the meta data.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With