Complex classes like ChangeSetItem 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 ChangeSetItem, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
29 | class ChangeSetItem extends DataObject implements Thumbnail |
||
30 | { |
||
31 | |||
32 | const EXPLICITLY = 'explicitly'; |
||
33 | |||
34 | const IMPLICITLY = 'implicitly'; |
||
35 | |||
36 | /** Represents an object deleted */ |
||
37 | const CHANGE_DELETED = 'deleted'; |
||
38 | |||
39 | /** Represents an object which was modified */ |
||
40 | const CHANGE_MODIFIED = 'modified'; |
||
41 | |||
42 | /** Represents an object added */ |
||
43 | const CHANGE_CREATED = 'created'; |
||
44 | |||
45 | /** Represents an object which hasn't been changed directly, but owns a modified many_many relationship. */ |
||
46 | //const CHANGE_MANYMANY = 'manymany'; |
||
|
|||
47 | |||
48 | private static $table_name = 'ChangeSetItem'; |
||
49 | |||
50 | /** |
||
51 | * Represents that an object has not yet been changed, but |
||
52 | * should be included in this changeset as soon as any changes exist |
||
53 | */ |
||
54 | const CHANGE_NONE = 'none'; |
||
55 | |||
56 | private static $db = array( |
||
57 | 'VersionBefore' => 'Int', |
||
58 | 'VersionAfter' => 'Int', |
||
59 | 'Added' => "Enum('explicitly, implicitly', 'implicitly')" |
||
60 | ); |
||
61 | |||
62 | private static $has_one = array( |
||
63 | 'ChangeSet' => 'SilverStripe\ORM\Versioning\ChangeSet', |
||
64 | 'Object' => 'SilverStripe\ORM\DataObject', |
||
65 | ); |
||
66 | |||
67 | private static $many_many = array( |
||
68 | 'ReferencedBy' => 'SilverStripe\ORM\Versioning\ChangeSetItem' |
||
69 | ); |
||
70 | |||
71 | private static $belongs_many_many = array( |
||
72 | 'References' => 'ChangeSetItem.ReferencedBy' |
||
73 | ); |
||
74 | |||
75 | private static $indexes = array( |
||
76 | 'ObjectUniquePerChangeSet' => array( |
||
77 | 'type' => 'unique', |
||
78 | 'value' => '"ObjectID", "ObjectClass", "ChangeSetID"' |
||
79 | ) |
||
80 | ); |
||
81 | |||
82 | public function onBeforeWrite() |
||
88 | |||
89 | public function getTitle() |
||
98 | |||
99 | /** |
||
100 | * Get a thumbnail for this object |
||
101 | * |
||
102 | * @param int $width Preferred width of the thumbnail |
||
103 | * @param int $height Preferred height of the thumbnail |
||
104 | * @return string URL to the thumbnail, if available |
||
105 | */ |
||
106 | public function ThumbnailURL($width, $height) |
||
114 | |||
115 | /** |
||
116 | * Get the type of change: none, created, deleted, modified, manymany |
||
117 | * @return string |
||
118 | * @throws UnexpectedDataException |
||
119 | */ |
||
120 | public function getChangeType() |
||
156 | |||
157 | /** |
||
158 | * Find version of this object in the given stage |
||
159 | * |
||
160 | * @param string $stage |
||
161 | * @return DataObject|Versioned |
||
162 | * @throws UnexpectedDataException |
||
163 | */ |
||
164 | protected function getObjectInStage($stage) |
||
172 | |||
173 | /** |
||
174 | * Find latest version of this object |
||
175 | * @return DataObject|Versioned |
||
176 | * @throws UnexpectedDataException |
||
177 | */ |
||
178 | protected function getObjectLatestVersion() |
||
186 | |||
187 | /** |
||
188 | * Get all implicit objects for this change |
||
189 | * |
||
190 | * @return SS_List |
||
191 | */ |
||
192 | public function findReferenced() |
||
213 | |||
214 | /** |
||
215 | * Publish this item, then close it. |
||
216 | * |
||
217 | * Note: Unlike Versioned::doPublish() and Versioned::doUnpublish, this action is not recursive. |
||
218 | */ |
||
219 | public function publish() |
||
268 | |||
269 | /** |
||
270 | * Once this item (and all owned objects) are published, unlink |
||
271 | * all disowned objects |
||
272 | */ |
||
273 | public function unlinkDisownedObjects() |
||
280 | |||
281 | /** Reverts this item, then close it. **/ |
||
282 | public function revert() |
||
286 | |||
287 | public function canView($member = null) |
||
291 | |||
292 | public function canEdit($member = null) |
||
296 | |||
297 | public function canCreate($member = null, $context = array()) |
||
301 | |||
302 | public function canDelete($member = null) |
||
306 | |||
307 | /** |
||
308 | * Check if the BeforeVersion of this changeset can be restored to draft |
||
309 | * |
||
310 | * @param Member $member |
||
311 | * @return bool |
||
312 | */ |
||
313 | public function canRevert($member) |
||
334 | |||
335 | /** |
||
336 | * Check if this ChangeSetItem can be published |
||
337 | * |
||
338 | * @param Member $member |
||
339 | * @return bool |
||
340 | */ |
||
341 | public function canPublish($member = null) |
||
365 | |||
366 | /** |
||
367 | * Determine if this item has changes |
||
368 | * |
||
369 | * @return bool |
||
370 | */ |
||
371 | public function hasChange() |
||
375 | |||
376 | /** |
||
377 | * Default permissions for this ChangeSetItem |
||
378 | * |
||
379 | * @param string $perm |
||
380 | * @param Member $member |
||
381 | * @param array $context |
||
382 | * @return bool |
||
383 | */ |
||
384 | public function can($perm, $member = null, $context = array()) |
||
400 | |||
401 | /** |
||
402 | * Get the ChangeSetItems that reference a passed DataObject |
||
403 | * |
||
404 | * @param DataObject $object |
||
405 | * @return DataList |
||
406 | */ |
||
407 | public static function get_for_object($object) |
||
414 | |||
415 | /** |
||
416 | * Get the ChangeSetItems that reference a passed DataObject |
||
417 | * |
||
418 | * @param int $objectID The ID of the object |
||
419 | * @param string $objectClass The class of the object (or any parent class) |
||
420 | * @return DataList |
||
421 | */ |
||
422 | public static function get_for_object_by_id($objectID, $objectClass) |
||
429 | |||
430 | /** |
||
431 | * Gets the list of modes this record can be previewed in. |
||
432 | * |
||
433 | * {@link https://tools.ietf.org/html/draft-kelly-json-hal-07#section-5} |
||
434 | * |
||
435 | * @return array Map of links in acceptable HAL format |
||
436 | */ |
||
437 | public function getPreviewLinks() |
||
461 | |||
462 | /** |
||
463 | * Get edit link for this item |
||
464 | * |
||
465 | * @return string |
||
466 | */ |
||
467 | public function CMSEditLink() |
||
475 | } |
||
476 |
Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.
The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.
This check looks for comments that seem to be mostly valid code and reports them.