Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.
Common duplication problems, and corresponding solutions are:
Complex classes like EEH_File 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 EEH_File, and based on these observations, apply Extract Interface, too.
| 1 | <?php |
||
| 25 | class EEH_File extends EEH_Base implements EEHI_File |
||
| 26 | { |
||
| 27 | |||
| 28 | /** |
||
| 29 | * @var string $_credentials_form |
||
| 30 | */ |
||
| 31 | private static $_credentials_form; |
||
| 32 | |||
| 33 | /** |
||
| 34 | * @var WP_Filesystem_Base $_wp_filesystem |
||
| 35 | */ |
||
| 36 | protected static $_wp_filesystem; |
||
| 37 | |||
| 38 | |||
| 39 | /** |
||
| 40 | * @param string $filepath the filepath we want to work in. If its in the |
||
| 41 | * wp uploads directory, we'll want to just use the filesystem directly. |
||
| 42 | * If not provided, we have to assume its not in the uploads directory |
||
| 43 | * @return WP_Filesystem_Base |
||
| 44 | */ |
||
| 45 | private static function _get_wp_filesystem($filepath = ''): WP_Filesystem_Base |
||
| 57 | |||
| 58 | |||
| 59 | /** |
||
| 60 | * @return WP_Filesystem_Base |
||
| 61 | */ |
||
| 62 | private static function loadAlternateWpFileSystem(): WP_Filesystem_Base |
||
| 118 | |||
| 119 | |||
| 120 | /** |
||
| 121 | * @return WP_Filesystem_Base |
||
| 122 | */ |
||
| 123 | private static function loadWpFileSystem(): WP_Filesystem_Base |
||
| 197 | |||
| 198 | |||
| 199 | /** |
||
| 200 | * display_request_filesystem_credentials_form |
||
| 201 | */ |
||
| 202 | public static function display_request_filesystem_credentials_form() |
||
| 208 | |||
| 209 | |||
| 210 | /** |
||
| 211 | * verify_filepath_and_permissions |
||
| 212 | * checks that a file is readable and has sufficient file permissions set to access |
||
| 213 | * |
||
| 214 | * @access public |
||
| 215 | * @param string $full_file_path - full server path to the folder or file |
||
| 216 | * @param string $file_name - name of file if checking a file |
||
| 217 | * @param string $file_ext - file extension (ie: "php") if checking a file |
||
| 218 | * @param string $type_of_file - general type of file (ie: "module"), this is only used to improve error messages |
||
| 219 | * @return bool |
||
| 220 | */ |
||
| 221 | public static function verify_filepath_and_permissions( |
||
| 257 | |||
| 258 | |||
| 259 | /** |
||
| 260 | * _permissions_error_for_unreadable_filepath - attempts to determine why permissions are set incorrectly for a |
||
| 261 | * file or folder |
||
| 262 | * |
||
| 263 | * @access private |
||
| 264 | * @param string $full_file_path - full server path to the folder or file |
||
| 265 | * @param string $type_of_file - general type of file (ie: "module"), this is only used to improve error messages |
||
| 266 | * @return string |
||
| 267 | */ |
||
| 268 | private static function _permissions_error_for_unreadable_filepath( |
||
| 299 | |||
| 300 | |||
| 301 | /** |
||
| 302 | * ensure_folder_exists_and_is_writable |
||
| 303 | * ensures that a folder exists and is writable, will attempt to create folder if it does not exist |
||
| 304 | * Also ensures all the parent folders exist, and if not tries to create them. |
||
| 305 | * Also, if this function creates the folder, adds a .htaccess file and index.html file |
||
| 306 | * |
||
| 307 | * @param string $folder |
||
| 308 | * @return bool false if folder isn't writable; true if it exists and is writeable, |
||
| 309 | */ |
||
| 310 | public static function ensure_folder_exists_and_is_writable(string $folder = ''): bool |
||
| 344 | |||
| 345 | |||
| 346 | /** |
||
| 347 | * verify_is_writable - checks if a file or folder is writable |
||
| 348 | * |
||
| 349 | * @param string $full_path - full server path to file or folder |
||
| 350 | * @param string $file_or_folder - whether checking a file or folder |
||
| 351 | * @return bool |
||
| 352 | */ |
||
| 353 | public static function verify_is_writable(string $full_path = '', string $file_or_folder = 'folder'): bool |
||
| 370 | |||
| 371 | |||
| 372 | /** |
||
| 373 | * ensure_file_exists_and_is_writable |
||
| 374 | * ensures that a file exists and is writable, will attempt to create file if it does not exist. |
||
| 375 | * Also ensures all the parent folders exist, and if not tries to create them. |
||
| 376 | * |
||
| 377 | * @param string $full_file_path |
||
| 378 | * @return bool |
||
| 379 | */ |
||
| 380 | public static function ensure_file_exists_and_is_writable(string $full_file_path = ''): bool |
||
| 404 | |||
| 405 | |||
| 406 | /** |
||
| 407 | * Gets the parent folder. If provided with file, gets the folder that contains it. |
||
| 408 | * If provided a folder, gets its parent folder. |
||
| 409 | * |
||
| 410 | * @param string $file_or_folder_path |
||
| 411 | * @return string parent folder, ENDING with a directory separator |
||
| 412 | */ |
||
| 413 | public static function get_parent_folder(string $file_or_folder_path): string |
||
| 423 | |||
| 424 | |||
| 425 | /** |
||
| 426 | * get_file_contents |
||
| 427 | * |
||
| 428 | * @param string $full_file_path |
||
| 429 | * @return string |
||
| 430 | */ |
||
| 431 | public static function get_file_contents(string $full_file_path = ''): string |
||
| 446 | |||
| 447 | |||
| 448 | /** |
||
| 449 | * write_file |
||
| 450 | * |
||
| 451 | * @param string $full_file_path |
||
| 452 | * @param string $file_contents - the content to be written to the file |
||
| 453 | * @param string $file_type |
||
| 454 | * @return bool |
||
| 455 | */ |
||
| 456 | public static function write_to_file( |
||
| 499 | |||
| 500 | |||
| 501 | /** |
||
| 502 | * Wrapper for WP_Filesystem_Base::delete |
||
| 503 | * |
||
| 504 | * @param string $filepath |
||
| 505 | * @param boolean $recursive |
||
| 506 | * @param boolean|string $type 'd' for directory, 'f' for file |
||
| 507 | * @return boolean |
||
| 508 | */ |
||
| 509 | public static function delete(string $filepath, bool $recursive = false, $type = false): bool |
||
| 514 | |||
| 515 | |||
| 516 | /** |
||
| 517 | * exists |
||
| 518 | * checks if a file exists using the WP filesystem |
||
| 519 | * |
||
| 520 | * @param string $full_file_path |
||
| 521 | * @return bool |
||
| 522 | */ |
||
| 523 | public static function exists(string $full_file_path = ''): bool |
||
| 528 | |||
| 529 | |||
| 530 | /** |
||
| 531 | * is_readable |
||
| 532 | * checks if a file is_readable using the WP filesystem |
||
| 533 | * |
||
| 534 | * @param string $full_file_path |
||
| 535 | * @return bool |
||
| 536 | */ |
||
| 537 | public static function is_readable(string $full_file_path = ''): bool |
||
| 542 | |||
| 543 | |||
| 544 | /** |
||
| 545 | * remove_filename_from_filepath |
||
| 546 | * given a full path to a file including the filename itself, this removes the filename and returns the path, up |
||
| 547 | * to, but NOT including the filename OR slash |
||
| 548 | * |
||
| 549 | * @param string $full_file_path |
||
| 550 | * @return string |
||
| 551 | */ |
||
| 552 | public static function remove_filename_from_filepath(string $full_file_path = ''): string |
||
| 556 | |||
| 557 | |||
| 558 | /** |
||
| 559 | * get_filename_from_filepath. Arguably the same as basename() |
||
| 560 | * |
||
| 561 | * @param string $full_file_path |
||
| 562 | * @return string |
||
| 563 | */ |
||
| 564 | public static function get_filename_from_filepath(string $full_file_path = ''): string |
||
| 568 | |||
| 569 | |||
| 570 | /** |
||
| 571 | * get_file_extension |
||
| 572 | * |
||
| 573 | * @param string $full_file_path |
||
| 574 | * @return string |
||
| 575 | */ |
||
| 576 | public static function get_file_extension(string $full_file_path = ''): string |
||
| 580 | |||
| 581 | |||
| 582 | /** |
||
| 583 | * add_htaccess_deny_from_all so the web server cannot access this folder |
||
| 584 | * |
||
| 585 | * @param string $folder |
||
| 586 | * @return bool |
||
| 587 | */ |
||
| 588 | View Code Duplication | public static function add_htaccess_deny_from_all(string $folder = ''): bool |
|
| 599 | |||
| 600 | |||
| 601 | /** |
||
| 602 | * Adds an index file to this folder, so folks can't list all the file's contents |
||
| 603 | * |
||
| 604 | * @param string $folder |
||
| 605 | * @return boolean |
||
| 606 | */ |
||
| 607 | View Code Duplication | public static function add_index_file(string $folder): bool |
|
| 622 | |||
| 623 | |||
| 624 | /** |
||
| 625 | * Given that the file in $file_path has the normal name, (ie, CLASSNAME.whatever.php), |
||
| 626 | * extract that classname. |
||
| 627 | * |
||
| 628 | * @param string $file_path |
||
| 629 | * @return string |
||
| 630 | */ |
||
| 631 | public static function get_classname_from_filepath_with_standard_filename(string $file_path): string |
||
| 639 | |||
| 640 | |||
| 641 | /** |
||
| 642 | * standardise_directory_separators |
||
| 643 | * convert all directory separators in a file path. |
||
| 644 | * |
||
| 645 | * @param string $file_path |
||
| 646 | * @param bool $rtrim will remove trailing backslash |
||
| 647 | * @return string |
||
| 648 | */ |
||
| 649 | public static function standardise_directory_separators(string $file_path, bool $rtrim = false): string |
||
| 654 | |||
| 655 | |||
| 656 | /** |
||
| 657 | * end_with_directory_separator |
||
| 658 | * ensures that file path ends with '/' |
||
| 659 | * |
||
| 660 | * @param string $file_path |
||
| 661 | * @return string |
||
| 662 | */ |
||
| 663 | public static function end_with_directory_separator(string $file_path): string |
||
| 667 | |||
| 668 | |||
| 669 | /** |
||
| 670 | * shorthand for both EEH_FIle::end_with_directory_separator AND EEH_File::standardise_directory_separators |
||
| 671 | * |
||
| 672 | * @param string $file_path |
||
| 673 | * @return string |
||
| 674 | */ |
||
| 675 | public static function standardise_and_end_with_directory_separator(string $file_path): string |
||
| 679 | |||
| 680 | |||
| 681 | /** |
||
| 682 | * takes the folder name (with or without trailing slash) and finds the files it in, |
||
| 683 | * and what the class's name inside of each should be. |
||
| 684 | * |
||
| 685 | * @param array $folder_paths |
||
| 686 | * @param boolean $index_numerically if TRUE, the returned array will be indexed numerically; |
||
| 687 | * if FALSE (Default), returned array will be indexed by the filenames minus |
||
| 688 | * extensions. Set it TRUE if you know there are files in the directory with the |
||
| 689 | * same name but different extensions |
||
| 690 | * @return array if $index_numerically == TRUE keys are numeric , |
||
| 691 | * if $index_numerically == FALSE (Default) keys are what the class names SHOULD |
||
| 692 | * be; and values are their file paths |
||
| 693 | */ |
||
| 694 | public static function get_contents_of_folders(array $folder_paths = [], bool $index_numerically = false): array |
||
| 719 | |||
| 720 | |||
| 721 | /** |
||
| 722 | * Copies a file. Mostly a wrapper of WP_Filesystem::copy |
||
| 723 | * |
||
| 724 | * @param string $source_file |
||
| 725 | * @param string $destination_file |
||
| 726 | * @param boolean $overwrite |
||
| 727 | * @return boolean success |
||
| 728 | */ |
||
| 729 | public static function copy(string $source_file, string $destination_file, bool $overwrite = false): bool |
||
| 760 | |||
| 761 | |||
| 762 | /** |
||
| 763 | * Reports whether or not the filepath is in the EE uploads folder or not |
||
| 764 | * |
||
| 765 | * @param string $filepath |
||
| 766 | * @return boolean |
||
| 767 | */ |
||
| 768 | public static function is_in_uploads_folder(string $filepath): bool |
||
| 773 | |||
| 774 | |||
| 775 | /** |
||
| 776 | * Given a "local" filepath (what you probably thought was the only filepath), |
||
| 777 | * converts it into a "remote" filepath (the filepath the currently-in-use |
||
| 778 | * $wp_filesystem needs to use access the folder or file). |
||
| 779 | * See http://wordpress.stackexchange.com/questions/124900/using-wp-filesystem-in-plugins |
||
| 780 | * |
||
| 781 | * @param string $local_filepath the filepath to the folder/file locally |
||
| 782 | * @return string the remote filepath (eg the filepath the filesystem method, eg |
||
| 783 | * ftp or ssh, will use to access the folder |
||
| 784 | */ |
||
| 785 | public static function convert_local_filepath_to_remote_filepath(string $local_filepath): string |
||
| 790 | |||
| 791 | |||
| 792 | /** |
||
| 793 | * wrapper for WP_Filesystem::chmod() |
||
| 794 | * |
||
| 795 | * @param string $file Path to the file. |
||
| 796 | * @param int|false $mode Optional. The permissions as octal number, usually 0644 for files, |
||
| 797 | * 0755 for directories. Default false. |
||
| 798 | * @param bool $recursive Optional. If set to true, changes file permissions recursively. |
||
| 799 | * Default false. |
||
| 800 | * @return bool True on success, false on failure. |
||
| 801 | */ |
||
| 802 | public static function chmod(string $file, $mode = false, bool $recursive = false): bool |
||
| 807 | |||
| 808 | |||
| 809 | /** |
||
| 810 | * wrapper for WP_Filesystem::getchmod() |
||
| 811 | * |
||
| 812 | * @param string $file Path to the file. |
||
| 813 | * @return string Mode of the file (the last 3 digits). |
||
| 814 | */ |
||
| 815 | public static function permissions(string $file): string |
||
| 820 | |||
| 821 | |||
| 822 | /** |
||
| 823 | * wrapper for WP_Filesystem::owner() |
||
| 824 | * |
||
| 825 | * @param string $file Path to the file. |
||
| 826 | * @return string|false Username of the owner on success, false on failure. |
||
| 827 | */ |
||
| 828 | public static function owner(string $file) |
||
| 833 | |||
| 834 | |||
| 835 | /** |
||
| 836 | * wrapper for WP_Filesystem::group() |
||
| 837 | * |
||
| 838 | * @param string $file Path to the file. |
||
| 839 | * @return string|false The group on success, false on failure. |
||
| 840 | */ |
||
| 841 | public static function group(string $file) |
||
| 846 | |||
| 847 | |||
| 848 | /** |
||
| 849 | * wrapper for WP_Filesystem::move() |
||
| 850 | * |
||
| 851 | * @param string $source Path to the source file. |
||
| 852 | * @param string $destination Path to the destination file. |
||
| 853 | * @param bool $overwrite Optional. Whether to overwrite the destination file if it exists. |
||
| 854 | * Default false. |
||
| 855 | * @return bool True on success, false on failure. |
||
| 856 | */ |
||
| 857 | public static function move(string $source, string $destination, bool $overwrite = false): bool |
||
| 890 | |||
| 891 | |||
| 892 | /** |
||
| 893 | * @param string $source_file |
||
| 894 | * @return string |
||
| 895 | */ |
||
| 896 | private static function validateFileForCopyOrMove(string $source_file): string |
||
| 914 | |||
| 915 | |||
| 916 | /** |
||
| 917 | * @param string $destination_file |
||
| 918 | * @return string |
||
| 919 | */ |
||
| 920 | private static function validateFolderForCopyOrMove(string $destination_file): string |
||
| 939 | } |
||
| 940 |
This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.
Consider making the comparison explicit by using
empty(..)or! empty(...)instead.