self::RESET_AFTER + 1 && '' !== self::get_last_message() ) {
Ahrefs_Seo::set_fatal_error( null, self::get_last_message(), false, true );
} else {
Ahrefs_Seo::set_fatal_error( null, __( 'We are updating the database right now so please check back on this page in a few minutes. Thank you for your patience!', 'ahrefs-seo' ), false, true );
}
return false;
}
try {
set_transient( $transient_name, 1, MINUTE_IN_SECONDS ); // set value immediately.
$counter = self::counter_increase();
set_transient( $transient_name, $counter, MINUTE_IN_SECONDS );
Ahrefs_Seo::breadcrumbs( "Try {$counter}" );
if ( $counter > self::RESET_AFTER + 1 ) {
set_transient( $transient_name, $counter, HOUR_IN_SECONDS ); // do update once per hour.
$previous_version = 1; // do a full reset.
}
$result = true;
$charset_collate = $wpdb->get_charset_collate();
require_once ABSPATH . 'wp-admin/includes/upgrade.php';
if ( $previous_version > 1 ) {
$table_content_exists = $wpdb->get_var( "SHOW TABLES LIKE '{$wpdb->ahrefs_content}';" );
$unique_post_id_exists = false;
if ( $table_content_exists ) {
$info = $wpdb->get_row( "SHOW INDEX FROM {$wpdb->ahrefs_content} where key_name = 'post_id'", ARRAY_A );
$unique_post_id_exists = empty( $info['Non_unique'] );
$info = $wpdb->get_row( "SHOW INDEX FROM {$wpdb->ahrefs_content} where key_name = 'snapshot_and_post_id'", ARRAY_A );
if ( ! empty( $info ) ) {
$wpdb->query( "ALTER TABLE {$wpdb->ahrefs_content} DROP INDEX `snapshot_and_post_id`" ); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.SchemaChange -- index before 0.8, this is plugin table.
if ( ! empty( $wpdb->last_error ) && self::check_stop_error( $wpdb->last_error ) ) {
return false;
}
}
$info = $wpdb->get_results( "SHOW INDEX FROM {$wpdb->ahrefs_content} where key_name = 'PRIMARY'", ARRAY_A );
if ( is_array( $info ) ) {
$info = array_map(
function ( $item ) {
return isset( $item['Column_name'] ) ? $item['Column_name'] : '';
},
$info
);
if ( 3 !== count( $info ) || 3 !== count( array_intersect( $info, [ 'snapshot_id', 'post_id', 'taxonomy' ] ) ) ) { // other primary key exists.
$wpdb->query( "ALTER TABLE {$wpdb->ahrefs_content} DROP INDEX `PRIMARY`" ); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.SchemaChange -- indexes before 0.8, this is plugin table.
if ( ! empty( $wpdb->last_error ) && self::check_stop_error( $wpdb->last_error ) ) {
return false;
}
}
}
}
if ( $wpdb->get_var( "SHOW TABLES LIKE '{$wpdb->prefix}ahrefs_seo_keywords';" ) || $wpdb->get_var( "SHOW TABLES LIKE '{$wpdb->prefix}ahrefs_seo_backlinks';" ) || $unique_post_id_exists ) {
$previous_version = 1; // force update if old table exists or has old indexes.
}
if ( $table_content_exists ) {
$len = $wpdb->get_col_length( $wpdb->ahrefs_content, 'keyword' );
if ( ! empty( $len ) && is_array( $len ) && isset( $len['length'] ) && $len['length'] > 191 ) { // need to update column length.
$wpdb->query( "ALTER TABLE {$wpdb->ahrefs_content} CHANGE `keyword` `keyword` VARCHAR(191) DEFAULT NULL" ); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.SchemaChange -- this is plugin table.
if ( ! empty( $wpdb->last_error ) && self::check_stop_error( $wpdb->last_error ) ) {
return false;
}
$wpdb->flush();
}
}
}
if ( $previous_version > 0 && $previous_version < 57 ) { // do a full reset and run wizard again.
if ( ! self::reset_before_v0_7() ) {
return false;
}
}
$sql = "CREATE TABLE {$wpdb->ahrefs_content} (
`post_id` bigint(20) unsigned NOT NULL,
`taxonomy` varchar(32) NOT NULL DEFAULT '',
`snapshot_id` int(10) unsigned NOT NULL DEFAULT 0,
`total` int(10) DEFAULT NULL,
`total_month` int(10) DEFAULT NULL,
`organic` int(10) DEFAULT NULL,
`organic_month` int(10) DEFAULT NULL,
`backlinks` int(10) DEFAULT NULL,
`refdomains` int(10) DEFAULT NULL,
`position` float DEFAULT NULL,
`action` enum('added_since_last','noindex','manually_excluded','out_of_scope','newly_published','error_analyzing','do_nothing','update_yellow','merge','exclude','update_orange','delete','analyzing','analyzing_initial','out_of_scope_initial','analyzing_final','out_of_scope_analyzing','noncanonical','rewrite','redirected') NOT NULL DEFAULT 'added_since_last',
`inactive` tinyint(1) NOT NULL DEFAULT '0',
`is_excluded` tinyint(1) NOT NULL DEFAULT '0',
`is_included` tinyint(1) NOT NULL DEFAULT '0',
`is_noindex` tinyint(1) DEFAULT NULL,
`is_noncanonical` tinyint(1) DEFAULT NULL,
`is_redirected` tinyint(1) DEFAULT NULL,
`ignore_newly` tinyint(1) NOT NULL DEFAULT '0',
`ignore_noindex` tinyint(1) NOT NULL DEFAULT '0',
`is_approved_keyword` tinyint(1) NOT NULL DEFAULT '0',
`updated` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`tries` smallint(5) unsigned NOT NULL DEFAULT '0',
`error_traffic` text NULL DEFAULT NULL,
`error_backlinks` text NULL DEFAULT NULL,
`error_position` text NULL DEFAULT NULL,
`keyword` varchar(191) DEFAULT NULL,
`keyword_manual` varchar(191) DEFAULT NULL,
`position_need_update` tinyint(1) NOT NULL DEFAULT '1',
`keywords_need_update` tinyint(1) NOT NULL DEFAULT '1',
`last_well_date` date DEFAULT NULL,
`is_duplicated` int(1) unsigned NOT NULL DEFAULT '0',
`kw_gsc` text DEFAULT NULL,
`kw_idf` text DEFAULT NULL,
`kw_imported` text DEFAULT NULL,
`kw_pos` text DEFAULT NULL,
`kw_low` tinyint(1) unsigned DEFAULT NULL,
`kw_source` enum('no-keyword','too-short','gsc','tf-idf','manual','yoast','aioseo','rankmath') DEFAULT NULL,
`title` text NOT NULL,
`noindex_data` text DEFAULT NULL,
`canonical_data` text DEFAULT NULL,
`redirected_data` text DEFAULT NULL,
`badge` varchar(20) NOT NULL DEFAULT '',
`date_updated` datetime DEFAULT NULL,
KEY `post_id` (`post_id`),
PRIMARY KEY (`snapshot_id`, `post_id`, `taxonomy`),
KEY `snapshot_id` (`snapshot_id`),
KEY `keyword` (`keyword`),
KEY `inactive` (`inactive`),
KEY `last_well_date` (`last_well_date`),
KEY `action` (`action`),
KEY `is_duplicated` (`is_duplicated`)
) {$charset_collate};";
$s = dbDelta( $sql );
$error = $wpdb->last_error;
$query = $wpdb->last_query;
if ( ! empty( $error ) && ! self::retry_table_update( $sql, $wpdb->ahrefs_content ) ) {
$message = 'Unable to create or update Content table.';
$message_trans = __( 'Unable to create or update Content table.', 'ahrefs-seo' );
Ahrefs_Seo::notify( new Ahrefs_Seo_Exception( sprintf( '%s [%s] [%s] [%s] [%s]', $message, $error, (string) wp_json_encode( $sql ), (string) wp_json_encode( $s ), (string) wp_json_encode( $query ) ) ) ); // initial query, result and error.
Ahrefs_Seo_Errors::save_message( 'database', "{$message_trans} {$error}", Message::TYPE_ERROR );
if ( is_null( self::get_stop_error() ) ) {
self::set_error( __( 'Fatal error on DB tables update.', 'ahrefs-seo' ) . ' ' . $error );
}
if ( $counter < self::RESET_AFTER + 2 ) {
delete_transient( $transient_name );
}
return false;
}
$sql = "CREATE TABLE {$wpdb->ahrefs_snapshots} (
`snapshot_id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`time_start` datetime,
`time_end` datetime DEFAULT NULL,
`snapshot_status` enum('new','current','old','cancelled') NOT NULL DEFAULT 'new',
`traffic_median` float DEFAULT NULL,
`snapshot_version` tinyint(1) unsigned NOT NULL DEFAULT 1,
`require_update` tinyint(1) unsigned NOT NULL DEFAULT 0,
`rules_version` tinyint(1) unsigned NOT NULL DEFAULT 4,
`snapshot_type` enum('manual','scheduled','scheduled_restarted','manual_finished','scheduled_finished') NOT NULL DEFAULT 'manual',
`country` char(3) NOT NULL DEFAULT '',
PRIMARY KEY (`snapshot_id`),
KEY `snapshot_status` (`snapshot_status`)
) {$charset_collate};";
$s = dbDelta( $sql );
$error = $wpdb->last_error;
if ( ! empty( $error ) && ! self::retry_table_update( $sql, $wpdb->ahrefs_snapshots ) ) {
$message = 'Unable to create or update Snapshots table.';
$message_trans = __( 'Unable to create or update Snapshots table.', 'ahrefs-seo' );
Ahrefs_Seo::notify( new Ahrefs_Seo_Exception( sprintf( '%s [%s] [%s] [%s]', $message, $error, (string) wp_json_encode( $sql ), (string) wp_json_encode( $s ) ) ) ); // initial query, result and error.
Ahrefs_Seo_Errors::save_message( 'database', "{$message_trans} {$error}", Message::TYPE_ERROR );
if ( is_null( self::get_stop_error() ) ) {
self::set_error( __( 'Fatal error on DB tables update', 'ahrefs-seo' ) . ' ' . $error );
}
if ( $counter < self::RESET_AFTER + 2 ) {
delete_transient( $transient_name );
}
$result = false;
}
if ( $previous_version > 0 && $previous_version < 63 ) { // fill titles and dates.
self::update_before_v0_8();
}
if ( $previous_version > 0 && $previous_version < 68 ) { // fill last well date.
self::update_before_v0_8_4();
}
if ( $previous_version > 0 && $previous_version < 70 ) { // fill is_duplicated.
self::update_before_v0_8_5();
}
self::counter_reset();
delete_transient( $transient_name );
} catch ( Error $e ) {
Ahrefs_Seo::notify( $e, 'db' );
self::set_stop_error( 'Error during DB update: ' . $e->getMessage(), $e->getTraceAsString() );
Ahrefs_Seo::set_fatal_error( 'Error during DB update: ' . $e->getMessage(), $e->getTraceAsString(), true, true );
return false;
} catch ( Exception $e ) {
Ahrefs_Seo::notify( $e, 'db' );
self::set_stop_error( 'Error during DB update: ' . $e->getMessage(), $e->getTraceAsString() );
Ahrefs_Seo::set_fatal_error( 'Error during DB update: ' . $e->getMessage(), $e->getTraceAsString(), true, true );
return false;
}
return $result;
}
/**
* Retry table update.
* Put additional errors to breadcrumbs.
*
* @since 0.7.4
*
* @param string $sql SQL query.
* @param string $table_name Table name.
* @return bool
*/
private static function retry_table_update( $sql, $table_name ) {
/** @var wpdb $wpdb */
global $wpdb;
$last_error = $wpdb->last_error;
if ( false !== strpos( $last_error, "Unknown character set: 'utf" ) || false !== strpos( $last_error, "Unknown collation: 'utf" ) ) {
$original_sql = $sql;
$sql = str_replace( 'utf-8', 'utf8mb4', $original_sql );
$s = dbDelta( $sql );
if ( ! empty( $wpdb->last_error ) ) {
Ahrefs_Seo::breadcrumbs( sprintf( '%s [%s] [%s] [%s] [%s]', 'Retry', $wpdb->last_error, (string) wp_json_encode( $sql ), (string) wp_json_encode( $s ), (string) wp_json_encode( $wpdb->last_query ) ) );
$charset_collate = $wpdb->get_charset_collate();
if ( '' !== $charset_collate ) {
$sql = str_replace( $charset_collate, '', $original_sql ); // do not use it at all.
$s = dbDelta( $sql );
if ( ! empty( $wpdb->last_error ) ) {
Ahrefs_Seo::breadcrumbs( sprintf( '%s [%s] [%s] [%s] [%s]', 'Retry', $wpdb->last_error, (string) wp_json_encode( $sql ), (string) wp_json_encode( $s ), (string) wp_json_encode( $wpdb->last_query ) ) );
}
}
}
return empty( $wpdb->last_error );
} elseif ( false !== stripos( $last_error, 'Deadlock found when trying to get lock' ) ) {
Ahrefs_Seo::usleep( 750000 );
dbDelta( $sql );
return empty( $wpdb->last_error );
} elseif ( preg_match( '!Duplicate entry.*?for key!i', $last_error ) || preg_match( '!Multiple primary key defined!i', $last_error ) ) {
Ahrefs_Seo::breadcrumbs( sprintf( 'Drop table: %s. Reason: %s', $table_name, $last_error ) );
$wpdb->query( "DROP TABLE {$table_name}" ); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.SchemaChange,WordPress.DB.PreparedSQL.InterpolatedNotPrepared -- $table is correct table name.
if ( ! empty( $wpdb->last_error ) ) {
Ahrefs_Seo::breadcrumbs( sprintf( 'Drop table failed: %s', $wpdb->last_error ) );
if ( self::check_stop_error( $wpdb->last_error ) ) {
return false;
}
}
Ahrefs_Seo::usleep( 50000 );
dbDelta( $sql );
return empty( $wpdb->last_error );
} else {
self::check_stop_error( $wpdb->last_error );
}
return false;
}
/**
* Does last error message have stop error?
* Set stop error.
*
* @since 0.9.0
*
* @param string $last_error Last error.
* @return bool True: stop error found, false: no error.
*/
private static function check_stop_error( $last_error ) {
Ahrefs_Seo::breadcrumbs( sprintf( '%s(%d)', __METHOD__, $last_error ) );
if ( false !== stripos( $last_error, 'CREATE command denied' ) ) {
self::set_stop_error(
sprintf(
/* translators: %s: text "Ahrefs support" with link */
esc_html__( "CREATE command denied. The database user doesn't have permission to run CREATE queries. Please ask your server host to grant this permission or contact %s for help.", 'ahrefs-seo' ),
sprintf( '%s', esc_attr( Ahrefs_Seo::get_support_url( true ) ), esc_html__( 'Ahrefs support', 'ahrefs-seo' ) )
),
$last_error
);
return true;
} elseif ( false !== stripos( $last_error, 'ALTER command denied' ) ) {
self::set_stop_error(
sprintf(
/* translators: %s: text "Ahrefs support" with link */
esc_html__( "ALTER command denied. The database user doesn't have permission to run ALTER queries. Please ask your server host to grant this permission or contact %s for help.", 'ahrefs-seo' ),
sprintf( '%s', esc_attr( Ahrefs_Seo::get_support_url( true ) ), esc_html__( 'Ahrefs support', 'ahrefs-seo' ) )
),
$last_error
);
return true;
} elseif ( false !== stripos( $last_error, "Can't DROP" ) || false !== stripos( $last_error, 'DROP command denied' ) ) {
self::set_stop_error(
sprintf(
/* translators: %s: text "Ahrefs support" with link */
esc_html__( 'DROP command failed. Either ALTER or DROP database actions failed due to a misconfiguration or error on the server. Please check with your server host to fix this or contact %s for help.', 'ahrefs-seo' ),
sprintf( '%s', esc_attr( Ahrefs_Seo::get_support_url( true ) ), esc_html__( 'Ahrefs support', 'ahrefs-seo' ) )
),
$last_error
);
return true;
} elseif ( false !== stripos( $last_error, 'Duplicate key name' ) ) {
self::set_stop_error(
sprintf(
/* translators: %s: text "Ahrefs support" with link */
esc_html__( "Duplicate key name error. The database user doesn't have permission to perform ALTER or DROP database actions due to a misconfiguration or error on the server. Please check with your server host to fix this or contact %s for help.", 'ahrefs-seo' ),
sprintf( '%s', esc_attr( Ahrefs_Seo::get_support_url( true ) ), esc_html__( 'Ahrefs support', 'ahrefs-seo' ) )
),
$last_error
);
return true;
} elseif ( false !== stripos( $last_error, 'Multiple primary key' ) ) {
self::set_stop_error(
sprintf(
/* translators: %s: text "Ahrefs support" with link */
esc_html__( "Multiple primary key defined. The database user doesn't have permission to perform ALTER or DROP database actions due to a misconfiguration or error on the server. Please check with your server host to fix this or contact %s for help.", 'ahrefs-seo' ),
sprintf( '%s', esc_attr( Ahrefs_Seo::get_support_url( true ) ), esc_html__( 'Ahrefs support', 'ahrefs-seo' ) )
),
$last_error
);
return true;
} elseif ( false !== stripos( $last_error, 'Unknown column' ) ) {
self::set_stop_error(
sprintf(
/* translators: %s: text "Ahrefs support" with link */
esc_html__( "Unknown column error. The database user doesn't have permission to perform ALTER or DROP database actions due to a misconfiguration or error on the server. Please check with your server host to fix this or contact %s for help.", 'ahrefs-seo' ),
sprintf( '%s', esc_attr( Ahrefs_Seo::get_support_url( true ) ), esc_html__( 'Ahrefs support', 'ahrefs-seo' ) )
),
$last_error
);
return true;
}
return false;
}
/**
* Do a full reset of options and tables.
* Will run Wizard again.
*
* @since 0.7
*
* @return bool Success.
*/
private static function reset_before_v0_7() {
global $wpdb;
// phpcs:disable WordPress.DB.DirectDatabaseQuery.SchemaChange
// remove old tables.
if ( $wpdb->get_var( "SHOW TABLES LIKE '{$wpdb->prefix}ahrefs_seo_keywords';" ) ) {
$wpdb->query( "DROP TABLE {$wpdb->prefix}ahrefs_seo_keywords" );
if ( ! empty( $wpdb->last_error ) && self::check_stop_error( $wpdb->last_error ) ) {
return false;
}
}
if ( $wpdb->get_var( "SHOW TABLES LIKE '{$wpdb->prefix}ahrefs_seo_blacklist';" ) ) {
$wpdb->query( "DROP TABLE {$wpdb->prefix}ahrefs_seo_blacklist" );
if ( ! empty( $wpdb->last_error ) && self::check_stop_error( $wpdb->last_error ) ) {
return false;
}
}
if ( $wpdb->get_var( "SHOW TABLES LIKE '{$wpdb->prefix}ahrefs_seo_backlinks';" ) ) {
$wpdb->query( "DROP TABLE {$wpdb->prefix}ahrefs_seo_backlinks" );
if ( ! empty( $wpdb->last_error ) && self::check_stop_error( $wpdb->last_error ) ) {
return false;
}
}
if ( $wpdb->get_var( "SHOW TABLES LIKE '{$wpdb->ahrefs_content}';" ) ) {
$wpdb->query( "DROP TABLE {$wpdb->ahrefs_content}" );
if ( ! empty( $wpdb->last_error ) && self::check_stop_error( $wpdb->last_error ) ) {
return false;
}
}
if ( $wpdb->get_var( "SHOW TABLES LIKE '{$wpdb->ahrefs_snapshots}';" ) ) {
$wpdb->query( "DROP TABLE {$wpdb->ahrefs_snapshots}" );
if ( ! empty( $wpdb->last_error ) && self::check_stop_error( $wpdb->last_error ) ) {
return false;
}
}
self::remove_pre_v0_7_options();
self::reset_google_accounts();
self::force_wizard_run();
return true;
// phpcs:enable WordPress.DB.DirectDatabaseQuery.SchemaChange
}
/**
* Remove old options from New Backlinks screen.
*
* @since 0.7
*
* @return void
*/
private static function remove_pre_v0_7_options() {
$options = [
// blacklist.
'ahrefs-seo-blacklist-has-new',
'ahrefs-seo-blacklist-last-blacklisted-items',
'ahrefs-seo-blacklist-last-blacklisted-count',
// new backlinks.
'ahrefs-seo-last-backlinks-retrieval',
'ahrefs-seo-backlinks-low_memory',
'ahrefs-seo-update-backlink-interval',
'ahrefs-seo-update-backlink-update-links-count',
'ahrefs-seo-update-backlinks-has-new-links',
'ahrefs-seo-links-last-time-scheduled',
'ahrefs-seo-update-backlink-wizard-finished',
'ahrefs-seo-update-backlink-i-from',
'ahrefs-seo-update-backlink-i-to',
'ahrefs-seo-update-backlink-d-from',
'ahrefs-seo-update-backlink-d-to',
'ahrefs-seo-update-backlink-d-last',
// notice.
'ahrefs-seo-count-prev-time',
'ahrefs-seo-has-new-links',
'ahrefs-seo-admin-notice-hide-gsc',
// wizard.
'ahrefs-seo-wizard-audit-start',
];
array_walk(
$options,
function ( $value ) {
delete_option( $value );
}
);
}
/**
* Reset currently selected Google GA and GCS accounts.
* Do not reset existing tokens.
*
* @since 0.7.1
*
* @return void
*/
private static function reset_google_accounts() {
$analytics = Ahrefs_Seo_Analytics::get();
if ( $analytics->get_data_tokens()->is_token_set() ) {
$analytics->set_ua( '', '', '', '' );
wp_cache_flush();
}
}
/**
* Force Wizard run
*
* @since 0.7
*/
protected static function force_wizard_run() {
$options = [ '1', '2', '21', '3', '4' ];
array_walk(
$options,
function ( $option ) {
delete_option( "ahrefs-seo-is-initialized{$option}" );
}
);
delete_option( 'ahrefs-seo-wizard-1-step' );
}
/**
* Fill empty date values from posts table.
* Update existing snapshots.
*
* @since 0.8.0
*
* @return void
*/
private static function update_before_v0_8() {
global $wpdb;
// replace 'Delete' status by Update (orange).
$wpdb->update( $wpdb->ahrefs_content, [ 'action' => Ahrefs_Seo_Data_Content::ACTION4_REWRITE ], [ 'action' => 'delete' ], [ '%s' ], [ '%s' ] );
// fill title, badge and date for existing posts from older DB version.
$post_ids = $wpdb->get_col( "SELECT DISTINCT post_id FROM {$wpdb->ahrefs_content} WHERE taxonomy = '' AND title = ''" );
if ( $post_ids ) {
$values = $wpdb->get_results( "SELECT ID as 'id', post_title as 'title', post_type, post_date FROM {$wpdb->posts} WHERE ID IN (" . implode( ',', array_map( 'intval', $post_ids ) ) . ')', ARRAY_A ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
if ( count( $values ) ) {
foreach ( $values as $value ) {
$wpdb->update(
$wpdb->ahrefs_content,
[
'title' => $value['title'],
'badge' => $value['post_type'],
'date_updated' => $value['post_date'],
],
[
'post_id' => $value['id'],
'taxonomy' => '',
],
[ '%s', '%s', '%s' ],
[ '%d', '%s' ]
);
}
}
}
}
/**
* Fill last well date.
* Update existing snapshots.
*
* @since 0.8.4
*
* @return void
*/
private static function update_before_v0_8_4() {
global $wpdb;
$snapshot = new Snapshot();
$current_snapshot_id = $snapshot->get_current_snapshot_id();
$info = $snapshot->get_snapshot_info( $current_snapshot_id );
if ( is_string( $info['time_end'] ) ) {
list($date, $time) = explode( ' ', $info['time_end'], 2 );
$wpdb->update(
$wpdb->ahrefs_content,
[ 'last_well_date' => $date ],
[
'action' => Ahrefs_Seo_Data_Content::ACTION4_DO_NOTHING,
'snapshot_id' => $current_snapshot_id,
],
[ '%s' ],
[ '%s', '%d' ]
);
$new_snapshot_id = $snapshot->get_new_snapshot_id();
if ( ! is_null( $new_snapshot_id ) && $current_snapshot_id !== $new_snapshot_id ) {
// copy last well date from current snapshot to new, that is being in progress.
$well_list = $wpdb->get_results( $wpdb->prepare( "SELECT post_id, taxonomy, snapshot_id FROM {$wpdb->ahrefs_content} WHERE last_well_date IS NOT NULL AND snapshot_id = %d", $current_snapshot_id ), ARRAY_A );
if ( count( $well_list ) ) {
foreach ( $well_list as $row ) {
$post_tax = Post_Tax::create_from_array( $row )->set_snapshot_id( $new_snapshot_id );
$wpdb->update( $wpdb->ahrefs_content, [ 'last_well_date' => $date ], $post_tax->as_where_array(), [ '%s' ], $post_tax->as_where_format() );
}
}
}
}
}
/**
* Fill is_duplicated.
* Update existing snapshots.
*
* @since 0.8.5
*
* @return void
*/
private static function update_before_v0_8_5() {
$snapshot = new Snapshot();
$current_snapshot_id = $snapshot->get_current_snapshot_id();
$info = $snapshot->get_snapshot_info( $current_snapshot_id );
if ( is_string( $info['time_end'] ) ) {
( new Duplicated_Keywords() )->fill_duplicated_for_snapshot( $current_snapshot_id );
}
}
/**
* Get transient name based on current DB version
*
* @since 0.8.1
*
* @return string
*/
private static function get_transient_name() {
return self::TRANSIENT_UPDATING . Ahrefs_Seo::CURRENT_TABLE_VERSION;
}
/**
* Reset counter and last error message
*
* @since 0.8.1
*
* @return void
*/
private static function counter_reset() {
update_option( self::OPTION_COUNTER, 0, false );
update_option( self::OPTION_LAST_MESSAGE, '', false );
}
/**
* Get updates counter value
*
* @since 0.8.1
*
* @return int
*/
private static function counter_get() {
return intval( get_option( self::OPTION_COUNTER, 0 ) );
}
/**
* Increase and return value of counter
*
* @since 0.8.1
*
* @return int
*/
private static function counter_increase() {
$result = self::counter_get() + 1;
update_option( self::OPTION_COUNTER, $result, false );
return $result;
}
/**
* Set error message and save it as current fatal error
*
* @since 0.8.1
*
* @param string $error Error message.
* @return void
*/
private static function set_error( $error ) {
Ahrefs_Seo::set_fatal_error( null, $error );
update_option( self::OPTION_LAST_MESSAGE, $error, false );
}
/**
* Get last saved error message
*
* @since 0.8.1
*
* @return string Empty string if no last error.
*/
private static function get_last_message() {
return (string) get_option( self::OPTION_LAST_MESSAGE, '' );
}
/**
* Set stop error
*
* @since 0.9.0
*
* @param string $header The title part.
* @param string $message Content of textarea with technical message.
* @return void
*/
private static function set_stop_error( $header, $message ) {
update_option(
self::OPTION_STOP_ERROR,
[
'header' => $header,
'message' => $message,
]
);
update_option( Ahrefs_Seo::OPTION_TABLE_VERSION, 0 ); // reset table version, so we will try to update DB and show stop error.
}
/**
* Reset stop error
*
* @since 0.9.0
*
* @return void
*/
public static function reset_stop_error() {
delete_transient( self::get_transient_name() );
delete_option( self::OPTION_STOP_ERROR );
}
/**
* Get stop error message if any
*
* @since 0.9.0
*
* @return string|null
*/
private static function get_stop_error() {
$result = get_option( self::OPTION_STOP_ERROR, null );
return is_array( $result ) && isset( $result['message'] ) && is_string( $result['message'] ) ? $result['message'] : ( is_string( $result ) ? $result : null );
}
/**
* Get stop error header if any
*
* @since 0.9.0
*
* @return string|null
*/
private static function get_stop_header() {
$result = get_option( self::OPTION_STOP_ERROR, null );
return is_array( $result ) && isset( $result['header'] ) && is_string( $result['header'] ) ? $result['header'] : null;
}
}