internalOptions->internal->lastActiveVersion; // Don't run updates if the last active version is the same as the current version. if ( aioseoBrokenLinkChecker()->version === $lastActiveVersion ) { return; } // Try to acquire the lock. if ( ! aioseoBrokenLinkChecker()->core->db->acquireLock( 'aioseo_blc_run_updates_lock', 0 ) ) { // If we couldn't acquire the lock, exit early without doing anything. // This means another process is already running updates. return; } if ( version_compare( $lastActiveVersion, '1.0.0', '<' ) ) { $this->addInitialTables(); // phpcs:ignore WordPress.DateTime.RestrictedFunctions.date_date aioseoBrokenLinkChecker()->internalOptions->internal->minimumLinkScanDate = date( 'Y-m-d H:i:s', time() ); } if ( version_compare( $lastActiveVersion, '1.2.0', '<' ) ) { $this->dropInvalidMediaLinks(); $this->dropLinksWithInvalidHash(); } if ( version_compare( $lastActiveVersion, '1.2.6', '<' ) ) { aioseoBrokenLinkChecker()->access->addCapabilities(); } if ( version_compare( $lastActiveVersion, '1.2.7', '<' ) ) { $this->changeParagraphColumnType(); } } /** * Updates the latest version after all migrations and updates have run. * * @since 1.0.0 * * @return void */ public function updateLatestVersion() { if ( aioseoBrokenLinkChecker()->internalOptions->internal->lastActiveVersion === aioseoBrokenLinkChecker()->version ) { return; } aioseoBrokenLinkChecker()->internalOptions->internal->lastActiveVersion = aioseoBrokenLinkChecker()->version; aioseoBrokenLinkChecker()->core->db->bustCache(); aioseoBrokenLinkChecker()->core->cache->delete( 'db_schema' ); } /** * Adds our custom tables. * * @since 1.0.0 * * @return void */ public function addInitialTables() { $db = aioseoBrokenLinkChecker()->core->db->db; $charsetCollate = ''; if ( ! empty( $db->charset ) ) { $charsetCollate .= "DEFAULT CHARACTER SET {$db->charset}"; } if ( ! empty( $db->collate ) ) { $charsetCollate .= " COLLATE {$db->collate}"; } if ( ! aioseoBrokenLinkChecker()->core->db->tableExists( 'aioseo_blc_link_status' ) ) { $tableName = $db->prefix . 'aioseo_blc_link_status'; aioseoBrokenLinkChecker()->core->db->execute( "CREATE TABLE {$tableName} ( `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, `url` text NOT NULL, `url_hash` varchar(40) NOT NULL, `http_status_code` smallint(6) DEFAULT NULL, `broken` tinyint(1) unsigned DEFAULT 0 NOT NULL, `dismissed` tinyint(1) DEFAULT 0 NOT NULL, `request_duration` float DEFAULT NULL, `scan_count` int(4) unsigned DEFAULT 0 NOT NULL, `redirect_count` smallint(5) unsigned DEFAULT 0 NOT NULL, `final_url` text DEFAULT NULL, `first_failure` datetime DEFAULT NULL, `log` text DEFAULT NULL, `last_scan_date` datetime DEFAULT NULL, `created` datetime NOT NULL, `updated` datetime NOT NULL, PRIMARY KEY (id), UNIQUE KEY ndx_aioseo_blc_link_status_url_hash (url_hash) ) {$charsetCollate};" ); } if ( ! aioseoBrokenLinkChecker()->core->db->tableExists( 'aioseo_blc_links' ) ) { $tableName = $db->prefix . 'aioseo_blc_links'; aioseoBrokenLinkChecker()->core->db->execute( "CREATE TABLE {$tableName} ( `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, `post_id` bigint(20) unsigned NOT NULL, `blc_link_status_id` bigint(20) unsigned DEFAULT NULL, `url` text NOT NULL, `url_hash` varchar(40) NOT NULL, `hostname` text NOT NULL, `hostname_url` varchar(40) NOT NULL, `external` tinyint(1) DEFAULT 0 NOT NULL, `anchor` text NOT NULL, `phrase` text NOT NULL, `phrase_html` text NOT NULL, `paragraph` mediumtext NOT NULL, `paragraph_html` mediumtext NOT NULL, `created` datetime NOT NULL, `updated` datetime NOT NULL, PRIMARY KEY (id), KEY ndx_aioseo_blc_links_post_id (post_id), KEY ndx_aioseo_blc_links_hostname (hostname(10)) ) {$charsetCollate};" ); } if ( ! aioseoBrokenLinkChecker()->core->db->tableExists( 'aioseo_blc_notifications' ) ) { $tableName = $db->prefix . 'aioseo_blc_notifications'; aioseoBrokenLinkChecker()->core->db->execute( "CREATE TABLE {$tableName} ( `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, `notification_id` bigint(20) unsigned DEFAULT NULL, `notification_name` varchar(255) DEFAULT NULL, `slug` varchar(13) NOT NULL, `title` text NOT NULL, `content` longtext NOT NULL, `type` varchar(64) NOT NULL, `level` text NOT NULL, `start` datetime DEFAULT NULL, `end` datetime DEFAULT NULL, `button1_label` varchar(255) DEFAULT NULL, `button1_action` varchar(255) DEFAULT NULL, `button2_label` varchar(255) DEFAULT NULL, `button2_action` varchar(255) DEFAULT NULL, `dismissed` tinyint(1) NOT NULL DEFAULT 0, `new` tinyint(1) NOT NULL DEFAULT 1, `created` datetime NOT NULL, `updated` datetime NOT NULL, PRIMARY KEY (id), UNIQUE KEY ndx__aioseo_blc_notifications_slug (slug), KEY ndx__aioseo_blc_notifications_dates (start, end), KEY ndx__aioseo_blc_notifications_type (type), KEY ndx__aioseo_blc_notifications_dismissed (dismissed) ) {$charsetCollate};" ); } if ( ! aioseoBrokenLinkChecker()->core->db->tableExists( 'aioseo_blc_posts' ) ) { $tableName = $db->prefix . 'aioseo_blc_posts'; aioseoBrokenLinkChecker()->core->db->execute( "CREATE TABLE {$tableName} ( id bigint(20) unsigned NOT NULL AUTO_INCREMENT, `post_id` bigint(20) unsigned NOT NULL, link_scan_date datetime DEFAULT NULL, created datetime NOT NULL, updated datetime NOT NULL, PRIMARY KEY (id), KEY ndx_aioseo_blc_posts_post_id (post_id) ) {$charsetCollate};" ); } } /** * Removes all mailto and tel links from the database. * * @since 1.0.5 * * @return void */ private function dropInvalidMediaLinks() { $tableName = aioseoBrokenLinkChecker()->core->db->prefix . 'aioseo_blc_links'; aioseoBrokenLinkChecker()->core->db->execute( "DELETE FROM {$tableName} WHERE url LIKE 'mailto:%' OR url LIKE 'tel:%'" ); $tableName = aioseoBrokenLinkChecker()->core->db->prefix . 'aioseo_blc_link_status'; aioseoBrokenLinkChecker()->core->db->execute( "DELETE FROM {$tableName} WHERE url LIKE 'mailto:%' OR url LIKE 'tel:%'" ); } /** * Removes all links with percentage signs from the database as these had invalid hashes. * * @since 1.2.0 * * @return void */ private function dropLinksWithInvalidHash() { $blcPosts = aioseoBrokenLinkChecker()->core->db->prefix . 'aioseo_blc_posts'; $blcLinks = aioseoBrokenLinkChecker()->core->db->prefix . 'aioseo_blc_links'; aioseoBrokenLinkChecker()->core->db->execute( "UPDATE {$blcPosts} SET link_scan_date = NULL WHERE post_id IN ( SELECT post_id FROM {$blcLinks} WHERE url LIKE '%\\%%' )" ); $blcLinkStatus = aioseoBrokenLinkChecker()->core->db->prefix . 'aioseo_blc_link_status'; aioseoBrokenLinkChecker()->core->db->execute( "DELETE FROM {$blcLinkStatus} WHERE url LIKE '%\\%%'" ); } /** * Change the paragraph column type to mediumtext. * * @since 1.2.7 * * @return void */ private function changeParagraphColumnType() { if ( aioseoBrokenLinkChecker()->core->db->tableExists( 'aioseo_blc_links' ) ) { $tableName = aioseoBrokenLinkChecker()->core->db->prefix . 'aioseo_blc_links'; aioseoBrokenLinkChecker()->core->db->execute( "ALTER TABLE $tableName CHANGE paragraph paragraph mediumtext NOT NULL" ); aioseoBrokenLinkChecker()->core->db->execute( "ALTER TABLE $tableName CHANGE paragraph_html paragraph_html mediumtext NOT NULL" ); } } }