Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion inc/class-statify-api.php
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,9 @@ public static function track_visit( $request ) {
$target = filter_var( $target, FILTER_SANITIZE_URL );
}

Statify::track( $referrer, $target );
$meta = $request->get_param( 'meta' );

Statify::track( $referrer, $target, $meta );
}

return new WP_REST_Response( null, 204 );
Expand Down
77 changes: 71 additions & 6 deletions inc/class-statify-cron.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,12 @@ class Statify_Cron extends Statify {
*
* @since 0.3.0
* @version 1.4.0
* @wp-hook boolean statify__skip_aggregation
*/
public static function cleanup_data() {

// Global.
global $wpdb;

// Remove items.
// Remove old items.
$wpdb->query(
$wpdb->prepare(
"DELETE FROM `$wpdb->statify` WHERE created <= SUBDATE(%s, %d)",
Expand All @@ -38,9 +37,75 @@ public static function cleanup_data() {
)
);

// Aggregate data.
if ( ! apply_filters( 'statify__skip_aggregation', false ) ) {
self::aggregate_data();
}

// Optimize DB.
$wpdb->query(
"OPTIMIZE TABLE `$wpdb->statify`"
);
$wpdb->query( "OPTIMIZE TABLE `$wpdb->statify`" );
}

/**
* Aggregate data in database.
*
* @since 1.9
*/
public static function aggregate_data() {
global $wpdb;

// Get date of last aggregation.
if ( isset( self::$_options['last_aggregation'] ) ) {
// Value saved, use it.
$start = self::$_options['last_aggregation'];
} else {
// No? We need to clean up all data. Let's determine the oldest data in the database.
$start = $wpdb->get_col( "SELECT MIN(`created`) FROM `$wpdb->statify`" );
$start = $start[0];
}

if ( is_null( $start ) ) {
// No data available, i.e not cleaned up yet and no data in database.
return;
}

$now = new DateTime();
$date = new DateTime( $start );

// Iterate over every day from start (inclusive) til now.
while ( $date < $now ) {
$agg = $wpdb->get_results(
$wpdb->prepare(
"SELECT `created`, `referrer`, `target`, SUM(`hits`) as `hits` FROM `$wpdb->statify` WHERE `created` = %s GROUP BY `created`, `referrer`, `target`",
$date->format( 'Y-m-d' )
),
ARRAY_A
);

// Remove non-aggregated data and insert aggregates within one transaction.
$wpdb->query( 'START TRANSACTION' );
$res = $wpdb->query(
$wpdb->prepare(
"DELETE FROM `$wpdb->statify` WHERE `created` = %s",
$date->format( 'Y-m-d' )
)
);
if ( false !== $res ) {
foreach ( $agg as $a ) {
if ( false === $wpdb->insert( $wpdb->statify, $a ) ) {
$wpdb->query( 'ROLLBACK' );
break;
}
}
}
$wpdb->query( 'COMMIT' );

// Continue with next day.
$date->modify( '+1 day' );
}

// Remember last aggregation date.
self::$_options['last_aggregation'] = $now->format( 'Y-m-d' );
update_option( 'statify', self::$_options );
}
}
14 changes: 7 additions & 7 deletions inc/class-statify-dashboard.php
Original file line number Diff line number Diff line change
Expand Up @@ -320,7 +320,7 @@ private static function _select_data() {
$data = array(
'visits' => $wpdb->get_results(
$wpdb->prepare(
"SELECT `created` as `date`, COUNT(`created`) as `count` FROM `$wpdb->statify` GROUP BY `created` ORDER BY `created` DESC LIMIT %d",
"SELECT `created` as `date`, SUM(`hits`) as `count` FROM `$wpdb->statify` GROUP BY `created` ORDER BY `created` DESC LIMIT %d",
$days_show
),
ARRAY_A
Expand All @@ -330,15 +330,15 @@ private static function _select_data() {
if ( $today ) {
$data['target'] = $wpdb->get_results(
$wpdb->prepare(
"SELECT COUNT(`target`) as `count`, `target` as `url` FROM `$wpdb->statify` WHERE created = %s GROUP BY `target` ORDER BY `count` DESC, `url` ASC LIMIT %d",
"SELECT SUM(`hits`) as `count`, `target` as `url` FROM `$wpdb->statify` WHERE created = %s GROUP BY `target` ORDER BY `count` DESC, `url` ASC LIMIT %d",
$current_date,
$limit
),
ARRAY_A
);
$data['referrer'] = $wpdb->get_results(
$wpdb->prepare(
"SELECT COUNT(`referrer`) as `count`, `referrer` as `url`, SUBSTRING_INDEX(SUBSTRING_INDEX(TRIM(LEADING 'www.' FROM(TRIM(LEADING 'https://' FROM TRIM(LEADING 'http://' FROM TRIM(`referrer`))))), '/', 1), ':', 1) as `host` FROM `$wpdb->statify` WHERE `referrer` != '' AND created = %s GROUP BY `host` ORDER BY `count` DESC, `url` ASC LIMIT %d",
"SELECT SUM(`hits`) as `count`, `referrer` as `url`, SUBSTRING_INDEX(SUBSTRING_INDEX(TRIM(LEADING 'www.' FROM(TRIM(LEADING 'https://' FROM TRIM(LEADING 'http://' FROM TRIM(`referrer`))))), '/', 1), ':', 1) as `host` FROM `$wpdb->statify` WHERE `referrer` != '' AND created = %s GROUP BY `host` ORDER BY `count` DESC, `url` ASC LIMIT %d",
$current_date,
$limit
),
Expand All @@ -347,7 +347,7 @@ private static function _select_data() {
} else {
$data['target'] = $wpdb->get_results(
$wpdb->prepare(
"SELECT COUNT(`target`) as `count`, `target` as `url` FROM `$wpdb->statify` WHERE created > DATE_SUB(%s, INTERVAL %d DAY) GROUP BY `target` ORDER BY `count` DESC, `url` ASC LIMIT %d",
"SELECT SUM(`hits`) as `count`, `target` as `url` FROM `$wpdb->statify` WHERE created > DATE_SUB(%s, INTERVAL %d DAY) GROUP BY `target` ORDER BY `count` DESC, `url` ASC LIMIT %d",
$current_date,
$days_show,
$limit
Expand All @@ -356,7 +356,7 @@ private static function _select_data() {
);
$data['referrer'] = $wpdb->get_results(
$wpdb->prepare(
"SELECT COUNT(`referrer`) as `count`, `referrer` as `url`, SUBSTRING_INDEX(SUBSTRING_INDEX(TRIM(LEADING 'www.' FROM(TRIM(LEADING 'https://' FROM TRIM(LEADING 'http://' FROM TRIM(`referrer`))))), '/', 1), ':', 1) as `host` FROM `$wpdb->statify` WHERE `referrer` != '' AND created > DATE_SUB(%s, INTERVAL %d DAY) GROUP BY `host` ORDER BY `count` DESC, `url` ASC LIMIT %d",
"SELECT SUM(`hits`) as `count`, `referrer` as `url`, SUBSTRING_INDEX(SUBSTRING_INDEX(TRIM(LEADING 'www.' FROM(TRIM(LEADING 'https://' FROM TRIM(LEADING 'http://' FROM TRIM(`referrer`))))), '/', 1), ':', 1) as `host` FROM `$wpdb->statify` WHERE `referrer` != '' AND created > DATE_SUB(%s, INTERVAL %d DAY) GROUP BY `host` ORDER BY `count` DESC, `url` ASC LIMIT %d",
$current_date,
$days_show,
$limit
Expand All @@ -369,12 +369,12 @@ private static function _select_data() {
$data['visit_totals'] = array(
'today' => $wpdb->get_var(
$wpdb->prepare(
"SELECT COUNT(`created`) FROM `$wpdb->statify` WHERE created = %s",
"SELECT SUM(`hits`) FROM `$wpdb->statify` WHERE created = %s",
$current_date
)
),
'since_beginning' => $wpdb->get_row(
"SELECT COUNT(`created`) AS `count`, MIN(`created`) AS `date` FROM `$wpdb->statify`",
"SELECT SUM(`hits`) AS `count`, MIN(`created`) AS `date` FROM `$wpdb->statify`",
ARRAY_A
),
);
Expand Down
28 changes: 26 additions & 2 deletions inc/class-statify-frontend.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,29 @@
*/
class Statify_Frontend extends Statify {

/**
* Returns key value pair array with tracking metadata.
*
* @return array
*/
private static function load_metadata() {
$meta = array();

foreach ( Statify::get_metafields() as $field ) {
// Get values.
if (
isset( $field['key'] ) &&
is_string( $field['key'] ) &&
isset( $field['callback'] ) &&
is_callable( $field['callback'] )
) {
$meta[ $field['key'] ] = call_user_func( $field['callback'] );
}
}

return $meta;
}

/**
* Track the page view
*
Expand All @@ -44,7 +67,7 @@ public static function track_visit( $is_snippet = false ) {
$referrer = filter_var( wp_unslash( $_SERVER['HTTP_REFERER'] ), FILTER_SANITIZE_URL );
}

Statify::track( $referrer, $target );
Statify::track( $referrer, $target, self::load_metadata() );
}

/**
Expand Down Expand Up @@ -94,9 +117,10 @@ public static function wp_footer() {
true
);

// Add endpoint to script.
// Add endpoint and tracking meta data to script.
$script_data = array(
'url' => esc_url_raw( rest_url( Statify_Api::REST_NAMESPACE . '/' . Statify_Api::REST_ROUTE_TRACK ) ),
'tracking_meta' => self::load_metadata(),
);
if ( Statify::TRACKING_METHOD_JAVASCRIPT_WITH_NONCE_CHECK === self::$_options['snippet'] ) {
$script_data['nonce'] = wp_create_nonce( 'statify_track' );
Expand Down
5 changes: 2 additions & 3 deletions inc/class-statify-install.php
Original file line number Diff line number Diff line change
Expand Up @@ -82,8 +82,7 @@ private static function _apply() {
);
}

// Create the actual tables.
Statify_Table::init();
Statify_Table::create();
// Initialize the database schema.
Statify_Schema::init();
}
}
127 changes: 127 additions & 0 deletions inc/class-statify-schema.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
<?php
/**
* Statify: Statify_Schema class
*
* This file contains class for the plugin's DB scheme handling.
*
* @package Statify
* @since 2.0.0
*/

// Quit if accessed outside WP context.
defined( 'ABSPATH' ) || exit;

/**
* Statify DB Schema
*
* @since 2.0.0
*/
class Statify_Schema {
/**
* Database tables
*
* @var string[]
*/
public static $tables = array(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe this should not be public and/or constant?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Const array is PHP 5.6+ iirc (currently supported 5.3+)
But feel free to raise the requirements, if that make things easier here.

Copy link
Member

@2ndkauboy 2ndkauboy Mar 20, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Constant arrays is not a thing at all 😆 Like not before PHP 7+, so we just make it private.

'statify',
'statifymeta',
);

/**
* Needed statify db version for current plugin version
*
* @var string
*/
public static $db_version = '2.0.0';

/**
* Definition of the custom tables.
*
* @since 2.0.0
* @version 2.0.0
*/
public static function init() {
// Global.
global $wpdb;

foreach ( static::$tables as $table ) {
$wpdb->tables[] = $table;
$wpdb->$table = $wpdb->get_blog_prefix() . $table;
}

self::maybe_create_tables();
}

/**
* Create the tables.
*
* @since 2.0.0
* @version 2.0.0
*/
public static function maybe_create_tables() {
$current_db_version = get_option( 'statify_db_version', '1.8.4' );
if ( $current_db_version === self::$db_version ) {
return;
}

// Global.
global $wpdb, $charset_collate;

/**
* Use same index length like the WordPress core
*
* @see wp_get_db_schema()
*/
$max_index_length = 191;

// Include.
require_once ABSPATH . 'wp-admin/includes/upgrade.php';

// Create statify table.
dbDelta(
"CREATE TABLE {$wpdb->statify} (
id bigint(20) unsigned NOT NULL auto_increment,
created date NOT NULL default '0000-00-00',
referrer varchar(255) NOT NULL default '',
target varchar(255) NOT NULL default '',
hits integer NOT NULL default 1,
PRIMARY KEY (id),
KEY referrer (referrer),
KEY target (target),
KEY created (created)
) {$charset_collate};"
);

// Create statifymeta table.
dbDelta(
"CREATE TABLE {$wpdb->statifymeta} (
meta_id bigint(20) unsigned NOT NULL auto_increment,
statify_id bigint(20) unsigned NOT NULL default 0,
meta_key varchar(255) default NULL,
meta_value longtext,
PRIMARY KEY (meta_id),
KEY statify_id (statify_id),
KEY meta_key (meta_key({$max_index_length}))
) {$charset_collate};"
);

update_option( 'statify_db_version', self::$db_version );
}

/**
* Remove the custom tables.
*
* @since 2.0.0
* @version 2.0.0
*/
public static function drop_tables() {
global $wpdb;

// Remove.
foreach ( static::$tables as $table ) {
$wpdb->query( "DROP TABLE IF EXISTS `{$wpdb->$table}`" ); // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared
}

delete_option( 'statify_db_version' );
}
}
Loading