Operations/Activator.php 0000755 00000006703 15111632166 0011347 0 ustar 00 execute();
}
/**
* Execute the core function.
*
* @return void
*/
public function execute()
{
$this->loadRequiredFiles();
if (is_multisite() && $this->networkWide) {
$blogIds = $this->wpdb->get_col("SELECT `blog_id` FROM {$this->wpdb->blogs}");
foreach ($blogIds as $blogId) {
switch_to_blog($blogId);
$this->checkIsFresh();
TableHandler::createAllTables();
restore_current_blog();
}
} else {
$this->checkIsFresh();
TableHandler::createAllTables();
}
BackgroundProcessFactory::markBackgroundProcessesAsInitiated();
$this->createOptions();
$this->initializeVersion();
SchemaMaintainer::repair(true);
}
/**
* Ensures the plugin version is stored in the database.
*
* If the version option does not already exist, this method will
* initialize it by calling updateVersion().
*
* @return void
*/
private function initializeVersion() {
$version = get_option('wp_statistics_plugin_version');
if (!empty($version)) {
return;
}
$this->updateVersion();
}
/**
* Creates the default options if they do not already exist.
*
* @return bool
*/
private function createOptions()
{
$existedOption = get_option(Option::$opt_name);
if ($existedOption === false || (isset($existedOption) and !is_array($existedOption))) {
update_option(Option::$opt_name, Option::defaultOption());
}
}
/**
* Load core plugin classes required during activation.
*
* We include them explicitly here because activation runs in a minimal context and some
* runtime bootstrapping (like conditional autoloaders) may not yet be in place.
*
* @return void
* @todo Remove this method after the included files are migrated to PSR-4 autoloading.
*/
private function loadRequiredFiles()
{
require_once WP_STATISTICS_DIR . 'includes/class-wp-statistics-option.php';
require_once WP_STATISTICS_DIR . 'includes/class-wp-statistics-helper.php';
require_once WP_STATISTICS_DIR . 'includes/class-wp-statistics-visitor.php';
require_once WP_STATISTICS_DIR . 'includes/libraries/wp-background-processing/wp-async-request.php';
require_once WP_STATISTICS_DIR . 'includes/libraries/wp-background-processing/wp-background-process.php';
}
} Operations/Loader.php 0000755 00000004700 15111632166 0010614 0 ustar 00 execute();
}
/**
* Execute the core function.
*
* @return void
*/
public function execute()
{
add_action('wpmu_new_blog', [$this, 'addTableOnCreateBlog'], 10, 1);
add_filter('wpmu_drop_tables', [$this, 'removeTableOnDeleteBlog']);
add_filter('plugin_row_meta', [$this, 'addMetaLinks'], 10, 2);
}
public function addTableOnCreateBlog($blogId)
{
if (!is_plugin_active_for_network(plugin_basename(WP_STATISTICS_MAIN_FILE))) {
return;
}
$options = get_option(Option::$opt_name);
switch_to_blog($blogId);
TableHandler::createAllTables();
update_option(Option::$opt_name, $options);
restore_current_blog();
}
public function removeTableOnDeleteBlog($tables)
{
$tables[] = array_merge($tables, DB::table('all'));
return $tables;
}
public function addMetaLinks($links, $file)
{
if ($file !== plugin_basename(WP_STATISTICS_MAIN_FILE)) {
return $links;
}
$pluginUrl = 'https://wordpress.org/plugins/wp-statistics/';
$links[] = '' . esc_html__('Visit WordPress.org page', 'wp-statistics') . '';
$rateUrl = 'https://wordpress.org/support/plugin/wp-statistics/reviews/?rate=5#new-post';
$links[] = '' . esc_html__('Rate this plugin', 'wp-statistics') . '';
return $links;
}
} Operations/Uninstaller.php 0000755 00000011115 15111632166 0011704 0 ustar 00 execute();
}
/**
* Execute the core function.
*
* @return void
*/
public function execute()
{
$this->loadRequiredFiles();
if (is_multisite()) {
$blog_ids = $this->wpdb->get_col("SELECT `blog_id` FROM {$this->wpdb->blogs}");
foreach ($blog_ids as $blog_id) {
switch_to_blog($blog_id);
if (Option::get('delete_data_on_uninstall')) {
$this->cleanupSiteData();
}
restore_current_blog();
}
} else {
if (Option::get('delete_data_on_uninstall')) {
$this->cleanupSiteData();
}
}
}
/**
* Removes database options, user meta keys & tables
*/
public function cleanupSiteData()
{
// Delete the options from the WordPress options table.
delete_option('wp_statistics');
delete_option('wp_statistics_privacy_status');
delete_option('wp_statistics_plugin_version');
delete_option('wp_statistics_referrals_detail');
delete_option('wp_statistics_overview_page_ads');
delete_option('wp_statistics_users_city');
delete_option('wp_statistics_activate_addons');
delete_option('wp_statistics_disable_addons');
delete_option('wp_statistics_disable_addons_notice');
delete_option('wp_statistics_check_user_online');
delete_option('wp_statistics_daily_salt');
delete_option('wp_statistics_dismissed_notices');
delete_option('wp_statistics_dismissed_widgets');
delete_option('wp_statistics_jobs');
delete_option('wp_statistics_user_modals');
delete_option('wp_statistics_closed_widgets');
delete_option('wp_statistics_licenses');
delete_option('wp_statistics_tracker_js_errors');
delete_option('wp_statistics_db');
delete_option('wp_statistics_installation_time');
delete_option('wps_robotlist');
delete_option('wp_statistics_cipher_key');
// Delete the transients.
delete_transient('wps_top_referring');
delete_transient('wps_excluded_hostname_to_ip_cache');
delete_transient('wps_check_rest_api');
// Remove All Scheduled
if (function_exists('wp_clear_scheduled_hook')) {
wp_clear_scheduled_hook('wp_statistics_geoip_hook');
wp_clear_scheduled_hook('wp_statistics_report_hook');
wp_clear_scheduled_hook('wp_statistics_referrerspam_hook');
wp_clear_scheduled_hook('wp_statistics_dbmaint_hook');
wp_clear_scheduled_hook('wp_statistics_dbmaint_visitor_hook');
wp_clear_scheduled_hook('wp_statistics_add_visit_hook');
wp_clear_scheduled_hook('wp_statistics_optimize_table');
wp_clear_scheduled_hook('wp_statistics_daily_cron_hook');
}
// Delete all hashed files and their options
$assetNameObfuscator = new AssetNameObfuscator();
$assetNameObfuscator->deleteAllHashedFiles();
$assetNameObfuscator->deleteDatabaseOption();
// Delete the user options.
$this->wpdb->query("DELETE FROM {$this->wpdb->usermeta} WHERE `meta_key` LIKE 'wp_statistics%'");
$this->wpdb->query("DELETE FROM {$this->wpdb->postmeta} WHERE `meta_key` LIKE 'wp_statistics%'");
// Drop the tables
foreach (DB::table() as $tbl) {
$this->wpdb->query("DROP TABLE IF EXISTS {$tbl}");
}
}
/**
* Load core classes needed during uninstall.
*
* @return void
* @todo Remove after PSR-4 autoloading is in place.
*/
private function loadRequiredFiles()
{
require_once WP_STATISTICS_DIR . 'includes/class-wp-statistics-option.php';
require_once WP_STATISTICS_DIR . 'includes/class-wp-statistics-db.php';
}
} Operations/Updater.php 0000755 00000037402 15111632166 0011017 0 ustar 00 initializeDefaultOptions();
}
if (!$this->isUpdated()) {
return;
}
$this->checkIsFresh();
TableHandler::createAllTables();
$this->legacyMigrations();
$this->updateVersion();
SchemaManager::init();
SchemaMaintainer::repair(true);
}
/**
* Execute the legacy migrations.
*
* @return void
*/
private function legacyMigrations()
{
$userOnlineTable = DB::table('useronline');
$pagesTable = DB::table('pages');
$visitorTable = DB::table('visitor');
$historicalTable = DB::table('historical');
$searchTable = DB::getTableName('search');
/**
* Add source channel column to visitors table
*
* @version 14.11
*/
$result = $this->wpdb->query("SHOW COLUMNS FROM {$visitorTable} LIKE 'source_channel'");
if ($result == 0) {
$this->wpdb->query("ALTER TABLE {$visitorTable} ADD `source_channel` VARCHAR(50) NULL;");
}
/**
* Add source name column to visitors table
*
* @version 14.11
*/
$result = $this->wpdb->query("SHOW COLUMNS FROM {$visitorTable} LIKE 'source_name'");
if ($result == 0) {
$this->wpdb->query("ALTER TABLE {$visitorTable} ADD `source_name` VARCHAR(100) NULL;");
}
/**
* Add visitor id column to user online table
*
* @version 14.11
*/
$result = $this->wpdb->query("SHOW COLUMNS FROM {$userOnlineTable} LIKE 'visitor_id'");
if ($result == 0) {
$this->wpdb->query("ALTER TABLE {$userOnlineTable} ADD `visitor_id` bigint(20) NOT NULL;");
}
/**
* Add visitor city
*
* @version 14.5.2
*/
$result = $this->wpdb->query("SHOW COLUMNS FROM {$visitorTable} LIKE 'city'");
if ($result == 0) {
$this->wpdb->query("ALTER TABLE {$visitorTable} ADD `city` VARCHAR(100) NULL;");
}
/**
* Add visitor region
*
* @version 14.7.0
*/
$result = $this->wpdb->query("SHOW COLUMNS FROM {$visitorTable} LIKE 'region'");
if ($result == 0) {
$this->wpdb->query("ALTER TABLE {$visitorTable} ADD `region` VARCHAR(100) NULL;");
}
/**
* Add visitor continent
*
* @version 14.7.0
*/
$result = $this->wpdb->query("SHOW COLUMNS FROM {$visitorTable} LIKE 'continent'");
if ($result == 0) {
$this->wpdb->query("ALTER TABLE {$visitorTable} ADD `continent` VARCHAR(50) NULL;");
}
/**
* Add visitor device type
*
* @version 13.2.4
*/
$result = $this->wpdb->query("SHOW COLUMNS FROM {$visitorTable} LIKE 'device'");
if ($result == 0) {
$this->wpdb->query("ALTER TABLE {$visitorTable} ADD `device` VARCHAR(180) NULL AFTER `version`, ADD INDEX `device` (`device`);");
}
/**
* Add visitor device model
*
* @version 13.2.4
*/
$result = $this->wpdb->query("SHOW COLUMNS FROM {$visitorTable} LIKE 'model'");
if ($result == 0) {
$this->wpdb->query("ALTER TABLE {$visitorTable} ADD `model` VARCHAR(180) NULL AFTER `device`, ADD INDEX `model` (`model`);");
}
/**
* Set to BigINT Fields (AUTO_INCREMENT)
*
* @version 13.0.0
*/
/*
* MySQL since version 8.0.19 doesn't honot display width specification
* so we have to handle accept BIGINT(20) and BIGINT.
*
* see: https://dev.mysql.com/doc/relnotes/mysql/8.0/en/news-8-0-19.html
* - section Deprecation and Removal Notes
*/
if (!DB::isColumnType('visitor', 'ID', 'bigint(20)') && !DB::isColumnType('visitor', 'ID', 'bigint')) {
$this->wpdb->query("ALTER TABLE {$visitorTable} CHANGE `ID` `ID` BIGINT(20) NOT NULL AUTO_INCREMENT;");
}
if (!DB::isColumnType('exclusions', 'ID', 'bigint(20)') && !DB::isColumnType('exclusions', 'ID', 'bigint')) {
$this->wpdb->query("ALTER TABLE `" . DB::table('exclusions') . "` CHANGE `ID` `ID` BIGINT(20) NOT NULL AUTO_INCREMENT;");
}
if (!DB::isColumnType('useronline', 'ID', 'bigint(20)') && !DB::isColumnType('useronline', 'ID', 'bigint')) {
$this->wpdb->query("ALTER TABLE {$userOnlineTable} CHANGE `ID` `ID` BIGINT(20) NOT NULL AUTO_INCREMENT;");
}
/**
* Change Charset All Table To New WordPress Collate
* Reset Overview Order Meta Box View
* Added User_id column in wp_statistics_visitor Table
*
* @see https://developer.wordpress.org/reference/classes/wpdb/has_cap/
* @version 13.0.0
*/
$list_table = DB::table('all');
foreach ($list_table as $k => $name) {
$tbl_info = DB::getTableInformation($name);
if (!empty($tbl_info['Collation']) && !empty($this->wpdb->collate) && $tbl_info['Collation'] != $this->wpdb->collate) {
$this->wpdb->query(
$this->wpdb->prepare("ALTER TABLE `" . $name . "` DEFAULT CHARSET=%s COLLATE %s ROW_FORMAT = COMPACT;", $this->wpdb->charset, $this->wpdb->collate)
);
}
}
if (version_compare($this->currentVersion, '13.0', '<=')) {
$this->wpdb->query("DELETE FROM `" . $this->wpdb->usermeta . "` WHERE `meta_key` = 'meta-box-order_toplevel_page_wps_overview_page'");
}
$result = $this->wpdb->query("SHOW COLUMNS FROM {$visitorTable} LIKE 'user_id'");
if ($result == 0) {
$this->wpdb->query("ALTER TABLE `" . $visitorTable . "` ADD `user_id` BIGINT(48) NOT NULL AFTER `location`");
}
if (DB::ExistTable($searchTable)) {
$this->wpdb->query("DROP TABLE `$searchTable`");
}
/**
* Added new Fields to user_online Table
*
* @version 12.6.1
*/
if (DB::ExistTable($userOnlineTable)) {
// Add index ip.
$result = $this->wpdb->query("SHOW INDEX FROM `" . $userOnlineTable . "` WHERE Key_name = 'ip'");
if (!$result) {
$this->wpdb->query("ALTER TABLE `" . $userOnlineTable . "` ADD index (ip)");
}
}
/**
* Historical
*
* @version 14.4
*
*/
if (DB::ExistTable($historicalTable)) {
$result = $this->wpdb->query("SHOW INDEX FROM `" . $historicalTable . "` WHERE Key_name = 'page_id'");
// Remove index
if ($result) {
$this->wpdb->query("DROP INDEX `page_id` ON " . $historicalTable);
}
}
/**
* Added page_id column in statistics_pages
*
* @version 12.5.3
*/
if (DB::ExistTable($pagesTable)) {
$result = $this->wpdb->query("SHOW COLUMNS FROM `" . $pagesTable . "` LIKE 'page_id'");
if ($result == 0) {
$this->wpdb->query("ALTER TABLE `" . $pagesTable . "` ADD `page_id` BIGINT(20) NOT NULL AUTO_INCREMENT FIRST, ADD PRIMARY KEY (`page_id`);");
}
}
/**
* Removed date_ip from visitor table
* Drop the 'AString' column from visitors if it exists.
*
* @version 6.0
*/
if (DB::ExistTable($visitorTable)) {
$result = $this->wpdb->query("SHOW INDEX FROM `" . $visitorTable . "` WHERE Key_name = 'date_ip'");
if ($result > 1) {
$this->wpdb->query("DROP INDEX `date_ip` ON " . $visitorTable);
}
$result = $this->wpdb->query("SHOW COLUMNS FROM `" . $visitorTable . "` LIKE 'AString'");
if ($result > 0) {
$this->wpdb->query("ALTER TABLE `" . $visitorTable . "` DROP `AString`");
}
// Add index ip
$result = $this->wpdb->query("SHOW INDEX FROM `" . $visitorTable . "` WHERE Key_name = 'ip'");
if (!$result) {
$this->wpdb->query("ALTER TABLE `" . $visitorTable . "` ADD index (ip)");
}
}
/**
* Update options
*/
if (Option::get('privacy_audit') === false && version_compare($this->latestVersion, '14.7', '>=')) {
Option::update('privacy_audit', true);
}
if (Option::get('share_anonymous_data') === false && version_compare($this->latestVersion, '14.12', '>')) {
Option::update('share_anonymous_data', false);
}
if (Option::get('display_notifications') === false && version_compare($this->latestVersion, '14.12', '>')) {
Option::update('display_notifications', true);
}
if (Option::get('show_privacy_issues_in_report') === false && version_compare($this->latestVersion, '14.12', '>')) {
Option::update('show_privacy_issues_in_report', false);
}
/**
* Update GeoIP schedule from daily to monthly
*/
if (Option::get('schedule_geoip') && version_compare($this->currentVersion, '14.11', '<')) {
Event::reschedule('wp_statistics_geoip_hook', 'monthly');
}
/**
* Remove wp_statistics_marketing_campaign_hook, wp_statistics_notification_hook from schedule
*/
if (version_compare($this->latestVersion, '14.15', '>=')) {
Event::unschedule('wp_statistics_marketing_campaign_hook');
Event::unschedule('wp_statistics_notification_hook');
}
/**
* Remove wp_statistics_add_visit_hook from schedule
*/
if (version_compare($this->latestVersion, '14.15', '>=')) {
Event::unschedule('wp_statistics_add_visit_hook');
}
/**
* Remove all wp statistics transients
*/
if (version_compare($this->latestVersion, '14.15.1', '>=')) {
SystemCleaner::clearAllTransients();
}
/**
* Update consent integration to WP Consent API for backward compatibility
*/
$integration = Option::get('consent_integration');
$consentLevel = Option::get('consent_level_integration', 'functional');
$isWpConsentApiActive = IntegrationHelper::getIntegration('wp_consent_api')->isActive();
if ($isWpConsentApiActive && empty($integration) && $consentLevel !== 'disabled') {
Option::update('consent_integration', 'wp_consent_api');
}
/**
* Unset consent integration if consent level is disabled
*/
if ($integration === 'wp_consent_api' && $consentLevel === 'disabled') {
Option::update('consent_integration', '');
Option::update('consent_level_integration', 'functional');
}
/**
* Removes duplicate entries from the visitor_relationships table.
*
* @version 14.4
*/
//self::delete_duplicate_data(); // todo to move in background cronjob
/**
* Remove old hash format assets
*
* @version 14.8.1
*/
if (Option::get('bypass_ad_blockers', false) && $this->currentVersion == '14.8' && class_exists('WP_Statistics\Components\AssetNameObfuscator')) {
$assetNameObfuscator = new AssetNameObfuscator();
$assetNameObfuscator->deleteAllHashedFiles();
$assetNameObfuscator->deleteDatabaseOption();
}
// Enable Top Metrics in Advanced Reporting Add-on By Default
$advancedReportingOptions = Option::getAddonOptions('advanced_reporting');
if ($advancedReportingOptions !== false && Option::getByAddon('email_top_metrics', 'advanced_reporting') === false) {
Option::saveByAddon(array_merge(['email_top_metrics' => 1], $advancedReportingOptions), 'advanced_reporting');
}
/**
* Update old DataPlus options.
*
* @version 14.10
*/
if (version_compare($this->currentVersion, '14.10', '<') && (Option::get('link_tracker') || Option::get('download_tracker'))) {
Option::saveByAddon([
'link_tracker' => Option::get('link_tracker'),
'download_tracker' => Option::get('download_tracker'),
'latest_visitors_metabox' => '1',
], 'data_plus');
}
// Clear not used scheduled.
if (function_exists('wp_clear_scheduled_hook')) {
// Remove unused cron job for purging high hit count visitors daily
wp_clear_scheduled_hook('wp_statistics_dbmaint_visitor_hook');
// Remove referral db update cron
wp_clear_scheduled_hook('wp_statistics_referrals_db_hook');
}
/**
* Update old excluded URLs to the new structure with explicit wildcards.
*
* @version 14.10.3
*/
if (version_compare($this->currentVersion, '14.10.3', '<') && Option::get('excluded_urls')) {
$updatedExcludedUrls = $this->updateOldExcludedUrls();
if (!empty($updatedExcludedUrls)) {
Option::update('excluded_urls', implode("\n", $updatedExcludedUrls));
}
}
if (!Option::get('schedule_dbmaint') && version_compare($this->currentVersion, '14.15.5', '<')) {
Option::update('schedule_dbmaint_days', '0');
}
if (Option::get('schedule_dbmaint') && version_compare($this->currentVersion, '14.15.5', '<')) {
Event::reschedule('wp_statistics_dbmaint_hook', 'daily', DateTime::get('tomorrow midnight', 'U'));
}
}
/**
* Updates old excluded URLs to the new structure with explicit wildcards.
*
* @return array updated URLs.
*/
private function updateOldExcludedUrls()
{
$updatedUrls = [];
foreach (explode("\n", Option::get('excluded_urls')) as $url) {
$url = wp_make_link_relative($url);
$url = trim($url);
// If the URL contains a query string, strip it
$url = explode('?', $url)[0];
// Trim leading/trailing slashes
$url = trim($url, '/\\');
// If the URL doesn't end with an asterisk (*), add one and make it a wildcard
if (substr($url, -1) !== '*') {
$url .= '*';
}
// Add the URL to the new list if it's not similar to others
if (!in_array($url, $updatedUrls)) {
$updatedUrls[] = $url;
}
}
return $updatedUrls;
}
} AbstractCore.php 0000755 00000006730 15111632166 0007644 0 ustar 00 latestVersion = WP_STATISTICS_VERSION;
$this->networkWide = (bool)$networkWide;
$this->setWpdb();
}
/**
* Initialize the wpdb property from the global $wpdb.
*/
private function setWpdb()
{
global $wpdb;
$this->wpdb = $wpdb;
}
/**
* Initialize default options.
*
* @return void
*/
protected function initializeDefaultOptions()
{
$this->loadRequiredFiles();
$options = get_option(Option::$opt_name);
if (empty($options) || !is_array($options)) {
update_option(Option::$opt_name, Option::defaultOption());
}
}
/**
* Load required files.
*
* @return void
*/
private function loadRequiredFiles()
{
require_once WP_STATISTICS_DIR . 'includes/admin/class-wp-statistics-admin-template.php';
require_once WP_STATISTICS_DIR . 'includes/class-wp-statistics-option.php';
require_once WP_STATISTICS_DIR . 'includes/class-wp-statistics-helper.php';
require_once WP_STATISTICS_DIR . 'includes/class-wp-statistics-user-online.php';
require_once WP_STATISTICS_DIR . 'includes/class-wp-statistics-visitor.php';
}
/**
* Checks whether the plugin is a fresh installation.
*
* @return void
*/
protected function checkIsFresh()
{
$version = get_option('wp_statistics_plugin_version');
if (empty($version)) {
update_option('wp_statistics_is_fresh', true);
} else {
update_option('wp_statistics_is_fresh', false);
}
$installationTime = get_option('wp_statistics_installation_time');
if (empty($installationTime)) {
update_option('wp_statistics_installation_time', time());
}
}
/**
* Checks whether the plugin is updated.
*
* @return bool
*/
protected function isUpdated()
{
$this->currentVersion = get_option('wp_statistics_plugin_version', WP_STATISTICS_VERSION);
return $this->currentVersion != $this->latestVersion;
}
/**
* Update the plugin version.
*
* @return void
*/
protected function updateVersion()
{
update_option('wp_statistics_plugin_version', $this->latestVersion);
}
/**
* Execute the core function.
*
* @return void
*/
abstract public function execute();
}
CoreFactory.php 0000755 00000003157 15111632166 0007510 0 ustar 00