Complex classes like Parser 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 Parser, and based on these observations, apply Extract Interface, too.
| 1 | <?php | ||
| 24 | class Parser { | ||
| 25 | const MSG_NOT_FOUND = 'Error opening local file '; | ||
| 26 | |||
| 27 | /** | ||
| 28 | * @var string | ||
| 29 | */ | ||
| 30 | protected $timeZone; | ||
| 31 | |||
| 32 | // see error.h | ||
| 33 | const EXCEPTION_MAP = [ | ||
| 34 | ErrorCodes::LogonFailure => AuthenticationException::class, | ||
| 35 | ErrorCodes::PathNotFound => NotFoundException::class, | ||
| 36 | ErrorCodes::ObjectNotFound => NotFoundException::class, | ||
| 37 | ErrorCodes::NoSuchFile => NotFoundException::class, | ||
| 38 | ErrorCodes::NameCollision => AlreadyExistsException::class, | ||
| 39 | ErrorCodes::AccessDenied => AccessDeniedException::class, | ||
| 40 | ErrorCodes::DirectoryNotEmpty => NotEmptyException::class, | ||
| 41 | ErrorCodes::FileIsADirectory => InvalidTypeException::class, | ||
| 42 | ErrorCodes::NotADirectory => InvalidTypeException::class, | ||
| 43 | ErrorCodes::SharingViolation => FileInUseException::class, | ||
| 44 | ErrorCodes::InvalidParameter => InvalidParameterException::class | ||
| 45 | ]; | ||
| 46 | |||
| 47 | const MODE_STRINGS = [ | ||
| 48 | 'R' => FileInfo::MODE_READONLY, | ||
| 49 | 'H' => FileInfo::MODE_HIDDEN, | ||
| 50 | 'S' => FileInfo::MODE_SYSTEM, | ||
| 51 | 'D' => FileInfo::MODE_DIRECTORY, | ||
| 52 | 'A' => FileInfo::MODE_ARCHIVE, | ||
| 53 | 'N' => FileInfo::MODE_NORMAL | ||
| 54 | ]; | ||
| 55 | |||
| 56 | /** | ||
| 57 | * @param string $timeZone | ||
| 58 | */ | ||
| 59 | 	public function __construct(string $timeZone) { | ||
| 62 | |||
| 63 | 542 | 	private function getErrorCode(string $line): ?string { | |
| 72 | |||
| 73 | /** | ||
| 74 | 2 | * @param string[] $output | |
| 75 | * @param string $path | ||
| 76 | * @return no-return | ||
|  | |||
| 77 | 38 | * @throws Exception | |
| 78 | 38 | * @throws InvalidResourceException | |
| 79 | * @throws NotFoundException | ||
| 80 | */ | ||
| 81 | 38 | 	public function checkForError(array $output, string $path): void { | |
| 94 | |||
| 95 | /** | ||
| 96 | * check if the first line holds a connection failure | ||
| 97 | * | ||
| 98 | * @param string $line | ||
| 99 | * @throws AuthenticationException | ||
| 100 | 494 | * @throws InvalidHostException | |
| 101 | 494 | * @throws NoLoginServerException | |
| 102 | 494 | * @throws AccessDeniedException | |
| 103 | 2 | */ | |
| 104 | 	public function checkConnectionError(string $line): void { | ||
| 125 | 230 | ||
| 126 | 230 | 	public function parseMode(string $mode): int { | |
| 135 | |||
| 136 | /** | ||
| 137 | 14 | * @param string[] $output | |
| 138 | 14 | 	 * @return array{"mtime": int, "mode": int, "size": int} | |
| 139 | 14 | * @throws Exception | |
| 140 | 14 | */ | |
| 141 | 	public function parseStat(array $output): array { | ||
| 165 | 198 | ||
| 166 | 198 | /** | |
| 167 | * @param string[] $output | ||
| 168 | 198 | * @param string $basePath | |
| 169 | * @param callable(string):ACL[] $aclCallback | ||
| 170 | * @return FileInfo[] | ||
| 171 | */ | ||
| 172 | 488 | 	public function parseDir(array $output, string $basePath, callable $aclCallback): array { | |
| 193 | |||
| 194 | /** | ||
| 195 | * @param string[] $output | ||
| 196 | * @return array<string, string> | ||
| 197 | */ | ||
| 198 | 	public function parseListShares(array $output): array { | ||
| 214 | |||
| 215 | /** | ||
| 216 | * @param string[] $rawAcls | ||
| 217 | * @return ACL[] | ||
| 218 | */ | ||
| 219 | 	public function parseACLs(array $rawAcls): array { | ||
| 277 | } | ||
| 278 | 
This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.