curl_request_obj = $curl_request_obj;
$this->file_system_helper = $file_system_helper;
$this->db_upload_dir = $db_upload_dir;
$this->db_file_path = $this->db_upload_dir . Plugin_Constants::MAXMIND_DATA_FILENAME;
clearstatcache( true, $this->db_file_path );
}
/*
* Returns the error message if any in updating maxmind database. On success it returns an empty string
*
* @return String Error_message if any else empty string if no error
*
* @since 1.5.3
*/
public function get_error_message() {
$error_msg = "";
if ( ! file_exists( $this->db_file_path ) ) {
if ( ! is_writable( $this->db_upload_dir ) ) {
$error_msg = sprintf( esc_html__( "WordPress does not have permissions to write to the \"Downloads Folder\" (%s). Please grant permissions or pick a different folder from the Amazon Associates Link Builder plugin's settings page, otherwise your links to Amazon might not display correctly.", 'amazon-associates-link-builder' ), $this->db_upload_dir );
} else {
$error_msg = sprintf( __( "WordPress could not find file %1s at \"DownloadsFolder\"(%2s), so geo-targeted links will not work correctly. This file can be downloaded from here", 'amazon-associates-link-builder' ), Plugin_Constants::MAXMIND_DATA_FILENAME, $this->db_upload_dir, Library_Endpoints::GEOLITE_DB_DOWNLOAD_URL_FROM_MAXMIND_SERVER );
}
} else {
if ( ! is_readable( $this->db_file_path ) ) {
$error_msg = sprintf( esc_html__( "WordPress could not read %s. Please grant read permissions, otherwise your links to Amazon might not display correctly.", 'amazon-associates-link-builder' ), $this->db_file_path );
} else if ( $this->get_file_age( $this->db_file_path ) > AALB_GEOLITE_DB_MAX_ALLOWED_AGE ) {
if ( ! is_writable( $this->db_file_path ) ) {
$error_msg = sprintf( __( "WordPress does not have write permissions to update the file(%s). Please grant write permissions, otherwise geo-targeted links may not work correctly.", 'amazon-associates-link-builder' ), $this->db_file_path );
} else {
$error_msg = sprintf( __( "WordPress could not update file(%1s) for geo-targeted links feature, so these links may not work correctly. This file can be downloaded from here", 'amazon-associates-link-builder' ), $this->db_file_path, Library_Endpoints::GEOLITE_DB_DOWNLOAD_URL_FROM_MAXMIND_SERVER );
}
}
}
return $error_msg;
}
/*
* Finds the age of file
*
* @param String $file_path
*
* @return int Age of file in seconds
*
* @since 1.5.3
*/
private function get_file_age( $file_path ) {
return time() - filemtime( $file_path );
}
/*
* It checks if the GeoLite Db downloaded file has expired and call for update
*
* @since 1.5.0
*
*/
public function update_db_if_required() {
try {
if ( $this->is_file_update_permissible() ) {
$this->reset_db_keys_if_required();
if ( time() >= get_option( Db_Constants::GEOLITE_DB_DOWNLOAD_NEXT_RETRY_TIME ) ) {
if ( $this->should_update_db() ) {
$this->update_db();
}
$this->update_next_retry_time( Plugin_Constants::SUCCESS );
}
}
} catch ( Network_Call_Failure_Exception $e ) {
$this->action_on_update_db_failure( $e->errorMessage() );
} catch ( Unexpected_Network_Response_Exception $e ) {
$this->action_on_update_db_failure( $e->errorMessage() );
} catch ( \Exception $e ) {
$this->action_on_update_db_failure( "Unexpected Exception Ocurred" . $e->getMessage() );
}
}
/**
* Downloads & updates the maxmind db file(GeoLite2 Country)
*
* @argument HTTP Response $response
*
* @throws Network_Call_Failure_Exception
*
* @since 1.5.0
*
*/
private function update_db() {
$tmp_file = $this->curl_request_obj->download_file_to_temporary_file( Library_Endpoints::GEOLITE_COUNTRY_DB_DOWNLOAD_URL );
$this->file_system_helper->write_a_gzipped_file_to_disk( $this->db_file_path, $tmp_file );
}
/**
* It logs the error message and updates next retry time
*
* @param \String Error message
*
*
* @since 1.5.3
*
**/
private function action_on_update_db_failure( $error_msg ) {
$this->log_error( $error_msg );
$this->update_next_retry_time( Plugin_Constants::FAIL );
}
/*
* It checks if upload path has changed and in case of change, set lat upload path as new path, next retry time to 0 & reset failure counters
*
* @since 1.5.0
*
*/
private function reset_db_keys_if_required() {
if ( $this->is_upload_path_changed() ) {
update_option( Db_Constants::MAXMIND_DB_LAST_UPLOAD_PATH, $this->db_upload_dir );
update_option( Db_Constants::GEOLITE_DB_DOWNLOAD_NEXT_RETRY_TIME, 0 );
$this->reset_failure_counters();
}
}
/*
* It checks if earlier upload permissions were not present but were given just before running this function
*
* @return bool true if upload_permission_given_recently
*
* @since 1.5.3
*
*/
private function is_file_update_permissible() {
if ( ! file_exists( $this->db_file_path ) ) {
return is_writable( $this->db_upload_dir );
} else {
return is_readable( $this->db_file_path ) && is_writable( $this->db_file_path );
}
}
/*
* It checks if upload path for maxmind db has changed
*
* @since 1.5.3
*
*/
private function is_upload_path_changed() {
return $this->db_upload_dir !== get_option( Db_Constants::MAXMIND_DB_LAST_UPLOAD_PATH );
}
/*
* It checks if file is not present or if present, a newwer version is vavialble
*
* @since 1.5.0
*
* @bool True if geolite db should be updated
*/
private function should_update_db() {
return ! file_exists( $this->db_file_path ) || ( $this->is_updated_version_available() );
}
/*
* It checks if the current version of GeoLite Db file's last modified date is greater than the time file was written in db
*
* @ since 1.5.0
*
* @return bool True if geolite db's newer version is available
*/
private function is_updated_version_available() {
return strtotime( $this->curl_request_obj->get_last_modified_date_of_remote_file( Library_Endpoints::GEOLITE_COUNTRY_DB_DOWNLOAD_URL ) ) > filemtime( $this->db_file_path );
}
/**
* It updates the next retry time for downloading maxmind
*
* @param String status SUCCESS or FAIL
*
* @since 1.5.3
*
*/
private function update_next_retry_time( $status ) {
if ( $status == Plugin_Constants::SUCCESS ) {
update_option( Db_Constants::GEOLITE_DB_DOWNLOAD_NEXT_RETRY_TIME, time() + AALB_GEOLITE_DB_DOWNLOAD_RETRY_DURATION_ON_SUCCESS );
$this->reset_failure_counters();
} else {
update_option( Db_Constants::GEOLITE_DB_DOWNLOAD_NEXT_RETRY_TIME, time() + $this->get_next_retry_duration() );
}
}
/**
* It returns the next-retry duration & also updates no. of failed attempts & failure_duration
*
* @since 1.5.3
*
*/
private function get_next_retry_duration() {
$number_of_failed_attempts = get_option( Db_Constants::GEOLITE_DB_DOWNLOAD_FAILED_ATTEMPTS );
$new_retry_duration = AALB_GEOLITE_DB_DOWNLOAD_RETRY_DURATION_MIN * pow( 2, $number_of_failed_attempts );
if ( $new_retry_duration > AALB_GEOLITE_DB_DOWNLOAD_RETRY_DURATION_MAX ) {
$new_retry_duration = AALB_GEOLITE_DB_DOWNLOAD_RETRY_DURATION_MAX;
}
update_option( Db_Constants::GEOLITE_DB_DOWNLOAD_FAILED_ATTEMPTS, $number_of_failed_attempts + 1 );
update_option( Db_Constants::GEOLITE_DB_DOWNLOAD_RETRY_ON_FAILURE_DURATION, $new_retry_duration );
return $new_retry_duration;
}
/**
* It resets the failure counters for next retry
*
* @since 1.5.3
*
*/
private function reset_failure_counters() {
update_option( Db_Constants::GEOLITE_DB_DOWNLOAD_RETRY_ON_FAILURE_DURATION, AALB_GEOLITE_DB_DOWNLOAD_RETRY_DURATION_MIN );
update_option( Db_Constants::GEOLITE_DB_DOWNLOAD_FAILED_ATTEMPTS, 0 );
}
/*
* Log error if allowed
*
* @param String error_msg
*
* @since 1.5.3
*/
private function log_error( $error_msg ) {
if ( $this->should_log_error() ) {
error_log( $error_msg );
}
}
/*
* Checks if error should be logged or not
*
* @return bool true if should_log_error
*
* @since 1.5.3
*/
private function should_log_error() {
return current_user_can( 'activate_plugins' ) && is_admin();
}
}
?>