Complex classes like FileUploadReceiver 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 FileUploadReceiver, and based on these observations, apply Extract Interface, too.
| 1 | <?php |
||
| 32 | trait FileUploadReceiver |
||
| 33 | { |
||
| 34 | use UploadReceiver; |
||
| 35 | |||
| 36 | /** |
||
| 37 | * Flag to automatically determine and save a has_one-relationship |
||
| 38 | * on the saved record (e.g. a "Player" has_one "PlayerImage" would |
||
| 39 | * trigger saving the ID of newly created file into "PlayerImageID" |
||
| 40 | * on the record). |
||
| 41 | * |
||
| 42 | * @var boolean |
||
| 43 | */ |
||
| 44 | public $relationAutoSetting = true; |
||
| 45 | |||
| 46 | /** |
||
| 47 | * Parent data record. Will be infered from parent form or controller if blank. |
||
| 48 | * |
||
| 49 | * @var DataObject |
||
| 50 | */ |
||
| 51 | protected $record; |
||
| 52 | |||
| 53 | /** |
||
| 54 | * Items loaded into this field. May be a RelationList, or any other SS_List |
||
| 55 | * |
||
| 56 | * @var SS_List |
||
| 57 | */ |
||
| 58 | protected $items; |
||
| 59 | |||
| 60 | protected function constructFileUploadReceiver() |
||
| 64 | |||
| 65 | |||
| 66 | /** |
||
| 67 | * Force a record to be used as "Parent" for uploaded Files (eg a Page with a has_one to File) |
||
| 68 | * |
||
| 69 | * @param DataObject $record |
||
| 70 | * @return $this |
||
| 71 | */ |
||
| 72 | public function setRecord($record) |
||
| 77 | /** |
||
| 78 | * Get the record to use as "Parent" for uploaded Files (eg a Page with a has_one to File) If none is set, it will |
||
| 79 | * use Form->getRecord() or Form->Controller()->data() |
||
| 80 | * |
||
| 81 | * @return DataObject |
||
| 82 | */ |
||
| 83 | public function getRecord() |
||
| 112 | |||
| 113 | |||
| 114 | /** |
||
| 115 | * Loads the related record values into this field. This can be uploaded |
||
| 116 | * in one of three ways: |
||
| 117 | * |
||
| 118 | * - By passing in a list of file IDs in the $value parameter (an array with a single |
||
| 119 | * key 'Files', with the value being the actual array of IDs). |
||
| 120 | * - By passing in an explicit list of File objects in the $record parameter, and |
||
| 121 | * leaving $value blank. |
||
| 122 | * - By passing in a dataobject in the $record parameter, from which file objects |
||
| 123 | * will be extracting using the field name as the relation field. |
||
| 124 | * |
||
| 125 | * Each of these methods will update both the items (list of File objects) and the |
||
| 126 | * field value (list of file ID values). |
||
| 127 | * |
||
| 128 | * @param array $value Array of submitted form data, if submitting from a form |
||
| 129 | * @param array|DataObject|SS_List $record Full source record, either as a DataObject, |
||
| 130 | * SS_List of items, or an array of submitted form data |
||
| 131 | * @return $this Self reference |
||
| 132 | * @throws ValidationException |
||
| 133 | */ |
||
| 134 | public function setValue($value, $record = null) |
||
| 202 | |||
| 203 | /** |
||
| 204 | * Sets the items assigned to this field as an SS_List of File objects. |
||
| 205 | * Calling setItems will also update the value of this field, as well as |
||
| 206 | * updating the internal list of File items. |
||
| 207 | * |
||
| 208 | * @param SS_List $items |
||
| 209 | * @return $this self reference |
||
| 210 | */ |
||
| 211 | public function setItems(SS_List $items) |
||
| 215 | |||
| 216 | /** |
||
| 217 | * Retrieves the current list of files |
||
| 218 | * |
||
| 219 | * @return SS_List|File[] |
||
| 220 | */ |
||
| 221 | public function getItems() |
||
| 225 | |||
| 226 | /** |
||
| 227 | * Retrieves the list of selected file IDs |
||
| 228 | * |
||
| 229 | * @return array |
||
| 230 | */ |
||
| 231 | public function getItemIDs() |
||
| 236 | |||
| 237 | public function Value() |
||
| 242 | |||
| 243 | /** |
||
| 244 | * @param DataObject|DataObjectInterface $record |
||
| 245 | * @return $this |
||
| 246 | */ |
||
| 247 | public function saveInto(DataObjectInterface $record) |
||
| 277 | |||
| 278 | /** |
||
| 279 | * Loads the temporary file data into a File object |
||
| 280 | * |
||
| 281 | * @param array $tmpFile Temporary file data |
||
| 282 | * @param string $error Error message |
||
| 283 | * @return AssetContainer File object, or null if error |
||
| 284 | */ |
||
| 285 | protected function saveTemporaryFile($tmpFile, &$error = null) |
||
| 335 | |||
| 336 | /** |
||
| 337 | * Gets the foreign class that needs to be created, or 'File' as default if there |
||
| 338 | * is no relationship, or it cannot be determined. |
||
| 339 | * |
||
| 340 | * @param string $default Default value to return if no value could be calculated |
||
| 341 | * @return string Foreign class name. |
||
| 342 | */ |
||
| 343 | public function getRelationAutosetClass($default = File::class) |
||
| 360 | |||
| 361 | /** |
||
| 362 | * Set if relation can be automatically assigned to the underlying dataobject |
||
| 363 | * |
||
| 364 | * @param bool $auto |
||
| 365 | * @return $this |
||
| 366 | */ |
||
| 367 | public function setRelationAutoSetting($auto) |
||
| 372 | |||
| 373 | /** |
||
| 374 | * Check if relation can be automatically assigned to the underlying dataobject |
||
| 375 | * |
||
| 376 | * @return bool |
||
| 377 | */ |
||
| 378 | public function getRelationAutoSetting() |
||
| 382 | |||
| 383 | /** |
||
| 384 | * Given an array of post variables, extract all temporary file data into an array |
||
| 385 | * |
||
| 386 | * @param array $postVars Array of posted form data |
||
| 387 | * @return array List of temporary file data |
||
| 388 | */ |
||
| 389 | protected function extractUploadedFileData($postVars) |
||
| 416 | } |
||
| 417 |
This check looks for methods that are used by a trait but not required by it.
To illustrate, let’s look at the following code example
The trait
Idableprovides a methodequalsIdthat in turn relies on the methodgetId(). If this method does not exist on a class mixing in this trait, the method will fail.Adding the
getId()as an abstract method to the trait will make sure it is available.