Skip to content

Commit 707f3f3

Browse files
committed
introduce extended views per referrer
Add another view with bar chart and table showing requests per referrer. These views feature type and post filters. Data is retrieved via WP API.
1 parent 79d8039 commit 707f3f3

File tree

4 files changed

+303
-24
lines changed

4 files changed

+303
-24
lines changed

inc/class-statify-api.php

Lines changed: 48 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ class Statify_Api extends Statify {
2727
const REST_ROUTE_STATS = 'stats';
2828
const REST_ROUTE_STATS_EXTENDED = 'stats/extended';
2929
const REST_ROUTE_STATS_POSTS = 'stats/posts';
30+
const REST_ROUTE_STATS_REFERRERS = 'stats/referrers';
3031
const REST_ROUTE_POSTS = 'posts';
3132

3233
/**
@@ -78,6 +79,16 @@ public static function init(): void {
7879
)
7980
);
8081

82+
register_rest_route(
83+
self::REST_NAMESPACE,
84+
self::REST_ROUTE_STATS_REFERRERS,
85+
array(
86+
'methods' => WP_REST_Server::READABLE,
87+
'callback' => array( __CLASS__, 'get_stats_referrers' ),
88+
'permission_callback' => array( __CLASS__, 'user_can_see_stats' ),
89+
)
90+
);
91+
8192
register_rest_route(
8293
self::REST_NAMESPACE,
8394
self::REST_ROUTE_POSTS,
@@ -278,7 +289,7 @@ public static function get_posts(): WP_REST_Response {
278289
function ( $url ) {
279290
return array(
280291
'url' => $url,
281-
'title' => self::post_title( $url ),
292+
'title' => Statify_Evaluation::post_title( $url ),
282293
);
283294
},
284295
Statify_Evaluation::get_post_urls()
@@ -308,6 +319,7 @@ public static function get_stats_posts( WP_REST_Request $request ): WP_REST_Resp
308319
return new WP_REST_Response( array( 'error' => 'invalid post type' ), 400 );
309320
}
310321

322+
// Date filter.
311323
$start = self::get_date( $request, 'start' );
312324
$end = self::get_date( $request, 'end' );
313325
$cache = empty( $start ) && empty( $end );
@@ -330,7 +342,7 @@ function ( $d ) {
330342
return array(
331343
'count' => intval( $d['count'] ),
332344
'url' => $url,
333-
'title' => self::post_title( $url ),
345+
'title' => Statify_Evaluation::post_title( $url ),
334346
'type' => $type,
335347
'typeName' => self::type_name( $type ),
336348
);
@@ -370,6 +382,40 @@ function ( $d ) use ( $type ) {
370382
return new WP_REST_Response( $data );
371383
}
372384

385+
/**
386+
* Get stats per referrers.
387+
*
388+
* @param WP_REST_Request $request The request.
389+
*
390+
* @return WP_REST_Response The response.
391+
*
392+
* @since 2.0.0
393+
*/
394+
public static function get_stats_referrers( WP_REST_Request $request ): WP_REST_Response {
395+
// Single post requested?
396+
$post = $request->get_param( 'post' );
397+
398+
// Date filter.
399+
$start = self::get_date( $request, 'start' );
400+
$end = self::get_date( $request, 'end' );
401+
$data = false;
402+
if ( empty( $post ) && empty( $start ) && empty( $end ) ) {
403+
// Retrieve data from cache.
404+
$data = self::from_cache( 'referrers' );
405+
}
406+
if ( ! $data ) {
407+
// Generate data for all types.
408+
$data = Statify_Evaluation::get_views_for_all_referrers( $post, $start, $end );
409+
410+
if ( empty( $post ) && empty( $start ) && empty( $end ) ) {
411+
// Store in cache.
412+
self::update_cache( 'referrers', '', $data );
413+
}
414+
}
415+
416+
return new WP_REST_Response( $data );
417+
}
418+
373419
/**
374420
* Retrieve data from cache.
375421
*
@@ -397,28 +443,6 @@ private static function update_cache( string $scope, string $index, array $data
397443
);
398444
}
399445

400-
/**
401-
* Get post title by URL.
402-
*
403-
* @param string $url Target URL.
404-
*
405-
* @return string Post title, fallback to URL of not available.
406-
*/
407-
private static function post_title( string $url ): string {
408-
if ( '' === $url ) {
409-
return __( 'all posts', 'statify' );
410-
}
411-
if ( '/' === $url ) {
412-
return __( 'Home Page', 'statify' );
413-
}
414-
$post_id = url_to_postid( $url );
415-
if ( 0 === $post_id ) {
416-
return esc_url( $url );
417-
}
418-
419-
return get_the_title( $post_id );
420-
}
421-
422446
/**
423447
* Get post type by URL.
424448
*

inc/class-statify-evaluation.php

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,15 @@ public static function add_menu(): void {
6262
'statify_content',
6363
array( __CLASS__, 'show_content' )
6464
);
65+
66+
add_submenu_page(
67+
'statify_dashboard',
68+
__( 'Referrers', 'statify' ) . ' — ' . __( 'Statify', 'statify' ),
69+
__( 'Referrers', 'statify' ),
70+
'see_statify_evaluation',
71+
'statify_referrers',
72+
array( __CLASS__, 'show_referrers' )
73+
);
6574
}
6675

6776
/**
@@ -78,6 +87,13 @@ public static function show_content(): void {
7887
self::show_view( 'content' );
7988
}
8089

90+
/**
91+
* Show the referrers page.
92+
*/
93+
public static function show_referrers(): void {
94+
self::show_view( 'referrers' );
95+
}
96+
8197
/**
8298
* Load a specific page view.
8399
*
@@ -390,4 +406,26 @@ public static function get_post_types(): array {
390406

391407
return array_merge( array( 'post', 'page' ), get_post_types( $types_args ) );
392408
}
409+
410+
/**
411+
* Get post title by URL.
412+
*
413+
* @param string $url Target URL.
414+
*
415+
* @return string Post title, fallback to URL of not available.
416+
*/
417+
public static function post_title( string $url ): string {
418+
if ( '' === $url ) {
419+
return __( 'all posts', 'statify' );
420+
}
421+
if ( '/' === $url ) {
422+
return __( 'Home Page', 'statify' );
423+
}
424+
$post_id = url_to_postid( $url );
425+
if ( 0 === $post_id ) {
426+
return esc_url( $url );
427+
}
428+
429+
return get_the_title( $post_id );
430+
}
393431
}

