E option_name=%s", $option_name ),
ARRAY_A
);
}
if ( $careless_insert || ( ! $careless_update && empty( $result['option_id'] ) ) ) {
$result = $wpdb->query(
$wpdb->prepare(
"INSERT INTO {$wpdb->prefix}options ( option_name, option_value, autoload ) VALUES ( %s, %s, %s )",
array(
$option_name,
$option_value,
'no',
)
)
);
return $result;
}
if ( $careless_update || ! empty( $result['option_id'] ) ) {
$result = $wpdb->update(
"{$wpdb->prefix}options",
array(
'option_value' => $option_value,
'autoload' => 'no',
),
array( 'option_name' => $option_name )
);
return $result !== false;
}
}
public static function btl_update_autoload_option( $option_name, $autoload = false ) {
global $wpdb;
$result = $wpdb->get_row(
$wpdb->prepare( "SELECT * FROM {$wpdb->prefix}options WHERE option_name=%s", $option_name ),
ARRAY_A
);
if ( ! empty( $result['option_id'] ) && ! empty( $result['option_value'] ) ) {
if ( $autoload === false ) {
$result = $wpdb->update(
"{$wpdb->prefix}options",
array(
'option_value' => $result['option_value'],
'autoload' => 'no',
),
array( 'option_name' => $option_name )
);
} elseif ( $autoload === true ) {
$result = $wpdb->update(
"{$wpdb->prefix}options",
array(
'option_value' => $result['option_value'],
'autoload' => 'yes',
),
array( 'option_name' => $option_name )
);
}
return $result !== false;
}
}
public static function run_migration_for_ptrl_links_in_background( $installer, $links_count ) {
global $wpdb;
$per_page = 10000;
$total_page = ceil( $links_count / $per_page );
for ( $page = 1; $page <= $total_page; $page++ ) {
$offset = ( $page - 1 ) * $per_page;
$links = $wpdb->get_col(
"SELECT concat('prli_links-', ID) AS ID FROM {$wpdb->prefix}prli_links LIMIT $per_page OFFSET {$offset}",
0
);
$installer->data( $links )->save();
}
$installer->data( array( 'betterlinks_ptl_links_migrated' ) )->save();
return $installer;
}
public static function run_migration_for_ptrl_clicks_in_background( $installer, $clicks_count ) {
global $wpdb;
$per_page = 10000;
$total_page = ceil( $clicks_count / $per_page );
for ( $page = 1; $page <= $total_page; $page++ ) {
$offset = ( $page - 1 ) * $per_page;
$clicks = $wpdb->get_col(
"SELECT concat('prli_clicks-', ID) AS ID FROM {$wpdb->prefix}prli_clicks LIMIT $per_page OFFSET {$offset}",
0
);
$installer->data( $clicks )->save();
}
$installer->data( array( 'betterlinks_ptl_clicks_migrated' ) )->save();
return $installer;
}
public function generate_random_slug( $length = 3 ) {
$characters = '0123456789abcdefghijklmnopqrstuvwxyz';
$random_string = '';
$characters_length = strlen( $characters );
for ( $i = 0; $i < $length; $i++ ) {
$random_string .= $characters[ wp_rand( 0, $characters_length - 1 ) ];
}
$random_num = wp_rand( 0, 10 ) . wp_rand( 0, 10 ) . wp_rand( 0, 10 );
return $random_string . $random_num;
}
public function get_betterlinks_prefix() {
if ( BETTERLINKS_EXISTS_SETTINGS_JSON ) {
$data = Cache::get_json_settings();
if ( empty( $data ) ) {
$data = Cache::write_json_settings();
}
$prefix = ! empty( $data['prefix'] ) ? $data['prefix'] . '/' : '';
return $prefix;
}
$betterlinks_links = get_option( 'betterlinks_links', array() );
if ( is_string( $betterlinks_links ) ) {
$betterlinks_links = json_decode( $betterlinks_links, true );
}
$prefix = ! empty( $betterlinks_links['prefix'] ) ? $betterlinks_links['prefix'] . '/' : '';
return $prefix;
}
public function fetch_target_url( $target_url ) {
if ( empty( $target_url ) ) {
return false;
}
$http = new WP_Http();
$result = $http->get( $target_url, array( 'sslverify' => false ) );
$title = '';
if ( ! is_wp_error( $result ) && ! empty( $result['body'] ) && preg_match( '/
(.*)<\/title>/siU', $result['body'], $title_matches ) ) {
$title = html_entity_decode( $title_matches[1] );
}
return $title;
}
public static function insert_new_category( $slug ) {
if ( ! ! intval( $slug ) ) {
return $slug;
}
// Check if category exists and get its ID for AI
$existing_term = self::get_term_by_slug( self::make_slug( $slug ), 'category' );
if ( ! empty( $existing_term ) && is_array( $existing_term ) && count( $existing_term ) > 0 ) {
// Category exists, return its ID
return $existing_term[0]['ID'];
}
// Category doesn't exist, create it
$insert_id = self::insert_term(
array(
'term_name' => $slug,
'term_slug' => self::make_slug( $slug ),
'term_type' => 'category',
)
);
if ( $insert_id ) {
self::clear_query_cache();
return $insert_id;
}
return $slug;
}
public static function isJson( $string ) {
json_decode( $string );
return json_last_error() === JSON_ERROR_NONE;
}
public static function get_migratable_plugins() {
return [
'simple301redirects' => defined('SIMPLE301REDIRECTS_VERSION'),
'thirstyaffiliates' => class_exists('ThirstyAffiliates'),
'prettylinks' => defined('PRLI_VERSION'),
];
}
public static function init_tracking( $data, $utils ) {
global $betterlinks;
$user_agent = isset($_SERVER['HTTP_USER_AGENT']) ? $_SERVER['HTTP_USER_AGENT'] : ''; // phpcs:ignore
$dd = new DeviceDetector( $user_agent );
$dd->parse();
$data['is_bot'] = $dd->isBot();
if ( empty( $data['target_url'] ) || ! apply_filters( 'betterlinks/pre_before_redirect', $data ) ) {
// password protection logics
if( empty( $data['skip_password_protection'] ) ){
do_action( 'betterlinkspro/admin/check_password_protection', $data['short_url'], $data );
}
if ( empty( $data['target_url'] ) || ! apply_filters( 'betterlinks/pre_before_redirect', $data ) ) { // phpcs:ignore
return false;
}
}
$data = apply_filters( 'betterlinks/link/before_dispatch_redirect', $data ); // phpcs:ignore.
if ( empty( $data ) ) {
return false;
}
do_action( 'betterlinks/before_redirect', $data ); // phpcs:ignore.
$comparable_url = rtrim( preg_replace( '/https?\:\/\//', '', site_url( '/' ) ), '/' ) . '/' . $data['short_url'];
$destination_url = rtrim( preg_replace( '/https?\:\/\//', '', $data['target_url'] ), '/' );
$comparable_url = rtrim( preg_replace( '/^www\.?/', '', $comparable_url ), '/' );
$destination_url = rtrim( preg_replace( '/^www\.?/', '', $destination_url ), '/' );
if ( ! $data || $comparable_url === $destination_url ) {
return;
}
if ( filter_var( $data['track_me'], FILTER_VALIDATE_BOOLEAN ) ) {
$data = apply_filters( 'betterlinks/extra_tracking_data', $data, $dd );
$data['os'] = OperatingSystem::getOsFamily( $dd->getOs( 'name' ) );
$data['browser'] = Browser::getBrowserFamily( $dd->getClient( 'name' ) );
$data['device'] = $dd->getDeviceName();
if ( isset( $betterlinks['disablebotclicks'] ) && $betterlinks['disablebotclicks'] ) {
if ( ! $dd->isBot() ) {
$utils->start_trakcing( $data );
}
} else {
$utils->start_trakcing( $data );
}
}
}
/**
* Rebuild links JSON from database
* Useful when JSON file is corrupted or completely out of sync
*
* @since 2.6.0
* @return bool True if rebuild successful
*/
public static function rebuild_links_json() {
if ( ! BETTERLINKS_EXISTS_LINKS_JSON ) {
return false;
}
$formattedArray = self::get_links_for_json();
$json_file = trailingslashit( BETTERLINKS_UPLOAD_DIR_PATH ) . 'links.json';
return (bool) file_put_contents( $json_file, wp_json_encode( $formattedArray ) );
}
/**
* Sync all missing links from database to JSON file
* Checks if all database links exist in JSON and adds missing ones
* Called when admin page loads to ensure complete synchronization
*
* @since 2.6.2
* @return array Results: ['total' => count, 'synced' => count]
*/
public static function sync_all_missing_links_to_json() {
if ( ! BETTERLINKS_EXISTS_LINKS_JSON ) {
return array( 'total' => 0, 'synced' => 0 );
}
if ( ! function_exists( 'file_get_contents' ) || ! function_exists( 'file_put_contents' ) ) {
return array( 'total' => 0, 'synced' => 0 );
}
$json_file = trailingslashit( BETTERLINKS_UPLOAD_DIR_PATH ) . 'links.json';
// Read JSON file
if ( ! file_exists( $json_file ) ) {
// JSON doesn't exist, rebuild from scratch
self::rebuild_links_json();
return array( 'total' => 0, 'synced' => 0 );
}
$json_content = file_get_contents( $json_file );
$json_data = json_decode( $json_content, true );
// If JSON is corrupted, rebuild
if ( ! is_array( $json_data ) ) {
self::rebuild_links_json();
return array( 'total' => 0, 'synced' => 0 );
}
// Get all published links from database
global $wpdb;
$all_db_links = $wpdb->get_results(
"SELECT ID, short_url, wildcards FROM {$wpdb->prefix}betterlinks WHERE link_status = 'publish'",
ARRAY_A
);
$synced_count = 0;
$total_links = count( $all_db_links );
// Check each database link and add if missing from JSON
foreach ( $all_db_links as $db_link ) {
$short_url = $db_link['short_url'];
$link_id = $db_link['ID'];
$is_wildcard = isset( $db_link['wildcards'] ) && $db_link['wildcards'];
// Determine where to look
$target_section = $is_wildcard ? 'wildcards' : 'links';
// Check if link exists in JSON
$link_exists = false;
if ( isset( $json_data[ $target_section ] ) && is_array( $json_data[ $target_section ] ) ) {
if ( isset( $json_data[ $target_section ][ $short_url ] ) ) {
$link_exists = true;
}
}
// If missing, add it
if ( ! $link_exists ) {
$full_link_data = $wpdb->get_row(
$wpdb->prepare(
"SELECT * FROM {$wpdb->prefix}betterlinks WHERE ID = %d",
$link_id
),
ARRAY_A
);
if ( $full_link_data ) {
$formatted_link = self::json_link_formatter( $full_link_data );
if ( $formatted_link ) {
// Ensure target section exists
if ( ! isset( $json_data[ $target_section ] ) ) {
$json_data[ $target_section ] = array();
}
// Add missing link to JSON
$json_data[ $target_section ][ $short_url ] = $formatted_link;
$synced_count++;
}
}
}
}
// Write back to file if any links were synced
if ( $synced_count > 0 ) {
file_put_contents( $json_file, wp_json_encode( $json_data ) );
}
return array(
'total' => $total_links,
'synced' => $synced_count,
);
}
}