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 BambooHR 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 BambooHR, and based on these observations, apply Extract Interface, too.
| 1 | <?php |
||
| 248 | class BambooHR { |
||
| 249 | protected $companyDomain; |
||
| 250 | protected $httpHandler; |
||
| 251 | protected $baseUrl="https://api.bamboohr.com/api/gateway.php"; |
||
| 252 | |||
| 253 | /** |
||
| 254 | * |
||
| 255 | * |
||
| 256 | * @param string $companyDomain Either the subdomain of a BambooHR account ("example.bamboohr.com" => "example") or the full domain ("example.bamboohr.com") |
||
| 257 | * @param BambooHTTP $http |
||
| 258 | * @param string $baseUrl |
||
| 259 | */ |
||
| 260 | function __construct($companyDomain, BambooHTTP $http=null, $baseUrl=null) { |
||
| 272 | |||
| 273 | /** |
||
| 274 | * Set the api key to use. |
||
| 275 | * |
||
| 276 | * @param string $key |
||
| 277 | */ |
||
| 278 | function setSecretKey($key){ |
||
| 281 | |||
| 282 | /** |
||
| 283 | * Use the Login API to get a key for use in later API requests. |
||
| 284 | * To set the secretKey, you will need to parse the |
||
| 285 | * {@see \BambooHR\API\BambooHTTPResponse::$content} returned from this function and call |
||
| 286 | * {@see setSecretKey()} |
||
| 287 | * |
||
| 288 | * Use the {@see login()} as an alternative to this function that |
||
| 289 | * will do this work for you. |
||
| 290 | * |
||
| 291 | * @param string $applicationKey To ask about an applicationKey, email [email protected] |
||
| 292 | * @param string $email |
||
| 293 | * @param string $password |
||
| 294 | * @return \BambooHR\API\BambooHTTPResponse |
||
| 295 | * @link http://www.bamboohr.com/api/documentation/login.php |
||
| 296 | */ |
||
| 297 | View Code Duplication | function requestSecretKey($applicationKey, $email, $password) { |
|
| 304 | |||
| 305 | /** |
||
| 306 | * Use the Login API to get a key for use in later API requests. Also use the |
||
| 307 | * response to set up the authentication for future requests. Using this API |
||
| 308 | * requires you to contact BambooHR to get an applicationKey. |
||
| 309 | * |
||
| 310 | * @param string $applicationKey To ask about an applicationKey, email [email protected] |
||
| 311 | * @param string $email |
||
| 312 | * @param string $password |
||
| 313 | * @return bool |
||
| 314 | * @link http://www.bamboohr.com/api/documentation/login.php |
||
| 315 | */ |
||
| 316 | function login($applicationKey, $email, $password) { |
||
| 329 | |||
| 330 | /** |
||
| 331 | * |
||
| 332 | * |
||
| 333 | * @param int $employeeId |
||
| 334 | * @param array $fields an array of field aliases or ids |
||
| 335 | * @return \BambooHR\API\BambooHTTPResponse |
||
| 336 | * @link http://www.bamboohr.com/api/documentation/employees.php#getEmployee |
||
| 337 | */ |
||
| 338 | View Code Duplication | function getEmployee($employeeId, $fields=array()) { |
|
| 345 | |||
| 346 | /** |
||
| 347 | * |
||
| 348 | * @param int $reportId |
||
| 349 | * @param string $format one of xml, csv, xls, json, pdf |
||
| 350 | * @param bool $filterDuplicates |
||
| 351 | * @return \BambooHR\API\BambooHTTPResponse |
||
| 352 | * @link http://www.bamboohr.com/api/documentation/employees.php#requestCompanyReport |
||
| 353 | */ |
||
| 354 | function getReport($reportId, $format, $filterDuplicates=true) { |
||
| 363 | |||
| 364 | |||
| 365 | private function prepareKeyValues($values) { |
||
| 383 | |||
| 384 | /** |
||
| 385 | * Update an employee. pass a map of "fieldId" => "value". Does not work for table fields. |
||
| 386 | * |
||
| 387 | * @param int $employeeId |
||
| 388 | * @param array $fieldValues |
||
| 389 | * @return \BambooHR\API\BambooHTTPResponse |
||
| 390 | * @link http://www.bamboohr.com/api/documentation/employees.php#updateEmployee |
||
| 391 | */ |
||
| 392 | function updateEmployee($employeeId, $fieldValues=array()) { |
||
| 404 | |||
| 405 | /** |
||
| 406 | * |
||
| 407 | * @param int $employeeId |
||
| 408 | * @param array $fieldValues |
||
| 409 | * @return \BambooHR\API\BambooHTTPResponse |
||
| 410 | * @link http://www.bamboohr.com/api/documentation/employees.php#addEmployee |
||
| 411 | */ |
||
| 412 | function addEmployee($initialFieldValues=array()) { |
||
| 422 | |||
| 423 | /** |
||
| 424 | * |
||
| 425 | * @param string $format one of xml, csv, xls, json, pdf |
||
| 426 | * @param array $fields |
||
| 427 | * @param bool $filterDuplicates |
||
| 428 | * @param string $title |
||
| 429 | * @param string $lastChanged Date in ISO 8601 format, like: 2012-10-17T16:00:00Z |
||
| 430 | * @return \BambooHR\API\BambooHTTPResponse |
||
| 431 | * @link http://www.bamboohr.com/api/documentation/employees.php#requestCustomReport |
||
| 432 | */ |
||
| 433 | function getCustomReport($format, $fields, $filterDuplicates=true,$title="", $lastChanged="") { |
||
| 455 | |||
| 456 | /** |
||
| 457 | * |
||
| 458 | * @param int $employeeId |
||
| 459 | * @param string $tableName {@link http://www.bamboohr.com/api/documentation/tables.php#tables List of valid tables} |
||
| 460 | * @return \BambooHR\API\BambooHTTPResponse |
||
| 461 | * @link http://www.bamboohr.com/api/documentation/tables.php#getTable |
||
| 462 | */ |
||
| 463 | View Code Duplication | function getTable($employeeId, $tableName) { |
|
| 470 | |||
| 471 | /** |
||
| 472 | * |
||
| 473 | * @param string $since Date in ISO 8601 format, like: 2012-10-17T16:00:00Z |
||
| 474 | * @param string $type |
||
| 475 | * @return \BambooHR\API\BambooHTTPResponse |
||
| 476 | * @link http://www.bamboohr.com/api/documentation/changes.php#description |
||
| 477 | */ |
||
| 478 | View Code Duplication | function getChangedEmployees($since, $type="all") { |
|
| 484 | |||
| 485 | /** |
||
| 486 | * |
||
| 487 | * @param string $type |
||
| 488 | * @param Array $params |
||
| 489 | * @return \BambooHR\API\BambooHTTPResponse |
||
| 490 | * @link http://www.bamboohr.com/api/documentation/metadata.php |
||
| 491 | */ |
||
| 492 | View Code Duplication | function getMetaData($type, $params=array()) { |
|
| 498 | |||
| 499 | /** |
||
| 500 | * |
||
| 501 | * @return \BambooHR\API\BambooHTTPResponse |
||
| 502 | * @link http://www.bamboohr.com/api/documentation/metadata.php#users |
||
| 503 | */ |
||
| 504 | function getUsers() { |
||
| 507 | |||
| 508 | /** |
||
| 509 | * |
||
| 510 | * @return \BambooHR\API\BambooHTTPResponse |
||
| 511 | * @link http://www.bamboohr.com/api/documentation/metadata.php#lists |
||
| 512 | */ |
||
| 513 | function getLists() { |
||
| 516 | |||
| 517 | /** |
||
| 518 | * |
||
| 519 | * @return \BambooHR\API\BambooHTTPResponse |
||
| 520 | * @link http://www.bamboohr.com/api/documentation/metadata.php#fields |
||
| 521 | */ |
||
| 522 | function getFields() { |
||
| 525 | |||
| 526 | /** |
||
| 527 | * |
||
| 528 | * @return \BambooHR\API\BambooHTTPResponse |
||
| 529 | * @link http://www.bamboohr.com/api/documentation/metadata.php#tables |
||
| 530 | */ |
||
| 531 | function getTables() { |
||
| 534 | |||
| 535 | /** |
||
| 536 | * |
||
| 537 | * @param int $employeeId |
||
| 538 | * @param string $date (date in the format YYYY-mm-dd) |
||
| 539 | * @return \BambooHR\API\BambooHTTPResponse |
||
| 540 | * @link http://www.dev5.bamboohr.com/api/documentation/time_off.php#estimateFutureBalance |
||
| 541 | */ |
||
| 542 | function getTimeOffBalances($employeeId,$date) { |
||
| 548 | |||
| 549 | /** |
||
| 550 | * |
||
| 551 | * @return \BambooHR\API\BambooHTTPResponse |
||
| 552 | * @link http://www.dev5.bamboohr.com/api/documentation/metadata.php#timeOffTypes |
||
| 553 | */ |
||
| 554 | function getTimeOffTypes() { |
||
| 557 | |||
| 558 | /** |
||
| 559 | * |
||
| 560 | * @param type $arr array(["id" => int], ["action" => "(view|approve)"], ["type" => "id,id"],["status" => "(approved|denied|superceded|requested|canceled)"], ["start" => "YYYY-mm-dd"], ["end" => "YYYY-mm-dd"], ["employeeId" => "id"]) |
||
| 561 | * @return \BambooHR\API\BambooHTTPResponse |
||
| 562 | * @link http://www.dev5.bamboohr.com/api/documentation/time_off.php#requests |
||
| 563 | */ |
||
| 564 | function getTimeOffRequestsArr($arr) { |
||
| 577 | |||
| 578 | /** |
||
| 579 | * |
||
| 580 | * @param string $start format: "YYYY-mm-dd" |
||
| 581 | * @param string $end format "YYYY-mm-dd" |
||
| 582 | * @param string $status (approved|denied|superceded|requested|canceled) |
||
| 583 | * @param int $type A time off type id |
||
| 584 | * @param int $employeeId An employee id |
||
| 585 | * @return \BambooHR\API\BambooHTTPResponse |
||
| 586 | * @see getTimeOffTypes() |
||
| 587 | * @link http://www.bamboohr.com/api/documentation/time_off.php#requests |
||
| 588 | */ |
||
| 589 | function getTimeOffRequests($start="", $end="", $status="", $type="", $employeeId=0) { |
||
| 598 | |||
| 599 | /** |
||
| 600 | * |
||
| 601 | * @param int $employeeId An employee id |
||
| 602 | * @param string $tableName A table alias. Check out function |
||
| 603 | * @param array $values |
||
| 604 | * @return \BambooHR\API\BambooHTTPResponse |
||
| 605 | * @see getTables() |
||
| 606 | * @link http://www.bamboohr.com/api/documentation/tables.php#addRow |
||
| 607 | */ |
||
| 608 | View Code Duplication | function addTableRow($employeeId, $tableName, $values) { |
|
| 618 | |||
| 619 | /** |
||
| 620 | * |
||
| 621 | * @param int $employeeId |
||
| 622 | * @param string $start format: YYYY-mm-dd |
||
| 623 | * @param string $end format: YYYY-mm-dd |
||
| 624 | * @param int $timeOffTypeId |
||
| 625 | * @param float $amount |
||
| 626 | * @param string $status (approved|denied|superceded|requested|canceled) |
||
| 627 | * @param string $employeeNote |
||
| 628 | * @param string $managerNote |
||
| 629 | * @param int $previous |
||
| 630 | * @return \BambooHR\API\BambooHTTPResponse |
||
| 631 | * @link http://www.bamboohr.com/api/documentation/time_off.php#addrequest |
||
| 632 | */ |
||
| 633 | function addTimeOffRequest($employeeId, $start, $end, $timeOffTypeId, $amount, $status, $employeeNote, $managerNote,$previous=0) { |
||
| 663 | |||
| 664 | /** |
||
| 665 | * |
||
| 666 | * @param int $employeeId |
||
| 667 | * @param string $ymd format: "YYYY-m-d" |
||
| 668 | * @param int $requestId |
||
| 669 | * @return \BambooHR\API\BambooHTTPResponse |
||
| 670 | * @link http://www.bamboohr.com/api/documentation/time_off.php#addhistory |
||
| 671 | */ |
||
| 672 | function addTimeOffHistoryFromRequest($employeeId, $ymd, $requestId) { |
||
| 691 | |||
| 692 | /** |
||
| 693 | * |
||
| 694 | * @param int $employeeId |
||
| 695 | * @param string $ymd format: "YYYY-mm-dd" |
||
| 696 | * @param int $timeOffTypeId |
||
| 697 | * @param string $note |
||
| 698 | * @param float $amount |
||
| 699 | * @return \BambooHR\API\BambooHTTPResponse |
||
| 700 | * @link http://www.bamboohr.com/api/documentation/time_off.php#addhistory |
||
| 701 | * @see getTimeOffTypes() |
||
| 702 | */ |
||
| 703 | function recordTimeOffOverride($employeeId, $ymd, $timeOffTypeId, $note, $amount) { |
||
| 723 | |||
| 724 | /** |
||
| 725 | * |
||
| 726 | * @param int $employeeId |
||
| 727 | * @param string $tableName |
||
| 728 | * @param int $rowId |
||
| 729 | * @param array $values |
||
| 730 | * @return \BambooHR\API\BambooHTTPResponse |
||
| 731 | * @link http://www.bamboohr.com/api/documentation/tables.php#updateRow |
||
| 732 | * @see getTables() |
||
| 733 | */ |
||
| 734 | View Code Duplication | function updateTableRow($employeeId, $tableName, $rowId, $values) { |
|
| 744 | |||
| 745 | /** |
||
| 746 | * |
||
| 747 | * @param int $employeeId |
||
| 748 | * @param int $categoryId |
||
| 749 | * @param string $fileName |
||
| 750 | * @param string $contentType |
||
| 751 | * @param string $fileData |
||
| 752 | * @param string $shareWithEmployees (yes|no) |
||
| 753 | * @return \BambooHR\API\BambooHTTPResponse |
||
| 754 | * @link http://www.bamboohr.com/api/documentation/employees.php#uploadEmployeeFile |
||
| 755 | * @see listEmployeeFiles() |
||
| 756 | */ |
||
| 757 | View Code Duplication | function uploadEmployeeFile($employeeId, $categoryId, $fileName, $contentType, $fileData, $shareWithEmployees = 'no') { |
|
| 773 | |||
| 774 | /** |
||
| 775 | * |
||
| 776 | * @param int $requestId |
||
| 777 | * @param string $status (approved|denied|superceded|requested|canceled) |
||
| 778 | * @param string $note |
||
| 779 | * @return \BambooHR\API\BambooHTTPResponse |
||
| 780 | * @link http://www.bamboohr.com/api/documentation/time_off.php#updateRequestStatus |
||
| 781 | */ |
||
| 782 | function updateTimeOffRequestStatus($requestId, $status, $note) { |
||
| 789 | |||
| 790 | /** |
||
| 791 | * |
||
| 792 | * @param int $categoryId |
||
| 793 | * @param string $fileName |
||
| 794 | * @param string $contentType |
||
| 795 | * @param string $fileData |
||
| 796 | * @param string $shareWithEmployees (yes|no) |
||
| 797 | * @return \BambooHR\API\BambooHTTPResponse |
||
| 798 | * @link http://www.bamboohr.com/api/documentation/employees.php#uploadCompanyFile |
||
| 799 | * @see getCompanyFiles() |
||
| 800 | */ |
||
| 801 | View Code Duplication | function uploadCompanyFile($categoryId, $fileName, $contentType, $fileData, $shareWithEmployees = 'no') { |
|
| 817 | |||
| 818 | /** |
||
| 819 | * |
||
| 820 | * @param int $employeeId |
||
| 821 | * @return \BambooHR\API\BambooHTTPResponse |
||
| 822 | * @link http://www.bamboohr.com/api/documentation/employees.php#listEmployeeFiles |
||
| 823 | */ |
||
| 824 | View Code Duplication | function listEmployeeFiles($employeeId){ |
|
| 830 | |||
| 831 | /** |
||
| 832 | * |
||
| 833 | * @return \BambooHR\API\BambooHTTPResponse |
||
| 834 | * @link http://www.bamboohr.com/api/documentation/employees.php#listCompanyFiles |
||
| 835 | */ |
||
| 836 | View Code Duplication | function listCompanyFiles(){ |
|
| 842 | |||
| 843 | /** |
||
| 844 | * |
||
| 845 | * @param string $categoryName |
||
| 846 | * @return \BambooHR\API\BambooHTTPResponse |
||
| 847 | * @link http://www.bamboohr.com/api/documentation/employees.php#addEmployeeCategory |
||
| 848 | */ |
||
| 849 | View Code Duplication | function addEmployeeFileCategory($categoryName){ |
|
| 861 | |||
| 862 | /** |
||
| 863 | * |
||
| 864 | * @param string $categoryName |
||
| 865 | * @return \BambooHR\API\BambooHTTPResponse |
||
| 866 | * @link http://www.bamboohr.com/api/documentation/employees.php#addCompanyCategory |
||
| 867 | */ |
||
| 868 | View Code Duplication | function addCompanyFileCategory($categoryName){ |
|
| 880 | |||
| 881 | /** |
||
| 882 | * |
||
| 883 | * @param int $employeeId |
||
| 884 | * @param int $fileId |
||
| 885 | * @param array $values array(["name" => "new name"],["categoryId" => 1],["shareWithEmployee" => "(yes|no)"]); |
||
| 886 | * @return \BambooHR\API\BambooHTTPResponse |
||
| 887 | * @link http://www.bamboohr.com/api/documentation/employees.php#updateEmployeeFile |
||
| 888 | */ |
||
| 889 | View Code Duplication | function updateEmployeeFile($employeeId, $fileId, $values){ |
|
| 903 | |||
| 904 | /** |
||
| 905 | * |
||
| 906 | * @param int $fileId |
||
| 907 | * @param array $values array(["name" => "new name"],["categoryId" => 1],["shareWithEmployees" => "(yes|no)"]) |
||
| 908 | * @return \BambooHR\API\BambooHTTPResponse |
||
| 909 | * @link http://www.bamboohr.com/api/documentation/employees.php#updateCompanyFile |
||
| 910 | */ |
||
| 911 | View Code Duplication | function updateCompanyFile($fileId, $values){ |
|
| 925 | |||
| 926 | /** |
||
| 927 | * |
||
| 928 | * @param int $employeeId |
||
| 929 | * @param int $fileId |
||
| 930 | * @return \BambooHR\API\BambooHTTPResponse |
||
| 931 | * @link http://www.bamboohr.com/api/documentation/employees.php#downloadEmployeeFile |
||
| 932 | */ |
||
| 933 | View Code Duplication | function downloadEmployeeFile($employeeId, $fileId) { |
|
| 940 | |||
| 941 | /** |
||
| 942 | * |
||
| 943 | * @param int $fileId |
||
| 944 | * @return \BambooHR\API\BambooHTTPResponse |
||
| 945 | * @link http://www.bamboohr.com/api/documentation/employees.php#downloadCompanyFile |
||
| 946 | */ |
||
| 947 | View Code Duplication | function downloadCompanyFile($fileId){ |
|
| 953 | |||
| 954 | /** |
||
| 955 | * This api is undocumented. It is only useful for importing large numbers of |
||
| 956 | * employees. Look at the test_import.xml file for an example import. |
||
| 957 | * |
||
| 958 | * @param string $xml |
||
| 959 | * @return \BambooHR\API\BambooHTTPResponse |
||
| 960 | */ |
||
| 961 | View Code Duplication | function importEmployees($xml){ |
|
| 969 | |||
| 970 | /** |
||
| 971 | * |
||
| 972 | * @return \BambooHR\API\BambooHTTPResponse |
||
| 973 | * @link http://www.dev5.bamboohr.com/api/documentation/employees.php#getEmployeeDirectory |
||
| 974 | */ |
||
| 975 | View Code Duplication | function getDirectory() { |
|
| 981 | |||
| 982 | /** |
||
| 983 | * |
||
| 984 | * @param int |
||
| 985 | * @param int|string (1|2|small|tiny) |
||
| 986 | * @param array array(["width" => 100], ["height" => 100]) |
||
| 987 | * @return \BambooHR\API\BambooHTTPResponse |
||
| 988 | */ |
||
| 989 | View Code Duplication | function downloadEmployeePhoto($employeeId, $size, $params=array()) { |
|
| 998 | |||
| 999 | /** |
||
| 1000 | * |
||
| 1001 | * @param string an alias from {@see getTables()} |
||
| 1002 | * @param string format: 2012-19-29T11:53:05Z |
||
| 1003 | * @return \BambooHR\API\BambooHTTPResponse |
||
| 1004 | * @link http://www.bamboohr.com/api/documentation/tables.php#changedEmployeeTables |
||
| 1005 | */ |
||
| 1006 | function getChangedEmployeeTable($table,$since) { |
||
| 1012 | } |
||
| 1013 |
Having each class in a dedicated file usually plays nice with PSR autoloaders and is therefore a well established practice. If you use other autoloaders, you might not want to follow this rule.