Complex classes like Node 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 Node, and based on these observations, apply Extract Interface, too.
| 1 | <?php |
||
| 25 | abstract class Node implements INode, DAV\INode |
||
| 26 | { |
||
| 27 | /** |
||
| 28 | * name max lenght |
||
| 29 | */ |
||
| 30 | const MAX_NAME_LENGTH = 255; |
||
| 31 | |||
| 32 | |||
| 33 | /** |
||
| 34 | * Unique id |
||
| 35 | * |
||
| 36 | * @var ObjectId |
||
| 37 | */ |
||
| 38 | protected $_id; |
||
| 39 | |||
| 40 | |||
| 41 | /** |
||
| 42 | * Node name |
||
| 43 | * |
||
| 44 | * @var string |
||
| 45 | */ |
||
| 46 | protected $name = ''; |
||
| 47 | |||
| 48 | |||
| 49 | /** |
||
| 50 | * Owner |
||
| 51 | * |
||
| 52 | * @var ObjectId |
||
| 53 | */ |
||
| 54 | protected $owner; |
||
| 55 | |||
| 56 | |||
| 57 | /** |
||
| 58 | * User |
||
| 59 | * |
||
| 60 | * @var \Balloon\User |
||
| 61 | */ |
||
| 62 | protected $user; |
||
| 63 | |||
| 64 | |||
| 65 | /** |
||
| 66 | * Meta attributes |
||
| 67 | * |
||
| 68 | * @var array |
||
| 69 | */ |
||
| 70 | protected $meta = []; |
||
| 71 | |||
| 72 | |||
| 73 | /** |
||
| 74 | * Parent collection |
||
| 75 | * |
||
| 76 | * @var ObjectId |
||
| 77 | */ |
||
| 78 | protected $parent; |
||
| 79 | |||
| 80 | |||
| 81 | /** |
||
| 82 | * Is file deleted |
||
| 83 | * |
||
| 84 | * @var bool|UTCDateTime |
||
| 85 | */ |
||
| 86 | protected $deleted = false; |
||
| 87 | |||
| 88 | |||
| 89 | /** |
||
| 90 | * Is collection |
||
| 91 | * |
||
| 92 | * @var bool |
||
| 93 | */ |
||
| 94 | protected $directory = false; |
||
| 95 | |||
| 96 | |||
| 97 | /** |
||
| 98 | * Is shared? |
||
| 99 | * |
||
| 100 | * @var bool |
||
| 101 | */ |
||
| 102 | protected $shared = false; |
||
| 103 | |||
| 104 | |||
| 105 | /** |
||
| 106 | * Destory at a certain time |
||
| 107 | * |
||
| 108 | * @var UTCDateTime |
||
| 109 | */ |
||
| 110 | protected $destroy; |
||
| 111 | |||
| 112 | |||
| 113 | /** |
||
| 114 | * Changed timestamp |
||
| 115 | * |
||
| 116 | * @var UTCDateTime |
||
| 117 | */ |
||
| 118 | protected $changed; |
||
| 119 | |||
| 120 | |||
| 121 | /** |
||
| 122 | * Created timestamp |
||
| 123 | * |
||
| 124 | * @var UTCDateTime |
||
| 125 | */ |
||
| 126 | protected $created; |
||
| 127 | |||
| 128 | |||
| 129 | /** |
||
| 130 | * Point to antother node (Means this node is reference to $reference) |
||
| 131 | * |
||
| 132 | * @var ObjectId |
||
| 133 | */ |
||
| 134 | protected $reference; |
||
| 135 | |||
| 136 | |||
| 137 | /** |
||
| 138 | * Share link options |
||
| 139 | * |
||
| 140 | * @var bool|array |
||
| 141 | */ |
||
| 142 | protected $sharelink = false; |
||
| 143 | |||
| 144 | |||
| 145 | /** |
||
| 146 | * Raw attributes before any processing or modifications |
||
| 147 | * |
||
| 148 | * @var array |
||
| 149 | */ |
||
| 150 | protected $raw_attributes; |
||
| 151 | |||
| 152 | |||
| 153 | /** |
||
| 154 | * Readonly flag |
||
| 155 | * |
||
| 156 | * @var bool |
||
| 157 | */ |
||
| 158 | protected $readonly = false; |
||
| 159 | |||
| 160 | |||
| 161 | /** |
||
| 162 | * Filesystem |
||
| 163 | * |
||
| 164 | * @var Filesystem |
||
| 165 | */ |
||
| 166 | protected $_fs; |
||
| 167 | |||
| 168 | |||
| 169 | /** |
||
| 170 | * Database |
||
| 171 | * |
||
| 172 | * @var \MongoDB\Database |
||
| 173 | */ |
||
| 174 | protected $_db; |
||
| 175 | |||
| 176 | |||
| 177 | /** |
||
| 178 | * User |
||
| 179 | * |
||
| 180 | * @var User |
||
| 181 | */ |
||
| 182 | protected $_user; |
||
| 183 | |||
| 184 | |||
| 185 | /** |
||
| 186 | * Logger |
||
| 187 | * |
||
| 188 | * @var Logger |
||
| 189 | */ |
||
| 190 | protected $_logger; |
||
| 191 | |||
| 192 | |||
| 193 | /** |
||
| 194 | * Plugin |
||
| 195 | * |
||
| 196 | * @var Plugin |
||
| 197 | */ |
||
| 198 | protected $_pluginmgr; |
||
| 199 | |||
| 200 | |||
| 201 | /** |
||
| 202 | * Queue |
||
| 203 | * |
||
| 204 | * @var Queue |
||
| 205 | */ |
||
| 206 | protected $_queuemgr; |
||
| 207 | |||
| 208 | |||
| 209 | /** |
||
| 210 | * Config |
||
| 211 | * |
||
| 212 | * @var Config |
||
| 213 | */ |
||
| 214 | protected $_config; |
||
| 215 | |||
| 216 | |||
| 217 | /** |
||
| 218 | * Initialize |
||
| 219 | * |
||
| 220 | * @param BSONDocument $node |
||
| 221 | * @param Filesystem $fs |
||
| 222 | * @return void |
||
|
|
|||
| 223 | */ |
||
| 224 | public function __construct(?BSONDocument $node, Filesystem $fs) |
||
| 243 | |||
| 244 | |||
| 245 | /** |
||
| 246 | * Convert to filename |
||
| 247 | * |
||
| 248 | * @return string |
||
| 249 | */ |
||
| 250 | public function __toString() |
||
| 254 | |||
| 255 | |||
| 256 | /** |
||
| 257 | * Get filesystem |
||
| 258 | * |
||
| 259 | * @return Filesystem |
||
| 260 | */ |
||
| 261 | public function getFilesystem(): Filesystem |
||
| 265 | |||
| 266 | |||
| 267 | /** |
||
| 268 | * Get property |
||
| 269 | * |
||
| 270 | * @return mixed |
||
| 271 | */ |
||
| 272 | public function __call(string $attribute, array $params=[]) |
||
| 282 | |||
| 283 | |||
| 284 | /** |
||
| 285 | * Check if $node is a sub node of any parent nodes of this node |
||
| 286 | * |
||
| 287 | * @param INode $node |
||
| 288 | * @return bool |
||
| 289 | */ |
||
| 290 | public function isSubNode(INode $node): bool |
||
| 308 | |||
| 309 | |||
| 310 | /** |
||
| 311 | * Move node |
||
| 312 | * |
||
| 313 | * @param Collection $parent |
||
| 314 | * @param int $conflict |
||
| 315 | * @return INode |
||
| 316 | */ |
||
| 317 | public function setParent(Collection $parent, int $conflict=INode::CONFLICT_NOACTION): INode |
||
| 381 | |||
| 382 | |||
| 383 | /** |
||
| 384 | * Copy node |
||
| 385 | * |
||
| 386 | * @param Collection $parent |
||
| 387 | * @param int $conflict |
||
| 388 | * @param string $recursion |
||
| 389 | * @param bool $recursion_first |
||
| 390 | * @return INode |
||
| 391 | */ |
||
| 392 | abstract public function copyTo(Collection $parent, int $conflict=INode::CONFLICT_NOACTION, ?string $recursion=null, bool $recursion_first=true): INode; |
||
| 393 | |||
| 394 | |||
| 395 | /** |
||
| 396 | * Get share id |
||
| 397 | * |
||
| 398 | * @param bool $reference |
||
| 399 | * @return ObjectId |
||
| 400 | */ |
||
| 401 | public function getShareId(bool $reference=false): ?ObjectId |
||
| 417 | |||
| 418 | |||
| 419 | /** |
||
| 420 | * Check node |
||
| 421 | * |
||
| 422 | * @return void |
||
| 423 | */ |
||
| 424 | protected function _verifyAccess() |
||
| 441 | |||
| 442 | |||
| 443 | /** |
||
| 444 | * Get share node |
||
| 445 | * |
||
| 446 | * @param bool $reference |
||
| 447 | * @return Collection |
||
| 448 | */ |
||
| 449 | public function getShareNode(): ?Collection |
||
| 457 | |||
| 458 | |||
| 459 | /** |
||
| 460 | * Is node marked as readonly? |
||
| 461 | * |
||
| 462 | * @return bool |
||
| 463 | */ |
||
| 464 | public function isReadonly(): bool |
||
| 468 | |||
| 469 | |||
| 470 | /** |
||
| 471 | * Request is from node owner? |
||
| 472 | * |
||
| 473 | * @return bool |
||
| 474 | */ |
||
| 475 | public function isOwnerRequest(): bool |
||
| 476 | { |
||
| 477 | return ($this->_user !== null && $this->owner == $this->_user->getId()); |
||
| 478 | } |
||
| 479 | |||
| 480 | |||
| 481 | /** |
||
| 482 | * Check if node is kind of special |
||
| 483 | * |
||
| 484 | * @return bool |
||
| 485 | */ |
||
| 486 | public function isSpecial(): bool |
||
| 498 | |||
| 499 | |||
| 500 | /** |
||
| 501 | * Check if node is a sub node of a share |
||
| 502 | * |
||
| 503 | * @return bool |
||
| 504 | */ |
||
| 505 | public function isShareMember(): bool |
||
| 509 | |||
| 510 | |||
| 511 | /** |
||
| 512 | * Is share |
||
| 513 | * |
||
| 514 | * @return bool |
||
| 515 | */ |
||
| 516 | public function isShare(): bool |
||
| 520 | |||
| 521 | |||
| 522 | /** |
||
| 523 | * Is share (Reference or master share) |
||
| 524 | * |
||
| 525 | * @return bool |
||
| 526 | */ |
||
| 527 | public function isShared(): bool |
||
| 535 | |||
| 536 | |||
| 537 | /** |
||
| 538 | * Set the name |
||
| 539 | * |
||
| 540 | * @param string $name |
||
| 541 | * @return bool |
||
| 542 | */ |
||
| 543 | public function setName($name): bool |
||
| 556 | |||
| 557 | |||
| 558 | /** |
||
| 559 | * Check name |
||
| 560 | * |
||
| 561 | * @param string $name |
||
| 562 | * @return string |
||
| 563 | */ |
||
| 564 | public function checkName(string $name): string |
||
| 578 | |||
| 579 | |||
| 580 | /** |
||
| 581 | * Get the name |
||
| 582 | * |
||
| 583 | * @return string |
||
| 584 | */ |
||
| 585 | public function getName(): string |
||
| 589 | |||
| 590 | |||
| 591 | /** |
||
| 592 | * Check acl |
||
| 593 | * |
||
| 594 | * @param string $privilege |
||
| 595 | * @return bool |
||
| 596 | */ |
||
| 597 | public function isAllowed(string $privilege='r'): bool |
||
| 651 | |||
| 652 | |||
| 653 | /** |
||
| 654 | * Get privilege |
||
| 655 | * |
||
| 656 | * rw - READ/WRITE |
||
| 657 | * r - READ(only) |
||
| 658 | * w - WRITE(only) |
||
| 659 | * d - DENY |
||
| 660 | * |
||
| 661 | * @return string |
||
| 662 | */ |
||
| 663 | public function getAclPrivilege() |
||
| 763 | |||
| 764 | |||
| 765 | /** |
||
| 766 | * Get Attribute helper |
||
| 767 | * |
||
| 768 | * @param array|string $attribute |
||
| 769 | * @return array|string |
||
| 770 | */ |
||
| 771 | protected function _getAttribute($attribute) |
||
| 913 | |||
| 914 | |||
| 915 | /** |
||
| 916 | * Duplicate name with a uniqid within name |
||
| 917 | * |
||
| 918 | * @param string $name |
||
| 919 | * @return string |
||
| 920 | */ |
||
| 921 | protected function _getDuplicateName(?string $name=null): string |
||
| 940 | |||
| 941 | |||
| 942 | /** |
||
| 943 | * Undelete |
||
| 944 | * |
||
| 945 | * @param int $conflict |
||
| 946 | * @param string $recursion |
||
| 947 | * @param bool $recursion_first |
||
| 948 | * @return bool |
||
| 949 | */ |
||
| 950 | public function undelete(int $conflict=INode::CONFLICT_NOACTION, ?string $recursion=null, bool $recursion_first=true): bool |
||
| 1029 | |||
| 1030 | |||
| 1031 | /** |
||
| 1032 | * Is node deleted? |
||
| 1033 | * |
||
| 1034 | * @return bool |
||
| 1035 | */ |
||
| 1036 | public function isDeleted(): bool |
||
| 1040 | |||
| 1041 | |||
| 1042 | /** |
||
| 1043 | * Share link |
||
| 1044 | * |
||
| 1045 | * @param array $options |
||
| 1046 | * @return bool |
||
| 1047 | */ |
||
| 1048 | public function shareLink(array $options): bool |
||
| 1107 | |||
| 1108 | |||
| 1109 | /** |
||
| 1110 | * Get share options |
||
| 1111 | * |
||
| 1112 | * @return bool|array |
||
| 1113 | */ |
||
| 1114 | public function getShareLink() |
||
| 1122 | |||
| 1123 | |||
| 1124 | /** |
||
| 1125 | * Get last modified timestamp |
||
| 1126 | * |
||
| 1127 | * @return int |
||
| 1128 | */ |
||
| 1129 | public function getLastModified(): int |
||
| 1137 | |||
| 1138 | |||
| 1139 | /** |
||
| 1140 | * Get unique id |
||
| 1141 | * |
||
| 1142 | * @return ObjectId|string |
||
| 1143 | */ |
||
| 1144 | public function getId(bool $string=false) |
||
| 1152 | |||
| 1153 | |||
| 1154 | /** |
||
| 1155 | * Get parent |
||
| 1156 | * |
||
| 1157 | * @return Collection |
||
| 1158 | */ |
||
| 1159 | public function getParent(): ?Collection |
||
| 1160 | { |
||
| 1161 | try { |
||
| 1162 | if ($this->isRoot()) { |
||
| 1163 | return null; |
||
| 1164 | } elseif ($this->isInRoot()) { |
||
| 1165 | return $this->_fs->getRoot(); |
||
| 1166 | } else { |
||
| 1167 | $parent = $this->_fs->findNodeWithId($this->parent); |
||
| 1168 | if ($parent->isShare() && !$parent->isOwnerRequest() && $this->_user !== null) { |
||
| 1169 | $node = $this->_db->storage->findOne([ |
||
| 1170 | 'owner' => $this->_user->getId(), |
||
| 1171 | 'shared' => true, |
||
| 1172 | 'reference' => $this->parent, |
||
| 1173 | ]); |
||
| 1174 | |||
| 1175 | return new Collection($node, $this->_fs); |
||
| 1176 | } else { |
||
| 1177 | return $parent; |
||
| 1178 | } |
||
| 1179 | } |
||
| 1180 | } catch (Exception\NotFound $e) { |
||
| 1181 | throw new Exception\NotFound('parent node '.$this->parent.' could not be found', |
||
| 1182 | Exception\NotFound::PARENT_NOT_FOUND |
||
| 1183 | ); |
||
| 1184 | } |
||
| 1185 | } |
||
| 1186 | |||
| 1187 | |||
| 1188 | /** |
||
| 1189 | * Get parents |
||
| 1190 | * |
||
| 1191 | * @param array $parents |
||
| 1192 | * @return array |
||
| 1193 | */ |
||
| 1194 | public function getParents(?INode $node=null, array $parents=[]): array |
||
| 1210 | |||
| 1211 | |||
| 1212 | /** |
||
| 1213 | * Check if the node is a shared link |
||
| 1214 | * |
||
| 1215 | * @return bool |
||
| 1216 | */ |
||
| 1217 | public function isShareLink(): bool |
||
| 1221 | |||
| 1222 | |||
| 1223 | /** |
||
| 1224 | * Download |
||
| 1225 | * |
||
| 1226 | * @return void |
||
| 1227 | */ |
||
| 1228 | abstract public function get(); |
||
| 1229 | |||
| 1230 | |||
| 1231 | /** |
||
| 1232 | * Get as zip |
||
| 1233 | * |
||
| 1234 | * @return void |
||
| 1235 | */ |
||
| 1236 | public function getZip(): void |
||
| 1249 | |||
| 1250 | |||
| 1251 | /** |
||
| 1252 | * Create zip |
||
| 1253 | * |
||
| 1254 | * @param ZipStream $archive |
||
| 1255 | * @param bool $self true means that the zip represents the collection itself instead a child of the zip |
||
| 1256 | * @param INode $parent |
||
| 1257 | * @param string $path |
||
| 1258 | * @param int $depth |
||
| 1259 | * @return bool |
||
| 1260 | */ |
||
| 1261 | public function zip(ZipStream $archive, bool $self=true, ?INode $parent=null, string $path='', int $depth=0): bool |
||
| 1303 | |||
| 1304 | |||
| 1305 | /** |
||
| 1306 | * Is reference |
||
| 1307 | * |
||
| 1308 | * @return bool |
||
| 1309 | */ |
||
| 1310 | public function isReference(): bool |
||
| 1314 | |||
| 1315 | |||
| 1316 | /** |
||
| 1317 | * Set meta attribute |
||
| 1318 | * |
||
| 1319 | * @param array|string |
||
| 1320 | * @param mixed $value |
||
| 1321 | * @return INode |
||
| 1322 | */ |
||
| 1323 | public function setMetaAttribute($attributes, $value=null): INode |
||
| 1329 | |||
| 1330 | |||
| 1331 | /** |
||
| 1332 | * validate meta attribut |
||
| 1333 | * |
||
| 1334 | * @param array|string $attributes |
||
| 1335 | * @param mixed $value |
||
| 1336 | * @param array $set |
||
| 1337 | * @return array |
||
| 1338 | */ |
||
| 1339 | public static function validateMetaAttribute($attributes, $value=null, array $set=[]): array |
||
| 1362 | |||
| 1363 | |||
| 1364 | /** |
||
| 1365 | * Get meta attributes as array |
||
| 1366 | * |
||
| 1367 | * @param string|array $attribute Specify attributes to return |
||
| 1368 | * @return string|array |
||
| 1369 | */ |
||
| 1370 | public function getMetaAttribute($attribute=[]) |
||
| 1382 | |||
| 1383 | |||
| 1384 | /** |
||
| 1385 | * Mark node as readonly |
||
| 1386 | * |
||
| 1387 | * @param bool $readonly |
||
| 1388 | * @return bool |
||
| 1389 | */ |
||
| 1390 | public function setReadonly(bool $readonly=true): bool |
||
| 1395 | |||
| 1396 | |||
| 1397 | /** |
||
| 1398 | * Mark node as self-destroyable |
||
| 1399 | * |
||
| 1400 | * @param UTCDateTime $ts |
||
| 1401 | * @return bool |
||
| 1402 | */ |
||
| 1403 | public function setDestroyable(?UTCDateTime $ts): bool |
||
| 1413 | |||
| 1414 | |||
| 1415 | /** |
||
| 1416 | * Delete node |
||
| 1417 | * |
||
| 1418 | * Actually the node will not be deleted (Just set a delete flag), set $force=true to |
||
| 1419 | * delete finally |
||
| 1420 | * |
||
| 1421 | * @param bool $force |
||
| 1422 | * @param bool $recursion_first |
||
| 1423 | * @param string $recursion |
||
| 1424 | * @return bool |
||
| 1425 | */ |
||
| 1426 | abstract public function delete(bool $force=false, ?string $recursion=null, bool $recursion_first=true): bool; |
||
| 1427 | |||
| 1428 | |||
| 1429 | /** |
||
| 1430 | * Get original raw attributes before any processing |
||
| 1431 | * |
||
| 1432 | * @return array|\MongoDB\BSON\Document |
||
| 1433 | */ |
||
| 1434 | public function getRawAttributes() |
||
| 1438 | |||
| 1439 | |||
| 1440 | /** |
||
| 1441 | * Completly remove node |
||
| 1442 | * |
||
| 1443 | * @return bool |
||
| 1444 | */ |
||
| 1445 | abstract protected function _forceDelete(): bool; |
||
| 1446 | |||
| 1447 | |||
| 1448 | /** |
||
| 1449 | * Check if node is in root |
||
| 1450 | * |
||
| 1451 | * @return bool |
||
| 1452 | */ |
||
| 1453 | public function isInRoot(): bool |
||
| 1457 | |||
| 1458 | |||
| 1459 | /** |
||
| 1460 | * Check if node is an instance of the actual root collection |
||
| 1461 | * |
||
| 1462 | * @return bool |
||
| 1463 | */ |
||
| 1464 | public function isRoot(): bool |
||
| 1468 | |||
| 1469 | |||
| 1470 | /** |
||
| 1471 | * Resolve node path |
||
| 1472 | * |
||
| 1473 | * @return string |
||
| 1474 | */ |
||
| 1475 | public function getPath(): string |
||
| 1485 | |||
| 1486 | |||
| 1487 | /** |
||
| 1488 | * Save node attributes |
||
| 1489 | * |
||
| 1490 | * @param string|array $attributes |
||
| 1491 | * @param string|array $remove |
||
| 1492 | * @param string $recursion |
||
| 1493 | * @param bool $recursion_first |
||
| 1494 | * @return bool |
||
| 1495 | */ |
||
| 1496 | public function save($attributes=[], $remove=[], ?string $recursion=null, bool $recursion_first=true): bool |
||
| 1552 | |||
| 1553 | |||
| 1554 | /** |
||
| 1555 | * Get children |
||
| 1556 | * |
||
| 1557 | * @param array $filter |
||
| 1558 | * @param array $attributes |
||
| 1559 | * @param int $limit |
||
| 1560 | * @param string $cursor |
||
| 1561 | * @param bool $has_more |
||
| 1562 | * @return array |
||
| 1563 | */ |
||
| 1564 | public static function loadNodeAttributesWithCustomFilter( |
||
| 1611 | } |
||
| 1612 |
Adding a
@returnannotation to a constructor is not recommended, since a constructor does not have a meaningful return value.Please refer to the PHP core documentation on constructors.