js/dashboard.js

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,11 @@
1616
const chartElemMonthly = document.getElementById('statify_chart_monthly');
1717
const chartElemYearly = document.getElementById('statify_chart_yearly');
1818
const chartElemContent = document.getElementById('statify_chart_content');
19+
const chartElemReferrer = document.getElementById('statify_chart_referrer');
1920
const yearlyTable = document.getElementById('statify-table-yearly');
2021
const dailyTable = document.getElementById('statify-table-daily');
2122
const contentTable = document.getElementById('statify-table-posts');
23+
const referrersTable = document.getElementById('statify-table-referrer');
2224

2325
// Controls.
2426
const postInput = document.getElementById('statify-dashboard-post');
@@ -123,6 +125,28 @@
123125
});
124126
}
125127

128+
/**
129+
* Load statistics per referrer.
130+
*
131+
* @return {Promise<Array<{count: number, host: string, url: string}>>} Data promise from API.
132+
*/
133+
function loadPerReferrer() {
134+
const param = new URLSearchParams();
135+
const search = new URLSearchParams(window.location.search);
136+
['post', 'start', 'end'].forEach((p) => {
137+
const v = search.get(p);
138+
if (v) {
139+
param.set(p, v);
140+
}
141+
});
142+
143+
return wp.apiFetch({
144+
path:
145+
'/statify/v1/stats/referrers' +
146+
(param.size > 0 ? '?' + param : ''),
147+
});
148+
}
149+
126150
/**
127151
* Render daily statistics.
128152
*
@@ -616,6 +640,52 @@
616640
addExportButton(table);
617641
}
618642

643+
/**
644+
* Render referrers table.
645+
*
646+
* @param {HTMLTableElement} table Root element.
647+
* @param {Array<{count: number, host: string, url: string}>} data Data from API.
648+
*/
649+
function renderReferrersTable(table, data) {
650+
const tbody = table.querySelector('tbody');
651+
const sumRow = table.querySelectorAll('tfoot > tr > td');
652+
const rows = Array.from(tbody.querySelectorAll('tr'));
653+
654+
const total = data.map((d) => d.count).reduce((a, b) => a + b, 0);
655+
656+
data.forEach((d, idx) => {
657+
const row = document.createElement('TR');
658+
let col = document.createElement('TD');
659+
const link = document.createElement('A');
660+
link.href = d.url;
661+
link.innerText = d.host;
662+
col.append(link);
663+
row.appendChild(col);
664+
col = document.createElement('TD');
665+
col.classList.add('right');
666+
col.innerText = d.count.toString();
667+
row.appendChild(col);
668+
col = document.createElement('TD');
669+
col.classList.add('right');
670+
col.innerText = ((d.count / total) * 100).toFixed(2) + ' %';
671+
row.appendChild(col);
672+
673+
if (rows.length > idx) {
674+
tbody.replaceChild(row, rows[idx]);
675+
} else {
676+
tbody.appendChild(row);
677+
}
678+
});
679+
for (let i = data.length; i < rows.length; i++) {
680+
tbody.removeChild(rows[i]);
681+
}
682+
683+
sumRow[sumRow.length - 2].innerText = total;
684+
sumRow[sumRow.length - 1].innerText = '100.00 %';
685+
686+
addExportButton(table);
687+
}
688+
619689
/**
620690
* Convert daily to monthly data.
621691
*
@@ -697,6 +767,17 @@
697767
renderBarChart(chartElemContent, labels, values, true);
698768
}
699769
});
770+
} else if (referrersTable) {
771+
loadPerReferrer().then((data) => {
772+
renderReferrersTable(referrersTable, data);
773+
if (chartElemReferrer) {
774+
// Limit number of records.
775+
data = data.slice(0, 24);
776+
const labels = data.map((d) => d.host);
777+
const values = data.map((d) => d.count);
778+
renderBarChart(chartElemReferrer, labels, values, true);
779+
}
780+
});
700781
}
701782

702783
if (postInput && postList) {

0 commit comments

Comments
 (0)