First off, this is a fine piece of work.
Second, there are lessons to be learned that will take you to the next level.
First, whenever you find yourself writing 100% getters for every setter, consider that you're not actually doing encapsulation. One of the few bona fide reasons for this would be at-setting validation, but this app generally does validation after all of the parameters have been set. It's usually better to just make it a "dumb DTO" and use public properties everywhere. Here is my article on this topic: [PHPU] The Public Properties Debate.
Second, this PR is a great example of how so many developers think about Encapsulation in general. Too many of the lower-logic steps are exposed as public methods, compelling the end-developer to construct what is in effect overly complex recipes to do certain actions, recipes that would be much better generalized in the service classes that should provide them.
For instance