Complex classes like PrettyPageHandler 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 PrettyPageHandler, and based on these observations, apply Extract Interface, too.
| 1 | <?php  | 
            ||
| 18 | class PrettyPageHandler extends Handler  | 
            ||
| 19 | { | 
            ||
| 20 | /**  | 
            ||
| 21 | * Search paths to be scanned for resources, in the reverse  | 
            ||
| 22 | * order they're declared.  | 
            ||
| 23 | *  | 
            ||
| 24 | * @var array  | 
            ||
| 25 | */  | 
            ||
| 26 | private $searchPaths = [];  | 
            ||
| 27 | |||
| 28 | /**  | 
            ||
| 29 | * Fast lookup cache for known resource locations.  | 
            ||
| 30 | *  | 
            ||
| 31 | * @var array  | 
            ||
| 32 | */  | 
            ||
| 33 | private $resourceCache = [];  | 
            ||
| 34 | |||
| 35 | /**  | 
            ||
| 36 | * The name of the custom css file.  | 
            ||
| 37 | *  | 
            ||
| 38 | * @var string  | 
            ||
| 39 | */  | 
            ||
| 40 | private $customCss = null;  | 
            ||
| 41 | |||
| 42 | /**  | 
            ||
| 43 | * @var array[]  | 
            ||
| 44 | */  | 
            ||
| 45 | private $extraTables = [];  | 
            ||
| 46 | |||
| 47 | /**  | 
            ||
| 48 | * @var bool  | 
            ||
| 49 | */  | 
            ||
| 50 | private $handleUnconditionally = false;  | 
            ||
| 51 | |||
| 52 | /**  | 
            ||
| 53 | * @var string  | 
            ||
| 54 | */  | 
            ||
| 55 | private $pageTitle = "Whoops! There was an error.";  | 
            ||
| 56 | |||
| 57 | /**  | 
            ||
| 58 | * @var array[]  | 
            ||
| 59 | */  | 
            ||
| 60 | private $applicationPaths;  | 
            ||
| 61 | |||
| 62 | /**  | 
            ||
| 63 | * @var array[]  | 
            ||
| 64 | */  | 
            ||
| 65 | private $blacklist = [  | 
            ||
| 66 | '_GET' => [],  | 
            ||
| 67 | '_POST' => [],  | 
            ||
| 68 | '_FILES' => [],  | 
            ||
| 69 | '_COOKIE' => [],  | 
            ||
| 70 | '_SESSION' => [],  | 
            ||
| 71 | '_SERVER' => [],  | 
            ||
| 72 | '_ENV' => [],  | 
            ||
| 73 | ];  | 
            ||
| 74 | |||
| 75 | /**  | 
            ||
| 76 | * A string identifier for a known IDE/text editor, or a closure  | 
            ||
| 77 | * that resolves a string that can be used to open a given file  | 
            ||
| 78 | * in an editor. If the string contains the special substrings  | 
            ||
| 79 | * %file or %line, they will be replaced with the correct data.  | 
            ||
| 80 | *  | 
            ||
| 81 | * @example  | 
            ||
| 82 | * "txmt://open?url=%file&line=%line"  | 
            ||
| 83 | * @var mixed $editor  | 
            ||
| 84 | */  | 
            ||
| 85 | protected $editor;  | 
            ||
| 86 | |||
| 87 | /**  | 
            ||
| 88 | * A list of known editor strings  | 
            ||
| 89 | * @var array  | 
            ||
| 90 | 1 | */  | 
            |
| 91 | protected $editors = [  | 
            ||
| 92 | 1 | "sublime" => "subl://open?url=file://%file&line=%line",  | 
            |
| 93 | "textmate" => "txmt://open?url=file://%file&line=%line",  | 
            ||
| 94 | "emacs" => "emacs://open?url=file://%file&line=%line",  | 
            ||
| 95 | 1 | "macvim" => "mvim://open/?url=file://%file&line=%line",  | 
            |
| 96 | "phpstorm" => "phpstorm://open?file=%file&line=%line",  | 
            ||
| 97 | 1 | "idea" => "idea://open?file=%file&line=%line",  | 
            |
| 98 | ];  | 
            ||
| 99 | |||
| 100 | 1 | /**  | 
            |
| 101 | 1 | * Constructor.  | 
            |
| 102 | */  | 
            ||
| 103 | public function __construct()  | 
            ||
| 118 | |||
| 119 | /**  | 
            ||
| 120 | * @return int|null  | 
            ||
| 121 | 1 | */  | 
            |
| 122 | public function handle()  | 
            ||
| 264 | 1 | ||
| 265 | /**  | 
            ||
| 266 | 1 | * @return string  | 
            |
| 267 | 1 | */  | 
            |
| 268 | public function contentType()  | 
            ||
| 272 | |||
| 273 | /**  | 
            ||
| 274 | * Adds an entry to the list of tables displayed in the template.  | 
            ||
| 275 | * The expected data is a simple associative array. Any nested arrays  | 
            ||
| 276 | * will be flattened with print_r  | 
            ||
| 277 | * @param string $label  | 
            ||
| 278 | * @param array $data  | 
            ||
| 279 | 1 | */  | 
            |
| 280 | public function addDataTable($label, array $data)  | 
            ||
| 284 | |||
| 285 | 1 | /**  | 
            |
| 286 | * Lazily adds an entry to the list of tables displayed in the table.  | 
            ||
| 287 | 1 | * The supplied callback argument will be called when the error is rendered,  | 
            |
| 288 | * it should produce a simple associative array. Any nested arrays will  | 
            ||
| 289 | * be flattened with print_r.  | 
            ||
| 290 | 1 | *  | 
            |
| 291 | * @throws InvalidArgumentException If $callback is not callable  | 
            ||
| 292 | * @param string $label  | 
            ||
| 293 | * @param callable $callback Callable returning an associative array  | 
            ||
| 294 | */  | 
            ||
| 295 | public function addDataTableCallback($label, /* callable */ $callback)  | 
            ||
| 313 | |||
| 314 | /**  | 
            ||
| 315 | * Returns all the extra data tables registered with this handler.  | 
            ||
| 316 | * Optionally accepts a 'label' parameter, to only return the data  | 
            ||
| 317 | * table under that label.  | 
            ||
| 318 | * @param string|null $label  | 
            ||
| 319 | * @return array[]|callable  | 
            ||
| 320 | */  | 
            ||
| 321 | public function getDataTables($label = null)  | 
            ||
| 330 | |||
| 331 | /**  | 
            ||
| 332 | * Allows to disable all attempts to dynamically decide whether to  | 
            ||
| 333 | * handle or return prematurely.  | 
            ||
| 334 | * Set this to ensure that the handler will perform no matter what.  | 
            ||
| 335 | * @param bool|null $value  | 
            ||
| 336 | * @return bool|null  | 
            ||
| 337 | */  | 
            ||
| 338 | public function handleUnconditionally($value = null)  | 
            ||
| 346 | |||
| 347 | 1 | /**  | 
            |
| 348 | * Adds an editor resolver, identified by a string  | 
            ||
| 349 | 1 | * name, and that may be a string path, or a callable  | 
            |
| 350 | 1 | * resolver. If the callable returns a string, it will  | 
            |
| 351 | * be set as the file reference's href attribute.  | 
            ||
| 352 | *  | 
            ||
| 353 | * @example  | 
            ||
| 354 |      *  $run->addEditor('macvim', "mvim://open?url=file://%file&line=%line") | 
            ||
| 355 | * @example  | 
            ||
| 356 |      *   $run->addEditor('remove-it', function($file, $line) { | 
            ||
| 357 | * unlink($file);  | 
            ||
| 358 | * return "http://stackoverflow.com";  | 
            ||
| 359 | * });  | 
            ||
| 360 | * @param string $identifier  | 
            ||
| 361 | * @param string $resolver  | 
            ||
| 362 | */  | 
            ||
| 363 | public function addEditor($identifier, $resolver)  | 
            ||
| 367 | |||
| 368 | 4 | /**  | 
            |
| 369 | * Set the editor to use to open referenced files, by a string  | 
            ||
| 370 | * identifier, or a callable that will be executed for every  | 
            ||
| 371 | * file reference, with a $file and $line argument, and should  | 
            ||
| 372 | * return a string.  | 
            ||
| 373 | *  | 
            ||
| 374 | * @example  | 
            ||
| 375 | 4 |      *   $run->setEditor(function($file, $line) { return "file:///{$file}"; }); | 
            |
| 376 | 4 | * @example  | 
            |
| 377 |      *   $run->setEditor('sublime'); | 
            ||
| 378 | *  | 
            ||
| 379 | * @throws InvalidArgumentException If invalid argument identifier provided  | 
            ||
| 380 | * @param string|callable $editor  | 
            ||
| 381 | */  | 
            ||
| 382 | public function setEditor($editor)  | 
            ||
| 393 | 4 | ||
| 394 | /**  | 
            ||
| 395 | * Given a string file path, and an integer file line,  | 
            ||
| 396 | * executes the editor resolver and returns, if available,  | 
            ||
| 397 | * a string that may be used as the href property for that  | 
            ||
| 398 | * file reference.  | 
            ||
| 399 | 4 | *  | 
            |
| 400 | * @throws InvalidArgumentException If editor resolver does not return a string  | 
            ||
| 401 | * @param string $filePath  | 
            ||
| 402 | * @param int $line  | 
            ||
| 403 | * @return string|bool  | 
            ||
| 404 | */  | 
            ||
| 405 | 4 | public function getEditorHref($filePath, $line)  | 
            |
| 426 | 1 | ||
| 427 | /**  | 
            ||
| 428 | * Given a boolean if the editor link should  | 
            ||
| 429 | * act as an Ajax request. The editor must be a  | 
            ||
| 430 | * valid callable function/closure  | 
            ||
| 431 | 1 | *  | 
            |
| 432 | * @throws UnexpectedValueException If editor resolver does not return a boolean  | 
            ||
| 433 | * @param string $filePath  | 
            ||
| 434 | * @param int $line  | 
            ||
| 435 | * @return bool  | 
            ||
| 436 | */  | 
            ||
| 437 | public function getEditorAjax($filePath, $line)  | 
            ||
| 449 | 1 | ||
| 450 | /**  | 
            ||
| 451 | * Given a boolean if the editor link should  | 
            ||
| 452 | * act as an Ajax request. The editor must be a  | 
            ||
| 453 | * valid callable function/closure  | 
            ||
| 454 | *  | 
            ||
| 455 | * @param string $filePath  | 
            ||
| 456 | 1 | * @param int $line  | 
            |
| 457 | 1 | * @return array  | 
            |
| 458 | */  | 
            ||
| 459 | protected function getEditor($filePath, $line)  | 
            ||
| 494 | |||
| 495 | /**  | 
            ||
| 496 | * @param string $title  | 
            ||
| 497 | * @return void  | 
            ||
| 498 | */  | 
            ||
| 499 | public function setPageTitle($title)  | 
            ||
| 503 | |||
| 504 | /**  | 
            ||
| 505 | 2 | * @return string  | 
            |
| 506 | */  | 
            ||
| 507 | 2 | public function getPageTitle()  | 
            |
| 511 | |||
| 512 | /**  | 
            ||
| 513 | 1 | * Adds a path to the list of paths to be searched for  | 
            |
| 514 | 1 | * resources.  | 
            |
| 515 | *  | 
            ||
| 516 | * @throws InvalidArgumentException If $path is not a valid directory  | 
            ||
| 517 | *  | 
            ||
| 518 | * @param string $path  | 
            ||
| 519 | * @return void  | 
            ||
| 520 | */  | 
            ||
| 521 | public function addResourcePath($path)  | 
            ||
| 531 | |||
| 532 | 1 | /**  | 
            |
| 533 | * Adds a custom css file to be loaded.  | 
            ||
| 534 | *  | 
            ||
| 535 | * @param string $name  | 
            ||
| 536 | * @return void  | 
            ||
| 537 | */  | 
            ||
| 538 | public function addCustomCss($name)  | 
            ||
| 542 | |||
| 543 | /**  | 
            ||
| 544 | * @return array  | 
            ||
| 545 | */  | 
            ||
| 546 | public function getResourcePaths()  | 
            ||
| 550 | |||
| 551 | /**  | 
            ||
| 552 | * Finds a resource, by its relative path, in all available search paths.  | 
            ||
| 553 | * The search is performed starting at the last search path, and all the  | 
            ||
| 554 | * way back to the first, enabling a cascading-type system of overrides  | 
            ||
| 555 | * for all resources.  | 
            ||
| 556 | *  | 
            ||
| 557 | * @throws RuntimeException If resource cannot be found in any of the available paths  | 
            ||
| 558 | *  | 
            ||
| 559 | * @param string $resource  | 
            ||
| 560 | * @return string  | 
            ||
| 561 | */  | 
            ||
| 562 | protected function getResource($resource)  | 
            ||
| 588 | |||
| 589 | /**  | 
            ||
| 590 | * @deprecated  | 
            ||
| 591 | *  | 
            ||
| 592 | * @return string  | 
            ||
| 593 | */  | 
            ||
| 594 | public function getResourcesPath()  | 
            ||
| 601 | |||
| 602 | /**  | 
            ||
| 603 | * @deprecated  | 
            ||
| 604 | *  | 
            ||
| 605 | * @param string $resourcesPath  | 
            ||
| 606 | * @return void  | 
            ||
| 607 | */  | 
            ||
| 608 | public function setResourcesPath($resourcesPath)  | 
            ||
| 612 | |||
| 613 | /**  | 
            ||
| 614 | * Return the application paths.  | 
            ||
| 615 | *  | 
            ||
| 616 | * @return array  | 
            ||
| 617 | */  | 
            ||
| 618 | public function getApplicationPaths()  | 
            ||
| 622 | |||
| 623 | /**  | 
            ||
| 624 | * Set the application paths.  | 
            ||
| 625 | *  | 
            ||
| 626 | * @param array $applicationPaths  | 
            ||
| 627 | */  | 
            ||
| 628 | public function setApplicationPaths($applicationPaths)  | 
            ||
| 632 | |||
| 633 | /**  | 
            ||
| 634 | * blacklist a sensitive value within one of the superglobal arrays.  | 
            ||
| 635 | *  | 
            ||
| 636 | * @param $superGlobalName string the name of the superglobal array, e.g. '_GET'  | 
            ||
| 637 | * @param $key string the key within the superglobal  | 
            ||
| 638 | */  | 
            ||
| 639 |     public function blacklist($superGlobalName, $key) { | 
            ||
| 642 | |||
| 643 | /**  | 
            ||
| 644 | * Checks all values identified by the given superGlobalName within GLOBALS.  | 
            ||
| 645 | * Blacklisted values will be replaced by a equal length string cointaining only '*' characters.  | 
            ||
| 646 | *  | 
            ||
| 647 | * @param $superGlobalName string the name of the superglobal array, e.g. '_GET'  | 
            ||
| 648 | * @return array $values without sensitive data  | 
            ||
| 649 | */  | 
            ||
| 650 |     private function masked($superGlobalName) { | 
            ||
| 661 | }  | 
            ||
| 662 | 
If an expression can have both
false, andnullas possible values. It is generally a good practice to always use strict comparison to clearly distinguish between those two values.