I have an old Codeigniter project I am working on and I am trying to improve the codebase. Basically I am trying to decouple Codeigiter where I can and implement unit tests in the process.
Currently I am working on refactoring the User workflow: specifically adding or updating a User. As it stands, there is a controller method called "save" which handles everything including the following:
- check if username exists
- validate password
- update or insert User
- create a permission record (user can have many permissions)
- save User uploaded image to temp folder
- crop User uploaded image and save to temp folder
- upload cropped User image to S3 bucket
- update User with image
- redirect back to User index
As you can imagine, this controller is HUGE (and this is one of the more simple workflows in the app).
My biggest problem at the moment is being unable to test this due to all the coupling. I just have no idea where to start. I did a ton of reading in the last few weeks and here are my current thoughts:
- Create a service object which handles the whole process called UserSaveService. This would allow the controller to just call the service method and handle the redirects and flash errors/successes. This service would handle updating/inserting the user using the Codeigniter ActiveRecord models.
- Create objects (command object?) for each major component
- UploadImage: accepts a form name -> handles uploading image to temp folder -> returns a path of the uploaded image
- CropImage: accepts a path and crop dimensions -> crops the image and stores it in temp folder -> returns a path of the cropped image
- UploadToS3: accepts a file path (in this case a cropped image) and a bucket identifier -> uploads the file to S3 -> returns S3 url
My structure currently looks like:
application (codeigniter)
src
-- services
---- SaveUserService.php
-- commands
---- UploadImage.php
---- CropImage.php
---- UploadToS3.php
Does anyone have any recommendations? I would love to know what sort of patterns could be used here! I do realize this is a broad question so I hope it does not get closed, I just have no idea where else to take this kind of discussion. Thank you so much!