Complex classes like ExposeFields often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
While breaking up the class, it is a good idea to analyze how other classes use ExposeFields, and based on these observations, apply Extract Interface, too.
| 1 | <?php |
||
| 26 | class ExposeFields implements \Iterator |
||
| 27 | { |
||
| 28 | /** |
||
| 29 | * Current iteration position |
||
| 30 | * @var integer $position |
||
| 31 | */ |
||
| 32 | private $position = 0; |
||
| 33 | |||
| 34 | /** |
||
| 35 | * Expose fields to be used - multidimensional array |
||
| 36 | * @var array $fields |
||
| 37 | */ |
||
| 38 | private $fields; |
||
| 39 | |||
| 40 | /** |
||
| 41 | * The matched route |
||
| 42 | * @var RouteMetaData $route |
||
| 43 | */ |
||
| 44 | protected $route; |
||
| 45 | |||
| 46 | /** |
||
| 47 | * The route expose array - If explicitly set it overrides any default config settings |
||
| 48 | * @var array $route_expose |
||
| 49 | */ |
||
| 50 | protected $route_expose; |
||
| 51 | |||
| 52 | /** |
||
| 53 | * An array of classes that are registered on default expose depth. |
||
| 54 | * Temporary used during processExposeDepth to prevent you traversing up and down bi-directional relations |
||
| 55 | * @var array $registered_expose_classes ; |
||
| 56 | */ |
||
| 57 | protected $registered_expose_classes = []; |
||
| 58 | |||
| 59 | /** |
||
| 60 | * Create an instance of ExposeFields - use create() method |
||
| 61 | * @param RouteMetaData $route - requires a matched route |
||
| 62 | */ |
||
| 63 | 30 | private function __construct(RouteMetaData $route) |
|
| 64 | { |
||
| 65 | 30 | $this->route = $route; |
|
| 66 | 30 | $this->route_expose = $route->getExpose(); |
|
| 67 | 30 | } |
|
| 68 | |||
| 69 | /** |
||
| 70 | * Create an instance of ExposeFields |
||
| 71 | * @param RouteMetaData $route - requires a matched route |
||
| 72 | * @return \Drest\Query\ExposeFields |
||
| 73 | */ |
||
| 74 | 30 | public static function create(RouteMetaData $route) |
|
| 78 | |||
| 79 | /** |
||
| 80 | * Set the default exposure fields using the configured exposure depth |
||
| 81 | * @param EntityManagerRegistry $emr |
||
| 82 | * @param integer $exposureDepth |
||
| 83 | * @param integer $exposureRelationsFetchType |
||
| 84 | * @return ExposeFields $this object instance |
||
| 85 | */ |
||
| 86 | 22 | public function configureExposeDepth(EntityManagerRegistry $emr, $exposureDepth = 0, $exposureRelationsFetchType = null) |
|
| 102 | |||
| 103 | /** |
||
| 104 | * Configure the expose object to filter out fields that are not allowed to be use by the client. |
||
| 105 | * Unlike the configuring of the Pull request, this function will return the formatted array in a ResultSet object |
||
| 106 | * This is only applicable for a HTTP push (POST/PUT/PATCH) call |
||
| 107 | * @param array $pushed - the data push on the request |
||
| 108 | * @throws \Drest\DrestException |
||
| 109 | * @return \DrestCommon\ResultSet |
||
| 110 | * |
||
| 111 | * @todo: this should follow the same pattern as configurePullRequest |
||
| 112 | */ |
||
| 113 | 3 | public function configurePushRequest($pushed) |
|
| 125 | |||
| 126 | /** |
||
| 127 | * Filter out requested expose fields against what's allowed |
||
| 128 | * @param array $requested - The requested expose definition |
||
| 129 | * @param array $actual - current allowed expose definition |
||
| 130 | * @return array $request - The requested expose data with non-allowed data stripped off |
||
| 131 | */ |
||
| 132 | 3 | protected function filterPushExpose($requested, $actual) |
|
| 159 | |||
| 160 | |||
| 161 | /** |
||
| 162 | * Configure the expose object to filter out fields that have been explicitly requested by the client. |
||
| 163 | * This is only applicable for a HTTP pull (GET) call. For configuring |
||
| 164 | * @param array $requestOptions |
||
| 165 | * @param Request $request |
||
| 166 | * @return ExposeFields $this object instance |
||
| 167 | */ |
||
| 168 | 20 | public function configurePullRequest(array $requestOptions, Request $request) |
|
| 197 | |||
| 198 | |||
| 199 | /** |
||
| 200 | * An awesome solution was posted on (link below) to parse these using a regex |
||
| 201 | * http://stackoverflow.com/questions/16415558/regex-top-level-contents-from-a-string |
||
| 202 | * |
||
| 203 | * preg_match_all( |
||
| 204 | * '/(?<=\[) # Assert that the previous characters is a [ |
||
| 205 | * (?: # Match either... |
||
| 206 | * [^[\]]* # any number of characters except brackets |
||
| 207 | * | # or |
||
| 208 | * \[ # an opening bracket |
||
| 209 | * (?R) # containing a match of this very regex |
||
| 210 | * \] # followed by a closing bracket |
||
| 211 | * )* # Repeat as needed |
||
| 212 | * (?=\]) # Assert the next character is a ]/x', |
||
| 213 | * $string, $result, PREG_PATTERN_ORDER); |
||
| 214 | * |
||
| 215 | * @todo: Adapt the parser to use the regex above (will also need alter it to grab parent keys) |
||
| 216 | * |
||
| 217 | * Parses an expose string into an array |
||
| 218 | * Example: "username|email_address|profile[id|lastname|addresses[id]]|phone_numbers" |
||
| 219 | * @param string $string |
||
| 220 | * @return array $result |
||
| 221 | * @throws InvalidExposeFieldsException - if any syntax error occurs, or unable to parse the string |
||
| 222 | */ |
||
| 223 | 6 | protected function parseExposeString($string) |
|
| 235 | |||
| 236 | /** |
||
| 237 | * Recursively process the passed expose string |
||
| 238 | * @param string $string - the string to be processed |
||
| 239 | * @param array $results - passed by reference |
||
| 240 | * @throws InvalidExposeFieldsException if unable to correctly parse the square brackets. |
||
| 241 | */ |
||
| 242 | 5 | protected function recurseExposeString($string, &$results) |
|
| 265 | |||
| 266 | /** |
||
| 267 | * Get information on parsed (top-level) brackets |
||
| 268 | * @param string $string |
||
| 269 | * @return \stdClass $information contains parse information object containing a $parts array eg array( |
||
| 270 | * 'openBracket' => xx, - The position of the open bracket |
||
| 271 | * 'closeBracket' => xx - The position of the close bracket |
||
| 272 | * 'contents' => xx - The contents of the bracket |
||
| 273 | * 'tagName' => xx - The name of the accompanying tag |
||
| 274 | * ) |
||
| 275 | */ |
||
| 276 | 4 | private function parseStringParts($string) |
|
| 333 | |||
| 334 | /** |
||
| 335 | * Filter out requested expose fields against what's allowed |
||
| 336 | * @param array $requested - The requested expose definition - invalid / not allowed data is stripped off |
||
| 337 | * @param array $actual - current allowed expose definition |
||
| 338 | */ |
||
| 339 | 1 | protected function filterRequestedExpose(&$requested, &$actual) |
|
| 364 | |||
| 365 | /** |
||
| 366 | * Recursive function to generate default expose columns |
||
| 367 | * |
||
| 368 | * @param array $fields - array to be populated recursively (referenced) |
||
| 369 | * @param string $class - name of the class to process |
||
| 370 | * @param EntityManagerRegistry $emr - entity manager registry used to fetch class information |
||
| 371 | * @param integer $depth - maximum depth you want to travel through the relations |
||
| 372 | * @param integer $fetchType - The fetch type to be used |
||
| 373 | * @param integer|null $fetchType - The required fetch type of the relation |
||
| 374 | */ |
||
| 375 | 5 | protected function processExposeDepth(&$fields, $class, EntityManagerRegistry $emr, $depth = 0, $fetchType = null) |
|
| 402 | |||
| 403 | /** |
||
| 404 | * Get the expose fields |
||
| 405 | * @return array $fields |
||
| 406 | */ |
||
| 407 | 21 | public function toArray() |
|
| 415 | |||
| 416 | public function current() |
||
| 420 | |||
| 421 | public function key() |
||
| 425 | |||
| 426 | public function next() |
||
| 430 | |||
| 431 | public function rewind() |
||
| 435 | |||
| 436 | public function valid() |
||
| 440 | |||
| 441 | } |
||
| 442 |