Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Track internal search queries #242

Open
wants to merge 15 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 12 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
6 changes: 1 addition & 5 deletions css/dashboard.css
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@

#statify_dashboard .table {
padding-bottom: 12px;
flex: 1 0 50%;
}

#statify_dashboard .table p.sub {
Expand All @@ -86,11 +87,6 @@
overflow: hidden;
}

#statify_dashboard .table.referrer,
#statify_dashboard .table.target {
flex: 1 0 50%;
}

#statify_dashboard .table.total {
flex: 0 0 100%;
}
Expand Down
94 changes: 85 additions & 9 deletions inc/class-statify-dashboard.php
Original file line number Diff line number Diff line change
Expand Up @@ -301,8 +301,9 @@ public static function get_stats( $force_refresh = false ) {
/**
* Get stats from DB
*
* @since 0.1.0
* @version 1.4.0
* @since 0.1.0
* @since 1.4.0
* @since 2.0.0 Add search queries to `$data` array.
Copy link
Member

Choose a reason for hiding this comment

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

Is this common to add a "changelog" like this to PHPDoc? And now we also have three @since and no @version anymore. 🤔

Copy link
Member Author

Choose a reason for hiding this comment

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

I guess we used the @version wrong, if I am right, it is ment to set versions for APIs and similar (https://docs.phpdoc.org/guide/references/phpdoc/tags/version.html#version), and you can use multiple @since (https://docs.phpdoc.org/guide/references/phpdoc/tags/since.html#since)

Copy link
Contributor

@stklcode stklcode Mar 20, 2023

Choose a reason for hiding this comment

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

Yep, @since is commonly used for changelog purposes, mostly changes to method signature or high-level behavior (at least helpful on public API that can be quite helpful to have this information on hand in the IDE)
@version is meant for semantic changes and the state of the functionality.

Multiple of either one don’t make much sense, because they yield barely any information, just “something was done here“.

Something like this would be more or less meaningful:

@since 1.0 introduced (if this is left empty, the natural assumption would be the same)
@since 1.1 return boolean result instead of void
@since 1.2 make parameter $foo optional with default 42

@version 1.1

I personally often omit the version tags, if there is no real need for that. The since-tags often help even in the same project to see why a method is used in a non-optimal way or similar. In such cases the hint “method was updated in 1.2“ and “we use it since 1.1“ immediately presents a valid reason, so we don’t have to guess what someone may have thought here.

Btw. that is also done in WP core and the changelogs are rendered in the reference articles, e.g.: https://developer.wordpress.org/reference/functions/wp_parse_url/#changelog

Copy link
Member

Choose a reason for hiding this comment

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

"Since" we only use it on some functions and we don't even have a real "public API", would we even mind keeping these @since version numbers up to date?

Copy link
Contributor

Choose a reason for hiding this comment

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

Well, a public method is a public method and there are some recommendations out there for things like workarounds or custom triggers that call some of these. Some snippets given by ourselves in the support forums. Documenting API changes enables users of those to potentially migrate their logic without opening another support request, if changes are not self-explaining.

I agree, the majority of our code is designed for internal use and only exposed public for hooks etc.

But as with every project, that’s yet another part of documentation that might get out of sync over time. Though it’s probably one of the easier parts, as old annotations typically never become wrong, so we only have to append another one-liner, if necessary.

*
* @return array DB results
*/
Expand All @@ -322,7 +323,10 @@ 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`, COUNT(`created`) as `count`
FROM `$wpdb->statify`
GROUP BY `created`
ORDER BY `created` DESC LIMIT %d",
$days_show
),
ARRAY_A
Expand All @@ -332,15 +336,41 @@ 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 LIMIT %d",
"SELECT COUNT(`target`) as `count`, `target` as `url`
FROM `$wpdb->statify`
WHERE created = %s AND target NOT LIKE %s
GROUP BY `target`
ORDER BY `count` DESC LIMIT %d",
$current_date,
'/?s%',
$limit
),
ARRAY_A
);
$data['searches'] = $wpdb->get_results(
$wpdb->prepare(
"SELECT COUNT(`target`) as `count`, `target` as `url`
FROM `$wpdb->statify`
WHERE created = %s AND target LIKE %s
GROUP BY `target`
ORDER BY `count` DESC LIMIT %d",
$current_date,
'/?s%',
$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 LIMIT %d",
"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 LIMIT %d",
$current_date,
$limit
),
Expand All @@ -349,16 +379,43 @@ 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 LIMIT %d",
"SELECT COUNT(`target`) as `count`, `target` as `url`
FROM `$wpdb->statify`
WHERE created > DATE_SUB(%s, INTERVAL %d DAY) AND target NOT LIKE %s
GROUP BY `target`
ORDER BY `count` DESC LIMIT %d",
$current_date,
$days_show,
'/?s%',
$limit
),
ARRAY_A
);
$data['searches'] = $wpdb->get_results(
$wpdb->prepare(
"SELECT COUNT(`target`) as `count`, `target` as `url`
FROM `$wpdb->statify`
WHERE created > DATE_SUB(%s, INTERVAL %d DAY) AND target LIKE %s
GROUP BY `target`
ORDER BY `count` DESC LIMIT %d",
$current_date,
$days_show,
'/?s%',
$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 > DATE_SUB(%s, INTERVAL %d DAY) GROUP BY `host` ORDER BY `count` DESC LIMIT %d",
"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 LIMIT %d",
$current_date,
$days_show,
$limit
Expand All @@ -371,17 +428,36 @@ 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 COUNT(`created`)
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 COUNT(`created`) AS `count`, MIN(`created`) AS `date`
FROM `$wpdb->statify`",
ARRAY_A
),
);
}

return $data;
}

/**
* Parses a visit target and, if needed, modifies it for displaying.
*
* @param string $target URL target as displayed in widget.
*
* @return string
*/
public static function parse_target( $target ) {
// Modify for search strings.
if ( self::query_string_contains_search( $target ) ) {
$target = preg_replace( '/^\/\?s=/', '', $target );
return urldecode( $target );
}
return $target;
}
}
40 changes: 35 additions & 5 deletions inc/class-statify.php
Original file line number Diff line number Diff line change
Expand Up @@ -131,12 +131,25 @@ protected static function track( $referrer, $target ) {
// Relative target URL.
$target = user_trailingslashit( str_replace( home_url( '/', 'relative' ), '/', $target ) );

/* Global vars */
// Global vars.
global $wp_rewrite;

// Trim target URL.
if ( $wp_rewrite->permalink_structure ) {
$target = wp_parse_url( $target, PHP_URL_PATH );
// Maybe add trailing slash if that is no search query.
if ( ! self::query_string_contains_search( $target ) ) {
$target = user_trailingslashit( $target );

// Trim target url.
if ( $wp_rewrite->permalink_structure ) {
$target = wp_parse_url( $target, PHP_URL_PATH );
}
} else {
// Lowercase search query.
$target = strtolower( $target );

// Remove additional query parameters that might exist.
$target = preg_replace( '/^\/\?/', '', $target );
wp_parse_str( $target, $tmp );
$target = "/?s={$tmp['s']}";
}

// Init rows.
Expand Down Expand Up @@ -180,6 +193,23 @@ public static function parse_date( $date ) {
return date_i18n( get_option( 'date_format' ), strtotime( $date ) );
}

/**
* Checks a string of query parameters for the `s` query param.
*
* @param string $query_string String with query parameters.
*
* @since 2.0.0
*
* @return bool
*/
public static function query_string_contains_search( $query_string ) {
// Remove leading `/?`.
$query_string = preg_replace( '/^\/\?/', '', $query_string );
wp_parse_str( $query_string, $query_params );

return isset( $query_params['s'] ) && ! empty( $query_params['s'] );
}

/**
* Check JavaScript tracking.
*
Expand Down Expand Up @@ -286,7 +316,7 @@ private static function is_bot() {
*/
protected static function is_internal() {
// Skip for preview, 404 calls, feed, search, favicon and sitemap access.
return is_preview() || is_404() || is_feed() || is_search()
return is_preview() || is_404() || is_feed()
|| ( function_exists( 'is_favicon' ) && is_favicon() )
|| '' !== get_query_var( 'sitemap' ) || '' !== get_query_var( 'sitemap-stylesheet' );
}
Expand Down
45 changes: 45 additions & 0 deletions views/widget-front.php
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,56 @@ class_exists( 'Statify' ) || exit;
</div>

<div class="table target">
<<<<<<< HEAD
<p class="sub">
<?php esc_html_e( 'Top targets', 'statify' ); ?>
</p>

<div>
<table>
<?php foreach ( (array) $stats['target'] as $target ) { ?>
<tr>
<td class="b">
<?php echo (int) $target['count']; ?>
</td>
<td class="t">
<a href="<?php echo esc_url( home_url( $target['url'] ) ); ?>" target="_blank" rel="noopener noreferrer">
<?php echo esc_html( Statify_Dashboard::parse_target( $target['url'] ) ); ?>
</a>
</td>
</tr>
<?php } ?>
</table>
</div>
</div>
<?php } ?>

<?php if ( ! empty( $stats['searches'] ) ) { ?>
<div class="table searches">
<p class="sub">
<?php esc_html_e( 'Top searches', 'statify' ); ?>
</p>

<div>
<table>
<?php foreach ( (array) $stats['searches'] as $target ) { ?>
<tr>
<td class="b">
<?php echo (int) $target['count']; ?>
</td>
<td class="t">
<a href="<?php echo esc_url( home_url( $target['url'] ) ); ?>" target="_blank" rel="noopener noreferrer">
<?php echo esc_html( Statify_Dashboard::parse_target( $target['url'] ) ); ?>
</a>
</td>
</tr>
=======
<p class="sub"><?php esc_html_e( 'Top targets', 'statify' ); ?></p>
<table>
<tbody>
<?php for ( $i = 0; $i < $limit; $i++ ) { ?>
<tr class="placeholder"><td colspan="2">&nbsp;</td></tr>
>>>>>>> develop
florianbrinkmann marked this conversation as resolved.
Show resolved Hide resolved
<?php } ?>
</tbody>
</table>
Expand Down