I have this annoying problem in PHP with faking overloading constructors. I understand the concept, but the code I produce feels kind of ugly. It isn't a lot of code, just bad code. Any ideas on how to make this sane?
/**
* Instantiate Fencer object from user meta database.
*
* If fencer data does not exist in database and USFA ID is provided,
* it will automatically update from API
*
* If USFA ID is not provided, will throw exception
*
* If API data is provided, a user ID must also be provided
* that way we can save the data from the API to the user.
*
* @param int|null $user_id
* @param string|null $usfa_id
* @param array|null $raw_data
*
* @throws InvalidArgumentException
* 1. If the user does not exist and USFA ID not provided
* 2. Raw API data is provided, but not a User ID to save it to
*/
private function __construct( $user_id = null, $usfa_id = null, $raw_data = null ) {
if ( $raw_data === null ) {
if ( null === $user_id ) {
$user_id = self::get_user_id_from_usfa_id( $usfa_id );
}
$this->wp_id = $user_id;
$fencerdata = get_user_meta( $user_id, 'fence_plus_fencer_data', true );
if ( ! empty( $fencerdata ) ) {
foreach ( $fencerdata as $key => $data ) {
call_user_func( array( $this, 'set_' . $key ), $data );
// set all properties by calling internal setters based on fencer user meta data key
}
}
else if ( $usfa_id != null ) {
$this->usfa_id = $usfa_id;
$this->update();
$this->save();
}
else {
throw new InvalidArgumentException( "Fencer data does not exist. Instantiate with USFA ID", 1 );
}
}
else {
if ( null == $user_id ) {
throw new InvalidArgumentException( "User ID must be provided when instantiating with raw API data", 2 );
}
$this->wp_id = $user_id;
$this->process_api_data( array( $raw_data ) );
$this->interpret_data();
$this->save();
}
}