Skip to content

Instantly share code, notes, and snippets.

@borantula
Created January 14, 2017 21:24
Show Gist options
  • Select an option

  • Save borantula/8d1c3493ded37933aec96bdd77d08d00 to your computer and use it in GitHub Desktop.

Select an option

Save borantula/8d1c3493ded37933aec96bdd77d08d00 to your computer and use it in GitHub Desktop.
CakePHP Features Example
<?php
/**
* Components are tightly connected (or appears so) to the controllers
* and as the application grows bigger, some of the work is done other places
* like event listener classes, mailers, shell commands, custom project classes etc.
* When that happens this can lead to code duplication from your components to those places.
*
* On a CakePHP project we are working on we starting using a structure called Features (idea taken
* from a Laravel community), where we have a "Feature Runner" trait, and a feature class structure which
* only includes a constructor and handle public methods and run as in example. By adding use FeatureRunner to any class
* we can use those features anywhere in application. It is a basic class which uses ReflectionClass to run given feature with given
* arguments
*
* Two small examples:
* 1 - ProcessCampaignShortcodesFeature processes shortcodes of a mail template, like [FIRSTNAME] [LASTNAME] etc.
* I call this function mainly from EmailCampaignMailer but also called this from a controller where we can preview the content
* and later if I need this
* 2 - Create ICS file for an event for that user on a mail campaign. It is done in a mailer when we send confirmation,
* in a controller where user downloads and adds to calendar, also there a other features running in this feature, where a generic
* ics file is updated whenever the event is saved and this feature also working in an event listener
//in EmailCampaignMailer
//process shortcodes for email in content
$content = $this->runFeature(ProcessCampaignShortcodesFeature::class, compact('campaign', 'user'));
//creates an ics file for given user
$icsFile = $this->runFeature(CreateCampaignIcsFileFeature::class, compact('campaign', 'user'));
/**
* - With features it became easy to test smaller tasks (components are also easy of course, not comparing)
* - Not dependent to controller anymore, controllers are slimmer
* - Easy to document the project
*
* Of course I don't say this is certainly the way to go, but for us it was a way to go and worked so far. So in my opinion,
* instead of directing Components (which are under Controllers) for shared logic, something independent might be better.
*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment