modified file upgrade-temp-backup

This commit is contained in:
2026-07-28 15:05:31 +00:00
committed by Gitium
parent 64be23dffb
commit dd0a8b69b1
486 changed files with 123520 additions and 0 deletions

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,234 @@
<?php
/**
* Matomo - free/libre analytics platform
*
* @link https://matomo.org
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
* @package matomo
*/
namespace WP_Piwik;
use LiteSpeed\ESI;
/**
* Performs server side tracking for AI bots.
*
* Normal server side tracking: when no caching plugins or CDNs are being
* used, this class will send tracking requests in the wp_footer hook.
*
* When advanced-cache.php is used: when a caching plugin creates an
* advanced-cache.php file that WordPress uses, tracking must be done
* through the standalone script in misc/track_ai_bot.php. This script
* must be manually added to a user's wp-config.php file, right after
* ABSPATH is defined.
*
* When .htaccess is used: when a caching plugin modifies the .htaccess
* to serve cached files directly, AI bot tracking is not possible.
*
* When a CDN is used: when a CDN is used to serve cached content, AI
* bot tracking can be accomplished through the use of ESI (Edge Side Includes).
* In this case, this class outputs an `<esi:include>` directive that
* loads the misc/track_ai_bot.php script. This technique will only work
* for CDNs that support ESI.
*
* The misc/track_ai_bot.php script uses this class without all of WordPress loaded.
* It can also be loaded outside of WordPress. Because of this, it is important
* that the script and this class use as few total dependencies as possible. Otherwise,
* AI bot tracking reduce the performance of requests to cached content.
*/
class AIBotTracking {
private static $ai_bot_tracked = false;
private static $extensions_to_track = array(
'', // no extension
'htm',
'html',
'php',
);
/**
* @var Settings
*/
private $settings;
/**
* @var Logger
*/
private $logger;
/**
* @var AjaxTracker|null
*/
private $tracker = null;
/**
* @param Settings $settings
* @param Logger $logger
*/
public function __construct( Settings $settings, Logger $logger ) {
$this->settings = $settings;
$this->logger = $logger;
}
public function register_hooks() {
add_action( 'litespeed_init', array( $this, 'litespeed_init' ) );
add_action( 'wp_footer', array( $this, 'do_ai_bot_tracking' ), 999999 );
}
public function litespeed_init() {
if ( class_exists( ESI::class )
&& $this->settings->is_ai_bot_tracking_enabled_via_esi_includes()
) {
ESI::set_has_esi();
}
}
/**
* @param string|null $url
* @return void
*/
public function do_ai_bot_tracking( $url = null ) {
// track AI bots only once per request
if ( self::$ai_bot_tracked ) {
return;
}
self::$ai_bot_tracked = true;
// if using ESI to track, and not within the track_ai_bot.php script, output the appropriate ESI tag
$is_using_esi_to_track = $this->settings->is_ai_bot_tracking_enabled_via_esi_includes();
if (
$is_using_esi_to_track
&& empty( $GLOBALS['WP_PIWIK_IN_ESI'] )
) {
$track_script_url = plugins_url( '/misc/track_ai_bot.php', WP_PIWIK_FILE ) . '?mtm_esi=1&mtm_url=' . rawurlencode( AjaxTracker::getCurrentUrl() );
echo '<esi:include src="' . esc_attr( $track_script_url ) . '" cache-control="no-cache" />';
return;
}
if ( ! $this->is_doing_ai_bot_tracking_this_request() ) {
return;
}
$response_code = http_response_code();
$request_elapsed_ms = null;
// cannot track request time if executed via an esi:include
if (
empty( $GLOBALS['WP_PIWIK_IN_ESI'] )
&& array_key_exists( 'REQUEST_TIME_FLOAT', $_SERVER )
) {
// phpcs:ignore WordPress.Security.ValidatedSanitizedInput.MissingUnslash
$request_elapsed_ms = (int) ( ( microtime( true ) - floatval( $_SERVER['REQUEST_TIME_FLOAT'] ) ) * 1000 );
}
if ( empty( $response_code ) ) {
$response_code = 200;
}
// phpcs:ignore WordPress.WP.CapitalPDangit.Misspelled
$source = 'WordPress';
if ( empty( $url ) ) {
$url = AjaxTracker::getCurrentUrl();
}
$tracker = $this->get_tracker();
$tracker->setUrl( $url );
// cannot count bytes echo'd so no response size tracked
$tracker->doTrackPageViewIfAIBot( $response_code, null, $request_elapsed_ms, $source );
}
public function should_track_current_page() {
if ( is_admin() ) {
return false;
}
if ( defined( 'REST_REQUEST' ) && REST_REQUEST ) {
return false;
}
if ( wp_doing_ajax() ) {
return false;
}
if ( empty( $_SERVER['REQUEST_URI'] ) ) {
return false;
}
// phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
$request_path = (string) wp_parse_url( wp_unslash( $_SERVER['REQUEST_URI'] ), PHP_URL_PATH );
if ( preg_match( '/matomo\.php$/', $request_path ) ) {
return false;
}
if ( $this->is_request_for_file( $request_path ) ) {
return false;
}
return true;
}
private function is_request_for_file( $request_path ) {
if (
! empty( $_SERVER['DOCUMENT_ROOT'] )
// phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
&& is_dir( wp_unslash( $_SERVER['DOCUMENT_ROOT'] ) . $request_path )
) {
return false;
}
$extension = pathinfo( $request_path, PATHINFO_EXTENSION );
return ! in_array( $extension, self::$extensions_to_track, true );
}
public function is_js_execution_detected() {
return ! empty( $_COOKIE['matomo_has_js'] )
&& '1' === $_COOKIE['matomo_has_js'];
}
private function is_doing_ai_bot_tracking_this_request() {
if ( ! empty( $GLOBALS['WP_PIWIK_IN_ESI'] ) ) {
return true;
}
if ( ! $this->should_track_current_page() ) {
return false;
}
if ( $this->is_js_execution_detected() ) {
return false;
}
$tracker = $this->get_tracker();
// phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase
if ( ! AjaxTracker::isUserAgentAIBot( $tracker->userAgent ) ) {
return false;
}
if (
! $this->settings->is_ai_bot_tracking_enabled()
|| ! $this->settings->is_tracking_enabled()
) {
return false;
}
return true;
}
private function get_tracker() {
if ( empty( $this->tracker ) ) {
$this->tracker = new AjaxTracker( $this->settings, $this->logger );
$this->tracker->setRequestTimeout( 1 );
}
return $this->tracker;
}
}

View File

@ -0,0 +1,34 @@
<?php
namespace WP_Piwik;
abstract class Admin {
/**
* @var \WP_Piwik
*/
protected static $wp_piwik;
protected static $page_id;
/**
* @var Settings
*/
protected static $settings;
public function __construct( $wp_piwik, $settings ) {
self::$wp_piwik = $wp_piwik;
self::$settings = $settings;
}
abstract public function show();
abstract public function print_admin_scripts();
public function print_admin_styles() {
wp_enqueue_style( 'wp-piwik', self::$wp_piwik->get_plugin_url() . 'css/wp-piwik.css', array(), self::$wp_piwik->get_plugin_version() );
}
public function on_load() {
// empty
}
}

View File

@ -0,0 +1,16 @@
<?php
namespace WP_Piwik\Admin;
class Network extends \WP_Piwik\Admin\Statistics {
public function print_admin_scripts() {
$version = self::$wp_piwik->get_plugin_version();
wp_enqueue_script( 'wp-piwik', self::$wp_piwik->get_plugin_url() . 'js/wp-piwik.js', array(), $version, true );
wp_enqueue_script( 'wp-piwik-chartjs', self::$wp_piwik->get_plugin_url() . 'js/chartjs/chart.min.js', array(), $version, false );
}
public function on_load() {
self::$wp_piwik->onload_stats_page();
}
}

View File

@ -0,0 +1,133 @@
<?php
namespace WP_Piwik\Admin;
if ( ! class_exists( 'WP_List_Table' ) ) {
require_once ABSPATH . 'wp-admin/includes/class-wp-list-table.php';
}
/**
* phpcs:disable WordPress.DB.DirectDatabaseQuery.DirectQuery
* phpcs:disable WordPress.DB.DirectDatabaseQuery.NoCaching
*/
class Sitebrowser extends \WP_List_Table {
private $data = array();
/**
* @var \WP_Piwik
*/
private $wp_piwik;
public function __construct( $wp_piwik ) {
$this->wp_piwik = $wp_piwik;
if ( isset( $_REQUEST['s'] ) ) {
$cnt = $this->prepare_items( sanitize_text_field( wp_unslash( $_REQUEST['s'] ) ) );
} else {
$cnt = $this->prepare_items();
}
$this->show_search_form();
parent::__construct(
array(
'singular' => __( 'site', 'wp-piwik' ),
'plural' => __( 'sites', 'wp-piwik' ),
'ajax' => false,
)
);
if ( $cnt > 0 ) {
$this->display();
} else {
echo '<p>' . esc_html__( 'No site configured yet.', 'wp-piwik' ) . '</p>';
}
}
public function get_columns() {
$columns = array(
'id' => __( 'Blog ID', 'wp-piwik' ),
'name' => __( 'Title', 'wp-piwik' ),
'siteurl' => __( 'URL', 'wp-piwik' ),
'piwikid' => __( 'Site ID (Piwik)', 'wp-piwik' ),
);
return $columns;
}
public function prepare_items( $search = '' ) {
global $blog_id;
global $wpdb;
global $pagenow;
$current_page = $this->get_pagenum();
$per_page = 10;
if ( is_plugin_active_for_network( 'wp-piwik/wp-piwik.php' ) ) {
$search = '%' . $wpdb->esc_like( $search ) . '%';
// phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared, WordPress.DB.PreparedSQL.InterpolatedNotPrepared
$total_items = $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(*) FROM {$wpdb->blogs} WHERE CONCAT(domain, path) LIKE %s AND spam = 0 AND deleted = 0", $search ) );
$blogs = \WP_Piwik\Settings::get_blog_list( $per_page, $current_page, $search );
foreach ( $blogs as $blog ) {
$blog_details = get_blog_details( $blog['blog_id'], true );
$this->data [] = array(
'name' => $blog_details->blogname,
'id' => $blog_details->blog_id,
'siteurl' => $blog_details->siteurl,
'piwikid' => $this->wp_piwik->get_piwik_site_id( $blog_details->blog_id ),
);
}
} else {
$blog_details = get_bloginfo();
$this->data [] = array(
'name' => get_bloginfo( 'name' ),
'id' => '-',
'siteurl' => get_bloginfo( 'url' ),
'piwikid' => $this->wp_piwik->get_piwik_site_id(),
);
$total_items = 1;
}
$columns = $this->get_columns();
$hidden = array();
$sortable = array();
$this->_column_headers = array(
$columns,
$hidden,
$sortable,
);
$this->set_pagination_args(
array(
'total_items' => $total_items,
'per_page' => $per_page,
)
);
foreach ( $this->data as $key => $dataset ) {
if ( empty( $dataset['piwikid'] ) || 'n/a' === $dataset['piwikid'] ) {
$this->data [ $key ] ['piwikid'] = __( 'Site not created yet.', 'wp-piwik' );
}
if ( $this->wp_piwik->is_network_mode() ) {
$this->data [ $key ] ['name'] = '<a href="index.php?page=wp-piwik_stats&wpmu_show_stats=' . esc_attr( rawurlencode( $dataset['id'] ) ) . '">' . esc_html( $dataset['name'] ) . '</a>';
}
}
$this->items = $this->data;
return count( $this->items );
}
public function column_default( $item, $column_name ) {
switch ( $column_name ) {
case 'id':
case 'name':
case 'siteurl':
case 'piwikid':
return $item [ $column_name ];
default:
return print_r( $item, true );
}
}
private function show_search_form() {
$page = isset( $_REQUEST['page'] ) ? sanitize_text_field( wp_unslash( $_REQUEST['page'] ) ) : '';
?>
<form method="post">
<input type="hidden" name="page" value="<?php echo esc_attr( $page ); ?>" />
<?php $this->search_box( 'Search domain and path', 'wpPiwikSiteSearch' ); ?>
</form>
<?php
}
}

View File

@ -0,0 +1,55 @@
<?php
namespace WP_Piwik\Admin;
class Statistics extends \WP_Piwik\Admin {
/**
* @return void
* @phpcs:disable WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedVariableFound
*/
public function show() {
global $screen_layout_columns;
if ( empty( $screen_layout_columns ) ) {
$screen_layout_columns = 2;
}
if ( self::$settings->get_global_option( 'disable_timelimit' ) ) {
set_time_limit( 0 );
}
echo '<div id="wp-piwik-stats-general" class="wrap">';
echo '<h2>' . esc_html( 'WP-Piwik' === self::$settings->get_global_option( 'plugin_display_name' ) ? 'Piwik ' . esc_html__( 'Statistics', 'wp-piwik' ) : self::$settings->get_global_option( 'plugin_display_name' ) ) . '</h2>';
if ( self::$settings->check_network_activation() && function_exists( 'is_super_admin' ) && is_super_admin() ) {
if ( isset( $_GET['wpmu_show_stats'] ) ) {
switch_to_blog( (int) $_GET['wpmu_show_stats'] );
} elseif ( ! empty( $_GET['overview'] ) || ( function_exists( 'is_network_admin' ) && is_network_admin() ) ) {
new \WP_Piwik\Admin\Sitebrowser( self::$wp_piwik );
return;
}
echo '<p>' . esc_html__( 'Currently shown stats:', 'wp-piwik' ) . ' <a href="' . esc_attr( get_bloginfo( 'url' ) ) . '">' . esc_html( get_bloginfo( 'name' ) ) . '</a>. <a href="?page=wp-piwik_stats&overview=1">Show site overview</a>.</p>';
}
echo '<form action="admin-post.php" method="post"><input type="hidden" name="action" value="save_wp-piwik_stats_general" /><div id="dashboard-widgets" class="metabox-holder columns-' . esc_attr( $screen_layout_columns ) . esc_attr( 2 <= $screen_layout_columns ? ' has-right-sidebar' : '' ) . '">';
wp_nonce_field( 'wp-piwik_stats-general' );
wp_nonce_field( 'closedpostboxes', 'closedpostboxesnonce', false );
wp_nonce_field( 'meta-box-order', 'meta-box-order-nonce', false );
$columns = array( 'normal', 'side', 'column3' );
for ( $i = 0; $i < 3; $i++ ) {
// @phpstan-ignore-next-line
echo '<div id="postbox-container-' . esc_attr( $i + 1 ) . '" class="postbox-container">';
do_meta_boxes( self::$wp_piwik->stats_page_id, $columns[ $i ], null );
echo '</div>';
}
echo '</div></form></div>';
echo '<script>//<![CDATA[' . "\n";
echo 'jQuery(document).ready(function($) {$(".if-js-closed").removeClass("if-js-closed").addClass("closed"); postboxes.add_postbox_toggles(' . wp_json_encode( self::$wp_piwik->stats_page_id ) . ');});' . "\n";
echo '//]]></script>' . "\n";
if ( self::$settings->check_network_activation() && function_exists( 'is_super_admin' ) && is_super_admin() ) {
restore_current_blog();
}
}
public function print_admin_scripts() {
$version = self::$wp_piwik->get_plugin_version();
wp_enqueue_script( 'wp-piwik', self::$wp_piwik->get_plugin_url() . 'js/wp-piwik.js', array(), $version, true );
wp_enqueue_script( 'wp-piwik-chartjs', self::$wp_piwik->get_plugin_url() . 'js/chartjs/chart.min.js', array(), $version, false );
}
}

View File

@ -0,0 +1,175 @@
<?php
/**
* Matomo - free/libre analytics platform
*
* @link https://matomo.org
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
* @package matomo
*/
namespace WP_Piwik;
if ( ! defined( 'ABSPATH' ) ) {
exit; // if accessed directly
}
if ( ! class_exists( '\WP_Piwik\MatomoTracker' ) ) {
require_once __DIR__ . '/../../libs/matomo-php-tracker/MatomoTracker.php';
}
/**
* @phpcs:disable WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase
* @phpcs:disable WordPress.NamingConventions.ValidVariableName.VariableNotSnakeCase
* @phpcs:disable Generic.CodeAnalysis.UselessOverridingMethod.Found
*/
class AjaxTracker extends \WP_Piwik\MatomoTracker {
private $has_cookie = false;
private $logger;
public function __construct( Settings $settings, Logger $logger ) {
$this->logger = $logger;
$idsite = $settings->get_option( 'site_id' );
if ( ! $idsite ) {
return;
}
$api_endpoint = rtrim( $settings->get_matomo_url(), '/' ) . '/matomo.php';
parent::__construct( (int) $idsite, $api_endpoint );
$this->ip = false;
if ( ! $settings->get_global_option( 'disable_cookies' ) ) {
$cookie_domain = $this->get_tracking_cookie_domain( $settings );
$this->enableCookies( $cookie_domain );
} else {
$this->disableCookieSupport();
}
if ( $this->loadVisitorIdCookie() ) {
if ( ! empty( $this->cookieVisitorId ) ) {
$this->has_cookie = true;
$this->set_visitor_id_safe( $this->cookieVisitorId );
}
}
}
public function set_visitor_id_safe( $visitor_id ) {
try {
$this->setVisitorId( $visitor_id );
} catch ( \Exception $ex ) {
// do not fatal if the visitor ID is invalid for some reason
if ( ! $this->is_invalid_visitor_id_error( $ex ) ) {
throw $ex;
}
}
}
protected function setCookie( $cookieName, $cookieValue, $cookieTTL ) {
if ( ! $this->has_cookie ) {
// we only set / overwrite cookies if it is a visitor that has eg no JS enabled or ad blocker enabled etc.
// this way we will track all cart updates and orders into the same visitor on following requests.
// If we recognized the visitor before via cookie we want in our case to make sure to not overwrite
// any cookie
return parent::setCookie( $cookieName, $cookieValue, $cookieTTL );
}
return $this;
}
protected function sendRequest( string $url, string $method = 'GET', $data = null, bool $force = false ): string {
if ( ! $this->idSite ) {
$this->logger->log( 'ecommerce tracking could not find idSite, cannot send request' );
return ''; // not installed or synced yet
}
if ( $this->is_prerender() ) {
// do not track if for some reason we are prerendering
return '';
}
$args = array(
'method' => $method,
'headers' => array(
'User-Agent' => $this->userAgent,
),
'blocking' => false,
);
if ( ! empty( $data ) ) {
$args['body'] = $data;
}
$url = $url . '&bots=1';
try {
$response = $this->wp_remote_request( $url, $args );
} catch ( \Exception $ex ) {
$this->logger->log( 'ajax_tracker: ' . $ex->getMessage() );
return '';
}
if ( is_wp_error( $response ) ) {
$this->logger->log( 'ajax_tracker: ' . new \Exception( $response->get_error_message() ) );
return '';
}
return $response['body'];
}
private function is_invalid_visitor_id_error( \Exception $ex ) {
return strpos( $ex->getMessage(), 'setVisitorId() expects' ) === 0;
}
/**
* See https://developer.chrome.com/docs/web-platform/prerender-pages
*
* @return bool
*/
private function is_prerender() {
// phpcs:disable WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
$purpose = strtolower( isset( $_SERVER['HTTP_SEC_PURPOSE'] ) ? wp_unslash( $_SERVER['HTTP_SEC_PURPOSE'] ) : '' );
return strpos( $purpose, 'prefetch' ) !== false
|| strpos( $purpose, 'prerender' ) !== false;
}
/**
* for tests to override
*
* @param string $url
* @param array $args
* @return array|\WP_Error
*/
protected function wp_remote_request( $url, $args ) {
return wp_remote_request( $url, $args );
}
/**
* In Connect Matomo we want to rely entirely on JavaScript tracker
* for creating cookies.
*
* @return self
*/
protected function setFirstPartyCookies() {
// disabled
return $this;
}
public static function getCurrentUrl(): string {
return parent::getCurrentUrl();
}
public function get_tracking_cookie_domain( Settings $settings ) {
if (
$settings->get_global_option( 'track_across' )
|| $settings->get_global_option( 'track_crossdomain_linking' )
) {
$host = wp_parse_url( home_url(), PHP_URL_HOST );
if ( ! empty( $host ) ) {
return '*.' . $host;
}
}
return '';
}
}

View File

@ -0,0 +1,57 @@
<?php
namespace WP_Piwik;
abstract class Logger {
private $logger_name = 'unnamed';
private $start_microtime = null;
abstract public function logger_output( $logger_time, $logger_message );
public function __construct( $logger_name ) {
$this->set_name( $logger_name );
$this->set_start_microtime( microtime( true ) );
$this->log( 'Logging started -------------------------------' );
}
public static function make_logger() {
$logger = defined( 'WP_PIWIK_ACTIVATE_LOGGER' ) ? WP_PIWIK_ACTIVATE_LOGGER : 0;
switch ( $logger ) {
case 1:
return new \WP_Piwik\Logger\Screen( __CLASS__ );
case 2:
return new \WP_Piwik\Logger\File( __CLASS__ );
default:
return new \WP_Piwik\Logger\Dummy( __CLASS__ );
}
}
public function __destruct() {
$this->log( 'Logging finished ------------------------------' );
}
public function log( $logger_message ) {
$this->logger_output( $this->get_elapsed_microtime(), $logger_message );
}
private function set_name( $logger_name ) {
$this->logger_name = $logger_name;
}
public function get_name() {
return $this->logger_name;
}
private function set_start_microtime( $start_microtime ) {
$this->start_microtime = $start_microtime;
}
public function get_start_microtime() {
return $this->start_microtime;
}
public function get_elapsed_microtime() {
return microtime( true ) - $this->get_start_microtime();
}
}

View File

@ -0,0 +1,10 @@
<?php
namespace WP_Piwik\Logger;
class Dummy extends \WP_Piwik\Logger {
public function logger_output( $logger_time, $logger_message ) {
// empty
}
}

View File

@ -0,0 +1,55 @@
<?php
namespace WP_Piwik\Logger;
/**
* @phpcs:disable WordPress.WP.AlternativeFunctions.file_system_operations_fopen
* @phpcs:disable WordPress.WP.AlternativeFunctions.file_system_operations_fclose
* @phpcs:disable WordPress.WP.AlternativeFunctions.file_system_operations_fwrite
*/
class File extends \WP_Piwik\Logger {
private $logger_file = null;
private function encode_filename( $file_name ) {
$file_name = str_replace( ' ', '_', $file_name );
$file_name = preg_replace( '/[^0-9^a-z^_^.]/', '', $file_name );
return $file_name;
}
private function set_filename() {
$this->logger_file = WP_PIWIK_PATH . 'logs' . DIRECTORY_SEPARATOR .
gmdate( 'Ymd' ) . '_' . $this->encode_filename( $this->get_name() ) . '.log';
}
private function get_filename() {
return $this->logger_file;
}
private function open_file() {
if ( ! $this->logger_file ) {
$this->set_filename();
}
return fopen( $this->get_filename(), 'a' );
}
private function close_file( $file_handle ) {
fclose( $file_handle );
}
private function write_file( $file_handle, $file_content ) {
fwrite( $file_handle, $file_content . "\n" );
}
private function format_microtime( $logger_time ) {
return sprintf( '[%6s sec]', number_format( $logger_time, 3 ) );
}
public function logger_output( $logger_time, $logger_message ) {
$file_handle = $this->open_file();
if ( $file_handle ) {
$this->write_file( $file_handle, $this->format_microtime( $logger_time ) . ' ' . $logger_message );
$this->close_file( $file_handle );
}
}
}

View File

@ -0,0 +1,27 @@
<?php
namespace WP_Piwik\Logger;
class Screen extends \WP_Piwik\Logger {
private $logs = array();
private function format_microtime( $logger_time ) {
return sprintf( '[%6s sec]', number_format( $logger_time, 3 ) );
}
public function __construct( $logger_name ) {
add_action( is_admin() ? 'admin_footer' : 'wp_footer', array( $this, 'echo_results' ) );
parent::__construct( $logger_name );
}
public function logger_output( $logger_time, $logger_message ) {
$this->logs[] = $this->format_microtime( $logger_time ) . ' ' . $logger_message;
}
public function echo_results() {
echo '<pre>';
print_r( $this->logs );
echo '</pre>';
}
}

View File

@ -0,0 +1,132 @@
<?php
namespace WP_Piwik;
abstract class Request {
/**
* @var \WP_Piwik
*/
protected static $wp_piwik;
/**
* @var Settings
*/
protected static $settings;
protected static $debug;
protected static $last_error = '';
protected static $requests = array();
protected static $results = array();
protected static $is_cacheable = array();
protected static $piwik_version;
public function __construct( $wp_piwik, $settings ) {
self::$wp_piwik = $wp_piwik;
self::$settings = $settings;
self::register( 'API.getPiwikVersion', array() );
}
public function reset() {
self::$debug = null;
self::$requests = array();
self::$results = array();
self::$is_cacheable = array();
self::$piwik_version = null;
}
public static function register( $method, $parameter ) {
if ( 'API.getPiwikVersion' === $method ) {
$id = 'global.getPiwikVersion';
} else {
$id = 'method=' . $method . self::parameter_to_string( $parameter );
}
if (
in_array( $method, array( 'API.getPiwikVersion', 'SitesManager.getJavascriptTag', 'SitesManager.getSitesWithAtLeastViewAccess', 'SitesManager.getSitesIdFromSiteUrl', 'SitesManager.addSite', 'SitesManager.updateSite', 'SitesManager.getSitesWithAtLeastViewAccess' ), true ) ||
! isset( $parameter['date'] ) ||
! isset( $parameter['period'] ) ||
'last' === substr( $parameter['date'], 0, 4 ) ||
'today' === $parameter['date'] ||
( 'day' === $parameter['period'] && gmdate( 'Ymd' ) === $parameter['date'] ) ||
( 'month' === $parameter['period'] && gmdate( 'Ym' ) === $parameter['date'] ) ||
( 'week' === $parameter['period'] && gmdate( 'Ymd', strtotime( 'last Monday' ) ) === $parameter['date'] )
) {
self::$is_cacheable[ $id ] = false;
} else {
// phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.serialize_serialize
self::$is_cacheable[ $id ] = $method . '-' . serialize( $parameter );
}
if ( ! isset( self::$requests[ $id ] ) ) {
self::$requests[ $id ] = array(
'method' => $method,
'parameter' => $parameter,
);
}
return $id;
}
private static function parameter_to_string( $parameter ) {
$return = '';
if ( is_array( $parameter ) ) {
foreach ( $parameter as $key => $value ) {
$return .= '&' . $key . '=' . $value;
}
}
return $return;
}
public function perform( $id ) {
if ( self::$settings->get_global_option( 'cache' ) ) {
$cached = get_transient( 'wp-piwik_c_' . md5( self::$is_cacheable[ $id ] ) );
if ( ! empty( $cached ) && ! ( ! empty( $cached['result'] ) && 'error' === $cached['result'] ) ) {
self::$wp_piwik->log( 'Deliver cached data: ' . $id );
return $cached;
}
}
self::$wp_piwik->log( 'Perform request: ' . $id );
if ( ! isset( self::$requests[ $id ] ) ) {
return array(
'result' => 'error',
'message' => 'Request ' . $id . ' was not registered.',
);
} elseif ( ! isset( self::$results[ $id ] ) ) {
$this->request( $id );
}
if ( isset( self::$results[ $id ] ) ) {
if ( self::$settings->get_global_option( 'cache' ) && self::$is_cacheable[ $id ] ) {
set_transient( 'wp-piwik_c_' . md5( self::$is_cacheable[ $id ] ), self::$results[ $id ], WEEK_IN_SECONDS );
}
return self::$results[ $id ];
} else {
return false;
}
}
public function get_debug( $id ) {
return isset( self::$debug[ $id ] ) ? self::$debug[ $id ] : false;
}
protected function build_url( $config ) {
return http_build_query( $this->get_url_params( $config ), '', '&' );
}
protected function get_url_params( $config ) {
$params = [
'method' => $config['method'],
'idSite' => self::$settings->get_option( 'site_id' ),
];
$params = array_merge( $params, $config['parameter'] );
return $params;
}
protected function unserialize( $str ) {
self::$wp_piwik->log( 'Result string: ' . $str );
// phpcs:ignore WordPress.PHP.NoSilencedErrors.Discouraged
return ( json_decode( '', true ) === $str || false !== @json_decode( $str, true ) ) ? json_decode( $str, true ) : array();
}
public static function get_last_error() {
return self::$last_error;
}
abstract protected function request( $id );
}

View File

@ -0,0 +1,94 @@
<?php
namespace WP_Piwik\Request;
class Php extends \WP_Piwik\Request {
/**
* @var mixed
*/
private static $piwik_environment = false;
protected function request( $id ) {
$count = 0;
$url = self::$settings->get_global_option( 'piwik_url' );
foreach ( self::$requests as $request_id => $config ) {
if ( ! isset( self::$results[ $request_id ] ) ) {
if ( '' !== self::$settings->get_global_option( 'filter_limit' ) && is_numeric( self::$settings->get_global_option( 'filter_limit' ) ) ) {
$config['parameter']['filter_limit'] = self::$settings->get_global_option( 'filter_limit' );
}
$params = $this->get_url_params( $config );
$params['module'] = 'API';
$params['format'] = 'json';
$map[ $count ] = $request_id;
$result = $this->call( $id, $url, $params );
self::$results[ $map[ $count ] ] = $result;
++$count;
}
}
}
private function call( $id, $url, $params ) {
if ( ! defined( 'PIWIK_INCLUDE_PATH' ) ) {
return false;
}
if ( PIWIK_INCLUDE_PATH === false ) {
return array(
'result' => 'error',
'message' => __( 'Could not resolve', 'wp-piwik' ) . ' &quot;' . htmlentities( self::$settings->get_global_option( 'piwik_path' ) ) . '&quot;: ' . __( 'realpath() returns false', 'wp-piwik' ) . '.',
);
}
if ( file_exists( PIWIK_INCLUDE_PATH . '/index.php' ) ) {
require_once PIWIK_INCLUDE_PATH . '/index.php';
}
if ( file_exists( PIWIK_INCLUDE_PATH . '/core/API/Request.php' ) ) {
require_once PIWIK_INCLUDE_PATH . '/core/API/Request.php';
}
if ( class_exists( '\Piwik\Application\Environment' ) && ! self::$piwik_environment ) {
// Piwik 2.14.* compatibility fix
self::$piwik_environment = new \Piwik\Application\Environment( null );
self::$piwik_environment->init();
}
if ( class_exists( 'Piwik\FrontController' ) ) {
\Piwik\FrontController::getInstance()->init();
} else {
return array(
'result' => 'error',
'message' => __( 'Class Piwik\FrontController does not exists.', 'wp-piwik' ),
);
}
if ( class_exists( 'Piwik\API\Request' ) ) {
$params['token_auth'] = self::$settings->get_global_option( 'piwik_token' );
$request = new \Piwik\API\Request( $params );
} else {
return array(
'result' => 'error',
'message' => __( 'Class Piwik\API\Request does not exists.', 'wp-piwik' ),
);
}
$result = $request->process();
if ( ! headers_sent() ) {
header( 'Content-Type: text/html', true );
}
$result = $this->unserialize( $result );
if ( $GLOBALS ['wp-piwik_debug'] ) {
self::$debug[ $id ] = array( $params . '&token_auth=...' );
}
return $result;
}
public function reset() {
if (
class_exists( '\Piwik\Application\Environment' )
&& self::$piwik_environment instanceof \Piwik\Application\Environment
) {
self::$piwik_environment->destroy();
}
if ( class_exists( 'Piwik\FrontController' ) ) {
\Piwik\FrontController::unsetInstance();
}
parent::reset();
}
}

View File

@ -0,0 +1,126 @@
<?php
namespace WP_Piwik\Request;
/**
* TODO: switch to wp_remote_get
* phpcs:disable WordPress.WP.AlternativeFunctions.curl_curl_close
* phpcs:disable WordPress.WP.AlternativeFunctions.curl_curl_getinfo
* phpcs:disable WordPress.WP.AlternativeFunctions.curl_curl_error
* phpcs:disable WordPress.WP.AlternativeFunctions.curl_curl_init
* phpcs:disable WordPress.WP.AlternativeFunctions.curl_curl_setopt
* phpcs:disable WordPress.WP.AlternativeFunctions.curl_curl_exec
* phpcs:disable WordPress.WP.AlternativeFunctions.file_get_contents_file_get_contents
*/
class Rest extends \WP_Piwik\Request {
protected function request( $id ) {
$count = 0;
$url = self::$settings->get_matomo_url();
$params = 'module=API&method=API.getBulkRequest&format=json';
$filter_limit = self::$settings->get_global_option( 'filter_limit' );
if (
$filter_limit > 0
&& is_numeric( self::$settings->get_global_option( 'filter_limit' ) )
) {
$params .= '&filter_limit=' . self::$settings->get_global_option( 'filter_limit' );
}
foreach ( self::$requests as $request_id => $config ) {
if ( ! isset( self::$results[ $request_id ] ) ) {
$params .= '&urls[' . $count . ']=' . rawurlencode( $this->build_url( $config ) );
$map[ $count ] = $request_id;
++$count;
}
}
$use_curl = (
function_exists( 'curl_init' )
&& ini_get( 'allow_url_fopen' )
&& 'curl' === self::$settings->get_global_option( 'http_connection' )
) || (
function_exists( 'curl_init' )
&& ! ini_get( 'allow_url_fopen' )
);
$results = $use_curl ? $this->curl( $id, $url, $params ) : $this->fopen( $id, $url, $params );
if ( is_array( $results ) ) {
foreach ( $results as $num => $result ) {
if ( isset( $map[ $num ] ) ) {
self::$results[ $map[ $num ] ] = $result;
}
}
}
}
private function curl( $id, $url, $params ) {
if ( 'post' === self::$settings->get_global_option( 'http_method' ) ) {
$c = curl_init( $url );
curl_setopt( $c, CURLOPT_POST, 1 );
curl_setopt( $c, CURLOPT_POSTFIELDS, $params . '&token_auth=' . self::$settings->get_global_option( 'piwik_token' ) );
} else {
$c = curl_init( $url . '?' . $params . '&token_auth=' . self::$settings->get_global_option( 'piwik_token' ) );
}
curl_setopt( $c, CURLOPT_SSL_VERIFYPEER, ! self::$settings->get_global_option( 'disable_ssl_verify' ) );
curl_setopt( $c, CURLOPT_SSL_VERIFYHOST, ! self::$settings->get_global_option( 'disable_ssl_verify_host' ) ? 2 : 0 );
curl_setopt( $c, CURLOPT_USERAGENT, 'php' === self::$settings->get_global_option( 'piwik_useragent' ) ? ini_get( 'user_agent' ) : self::$settings->get_global_option( 'piwik_useragent_string' ) );
curl_setopt( $c, CURLOPT_RETURNTRANSFER, 1 );
curl_setopt( $c, CURLOPT_HEADER, $GLOBALS ['wp-piwik_debug'] );
curl_setopt( $c, CURLOPT_TIMEOUT, self::$settings->get_global_option( 'connection_timeout' ) );
$http_proxy_class = new \WP_HTTP_Proxy();
if ( $http_proxy_class->is_enabled() && $http_proxy_class->send_through_proxy( $url ) ) {
curl_setopt( $c, CURLOPT_PROXY, $http_proxy_class->host() );
curl_setopt( $c, CURLOPT_PROXYPORT, $http_proxy_class->port() );
if ( $http_proxy_class->use_authentication() ) {
curl_setopt( $c, CURLOPT_PROXYUSERPWD, $http_proxy_class->username() . ':' . $http_proxy_class->password() );
}
}
$result = curl_exec( $c );
self::$last_error = curl_error( $c );
if ( $GLOBALS ['wp-piwik_debug'] ) {
$header_size = curl_getinfo( $c, CURLINFO_HEADER_SIZE );
$header = substr( $result, 0, $header_size );
$body = substr( $result, $header_size );
$result = $this->unserialize( $body );
self::$debug[ $id ] = array( $header, $url . '?' . $params . '&token_auth=...' );
} else {
$result = $this->unserialize( $result );
}
if ( version_compare( PHP_VERSION, '8', '<' ) ) {
curl_close( $c );
}
return $result;
}
private function fopen( $id, $url, $params ) {
$context_definition = array(
'http' => array(
'timeout' => self::$settings->get_global_option( 'connection_timeout' ),
'header' => "Content-type: application/x-www-form-urlencoded\r\n",
),
);
$context_definition['ssl'] = array();
if ( self::$settings->get_global_option( 'disable_ssl_verify' ) ) {
$context_definition['ssl'] = array(
'allow_self_signed' => true,
'verify_peer' => false,
);
}
if ( self::$settings->get_global_option( 'disable_ssl_verify_host' ) ) {
$context_definition['ssl']['verify_peer_name'] = false;
}
if ( self::$settings->get_global_option( 'http_method' ) === 'post' ) {
$full_url = $url;
$context_definition['http']['method'] = 'POST';
$context_definition['http']['content'] = $params . '&token_auth=' . self::$settings->get_global_option( 'piwik_token' );
} else {
$full_url = $url . '?' . $params . '&token_auth=' . self::$settings->get_global_option( 'piwik_token' );
}
$context = stream_context_create( $context_definition );
// phpcs:ignore WordPress.PHP.NoSilencedErrors.Discouraged
$result = $this->unserialize( @file_get_contents( $full_url, false, $context ) );
if ( $GLOBALS ['wp-piwik_debug'] ) {
self::$debug[ $id ] = array( get_headers( $full_url, 1 ), $url . '?' . $params . '&token_auth=...' );
}
return $result;
}
}

View File

@ -0,0 +1,486 @@
<?php
namespace WP_Piwik;
/**
* Manage WP-Piwik settings
*
* @author Andr&eacute; Br&auml;kling
* @package WP_Piwik
*
* TODO: do not disable this at some point
* @phpcs:disable WordPress.DB.DirectDatabaseQuery.NoCaching
* @phpcs:disable WordPress.DB.DirectDatabaseQuery.DirectQuery
*/
class Settings {
const TRACK_AI_BOTS = 'track_ai_bots';
const TRACK_AI_BOTS_USING_ESI = 'track_ai_bots_using_esi';
/**
* @var \WP_Piwik variables and default settings container
*/
private static $wp_piwik;
private static $default_settings;
/**
*
* @var array Define callback functions for changed settings
*/
private $check_settings = array(
'piwik_url' => 'check_piwik_url',
'piwik_token' => 'check_piwik_token',
'site_id' => 'request_piwik_site_id',
'tracking_code' => 'prepare_tracking_code',
'noscript_code' => 'prepare_nocscript_code',
);
/**
* @var array default configuration set
*/
private $global_settings = array(
// Plugin settings
'revision' => 0,
'last_settings_update' => 0,
// User settings: Piwik configuration
'piwik_mode' => 'http',
'piwik_url' => '',
'piwik_path' => '',
'piwik_user' => '',
'matomo_user' => '',
'piwik_token' => '',
'auto_site_config' => true,
// User settings: Stats configuration
'default_date' => 'yesterday',
'stats_seo' => false,
'stats_ecommerce' => false,
'dashboard_widget' => false,
'dashboard_ecommerce' => false,
'dashboard_chart' => false,
'dashboard_seo' => false,
'toolbar' => false,
'capability_read_stats' => array(
'administrator' => true,
),
'perpost_stats' => 'disabled',
'plugin_display_name' => 'Connect Matomo',
'piwik_shortcut' => false,
'shortcodes' => false,
// User settings: Tracking configuration
'track_mode' => 'disabled',
'track_codeposition' => 'footer',
'track_noscript' => false,
'track_nojavascript' => false,
'proxy_url' => '',
'track_content' => 'disabled',
'track_search' => false,
'track_404' => false,
'add_post_annotations' => array(),
'add_customvars_box' => false,
'add_download_extensions' => '',
'set_download_extensions' => '',
'set_link_classes' => '',
'set_download_classes' => '',
'require_consent' => 'disabled',
'disable_cookies' => false,
'limit_cookies' => false,
'limit_cookies_visitor' => 34186669, // Piwik default 13 months
'limit_cookies_session' => 1800, // Piwik default 30 minutes
'limit_cookies_referral' => 15778463, // Piwik default 6 months
'track_admin' => false,
'capability_stealth' => array(),
'track_across' => false,
'track_across_alias' => false,
'track_crossdomain_linking' => false,
'track_feed' => false,
'track_feed_addcampaign' => false,
'track_feed_campaign' => 'feed',
'track_heartbeat' => 0,
'track_user_id' => 'disabled',
// User settings: Expert configuration
'cache' => true,
'http_connection' => 'curl',
'http_method' => 'post',
'disable_timelimit' => false,
'filter_limit' => '',
'connection_timeout' => 5,
'disable_ssl_verify' => false,
'disable_ssl_verify_host' => false,
'piwik_useragent' => 'php',
'piwik_useragent_string' => 'WP-Piwik',
'dnsprefetch' => false,
'track_datacfasync' => false,
'track_cdnurl' => '',
'track_cdnurlssl' => '',
'force_protocol' => 'disabled',
'remove_type_attribute' => false,
'update_notice' => 'enabled',
self::TRACK_AI_BOTS => false,
self::TRACK_AI_BOTS_USING_ESI => false,
);
private $settings = array(
'name' => '',
'site_id' => null,
'noscript_code' => '',
'tracking_code' => '',
'last_tracking_code_update' => 0,
'dashboard_revision' => 0,
);
private $settings_changed = false;
/**
* Constructor class to prepare settings manager
*
* @param \WP_Piwik $wp_piwik
* active WP-Piwik instance
*/
public function __construct( $wp_piwik ) {
self::$wp_piwik = $wp_piwik;
self::$wp_piwik->log( 'Store default settings' );
self::$default_settings = array(
'globalSettings' => $this->global_settings,
'settings' => $this->settings,
);
self::$wp_piwik->log( 'Load settings' );
foreach ( $this->global_settings as $key => $default ) {
$this->global_settings [ $key ] = ( $this->check_network_activation() ? get_site_option( 'wp-piwik_global-' . $key, $default ) : get_option( 'wp-piwik_global-' . $key, $default ) );
}
foreach ( $this->settings as $key => $default ) {
$this->settings [ $key ] = get_option( 'wp-piwik-' . $key, $default );
}
}
/**
* Save all settings as WordPress options
*/
public function save() {
global $wp_roles;
if ( ! $this->settings_changed ) {
self::$wp_piwik->log( 'No settings changed yet' );
return;
}
self::$wp_piwik->log( 'Save settings' );
$this->global_settings['plugin_display_name'] = htmlspecialchars( $this->global_settings['plugin_display_name'], ENT_QUOTES, 'utf-8' );
foreach ( $this->global_settings as $key => $value ) {
if ( $this->check_network_activation() ) {
update_site_option( 'wp-piwik_global-' . $key, $value );
} else {
update_option( 'wp-piwik_global-' . $key, $value );
}
}
foreach ( $this->settings as $key => $value ) {
update_option( 'wp-piwik-' . $key, $value );
}
foreach ( $wp_roles->role_names as $str_key => $str_name ) {
$obj_role = get_role( $str_key );
$caps = array( 'stealth', 'read_stats' );
foreach ( $caps as $str_cap ) {
$ary_caps = $this->get_global_option( 'capability_' . $str_cap );
if ( isset( $ary_caps [ $str_key ] ) && $ary_caps [ $str_key ] ) {
$wp_roles->add_cap( $str_key, 'wp-piwik_' . $str_cap );
} else {
$wp_roles->remove_cap( $str_key, 'wp-piwik_' . $str_cap );
}
}
}
$this->settings_changed = false;
}
/**
* Get a global option's value which should not be empty
*
* @param string $key
* option key
* @return string option value
*/
public function get_not_empty_global_option( $key ) {
return isset( $this->global_settings [ $key ] ) && ! empty( $this->global_settings [ $key ] ) ? $this->global_settings [ $key ] : self::$default_settings ['globalSettings'] [ $key ];
}
/**
* Get a global option's value
*
* @param string $key
* option key
* @return mixed option value
*/
public function get_global_option( $key ) {
return isset( $this->global_settings [ $key ] ) ? $this->global_settings [ $key ] : self::$default_settings ['globalSettings'] [ $key ];
}
/**
* Get an option's value related to a specific blog
*
* @param string $key
* option key
* @param int $blog_id
* blog ID (default: current blog)
* @return mixed
*/
public function get_option( $key, $blog_id = null ) {
if ( $this->check_network_activation() && ! empty( $blog_id ) ) {
return get_blog_option( $blog_id, 'wp-piwik-' . $key );
}
return isset( $this->settings [ $key ] ) ? $this->settings [ $key ] : self::$default_settings ['settings'] [ $key ];
}
/**
* Set a global option's value
*
* @param string $key
* option key
* @param mixed $value
* new option value
*/
public function set_global_option( $key, $value ) {
$this->settings_changed = true;
self::$wp_piwik->log( 'Changed global option ' . $key . ': ' . ( is_array( $value ) ? wp_json_encode( $value ) : $value ) );
$this->global_settings [ $key ] = $value;
}
/**
* Set an option's value related to a specific blog
*
* @param string $key
* option key
* @param string $value
* new option value
* @param int $blog_id
* blog ID (default: current blog)
*/
public function set_option( $key, $value, $blog_id = null ) {
if ( empty( $blog_id ) ) {
$blog_id = get_current_blog_id();
}
$this->settings_changed = true;
self::$wp_piwik->log( 'Changed option ' . $key . ': ' . $value );
if ( $this->check_network_activation() ) {
update_blog_option( $blog_id, 'wp-piwik-' . $key, $value );
}
if ( get_current_blog_id() === $blog_id ) {
$this->settings [ $key ] = $value;
}
}
/**
* Reset settings to default
*/
public function reset_settings() {
self::$wp_piwik->log( 'Reset WP-Piwik settings' );
global $wpdb;
if ( $this->check_network_activation() ) {
$ary_blogs = self::get_blog_list();
if ( is_array( $ary_blogs ) ) {
foreach ( $ary_blogs as $ary_blog ) {
switch_to_blog( $ary_blog['blog_id'] );
$wpdb->query( "DELETE FROM $wpdb->options WHERE option_name LIKE 'wp-piwik-%'" );
restore_current_blog();
}
}
$wpdb->query( "DELETE FROM $wpdb->sitemeta WHERE meta_key LIKE 'wp-piwik_global-%'" );
} else {
$wpdb->query( "DELETE FROM $wpdb->options WHERE option_name LIKE 'wp-piwik_global-%'" );
}
}
/**
* Get blog list
*/
public static function get_blog_list( $limit = null, $page = null, $search = '' ) {
global $wpdb;
$query_limit = '';
if ( $limit && $page ) {
$query_limit = ' LIMIT ' . (int) ( ( $page - 1 ) * $limit ) . ',' . (int) $limit;
}
$like = '%' . $wpdb->esc_like( $search ) . '%';
// phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared, WordPress.DB.PreparedSQL.InterpolatedNotPrepared
return $wpdb->get_results( $wpdb->prepare( "SELECT blog_id FROM {$wpdb->blogs} WHERE CONCAT(domain, path) LIKE %s AND spam = 0 AND deleted = 0 ORDER BY blog_id" . $query_limit, $like ), ARRAY_A );
}
/**
* Check if plugin is network activated
*
* @return boolean Is network activated?
*/
public function check_network_activation() {
if ( ! function_exists( 'is_plugin_active_for_network' ) ) {
require_once ABSPATH . 'wp-admin/includes/plugin.php';
}
return is_plugin_active_for_network( 'wp-piwik/wp-piwik.php' );
}
/**
* Apply new configuration
*
* @param array $in
* new configuration set
*/
public function apply_changes( $in ) {
if ( ! self::$wp_piwik->is_valid_options_post() ) {
die( 'Invalid config changes.' );
}
$in = $this->check_settings( $in );
self::$wp_piwik->log( 'Apply changed settings:' );
foreach ( self::$default_settings ['globalSettings'] as $key => $val ) {
$this->set_global_option( $key, isset( $in [ $key ] ) ? $in [ $key ] : $val );
}
foreach ( self::$default_settings ['settings'] as $key => $val ) {
$this->set_option( $key, isset( $in [ $key ] ) ? $in [ $key ] : $val );
}
$this->set_global_option( 'last_settings_update', (string) time() );
$this->save();
}
/**
* Apply callback function on new settings
*
* @param array $in new configuration set
* @return array configuration set after callback functions were applied
*/
private function check_settings( $in ) {
foreach ( $this->check_settings as $key => $value ) {
if ( isset( $in [ $key ] ) ) {
$in [ $key ] = call_user_func_array(
array(
$this,
$value,
),
array(
$in [ $key ],
$in,
)
);
}
}
return $in;
}
/**
* Add slash to Piwik URL if necessary
*
* @param string $value
* Piwik URL
* @return string Piwik URL
* @phpstan-ignore method.unused
*/
private function check_piwik_url( $value ) {
return substr( $value, - 1, 1 ) !== '/' ? $value . '/' : $value;
}
/**
* Remove &amp;token_auth= from auth token
*
* @param string $value
* Piwik auth token
* @return string Piwik auth token
* @phpstan-ignore method.unused
*/
private function check_piwik_token( $value ) {
return str_replace( '&token_auth=', '', $value );
}
/**
* Request the site ID (if not set before)
*
* @param string|int $value
* site ID setting value
* @param array $in
* configuration set
* @return int Piwik site ID
* @phpstan-ignore method.unused
*/
private function request_piwik_site_id( $value, $in ) {
if ( $in ['auto_site_config'] && ! $value ) {
return self::$wp_piwik->get_piwik_site_id();
}
return intval( $value );
}
/**
* Prepare the tracking code
*
* @param string $value
* tracking code
* @param array $in
* configuration set
* @return string tracking code
* @phpstan-ignore method.unused
*/
private function prepare_tracking_code( $value, $in ) {
if ( 'manually' === $in['track_mode'] || 'disabled' === $in['track_mode'] ) {
$value = stripslashes( $value );
if ( $this->check_network_activation() ) {
update_site_option( 'wp-piwik-manually', $value );
}
return $value;
}
return '';
}
/**
* Prepare the nocscript code
*
* @param string $value
* noscript code
* @param array $in
* configuration set
* @return string noscript code
* @phpstan-ignore method.unused
*/
private function prepare_nocscript_code( $value, $in ) {
if ( 'manually' === $in['track_mode'] ) {
return stripslashes( $value );
}
return $this->get_option( 'noscript_code' );
}
/**
* Get debug data
*
* @return array WP-Piwik settings for debug output
*/
public function get_debug_data() {
$debug = array(
'global_settings' => $this->global_settings,
'settings' => $this->settings,
);
$debug['global_settings']['piwik_token'] = ! empty( $debug['global_settings']['piwik_token'] ) ? 'set' : 'not set';
return $debug;
}
public function is_ai_bot_tracking_enabled() {
return (bool) $this->get_global_option( self::TRACK_AI_BOTS );
}
public function is_ai_bot_tracking_enabled_via_esi_includes() {
return (bool) $this->get_global_option( self::TRACK_AI_BOTS_USING_ESI );
}
public function is_track_via_esi_enabled() {
return true === (bool) $this->get_global_option( 'track_ai_bots_using_esi' );
}
public function get_matomo_url() {
if ( 'http' === $this->get_global_option( 'piwik_mode' ) ) {
return $this->get_global_option( 'piwik_url' );
}
if ( 'cloud' === $this->get_global_option( 'piwik_mode' ) ) {
return 'https://' . $this->get_global_option( 'piwik_user' ) . '.innocraft.cloud/';
}
return 'https://' . $this->get_global_option( 'matomo_user' ) . '.matomo.cloud/';
}
public function is_tracking_enabled() {
return 'disabled' !== $this->get_global_option( 'track_mode' );
}
}

View File

@ -0,0 +1,34 @@
<?php
namespace WP_Piwik;
class Shortcode {
private $available = array(
'opt-out' => 'OptOut',
'post' => 'Post',
'overview' => 'Overview',
);
private $content;
/**
* @param array $attributes
* @param \WP_Piwik $wp_piwik
* @param Settings $settings
*/
public function __construct( $attributes, $wp_piwik, $settings ) {
$wp_piwik->log( 'Check requested shortcode widget ' . $attributes['module'] );
if ( isset( $attributes['module'] ) && isset( $this->available[ $attributes['module'] ] ) ) {
$wp_piwik->log( 'Add shortcode widget ' . $this->available[ $attributes['module'] ] );
$class = '\\WP_Piwik\\Widget\\' . $this->available[ $attributes['module'] ];
$widget = new $class( $wp_piwik, $settings, null, null, null, $attributes, true );
$widget->show();
$this->content = $widget->get();
}
}
public function get() {
return $this->content;
}
}

View File

@ -0,0 +1,45 @@
<?php
namespace WP_Piwik;
class Template {
/**
* @var Logger
*/
public static $logger;
/**
* @var Settings
*/
public static $settings;
/**
* @var \WP_Piwik
*/
public static $wp_piwik;
public function __construct( $wp_piwik, $settings ) {
self::$settings = $settings;
self::$wp_piwik = $wp_piwik;
}
public function output( $values, $key, $default_value = '' ) {
if ( isset( $values[ $key ] ) ) {
return $values[ $key ];
} else {
return $default_value;
}
}
public function tab_row( $name, $value ) {
echo '<tr><td>' . esc_html( $name ) . '</td><td>' . esc_html( $value ) . '</td></tr>';
}
public function get_range_last30() {
$diff = ( self::$settings->get_global_option( 'default_date' ) === 'yesterday' ) ? -86400 : 0;
$end = time() + $diff;
$start = time() - 2592000 + $diff;
return gmdate( 'Y-m-d', $start ) . ',' . gmdate( 'Y-m-d', $end );
}
}

View File

@ -0,0 +1,75 @@
<?php
namespace WP_Piwik\Template;
class MetaBoxCustomVars extends \WP_Piwik\Template {
public function addMetabox() {
add_meta_box(
'wp-piwik_post_customvars',
__( 'Piwik Custom Variables', 'wp-piwik' ),
array( &$this, 'showCustomvars' ),
array( 'post', 'page', 'custom_post_type' ),
'side',
'default'
);
}
public function showCustomvars( $obj_post, $obj_box ) {
wp_nonce_field( basename( __FILE__ ), 'wp-piwik_post_customvars_nonce' ); ?>
<table>
<tr><th></th><th><?php esc_html_e( 'Name', 'wp-piwik' ); ?></th><th><?php esc_html_e( 'Value', 'wp-piwik' ); ?></th></tr>
<?php for ( $i = 1; $i <= 5; $i++ ) { ?>
<tr>
<th><label for="wp-piwik_customvar1"><?php echo esc_attr( $i ); // @phpstan-ignore-line ?>: </label></th>
<td><input class="widefat" type="text" name="wp-piwik_custom_cat<?php echo esc_attr( $i ); // @phpstan-ignore-line ?>" value="<?php echo esc_attr( get_post_meta( $obj_post->ID, 'wp-piwik_custom_cat' . $i, true ) ); ?>" size="200" /></td>
<td><input class="widefat" type="text" name="wp-piwik_custom_val<?php echo esc_attr( $i ); // @phpstan-ignore-line ?>" value="<?php echo esc_attr( get_post_meta( $obj_post->ID, 'wp-piwik_custom_val' . $i, true ) ); ?>" size="200" /></td>
</tr>
<?php } ?>
</table>
<p><?php esc_html_e( 'Set custom variables for a page view', 'wp-piwik' ); ?>. (<a href="http://piwik.org/docs/custom-variables/"><?php esc_html_e( 'More information', 'wp-piwik' ); ?></a>.)</p>
<?php
}
public function saveCustomVars( $int_id, $obj_post ) {
// Verify the nonce before proceeding.
$nonce = isset( $_POST['wp-piwik_post_customvars_nonce'] )
// phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
? wp_unslash( $_POST['wp-piwik_post_customvars_nonce'] )
: '';
if (
empty( $nonce )
|| ! wp_verify_nonce( $nonce, basename( __FILE__ ) )
) {
return $int_id;
}
// Get post type object
$obj_post_type = get_post_type_object( $obj_post->post_type );
// Check if the current user has permission to edit the post.
if ( ! current_user_can( $obj_post_type->cap->edit_post, $int_id ) ) {
return $int_id;
}
$ary_names = array( 'cat', 'val' );
for ( $i = 1; $i <= 5; $i++ ) {
for ( $j = 0; $j <= 1; $j++ ) {
// Create key
$str_meta_key = 'wp-piwik_custom_' . $ary_names[ $j ] . $i;
// Get data
// phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
$str_meta_val = isset( $_POST[ $str_meta_key ] ) ? esc_html( wp_unslash( $_POST[ $str_meta_key ] ) ) : '';
// Get the meta value of the custom field key
$str_cur_val = get_post_meta( $int_id, $str_meta_key, true );
if ( $str_meta_val && '' === $str_cur_val ) {
// Add meta val:
add_post_meta( $int_id, $str_meta_key, $str_meta_val, true );
} elseif ( $str_meta_val && $str_meta_val !== $str_cur_val ) {
// Update meta val:
update_post_meta( $int_id, $str_meta_key, $str_meta_val );
} elseif ( '' === $str_meta_val && $str_cur_val ) {
// Delete meta val:
delete_post_meta( $int_id, $str_meta_key, $str_cur_val );
}
}
}
}
}

View File

@ -0,0 +1,264 @@
<?php
namespace WP_Piwik;
class TrackingCode {
/**
* @var \WP_Piwik
*/
private static $wp_piwik;
private $tracking_code;
public $is_404 = false;
public $is_search = false;
public $is_usertracking = false;
public function __construct( $wp_piwik ) {
self::$wp_piwik = $wp_piwik;
if ( ! self::$wp_piwik->is_current_tracking_code() || ! self::$wp_piwik->get_option( 'tracking_code' ) || strpos( self::$wp_piwik->get_option( 'tracking_code' ), '{"result":"error",' ) !== false ) {
self::$wp_piwik->update_tracking_code();
}
$this->tracking_code = ( self::$wp_piwik->is_network_mode() && self::$wp_piwik->get_global_option( 'track_mode' ) === 'manually' ) ? get_site_option( 'wp-piwik-manually' ) : self::$wp_piwik->get_option( 'tracking_code' );
}
public function get_tracking_code() {
if ( $this->is_usertracking ) {
$this->apply_user_tracking();
}
if ( $this->is_404 ) {
$this->apply_404_changes();
}
if ( $this->is_search ) {
$this->apply_search_changes();
}
if ( is_single() || is_page() ) {
$this->add_custom_values();
}
// ignoring for BC
// phpcs:disable WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound
// phpcs:ignore WordPress.NamingConventions.ValidHookName.UseUnderscores
$this->tracking_code = apply_filters( 'wp-piwik_tracking_code', $this->tracking_code );
return $this->tracking_code;
}
/**
* @param string $code
* @param Settings $settings
* @param Logger $logger
* @return array
*/
public static function prepare_tracking_code( $code, $settings, $logger ) {
global $current_user;
$logger->log( 'Apply tracking code changes:' );
$settings->set_option( 'last_tracking_code_update', (string) time() );
if ( preg_match( '/var u="([^"]*)";/', $code, $hits ) ) {
$fetched_proxy_url = $hits [1];
} else {
$fetched_proxy_url = '';
}
if ( $settings->get_global_option( 'remove_type_attribute' ) ) {
$code = str_replace(
array( ' type="text/javascript"', " type='text/javascript'" ),
'',
$code
);
}
if ( 'js' === $settings->get_global_option( 'track_mode' ) ) {
$code = str_replace(
array(
'piwik.js',
'piwik.php',
'matomo.js',
'matomo.php',
),
'js/index.php',
$code
);
} elseif ( 'proxy' === $settings->get_global_option( 'track_mode' ) ) {
$code = str_replace( 'piwik.js', 'matomo.php', $code );
$code = str_replace( 'matomo.js', 'matomo.php', $code );
$code = str_replace( 'piwik.php', 'matomo.php', $code );
$proxy = str_replace(
array(
'https://',
'http://',
),
'//',
plugins_url( 'wp-piwik' ) . '/proxy'
) . '/';
$code = preg_replace( '/var u="([^"]*)";/', 'var u="' . $proxy . '"', $code );
$code = preg_replace( '/img src="([^"]*)piwik.php/', 'img src="' . $proxy . 'matomo.php', $code );
$code = preg_replace( '/img src="([^"]*)matomo.php/', 'img src="' . $proxy . 'matomo.php', $code );
}
if ( $settings->get_global_option( 'track_cdnurl' ) || $settings->get_global_option( 'track_cdnurlssl' ) ) {
$code = str_replace(
array(
'var d=doc',
'g.src=u+',
),
array(
"var ucdn=(('https:' == document.location.protocol) ? 'https://" . ( $settings->get_global_option( 'track_cdnurlssl' ) ? $settings->get_global_option( 'track_cdnurlssl' ) : $settings->get_global_option( 'track_cdnurl' ) ) . "/' : 'http://" . ( $settings->get_global_option( 'track_cdnurl' ) ? $settings->get_global_option( 'track_cdnurl' ) : $settings->get_global_option( 'track_cdnurlssl' ) ) . "/');\nvar d=doc",
'g.src=ucdn+',
),
$code
);
}
if ( $settings->get_global_option( 'track_datacfasync' ) ) {
$code = str_replace( '<script type', '<script data-cfasync="false" type', $code );
}
if ( $settings->is_ai_bot_tracking_enabled() ) {
// recMode is a temporary parameter introduced in core to conditionally
// enable AI bot tracking. if AI bot tracking is enabled in Connect Matomo,
// we set it to `2` here, to enable "auto" mode when doing JS tracking. in
// this mode, tracking requests with AI bot user agents will be tracked as
// bots instead of visits, while all other requests will be tracked normally
// as visits.
$code = str_replace(
"_paq.push(['trackPageView']);",
"_paq.push(['appendToTrackingUrl', 'recMode=2']);\n_paq.push(['trackPageView']);",
$code
);
// set cookie via javascript cookie for known AI bots so we can skip tracking server side
// for them.
// NOTE: this must be done ONLY for known AI bots to be compliant with privacy regulations.
$user_agent_substrings = wp_json_encode( AjaxTracker::AI_BOT_USER_AGENT_SUBSTRINGS );
$cookie_set_fn = <<<EOF
_paq.push([ function () {
var userAgentSubstrings = $user_agent_substrings;
for (var i = 0; i < userAgentSubstrings.length; ++i) {
var isAiBotUserAgent = navigator.userAgent.toLowerCase().indexOf(userAgentSubstrings[i].toLowerCase()) !== -1;
if (isAiBotUserAgent) {
var path = this.getCookiePath();
var domain = this.getCookieDomain();
var sameSite = 'Lax';
document.cookie = 'matomo_has_js=1;path=' +
(path || '/') +
(domain ? ';domain=' + domain : '') +
';SameSite=' + sameSite
;
return;
}
}
} ]);
EOF;
$code = str_replace(
"_paq.push(['trackPageView']);",
$cookie_set_fn . "\n_paq.push(['trackPageView']);",
$code
);
}
if ( $settings->get_global_option( 'set_download_extensions' ) ) {
$code = str_replace( "_paq.push(['trackPageView']);", "_paq.push(['setDownloadExtensions', " . wp_json_encode( $settings->get_global_option( 'set_download_extensions' ) ) . "]);\n_paq.push(['trackPageView']);", $code );
}
if ( $settings->get_global_option( 'add_download_extensions' ) ) {
$code = str_replace( "_paq.push(['trackPageView']);", "_paq.push(['addDownloadExtensions', " . wp_json_encode( $settings->get_global_option( 'add_download_extensions' ) ) . "]);\n_paq.push(['trackPageView']);", $code );
}
if ( $settings->get_global_option( 'set_download_classes' ) ) {
$code = str_replace( "_paq.push(['trackPageView']);", "_paq.push(['setDownloadClasses', " . wp_json_encode( $settings->get_global_option( 'set_download_classes' ) ) . "]);\n_paq.push(['trackPageView']);", $code );
}
if ( $settings->get_global_option( 'set_link_classes' ) ) {
$code = str_replace( "_paq.push(['trackPageView']);", "_paq.push(['setLinkClasses', " . wp_json_encode( $settings->get_global_option( 'set_link_classes' ) ) . "]);\n_paq.push(['trackPageView']);", $code );
}
if ( $settings->get_global_option( 'limit_cookies' ) ) {
$code = str_replace( "_paq.push(['trackPageView']);", "_paq.push(['setVisitorCookieTimeout', " . wp_json_encode( $settings->get_global_option( 'limit_cookies_visitor' ) ) . "]);\n_paq.push(['setSessionCookieTimeout', " . wp_json_encode( $settings->get_global_option( 'limit_cookies_session' ) ) . "]);\n_paq.push(['setReferralCookieTimeout', " . wp_json_encode( $settings->get_global_option( 'limit_cookies_referral' ) ) . "]);\n_paq.push(['trackPageView']);", $code );
}
if ( 'disabled' !== $settings->get_global_option( 'force_protocol' ) ) {
$code = str_replace( '"//', '"' . $settings->get_global_option( 'force_protocol' ) . '://', $code );
}
if ( 'all' === $settings->get_global_option( 'track_content' ) ) {
$code = str_replace( "_paq.push(['trackPageView']);", "_paq.push(['trackPageView']);\n_paq.push(['trackAllContentImpressions']);", $code );
} elseif ( 'visible' === $settings->get_global_option( 'track_content' ) ) {
$code = str_replace( "_paq.push(['trackPageView']);", "_paq.push(['trackPageView']);\n_paq.push(['trackVisibleContentImpressions']);", $code );
}
if ( (int) $settings->get_global_option( 'track_heartbeat' ) > 0 ) {
$code = str_replace( "_paq.push(['trackPageView']);", "_paq.push(['trackPageView']);\n_paq.push(['enableHeartBeatTimer', " . (int) $settings->get_global_option( 'track_heartbeat' ) . ']);', $code );
}
if ( 'consent' === $settings->get_global_option( 'require_consent' ) ) {
$code = str_replace( "_paq.push(['trackPageView']);", "_paq.push(['requireConsent']);\n_paq.push(['trackPageView']);", $code );
} elseif ( 'cookieconsent' === $settings->get_global_option( 'require_consent' ) ) {
$code = str_replace( "_paq.push(['trackPageView']);", "_paq.push(['requireCookieConsent']);\n_paq.push(['trackPageView']);", $code );
}
$no_script = array();
preg_match( '/<noscript>(.*)<\/noscript>/', $code, $no_script );
if ( isset( $no_script [0] ) ) {
if ( $settings->get_global_option( 'track_nojavascript' ) ) {
$no_script [0] = str_replace( '?idsite', '?rec=1&idsite', $no_script [0] );
}
$no_script = $no_script [0];
} else {
$no_script = '';
}
$script = preg_replace( '/<noscript>(.*)<\/noscript>/', '', $code );
$script = preg_replace( '/\s+(\r\n|\r|\n)/', '$1', $script );
$logger->log( 'Finished tracking code: ' . $script );
$logger->log( 'Finished noscript code: ' . $no_script );
return array(
'script' => $script,
'noscript' => $no_script,
'proxy' => $fetched_proxy_url,
);
}
private function apply_404_changes() {
self::$wp_piwik->log( 'Apply 404 changes. Blog ID: ' . get_current_blog_id() . ' Site ID: ' . self::$wp_piwik->get_option( 'site_id' ) );
$this->tracking_code = str_replace( "_paq.push(['trackPageView']);", "_paq.push(['setDocumentTitle', '404/URL = '+String(document.location.pathname+document.location.search).replace(/\//g,'%2f') + '/From = ' + String(document.referrer).replace(/\//g,'%2f')]);\n_paq.push(['trackPageView']);", $this->tracking_code );
}
private function apply_search_changes() {
global $wp_query;
self::$wp_piwik->log( 'Apply search tracking changes. Blog ID: ' . get_current_blog_id() . ' Site ID: ' . self::$wp_piwik->get_option( 'site_id' ) );
$int_result_count = $wp_query->found_posts;
$this->tracking_code = str_replace( "_paq.push(['trackPageView']);", "_paq.push(['trackSiteSearch','" . get_search_query() . "', false, " . $int_result_count . "]);\n_paq.push(['trackPageView']);", $this->tracking_code );
}
private function apply_user_tracking() {
$pk_user_id = null;
if ( \is_user_logged_in() ) {
// Get the User ID Admin option, and the current user's data
$uid_from = self::$wp_piwik->get_global_option( 'track_user_id' );
$current_user = wp_get_current_user(); // current user
// Get the user ID based on the admin setting
if ( 'uid' === $uid_from ) {
$pk_user_id = $current_user->ID;
} elseif ( 'email' === $uid_from ) {
$pk_user_id = $current_user->user_email;
} elseif ( 'username' === $uid_from ) {
$pk_user_id = $current_user->user_login;
} elseif ( 'displayname' === $uid_from ) {
$pk_user_id = $current_user->display_name;
}
}
// ignoring for BC
// phpcs:disable WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound
// phpcs:ignore WordPress.NamingConventions.ValidHookName.UseUnderscores
$pk_user_id = apply_filters( 'wp-piwik_tracking_user_id', $pk_user_id );
// Check we got a User ID to track, and track it
if ( isset( $pk_user_id ) && ! empty( $pk_user_id ) ) {
$this->tracking_code = str_replace( "_paq.push(['trackPageView']);", "_paq.push(['setUserId', '" . esc_js( $pk_user_id ) . "']);\n_paq.push(['trackPageView']);", $this->tracking_code );
}
}
private function add_custom_values() {
$custom_vars = '';
for ( $i = 1; $i <= 5; $i++ ) {
$post_id = get_the_ID();
$meta_key = get_post_meta( $post_id, 'wp-piwik_custom_cat' . $i, true );
$meta_val = get_post_meta( $post_id, 'wp-piwik_custom_val' . $i, true );
if ( ! empty( $meta_key ) && ! empty( $meta_val ) ) {
$custom_vars .= "_paq.push(['setCustomVariable'," . $i . ', ' . wp_json_encode( $meta_key ) . ', ' . wp_json_encode( $meta_val ) . ", 'page']);\n";
}
}
if ( ! empty( $custom_vars ) ) {
$this->tracking_code = str_replace( "_paq.push(['trackPageView']);", $custom_vars . "_paq.push(['trackPageView']);", $this->tracking_code );
}
}
}

View File

@ -0,0 +1,476 @@
<?php
namespace WP_Piwik;
use WP_Piwik;
/**
* Abstract widget class
*
* @author Andr&eacute; Br&auml;kling
* @package WP_Piwik
*/
abstract class Widget {
/**
*
* @var WP_Piwik
*/
protected static $wp_piwik;
/**
* @var Settings
*/
protected static $settings;
protected $is_shortcode = false;
protected $method = '';
protected $title = '';
protected $context = 'side';
protected $priority = 'core';
protected $parameter = array();
protected $api_id = array();
protected $page_id = 'dashboard';
protected $blog_id = null;
protected $name = 'Value';
protected $limit = 10;
protected $content = '';
protected $output = '';
/**
* Widget constructor
*
* @param WP_Piwik $wp_piwik
* current WP-Piwik object
* @param Settings $settings
* current WP-Piwik settings
* @param string $page_id
* WordPress page ID (default: dashboard)
* @param string $context
* WordPress meta box context (defualt: side)
* @param string $priority
* WordPress meta box priority (default: default)
* @param array $params
* widget parameters (default: empty array)
* @param boolean $is_shortcode
* is the widget shown inline? (default: false)
*/
public function __construct( $wp_piwik, $settings, $page_id = 'dashboard', $context = 'side', $priority = 'default', $params = array(), $is_shortcode = false ) {
self::$wp_piwik = $wp_piwik;
self::$settings = $settings;
$this->page_id = $page_id;
$this->context = $context;
$this->priority = $priority;
if ( self::$settings->check_network_activation() && function_exists( 'is_super_admin' ) && is_super_admin() && isset( $_GET ['wpmu_show_stats'] ) ) {
switch_to_blog( (int) $_GET ['wpmu_show_stats'] );
$this->blog_id = get_current_blog_id();
restore_current_blog();
}
$this->is_shortcode = $is_shortcode;
$prefix = ( 'dashboard' === $this->page_id ? self::$settings->get_global_option( 'plugin_display_name' ) . ' - ' : '' );
$this->configure( $prefix, $params );
if ( is_array( $this->method ) ) {
foreach ( $this->method as $method ) {
$this->api_id [ $method ] = Request::register( $method, $this->parameter );
self::$wp_piwik->log( 'Register request: ' . $this->api_id [ $method ] );
}
} else {
$this->api_id [ $this->method ] = Request::register( $this->method, $this->parameter );
self::$wp_piwik->log( 'Register request: ' . $this->api_id [ $this->method ] );
}
if ( $this->is_shortcode ) {
return;
}
add_meta_box(
$this->get_name(),
$this->title,
array(
$this,
'show',
),
$page_id,
$this->context,
$this->priority
);
}
/**
* Conifguration dummy method
*
* @param string $prefix
* metabox title prefix (default: empty)
* @param array $params
* widget parameters (default: empty array)
*/
protected function configure( $prefix = '', $params = array() ) {
}
/**
* Default show widget method, handles default Piwik output
*/
public function show() {
$response = self::$wp_piwik->request( $this->api_id [ $this->method ] );
if ( ! empty( $response ['result'] ) && 'error' === $response['result'] ) {
$this->out( '<strong>' . esc_html__( 'Piwik error', 'wp-piwik' ) . ':</strong> ' . esc_html( $response['message'] ) );
} else {
if ( isset( $response [0] ['nb_uniq_visitors'] ) ) {
$unique = 'nb_uniq_visitors';
} else {
$unique = 'sum_daily_nb_uniq_visitors';
}
$table_head = array(
'label' => $this->name,
);
$table_head [ $unique ] = __( 'Unique', 'wp-piwik' );
if ( isset( $response [0] ['nb_visits'] ) ) {
$table_head ['nb_visits'] = __( 'Visits', 'wp-piwik' );
}
if ( isset( $response [0] ['nb_hits'] ) ) {
$table_head ['nb_hits'] = __( 'Hits', 'wp-piwik' );
}
if ( isset( $response [0] ['nb_actions'] ) ) {
$table_head ['nb_actions'] = __( 'Actions', 'wp-piwik' );
}
$table_body = array();
$count = 0;
if ( is_array( $response ) ) {
foreach ( $response as $row_key => $row ) {
++$count;
$table_body[ $row_key ] = array();
foreach ( $table_head as $key => $value ) {
$table_body[ $row_key ] [] = isset( $row[ $key ] ) ? $row[ $key ] : '-';
}
if ( 10 === $count ) {
break;
}
}
}
$this->table( $table_head, $table_body, null );
}
}
/**
* Display or store shortcode output
*/
protected function out( $output ) {
if ( $this->is_shortcode ) {
$this->output .= $output;
} else {
// phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
echo $output;
}
}
/**
* Return shortcode output
*/
public function get() {
return $this->output;
}
/**
* Display a HTML table
*
* @param array|null $thead
* table header content (array of cells)
* @param array $tbody
* table body content (array of rows)
* @param array|null $tfoot
* table footer content (array of cells)
* @param string|false $css_class
* CSS class name to apply on table sections
* @param array $java_script
* array of javascript code to apply on body rows
* @param array $css_classes
* array mapping keys in $tbody to css classes to apply on table rows.
*/
protected function table( $thead, $tbody = array(), $tfoot = array(), $css_class = false, $java_script = array(), $css_classes = array() ) {
$this->out( '<div class="table"><table class="widefat wp-piwik-table">' );
if ( $this->is_shortcode && $this->title ) {
$colspan = ! empty( $tbody ) ? count( $tbody[0] ) : 2;
$this->out( '<tr><th colspan="' . $colspan . '">' . esc_html( $this->title ) . '</th></tr>' );
}
if ( ! empty( $thead ) ) {
$this->tab_head( $thead, $css_class );
}
if ( ! empty( $tbody ) ) {
$this->tab_body( $tbody, $css_class, $java_script, $css_classes );
} else {
$this->out( '<tr><td colspan="10">' . esc_html__( 'No data available.', 'wp-piwik' ) . '</td></tr>' );
}
if ( ! empty( $tfoot ) ) {
$this->tab_foot( $tfoot, $css_class );
}
$this->out( '</table></div>' );
}
/**
* Display a HTML table header
*
* @param array $thead
* array of cells.
* @param string|false $css_class
* CSS class to apply
*/
private function tab_head( $thead, $css_class = false ) {
$this->out( '<thead' . ( $css_class ? ' class="' . esc_attr( $css_class ) . '"' : '' ) . '><tr>' );
$count = 0;
foreach ( $thead as $value ) {
$this->out( '<th' . ( $count++ ? ' class="right"' : '' ) . '>' . esc_html( $value ) . '</th>' );
}
$this->out( '</tr></thead>' );
}
/**
* Display a HTML table body
*
* @param array $tbody
* array of rows, each row containing an array of cells
* @param string $css_class
* CSS class to apply
* @param array $java_script
* array of javascript code to apply (one item per row)
*/
private function tab_body( $tbody, $css_class = '', $java_script = array(), $css_classes = array() ) {
$this->out( '<tbody' . ( $css_class ? ' class="' . esc_attr( $css_class ) . '"' : '' ) . '>' );
foreach ( $tbody as $key => $trow ) {
$this->tab_row( $trow, isset( $java_script [ $key ] ) ? $java_script [ $key ] : '', isset( $css_classes [ $key ] ) ? $css_classes [ $key ] : '' );
}
$this->out( '</tbody>' );
}
/**
* Display a HTML table footer
*
* @param array $tfoot
* array of cells
* @param string|false $css_class
* CSS class to apply
*/
private function tab_foot( $tfoot, $css_class = false ) {
$this->out( '<tfoot' . ( $css_class ? ' class="' . esc_attr( $css_class ) . '"' : '' ) . '><tr>' );
$count = 0;
foreach ( $tfoot as $value ) {
// $value is allowed to contain html
$this->out( '<td' . ( $count++ ? ' class="right"' : '' ) . '>' . $value . '</td>' );
}
$this->out( '</tr></tfoot>' );
}
/**
* Display a HTML table row
*
* @param array $trow
* array of cells
* @param string $java_script
* javascript code to apply
*/
private function tab_row( $trow, $java_script = '', $css_class = '' ) {
$this->out( '<tr' . ( ! empty( $java_script ) ? ' onclick="' . esc_attr( esc_js( $java_script ) ) . '"' : '' ) . ( ! empty( $css_class ) ? ' class="' . esc_attr( $css_class ) . '"' : '' ) . '>' );
$count = 0;
foreach ( $trow as $tcell ) {
$this->out( '<td' . ( $count++ ? ' class="right"' : '' ) . '>' . esc_html( $tcell ) . '</td>' );
}
$this->out( '</tr>' );
}
/**
* Get the current request's Piwik time settings
*
* @return array time settings: period => Piwik period, date => requested date, description => time description to show in widget title
*/
protected function get_time_settings() {
switch ( self::$settings->get_global_option( 'default_date' ) ) {
case 'today':
$period = 'day';
$date = 'today';
$description = __( 'today', 'wp-piwik' );
break;
case 'current_month':
$period = 'month';
$date = 'today';
$description = __( 'current month', 'wp-piwik' );
break;
case 'last_month':
$period = 'month';
$date = gmdate( 'Y-m-d', strtotime( 'last day of previous month' ) );
$description = __( 'last month', 'wp-piwik' );
break;
case 'current_week':
$period = 'week';
$date = 'today';
$description = __( 'current week', 'wp-piwik' );
break;
case 'last_week':
$period = 'week';
$date = gmdate( 'Y-m-d', strtotime( '-1 week' ) );
$description = __( 'last week', 'wp-piwik' );
break;
case 'yesterday':
default:
$period = 'day';
$date = 'yesterday';
$description = __( 'yesterday', 'wp-piwik' );
break;
}
if ( isset( $_GET['date'] ) ) {
$date = intval( wp_unslash( $_GET['date'] ) );
// phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
$description = $this->date_format( wp_unslash( $_GET['date'] ), $period );
}
return array(
'period' => $period,
'date' => $date,
'description' => $description,
);
}
/**
* Format a date to show in widget
*
* @param string $date
* date string
* @param string $period
* Piwik period
* @return string formatted date
*/
protected function date_format( $date, $period = 'day' ) {
$prefix = '';
switch ( $period ) {
case 'week':
$prefix = __( 'week', 'wp-piwik' ) . ' ';
$format = 'W/Y';
break;
case 'short_week':
$format = 'W';
break;
case 'month':
$format = 'F Y';
$date = gmdate( 'Y-m-d', strtotime( $date ) );
break;
default:
$format = get_option( 'date_format' );
}
return $prefix . date_i18n( $format, strtotime( $date ) );
}
/**
* Format time to show in widget
*
* @param int $time
* time in seconds
* @return string formatted time
*/
protected function time_format( $time ) {
return floor( $time / 3600 ) . 'h ' . floor( ( $time % 3600 ) / 60 ) . 'm ' . floor( ( $time % 3600 ) % 60 ) . 's';
}
/**
* Convert Piwik range into meaningful text
*
* @return string range description
*/
public function range_name() {
switch ( $this->parameter ['date'] ) {
case 'last90':
return __( 'last 90 days', 'wp-piwik' );
case 'last60':
return __( 'last 60 days', 'wp-piwik' );
case 'last30':
return __( 'last 30 days', 'wp-piwik' );
case 'last12':
switch ( $this->parameter['period'] ) {
case 'day':
return __( 'last 12 days', 'wp-piwik' );
case 'week':
return __( 'last 12 weeks', 'wp-piwik' );
case 'month':
return __( 'last 12 months', 'wp-piwik' );
case 'year':
return __( 'last 12 years', 'wp-piwik' );
default:
return __( 'last 12', 'wp-piwik' ) . $this->parameter['period'];
}
default:
return $this->parameter ['date'];
}
}
/**
* Get the widget name
*
* @return string widget name
*/
public function get_name() {
return str_replace( '\\', '-', get_called_class() );
}
/**
* Display a pie chart
*
* @param array $data chart data array(array(0 => name, 1 => value))
*/
public function pie_chart( $data ) {
$labels = array();
$values = array();
foreach ( $data as $key => $data_set ) {
$labels[] = $data_set[0];
$values[] = $data_set[1];
if ( 'Others' === $key ) {
break;
}
}
?>
<div>
<canvas id="<?php echo esc_attr( 'wp-piwik_stats_' . $this->get_name() . '_graph' ); ?>"></canvas>
</div>
<script>
new Chart(
document.getElementById(<?php echo wp_json_encode( 'wp-piwik_stats_' . $this->get_name() . '_graph' ); ?>),
{
type: 'pie',
data: {
labels: <?php echo wp_json_encode( $labels ); ?>,
datasets: [
{
label: '',
data: <?php echo wp_json_encode( $values ); ?>,
backgroundColor: [
'#4dc9f6',
'#f67019',
'#f53794',
'#537bc4',
'#acc236',
'#166a8f',
'#00a950',
'#58595b',
'#8549ba'
]
}
]
},
options: {
radius:"90%"
}
}
);
</script>
<?php
}
/**
* Return an array value by key, return '-' if not set
*
* @param array $values
* array to get a value from
* @param string $key
* key of the value to get from array
* @return string|float found value or '-' as a placeholder
*/
protected function value( $values, $key ) {
return isset( $values[ $key ] ) ? $values[ $key ] : '-';
}
}

View File

@ -0,0 +1,80 @@
<?php
namespace WP_Piwik\Widget;
use WP_Piwik\Widget;
class BrowserDetails extends Widget {
public $class_name = __CLASS__;
protected function configure( $prefix = '', $params = array() ) {
$time_settings = $this->get_time_settings();
$this->parameter = array(
'idSite' => self::$wp_piwik->get_piwik_site_id( $this->blog_id ),
'period' => $time_settings['period'],
'date' => $time_settings['date'],
);
$this->title = $prefix . __( 'Browser Details', 'wp-piwik' ) . ' (' . $time_settings['description'] . ')';
$this->method = 'DevicesDetection.getBrowserVersions';
$this->context = 'normal';
$version = self::$wp_piwik->get_plugin_version();
wp_enqueue_script( 'wp-piwik', self::$wp_piwik->get_plugin_url() . 'js/wp-piwik.js', array(), $version, true );
wp_enqueue_script( 'wp-piwik-chartjs', self::$wp_piwik->get_plugin_url() . 'js/chartjs/chart.min.js', array(), $version, false );
wp_enqueue_style( 'wp-piwik', self::$wp_piwik->get_plugin_url() . 'css/wp-piwik.css', array(), $version );
}
public function show() {
$response = self::$wp_piwik->request( $this->api_id[ $this->method ] );
$table_body = array();
if ( ! empty( $response['result'] ) && 'error' === $response['result'] ) {
echo '<strong>' . esc_html__( 'Piwik error', 'wp-piwik' ) . ':</strong> ' . esc_html( $response['message'] );
} else {
$table_head = array( __( 'Browser', 'wp-piwik' ), __( 'Unique', 'wp-piwik' ), __( 'Percent', 'wp-piwik' ) );
if ( isset( $response[0]['nb_uniq_visitors'] ) ) {
$unique = 'nb_uniq_visitors';
} else {
$unique = 'sum_daily_nb_uniq_visitors';
}
$count = 0;
$sum = 0;
$js = array();
$css_class = array();
if ( is_array( $response ) ) {
foreach ( $response as $row ) {
++$count;
$sum += isset( $row[ $unique ] ) ? $row[ $unique ] : 0;
if ( $count < $this->limit ) {
$table_body[ $row['label'] ] = array( $row['label'], $row[ $unique ], 0 );
} elseif ( ! isset( $table_body['Others'] ) ) {
$table_body['Others'] = array( $row['label'], $row[ $unique ], 0 );
$css_class['Others'] = 'wp-piwik-hideDetails';
$js['Others'] = '$j' . "( '.wp-piwik-hideDetails' ).toggle( 'hidden' );";
$table_body[ $row['label'] ] = array( $row['label'], $row[ $unique ], 0 );
$css_class[ $row['label'] ] = 'wp-piwik-hideDetails hidden';
$js[ $row['label'] ] = '$j' . "( '.wp-piwik-hideDetails' ).toggle( 'hidden' );";
} else {
$table_body['Others'][1] += $row[ $unique ];
$table_body[ $row['label'] ] = array( $row['label'], $row[ $unique ], 0 );
$css_class[ $row['label'] ] = 'wp-piwik-hideDetails hidden';
$js[ $row['label'] ] = '$j' . "( '.wp-piwik-hideDetails' ).toggle( 'hidden' );";
}
}
}
if ( $count > $this->limit ) {
$table_body['Others'][0] = __( 'Others', 'wp-piwik' );
}
foreach ( $table_body as $key => $row ) {
$table_body[ $key ][2] = number_format( $row[1] / $sum * 100, 2 ) . '%';
}
if ( ! empty( $table_body ) ) {
$this->pie_chart( $table_body );
}
$this->table( $table_head, $table_body, null, false, $js, $css_class );
}
}
}

View File

@ -0,0 +1,83 @@
<?php
namespace WP_Piwik\Widget;
use WP_Piwik\Widget;
class Browsers extends Widget {
public $class_name = __CLASS__;
protected function configure( $prefix = '', $params = array() ) {
$time_settings = $this->get_time_settings();
$this->parameter = array(
'idSite' => self::$wp_piwik->get_piwik_site_id( $this->blog_id ),
'period' => $time_settings['period'],
'date' => $time_settings['date'],
);
$this->title = $prefix . __( 'Browsers', 'wp-piwik' ) . ' (' . $time_settings['description'] . ')';
$this->method = 'DevicesDetection.getBrowsers';
$this->context = 'normal';
$version = self::$wp_piwik->get_plugin_version();
wp_enqueue_script( 'wp-piwik', self::$wp_piwik->get_plugin_url() . 'js/wp-piwik.js', array(), $version, true );
wp_enqueue_script( 'wp-piwik-chartjs', self::$wp_piwik->get_plugin_url() . 'js/chartjs/chart.min.js', array(), $version, false );
wp_enqueue_style( 'wp-piwik', self::$wp_piwik->get_plugin_url() . 'css/wp-piwik.css', array(), $version );
}
public function show() {
$response = self::$wp_piwik->request( $this->api_id[ $this->method ] );
$table_body = array();
if ( ! empty( $response['result'] ) && 'error' === $response['result'] ) {
echo '<strong>' . esc_html__( 'Piwik error', 'wp-piwik' ) . ':</strong> ' . esc_html( $response['message'] );
} else {
$table_head = array( __( 'Browser', 'wp-piwik' ), __( 'Unique', 'wp-piwik' ), __( 'Percent', 'wp-piwik' ) );
if ( isset( $response[0]['nb_uniq_visitors'] ) ) {
$unique = 'nb_uniq_visitors';
} else {
$unique = 'sum_daily_nb_uniq_visitors';
}
$count = 0;
$sum = 0;
$js = array();
$css_class = array();
if ( is_array( $response ) ) {
foreach ( $response as $row ) {
++$count;
$sum += isset( $row[ $unique ] ) ? $row[ $unique ] : 0;
if ( $count < $this->limit ) {
$table_body[ $row['label'] ] = array( $row['label'], $row[ $unique ], 0 );
} elseif ( ! isset( $table_body['Others'] ) ) {
$table_body['Others'] = array( $row['label'], $row[ $unique ], 0 );
$css_class['Others'] = 'wp-piwik-hideDetails';
$js['Others'] = '$j' . "( '.wp-piwik-hideDetails' ).toggle( 'hidden' );";
$table_body[ $row['label'] ] = array( $row['label'], $row[ $unique ], 0 );
$css_class[ $row['label'] ] = 'wp-piwik-hideDetails hidden';
$js[ $row['label'] ] = '$j' . "( '.wp-piwik-hideDetails' ).toggle( 'hidden' );";
} else {
$table_body['Others'][1] += $row[ $unique ];
$table_body[ $row['label'] ] = array( $row['label'], $row[ $unique ], 0 );
$css_class[ $row['label'] ] = 'wp-piwik-hideDetails hidden';
$js[ $row['label'] ] = '$j' . "( '.wp-piwik-hideDetails' ).toggle( 'hidden' );";
}
}
}
if ( $count > $this->limit ) {
$table_body['Others'][0] = __( 'Others', 'wp-piwik' );
} elseif ( $count === $this->limit ) {
$css_class['Others'] = '';
$js['Others'] = '';
}
foreach ( $table_body as $key => $row ) {
$table_body[ $key ][2] = number_format( $row[1] / $sum * 100, 2 ) . '%';
}
if ( ! empty( $table_body ) ) {
$this->pie_chart( $table_body );
}
$this->table( $table_head, $table_body, null, false, $js, $css_class );
}
}
}

View File

@ -0,0 +1,100 @@
<?php
namespace WP_Piwik\Widget;
use WP_Piwik\Widget;
class Chart extends Visitors {
public $class_name = __CLASS__;
public function show() {
$result = $this->request_data();
$response = $result['response'];
if ( ! $result['success'] ) {
$message = '';
if ( is_array( $this->method ) ) {
foreach ( $this->method as $m ) {
if ( empty( $response[ $m ]['message'] ) ) {
continue;
}
$message .= ' ' . $m . ' - ' . $response[ $m ]['message'];
}
} else {
$message = $response[ $this->method ]['message'];
}
echo '<strong>' . esc_html__( 'Piwik error', 'wp-piwik' ) . ':</strong> ' . esc_html( $message );
} else {
$values = array();
$labels = array();
$bounced = array();
$unique = array();
$count = 0;
$unique_sum = 0;
if ( is_array( $response['VisitsSummary.getVisits'] ) ) {
foreach ( $response['VisitsSummary.getVisits'] as $date => $value ) {
++$count;
$values [] = $value;
$unique [] = $response['VisitsSummary.getUniqueVisitors'][ $date ];
$bounced [] = $response['VisitsSummary.getBounceCount'][ $date ];
if ( 'week' === $this->parameter['period'] ) {
preg_match( '/[0-9]{4}-(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1])/', $date, $date_list );
$text_key = $this->date_format( $date_list[0], 'short_week' );
} else {
$text_key = substr( $date, -2 );
}
$labels [] = array( $text_key );
$unique_sum += $response['VisitsSummary.getActions'][ $date ];
}
} else {
$values = array( 0 );
$labels = array( array( 0, '-' ) );
$unique = array( 0 );
$bounced = array( 0 );
}
$average = round( $unique_sum / 30, 0 );
?>
<div>
<canvas id="wp-piwik_stats_vistors_graph" style="height:220px;"></canvas>
</div>
<script>
new Chart(
document.getElementById('wp-piwik_stats_vistors_graph'),
{
type: 'line',
data: {
labels: <?php echo wp_json_encode( $labels ); ?>,
datasets: [
{
label: 'Visitors',
backgroundColor: '#0277bd',
borderColor: '#0277bd',
data: <?php echo wp_json_encode( $values ); ?>,
borderWidth: 1
},
{
label: 'Unique',
backgroundColor: '#ff8f00',
borderColor: '#ff8f00',
data: <?php echo wp_json_encode( $unique ); ?>,
borderWidth: 1
},
{
label: 'Bounced',
backgroundColor: '#ad1457',
borderColor: '#ad1457',
data: <?php echo wp_json_encode( $bounced ); ?>,
borderWidth: 1
},
]
},
options: {}
}
);
</script>
<?php
}
}
}

View File

@ -0,0 +1,83 @@
<?php
namespace WP_Piwik\Widget;
use WP_Piwik\Widget;
class City extends Widget {
public $class_name = __CLASS__;
protected function configure( $prefix = '', $params = array() ) {
$time_settings = $this->get_time_settings();
$this->parameter = array(
'idSite' => self::$wp_piwik->get_piwik_site_id( $this->blog_id ),
'period' => $time_settings['period'],
'date' => $time_settings['date'],
);
$this->title = $prefix . __( 'Cities', 'wp-piwik' ) . ' (' . $time_settings['description'] . ')';
$this->method = 'UserCountry.getCity';
$this->context = 'normal';
$version = self::$wp_piwik->get_plugin_version();
wp_enqueue_script( 'wp-piwik', self::$wp_piwik->get_plugin_url() . 'js/wp-piwik.js', array(), $version, true );
wp_enqueue_script( 'wp-piwik-chartjs', self::$wp_piwik->get_plugin_url() . 'js/chartjs/chart.min.js', array(), $version, false );
wp_enqueue_style( 'wp-piwik', self::$wp_piwik->get_plugin_url() . 'css/wp-piwik.css', array(), $version );
}
public function show() {
$response = self::$wp_piwik->request( $this->api_id[ $this->method ] );
$table_body = array();
if ( ! empty( $response['result'] ) && 'error' === $response['result'] ) {
echo '<strong>' . esc_html__( 'Piwik error', 'wp-piwik' ) . ':</strong> ' . esc_html( $response['message'] );
} else {
$table_head = array( __( 'City', 'wp-piwik' ), __( 'Unique', 'wp-piwik' ), __( 'Percent', 'wp-piwik' ) );
if ( isset( $response[0]['nb_uniq_visitors'] ) ) {
$unique = 'nb_uniq_visitors';
} else {
$unique = 'sum_daily_nb_uniq_visitors';
}
$count = 0;
$sum = 0;
$js = array();
$css_class = array();
if ( is_array( $response ) ) {
foreach ( $response as $row ) {
++$count;
$sum += isset( $row[ $unique ] ) ? $row[ $unique ] : 0;
if ( $count < $this->limit ) {
$table_body[ $row['label'] ] = array( $row['label'], $row[ $unique ], 0 );
} elseif ( ! isset( $table_body['Others'] ) ) {
$table_body['Others'] = array( $row['label'], $row[ $unique ], 0 );
$css_class['Others'] = 'wp-piwik-hideDetails';
$js['Others'] = '$j' . "( '.wp-piwik-hideDetails' ).toggle( 'hidden' );";
$table_body[ $row['label'] ] = array( $row['label'], $row[ $unique ], 0 );
$css_class[ $row['label'] ] = 'wp-piwik-hideDetails hidden';
$js[ $row['label'] ] = '$j' . "( '.wp-piwik-hideDetails' ).toggle( 'hidden' );";
} else {
$table_body['Others'][1] += $row[ $unique ];
$table_body[ $row['label'] ] = array( $row['label'], $row[ $unique ], 0 );
$css_class[ $row['label'] ] = 'wp-piwik-hideDetails hidden';
$js[ $row['label'] ] = '$j' . "( '.wp-piwik-hideDetails' ).toggle( 'hidden' );";
}
}
}
if ( $count > $this->limit ) {
$table_body['Others'][0] = __( 'Others', 'wp-piwik' );
} elseif ( $count === $this->limit ) {
$css_class['Others'] = '';
$js['Others'] = '';
}
foreach ( $table_body as $key => $row ) {
$table_body[ $key ][2] = number_format( $row[1] / $sum * 100, 2 ) . '%';
}
if ( ! empty( $table_body ) ) {
$this->pie_chart( $table_body );
}
$this->table( $table_head, $table_body, null, false, $js, $css_class );
}
}
}

View File

@ -0,0 +1,83 @@
<?php
namespace WP_Piwik\Widget;
use WP_Piwik\Widget;
class Country extends Widget {
public $class_name = __CLASS__;
protected function configure( $prefix = '', $params = array() ) {
$time_settings = $this->get_time_settings();
$this->parameter = array(
'idSite' => self::$wp_piwik->get_piwik_site_id( $this->blog_id ),
'period' => $time_settings['period'],
'date' => $time_settings['date'],
);
$this->title = $prefix . __( 'Countries', 'wp-piwik' ) . ' (' . $time_settings['description'] . ')';
$this->method = 'UserCountry.getCountry ';
$this->context = 'normal';
$version = self::$wp_piwik->get_plugin_version();
wp_enqueue_script( 'wp-piwik', self::$wp_piwik->get_plugin_url() . 'js/wp-piwik.js', array(), $version, true );
wp_enqueue_script( 'wp-piwik-chartjs', self::$wp_piwik->get_plugin_url() . 'js/chartjs/chart.min.js', array(), $version, false );
wp_enqueue_style( 'wp-piwik', self::$wp_piwik->get_plugin_url() . 'css/wp-piwik.css', array(), $version );
}
public function show() {
$response = self::$wp_piwik->request( $this->api_id[ $this->method ] );
$table_body = array();
if ( ! empty( $response['result'] ) && 'error' === $response['result'] ) {
echo '<strong>' . esc_html__( 'Piwik error', 'wp-piwik' ) . ':</strong> ' . esc_html( $response['message'] );
} else {
$table_head = array( __( 'Country', 'wp-piwik' ), __( 'Unique', 'wp-piwik' ), __( 'Percent', 'wp-piwik' ) );
if ( isset( $response[0]['nb_uniq_visitors'] ) ) {
$unique = 'nb_uniq_visitors';
} else {
$unique = 'sum_daily_nb_uniq_visitors';
}
$count = 0;
$sum = 0;
$js = array();
$css_class = array();
if ( is_array( $response ) ) {
foreach ( $response as $row ) {
++$count;
$sum += isset( $row[ $unique ] ) ? $row[ $unique ] : 0;
if ( $count < $this->limit ) {
$table_body[ $row['label'] ] = array( $row['label'], $row[ $unique ], 0 );
} elseif ( ! isset( $table_body['Others'] ) ) {
$table_body['Others'] = array( $row['label'], $row[ $unique ], 0 );
$css_class['Others'] = 'wp-piwik-hideDetails';
$js['Others'] = '$j' . "( '.wp-piwik-hideDetails' ).toggle( 'hidden' );";
$table_body[ $row['label'] ] = array( $row['label'], $row[ $unique ], 0 );
$css_class[ $row['label'] ] = 'wp-piwik-hideDetails hidden';
$js[ $row['label'] ] = '$j' . "( '.wp-piwik-hideDetails' ).toggle( 'hidden' );";
} else {
$table_body['Others'][1] += $row[ $unique ];
$table_body[ $row['label'] ] = array( $row['label'], $row[ $unique ], 0 );
$css_class[ $row['label'] ] = 'wp-piwik-hideDetails hidden';
$js[ $row['label'] ] = '$j' . "( '.wp-piwik-hideDetails' ).toggle( 'hidden' );";
}
}
}
if ( $count > $this->limit ) {
$table_body['Others'][0] = __( 'Others', 'wp-piwik' );
} elseif ( $count === $this->limit ) {
$css_class['Others'] = '';
$js['Others'] = '';
}
foreach ( $table_body as $key => $row ) {
$table_body[ $key ][2] = number_format( $row[1] / $sum * 100, 2 ) . '%';
}
if ( ! empty( $table_body ) ) {
$this->pie_chart( $table_body );
}
$this->table( $table_head, $table_body, null, false, $js, $css_class );
}
}
}

View File

@ -0,0 +1,53 @@
<?php
namespace WP_Piwik\Widget;
class Ecommerce extends \WP_Piwik\Widget {
public $class_name = __CLASS__;
protected function configure( $prefix = '', $params = array() ) {
$time_settings = $this->get_time_settings();
$this->title = $prefix . __( 'E-Commerce', 'wp-piwik' );
$this->method = 'Goals.get';
$this->parameter = array(
'idSite' => self::$wp_piwik->get_piwik_site_id( $this->blog_id ),
'period' => $time_settings['period'],
'date' => $time_settings['date'],
);
}
public function show() {
$response = self::$wp_piwik->request( $this->api_id[ $this->method ] );
if ( ! empty( $response['result'] ) && 'error' === $response['result'] ) {
echo '<strong>' . esc_html__( 'Piwik error', 'wp-piwik' ) . ':</strong> ' . esc_html( $response['message'] );
} else {
$table_head = null;
$revenue = is_numeric( $this->value( $response, 'revenue' ) ) ? number_format( (float) $this->value( $response, 'revenue' ), 2 ) : '';
$revenue_new = is_numeric( $this->value( $response, 'revenue_new_visit' ) ) ? number_format( (float) $this->value( $response, 'revenue_new_visit' ), 2 ) : '';
$revenue_return = is_numeric( $this->value( $response, 'revenue_returning_visit' ) ) ? number_format( (float) $this->value( $response, 'revenue_returning_visit' ), 2 ) : '';
$table_body = array(
array( __( 'Conversions', 'wp-piwik' ) . ':', $this->value( $response, 'nb_conversions' ) ),
array( __( 'Visits converted', 'wp-piwik' ) . ':', $this->value( $response, 'nb_visits_converted' ) ),
array( __( 'Revenue', 'wp-piwik' ) . ':', $revenue ),
array( __( 'Conversion rate', 'wp-piwik' ) . ':', $this->value( $response, 'conversion_rate' ) ),
array( __( 'Conversions (new visitor)', 'wp-piwik' ) . ':', $this->value( $response, 'nb_conversions_new_visit' ) ),
array( __( 'Visits converted (new visitor)', 'wp-piwik' ) . ':', $this->value( $response, 'nb_visits_converted_new_visit' ) ),
array( __( 'Revenue (new visitor)', 'wp-piwik' ) . ':', $revenue_new ),
array( __( 'Conversion rate (new visitor)', 'wp-piwik' ) . ':', $this->value( $response, 'conversion_rate_new_visit' ) ),
array( __( 'Conversions (returning visitor)', 'wp-piwik' ) . ':', $this->value( $response, 'nb_conversions_returning_visit' ) ),
array( __( 'Visits converted (returning visitor)', 'wp-piwik' ) . ':', $this->value( $response, 'nb_visits_converted_returning_visit' ) ),
array( __( 'Revenue (returning visitor)', 'wp-piwik' ) . ':', $revenue_return ),
array( __( 'Conversion rate (returning visitor)', 'wp-piwik' ) . ':', $this->value( $response, 'conversion_rate_returning_visit' ) ),
);
$table_foot = self::$settings->get_global_option( 'piwik_shortcut' )
? array(
esc_html__( 'Shortcut', 'wp-piwik' ) . ':',
'<a href="' . esc_attr( self::$settings->get_global_option( 'piwik_url' ) ) . '">Piwik</a>',
)
: null;
$this->table( $table_head, $table_body, $table_foot );
}
}
}

View File

@ -0,0 +1,55 @@
<?php
namespace WP_Piwik\Widget;
class Items extends \WP_Piwik\Widget {
public $class_name = __CLASS__;
protected function configure( $prefix = '', $params = array() ) {
$time_settings = $this->get_time_settings();
$this->title = $prefix . __( 'E-Commerce Items', 'wp-piwik' );
$this->method = 'Goals.getItemsName';
$this->parameter = array(
'idSite' => self::$wp_piwik->get_piwik_site_id( $this->blog_id ),
'period' => $time_settings['period'],
'date' => $time_settings['date'],
);
}
public function show() {
$response = self::$wp_piwik->request( $this->api_id[ $this->method ] );
if ( ! empty( $response['result'] ) && 'error' === $response['result'] ) {
echo '<strong>' . esc_html__( 'Piwik error', 'wp-piwik' ) . ':</strong> ' . esc_html( $response['message'] );
} else {
$table_head = array(
__( 'Label', 'wp-piwik' ),
__( 'Revenue', 'wp-piwik' ),
__( 'Quantity', 'wp-piwik' ),
__( 'Orders', 'wp-piwik' ),
__( 'Avg. price', 'wp-piwik' ),
__( 'Avg. quantity', 'wp-piwik' ),
__( 'Conversion rate', 'wp-piwik' ),
);
$table_body = array();
if ( is_array( $response ) ) {
foreach ( $response as $data ) {
array_push(
$table_body,
array(
$data['label'],
number_format( $data['revenue'], 2 ),
$data['quantity'],
$data['orders'],
number_format( $data['avg_price'], 2 ),
$data['avg_quantity'],
$data['conversion_rate'],
)
);
}
}
$table_foot = array();
$this->table( $table_head, $table_body, $table_foot );
}
}
}

View File

@ -0,0 +1,55 @@
<?php
namespace WP_Piwik\Widget;
class ItemsCategory extends \WP_Piwik\Widget {
public $class_name = __CLASS__;
protected function configure( $prefix = '', $params = array() ) {
$time_settings = $this->get_time_settings();
$this->title = $prefix . __( 'E-Commerce Item Categories', 'wp-piwik' );
$this->method = 'Goals.getItemsCategory';
$this->parameter = array(
'idSite' => self::$wp_piwik->get_piwik_site_id( $this->blog_id ),
'period' => $time_settings['period'],
'date' => $time_settings['date'],
);
}
public function show() {
$response = self::$wp_piwik->request( $this->api_id[ $this->method ] );
if ( ! empty( $response['result'] ) && 'error' === $response['result'] ) {
echo '<strong>' . esc_html__( 'Piwik error', 'wp-piwik' ) . ':</strong> ' . esc_html( $response['message'] );
} else {
$table_head = array(
__( 'Label', 'wp-piwik' ),
__( 'Revenue', 'wp-piwik' ),
__( 'Quantity', 'wp-piwik' ),
__( 'Orders', 'wp-piwik' ),
__( 'Avg. price', 'wp-piwik' ),
__( 'Avg. quantity', 'wp-piwik' ),
__( 'Conversion rate', 'wp-piwik' ),
);
$table_body = array();
if ( is_array( $response ) ) {
foreach ( $response as $data ) {
array_push(
$table_body,
array(
$data['label'],
isset( $data['revenue'] ) ? number_format( $data['revenue'], 2 ) : '-.--',
isset( $data['quantity'] ) ? $data['quantity'] : '-',
isset( $data['orders'] ) ? $data['orders'] : '-',
number_format( $data['avg_price'], 2 ),
$data['avg_quantity'],
$data['conversion_rate'],
)
);
}
}
$table_foot = array();
$this->table( $table_head, $table_body, $table_foot );
}
}
}

View File

@ -0,0 +1,20 @@
<?php
namespace WP_Piwik\Widget;
class Keywords extends \WP_Piwik\Widget {
public $class_name = __CLASS__;
protected function configure( $prefix = '', $params = array() ) {
$time_settings = $this->get_time_settings();
$this->parameter = array(
'idSite' => self::$wp_piwik->get_piwik_site_id( $this->blog_id ),
'period' => $time_settings['period'],
'date' => $time_settings['date'],
);
$this->title = $prefix . __( 'Keywords', 'wp-piwik' ) . ' (' . $time_settings['description'] . ')';
$this->method = 'Referrers.getKeywords';
$this->name = 'Keyword';
}
}

View File

@ -0,0 +1,83 @@
<?php
namespace WP_Piwik\Widget;
use WP_Piwik\Widget;
class Models extends Widget {
public $class_name = __CLASS__;
protected function configure( $prefix = '', $params = array() ) {
$time_settings = $this->get_time_settings();
$this->parameter = array(
'idSite' => self::$wp_piwik->get_piwik_site_id( $this->blog_id ),
'period' => $time_settings['period'],
'date' => $time_settings['date'],
);
$this->title = $prefix . __( 'Models', 'wp-piwik' ) . ' (' . $time_settings['description'] . ')';
$this->method = 'DevicesDetection.getModel';
$this->context = 'normal';
$version = self::$wp_piwik->get_plugin_version();
wp_enqueue_script( 'wp-piwik', self::$wp_piwik->get_plugin_url() . 'js/wp-piwik.js', array(), $version, true );
wp_enqueue_script( 'wp-piwik-chartjs', self::$wp_piwik->get_plugin_url() . 'js/chartjs/chart.min.js', array(), $version, false );
wp_enqueue_style( 'wp-piwik', self::$wp_piwik->get_plugin_url() . 'css/wp-piwik.css', array(), $version );
}
public function show() {
$response = self::$wp_piwik->request( $this->api_id[ $this->method ] );
$table_body = array();
if ( ! empty( $response['result'] ) && 'error' === $response['result'] ) {
echo '<strong>' . esc_html__( 'Piwik error', 'wp-piwik' ) . ':</strong> ' . esc_html( $response['message'] );
} else {
$table_head = array( __( 'Model', 'wp-piwik' ), __( 'Unique', 'wp-piwik' ), __( 'Percent', 'wp-piwik' ) );
if ( isset( $response[0]['nb_uniq_visitors'] ) ) {
$unique = 'nb_uniq_visitors';
} else {
$unique = 'sum_daily_nb_uniq_visitors';
}
$count = 0;
$sum = 0;
$js = array();
$css_class = array();
if ( is_array( $response ) ) {
foreach ( $response as $row ) {
++$count;
$sum += isset( $row[ $unique ] ) ? $row[ $unique ] : 0;
if ( $count < $this->limit ) {
$table_body[ $row['label'] ] = array( htmlentities( $row['label'] ), $row[ $unique ], 0 );
} elseif ( ! isset( $table_body['Others'] ) ) {
$table_body['Others'] = array( $row['label'], $row[ $unique ], 0 );
$css_class['Others'] = 'wp-piwik-hideDetails';
$js['Others'] = '$j' . "( '.wp-piwik-hideDetails' ).toggle( 'hidden' );";
$table_body[ $row['label'] ] = array( $row['label'], $row[ $unique ], 0 );
$css_class[ $row['label'] ] = 'wp-piwik-hideDetails hidden';
$js[ $row['label'] ] = '$j' . "( '.wp-piwik-hideDetails' ).toggle( 'hidden' );";
} else {
$table_body['Others'][1] += $row[ $unique ];
$table_body[ $row['label'] ] = array( $row['label'], $row[ $unique ], 0 );
$css_class[ $row['label'] ] = 'wp-piwik-hideDetails hidden';
$js[ $row['label'] ] = '$j' . "( '.wp-piwik-hideDetails' ).toggle( 'hidden' );";
}
}
}
if ( $count > $this->limit ) {
$table_body['Others'][0] = __( 'Others', 'wp-piwik' );
} elseif ( $count === $this->limit ) {
$css_class['Others'] = '';
$js['Others'] = '';
}
foreach ( $table_body as $key => $row ) {
$table_body[ $key ][2] = number_format( $row[1] / $sum * 100, 2 ) . '%';
}
if ( ! empty( $table_body ) ) {
$this->pie_chart( $table_body );
}
$this->table( $table_head, $table_body, null, false, $js, $css_class );
}
}
}

View File

@ -0,0 +1,43 @@
<?php
namespace WP_Piwik\Widget;
class Noresult extends \WP_Piwik\Widget {
public $class_name = __CLASS__;
protected function configure( $prefix = '', $params = array() ) {
$time_settings = $this->get_time_settings();
$this->parameter = array(
'idSite' => self::$wp_piwik->get_piwik_site_id( $this->blog_id ),
'period' => $time_settings['period'],
'date' => $time_settings['date'],
);
$this->title = $prefix . __( 'Site Search', 'wp-piwik' ) . ' (' . $time_settings['description'] . ')';
$this->method = 'Actions.getSiteSearchNoResultKeywords';
}
public function show() {
$response = self::$wp_piwik->request( $this->api_id[ $this->method ] );
if (
! empty( $response['result'] )
&& 'error' === $response['result']
) {
echo '<strong>' . esc_html__( 'Piwik error', 'wp-piwik' ) . ':</strong> ' . esc_html( $response['message'] );
} else {
$table_head = array( __( 'Keyword', 'wp-piwik' ), __( 'Requests', 'wp-piwik' ), __( 'Bounced', 'wp-piwik' ) );
$table_body = array();
$count = 0;
if ( is_array( $response ) ) {
foreach ( $response as $row ) {
++$count;
$table_body[] = array( $row['label'], $row['nb_visits'], $row['bounce_rate'] );
if ( 10 === $count ) {
break;
}
}
}
$this->table( $table_head, $table_body, null );
}
}
}

View File

@ -0,0 +1,35 @@
<?php
namespace WP_Piwik\Widget;
class OptOut extends \WP_Piwik\Widget {
public $class_name = __CLASS__;
protected function configure( $prefix = '', $params = array() ) {
$this->parameter = $params;
}
public function show() {
$protocol = ( isset( $_SERVER ['HTTPS'] ) && 'off' !== $_SERVER ['HTTPS'] ) ? 'https' : 'http';
switch ( self::$settings->get_global_option( 'piwik_mode' ) ) {
case 'php':
$piwik_url = $protocol . ':' . self::$settings->get_global_option( 'proxy_url' );
break;
case 'cloud':
$piwik_url = 'https://' . self::$settings->get_global_option( 'piwik_user' ) . '.innocraft.cloud/';
break;
case 'cloud-matomo':
$piwik_url = 'https://' . self::$settings->get_global_option( 'matomo_user' ) . '.matomo.cloud/';
break;
default:
$piwik_url = self::$settings->get_global_option( 'piwik_url' );
break;
}
$width = ( isset( $this->parameter['width'] ) ? rawurlencode( $this->parameter['width'] ) : '' );
$height = ( isset( $this->parameter['height'] ) ? rawurlencode( $this->parameter['height'] ) : '' );
$idsite = ( isset( $this->parameter['idsite'] ) ? 'idsite=' . (int) $this->parameter['idsite'] . '&' : '' );
$language = ( isset( $this->parameter['language'] ) ? rawurlencode( $this->parameter['language'] ) : 'en' );
$this->out( '<iframe frameborder="no" width="' . esc_attr( $width ) . '" height="' . esc_attr( $height ) . '" src="' . esc_attr( $piwik_url . 'index.php?module=CoreAdminHome&action=optOut&' . $idsite . 'language=' . $language ) . '"></iframe>' );
}
}

View File

@ -0,0 +1,77 @@
<?php
namespace WP_Piwik\Widget;
class Overview extends \WP_Piwik\Widget {
public $class_name = __CLASS__;
protected function configure( $prefix = '', $params = array() ) {
$time_settings = $this->get_time_settings();
$this->parameter = array(
'idSite' => self::$wp_piwik->get_piwik_site_id( $this->blog_id ),
'period' => isset( $params['period'] ) ? $params['period'] : $time_settings['period'],
'date' => isset( $params['date'] ) ? $params['date'] : $time_settings['date'],
'description' => $time_settings['description'],
);
$this->title = ! $this->is_shortcode ? $prefix . __( 'Overview', 'wp-piwik' ) . ' (' . ( 'dashboard' === $this->page_id ? $this->range_name() : $time_settings['description'] ) . ')' : ( $params['title'] ? $params['title'] : '' );
$this->method = 'VisitsSummary.get';
}
public function show() {
$response = self::$wp_piwik->request( $this->api_id[ $this->method ] );
if ( ! empty( $response['result'] ) && 'error' === $response['result'] ) {
echo '<strong>' . esc_html__( 'Piwik error', 'wp-piwik' ) . ':</strong> ' . esc_html( $response['message'] );
} else {
if ( in_array( $this->parameter['date'], array( 'last30', 'last60', 'last90' ), true ) ) {
$result = array();
if ( is_array( $response ) ) {
foreach ( $response as $data ) {
foreach ( $data as $key => $value ) {
if ( isset( $result[ $key ] ) && is_numeric( $value ) ) {
$result[ $key ] += $value;
} elseif ( is_numeric( $value ) ) {
$result[ $key ] = $value;
} else {
$result[ $key ] = 0;
}
}
}
if ( isset( $result['nb_visits'] ) && $result['nb_visits'] > 0 ) {
$result['nb_actions_per_visit'] = round( $result['nb_actions'] / $result['nb_visits'], 1 );
$result['bounce_rate'] = round( $result['bounce_count'] / $result['nb_visits'] * 100, 1 ) . '%';
$result['avg_time_on_site'] = round( $result['sum_visit_length'] / $result['nb_visits'], 0 );
} else {
$result['nb_actions_per_visit'] = 0;
$result['bounce_rate'] = 0;
$result['avg_time_on_site'] = 0;
}
}
$response = $result;
}
$time = isset( $response['sum_visit_length'] ) ? $this->time_format( $response['sum_visit_length'] ) : '-';
$avg_time = isset( $response['avg_time_on_site'] ) ? $this->time_format( $response['avg_time_on_site'] ) : '-';
$table_head = null;
$table_body = array( array( __( 'Visitors', 'wp-piwik' ) . ':', $this->value( $response, 'nb_visits' ) ) );
if ( '-' !== $this->value( $response, 'nb_uniq_visitors' ) ) {
array_push( $table_body, array( __( 'Unique visitors', 'wp-piwik' ) . ':', $this->value( $response, 'nb_uniq_visitors' ) ) );
}
array_push(
$table_body,
array( __( 'Page views', 'wp-piwik' ) . ':', $this->value( $response, 'nb_actions' ) . ' (&#216; ' . $this->value( $response, 'nb_actions_per_visit' ) . ')' ),
array( __( 'Total time spent', 'wp-piwik' ) . ':', $time . ' (&#216; ' . $avg_time . ')' ),
array( __( 'Bounce count', 'wp-piwik' ) . ':', $this->value( $response, 'bounce_count' ) . ' (' . $this->value( $response, 'bounce_rate' ) . ')' )
);
if ( ! in_array( $this->parameter['date'], array( 'last30', 'last60', 'last90' ), true ) ) {
array_push( $table_body, array( __( 'Time/visit', 'wp-piwik' ) . ':', $avg_time ), array( __( 'Max. page views in one visit', 'wp-piwik' ) . ':', $this->value( $response, 'max_actions' ) ) );
}
$table_foot = self::$settings->get_global_option( 'piwik_shortcut' )
? array(
esc_html__( 'Shortcut', 'wp-piwik' ) . ':',
'<a href="' . esc_attr( self::$settings->get_global_option( 'piwik_url' ) ) . '" target="_BLANK">Matomo</a>',
)
: null;
$this->table( $table_head, $table_body, $table_foot );
}
}
}

View File

@ -0,0 +1,20 @@
<?php
namespace WP_Piwik\Widget;
class Pages extends \WP_Piwik\Widget {
public $class_name = __CLASS__;
protected function configure( $prefix = '', $params = array() ) {
$time_settings = $this->get_time_settings();
$this->parameter = array(
'idSite' => self::$wp_piwik->get_piwik_site_id( $this->blog_id ),
'period' => $time_settings['period'],
'date' => $time_settings['date'],
);
$this->title = $prefix . __( 'Pages', 'wp-piwik' ) . ' (' . $time_settings['description'] . ')';
$this->method = 'Actions.getPageTitles';
$this->name = __( 'Page', 'wp-piwik' );
}
}

View File

@ -0,0 +1,40 @@
<?php
namespace WP_Piwik\Widget;
class Plugins extends \WP_Piwik\Widget {
public $class_name = __CLASS__;
protected function configure( $prefix = '', $params = array() ) {
$time_settings = $this->get_time_settings();
$this->parameter = array(
'idSite' => self::$wp_piwik->get_piwik_site_id( $this->blog_id ),
'period' => $time_settings['period'],
'date' => $time_settings['date'],
);
$this->title = $prefix . __( 'Plugins', 'wp-piwik' ) . ' (' . $time_settings['description'] . ')';
$this->method = 'DevicePlugins.getPlugin';
}
public function show() {
$response = self::$wp_piwik->request( $this->api_id[ $this->method ] );
if ( ! empty( $response['result'] ) && 'error' === $response['result'] ) {
echo '<strong>' . esc_html__( 'Piwik error', 'wp-piwik' ) . ':</strong> ' . esc_html( $response['message'] );
} else {
$table_head = array( __( 'Plugin', 'wp-piwik' ), __( 'Visits', 'wp-piwik' ), __( 'Percent', 'wp-piwik' ) );
$table_body = array();
$count = 0;
if ( is_array( $response ) ) {
foreach ( $response as $row ) {
++$count;
$table_body[] = array( $row['label'], $row['nb_visits'], $row['nb_visits_percentage'] );
if ( 10 === $count ) {
break;
}
}
}
$this->table( $table_head, $table_body, null );
}
}
}

View File

@ -0,0 +1,95 @@
<?php
namespace WP_Piwik\Widget;
class Post extends \WP_Piwik\Widget {
public $class_name = __CLASS__;
protected function configure( $prefix = '', $params = array() ) {
global $post;
$time_settings = $this->get_time_settings();
$this->parameter = array(
'idSite' => self::$wp_piwik->get_piwik_site_id( $this->blog_id ),
'period' => isset( $params['period'] ) ? $params['period'] : $time_settings['period'],
'date' => isset( $params['date'] ) ? $params['date'] : $time_settings['date'],
'key' => isset( $params['key'] ) ? $params['key'] : null,
'pageUrl' => isset( $params['url'] ) ? $params['url'] : get_permalink( $post->ID ),
'description' => $time_settings['description'],
);
$this->title = $prefix . esc_html__( 'Overview', 'wp-piwik' ) . ' (' . $this->parameter['date'] . ')';
$this->method = 'Actions.getPageUrl';
}
public function show() {
$response = self::$wp_piwik->request( $this->api_id[ $this->method ] );
if ( ! empty( $response['result'] ) && 'error' === $response['result'] ) {
echo '<strong>' . esc_html__( 'Piwik error', 'wp-piwik' ) . ':</strong> ' . esc_html( $response['message'] );
} else {
if ( in_array( $this->parameter['date'], array( 'last30', 'last60', 'last90' ), true ) ) {
$result = array();
if ( is_array( $response ) ) {
foreach ( $response as $data ) {
if ( isset( $data[0] ) ) {
foreach ( $data[0] as $key => $value ) {
if ( isset( $result[ $key ] ) && is_numeric( $value ) ) {
$result[ $key ] += $value;
} elseif ( is_numeric( $value ) ) {
$result[ $key ] = $value;
} else {
$result[ $key ] = 0;
}
}
}
}
if ( isset( $result['nb_visits'] ) && $result['nb_visits'] > 0 ) {
$result['nb_actions_per_visit'] = round( ( isset( $result['nb_actions'] ) ? $result['nb_actions'] : 0 ) / $result['nb_visits'], 1 );
$result['bounce_rate'] = round( ( isset( $result['bounce_count'] ) ? $result['bounce_count'] : 0 ) / $result['nb_visits'] * 100, 1 ) . '%';
$result['avg_time_on_site'] = round( ( isset( $result['sum_visit_length'] ) ? $result['sum_visit_length'] : 0 ) / $result['nb_visits'], 0 );
} else {
$result['nb_actions_per_visit'] = 0;
$result['bounce_rate'] = 0;
$result['avg_time_on_site'] = 0;
}
}
$response = $result;
} else {
if ( isset( $response[0] ) ) {
$response = $response[0];
}
if ( $this->parameter['key'] ) {
$this->out( isset( $response[ $this->parameter['key'] ] ) ? esc_html( $response[ $this->parameter['key'] ] ) : '<em>not defined</em>' );
return;
}
}
$time = isset( $response['sum_visit_length'] ) ? $this->time_format( $response['sum_visit_length'] ) : '-';
$avg_time = isset( $response['avg_time_on_site'] ) ? $this->time_format( $response['avg_time_on_site'] ) : '-';
$table_head = null;
$table_body = array( array( __( 'Visitors', 'wp-piwik' ) . ':', $this->value( $response, 'nb_visits' ) ) );
if ( '-' !== $this->value( $response, 'nb_uniq_visitors' ) ) {
array_push( $table_body, array( __( 'Unique visitors', 'wp-piwik' ) . ':', $this->value( $response, 'nb_uniq_visitors' ) ) );
} elseif ( '-' !== $this->value( $response, 'sum_daily_nb_uniq_visitors' ) ) {
array_push( $table_body, __( 'Unique visitors', 'wp-piwik' ) . ':', $this->value( $response, 'sum_daily_nb_uniq_visitors' ) );
}
array_push(
$table_body,
array( __( 'Page views', 'wp-piwik' ) . ':', $this->value( $response, 'nb_hits' ) . ' (&#216; ' . $this->value( $response, 'entry_nb_actions' ) . ')' ),
array( __( 'Total time spent', 'wp-piwik' ) . ':', $time ),
array( __( 'Bounce count', 'wp-piwik' ) . ':', $this->value( $response, 'entry_bounce_count' ) . ' (' . $this->value( $response, 'bounce_rate' ) . ')' ),
array( __( 'Time/visit', 'wp-piwik' ) . ':', $avg_time ),
array( __( 'Min. generation time', 'wp-piwik' ) . ':', $this->value( $response, 'min_time_generation' ) ),
array( __( 'Max. generation time', 'wp-piwik' ) . ':', $this->value( $response, 'max_time_generation' ) )
);
if ( ! in_array( $this->parameter['date'], array( 'last30', 'last60', 'last90' ), true ) ) {
array_push( $table_body, array( __( 'Time/visit', 'wp-piwik' ) . ':', $avg_time ), array( __( 'Max. page views in one visit', 'wp-piwik' ) . ':', $this->value( $response, 'max_actions' ) ) );
}
$table_foot = self::$settings->get_global_option( 'piwik_shortcut' )
? array(
esc_html__( 'Shortcut', 'wp-piwik' ) . ':',
'<a href="' . esc_attr( self::$settings->get_global_option( 'piwik_url' ) ) . '">Piwik</a>',
)
: null;
$this->table( $table_head, $table_body, $table_foot );
}
}
}

View File

@ -0,0 +1,20 @@
<?php
namespace WP_Piwik\Widget;
class Referrers extends \WP_Piwik\Widget {
public $class_name = __CLASS__;
protected function configure( $prefix = '', $params = array() ) {
$time_settings = $this->get_time_settings();
$this->parameter = array(
'idSite' => self::$wp_piwik->get_piwik_site_id( $this->blog_id ),
'period' => $time_settings['period'],
'date' => $time_settings['date'],
);
$this->title = $prefix . __( 'Referrers', 'wp-piwik' ) . ' (' . $time_settings['description'] . ')';
$this->method = 'Referrers.getWebsites';
$this->name = 'Referrer';
}
}

View File

@ -0,0 +1,77 @@
<?php
namespace WP_Piwik\Widget;
class Screens extends \WP_Piwik\Widget {
public $class_name = __CLASS__;
protected function configure( $prefix = '', $params = array() ) {
$time_settings = $this->get_time_settings();
$this->parameter = array(
'idSite' => self::$wp_piwik->get_piwik_site_id( $this->blog_id ),
'period' => $time_settings['period'],
'date' => $time_settings['date'],
);
$this->title = $prefix . __( 'Resolutions', 'wp-piwik' ) . ' (' . $time_settings['description'] . ')';
$this->method = 'Resolution.getResolution';
$this->context = 'normal';
$version = self::$wp_piwik->get_plugin_version();
wp_enqueue_script( 'wp-piwik', self::$wp_piwik->get_plugin_url() . 'js/wp-piwik.js', array(), $version, true );
wp_enqueue_script( 'wp-piwik-chartjs', self::$wp_piwik->get_plugin_url() . 'js/chartjs/chart.min.js', array(), $version, false );
wp_enqueue_style( 'wp-piwik', self::$wp_piwik->get_plugin_url() . 'css/wp-piwik.css', array(), $version );
}
public function show() {
$response = self::$wp_piwik->request( $this->api_id[ $this->method ] );
$table_body = array();
if ( ! empty( $response['result'] ) && 'error' === $response['result'] ) {
echo '<strong>' . esc_html__( 'Piwik error', 'wp-piwik' ) . ':</strong> ' . esc_html( $response['message'] );
} else {
$table_head = array( __( 'Resolution', 'wp-piwik' ), __( 'Unique', 'wp-piwik' ), __( 'Percent', 'wp-piwik' ) );
if ( isset( $response[0]['nb_uniq_visitors'] ) ) {
$unique = 'nb_uniq_visitors';
} else {
$unique = 'sum_daily_nb_uniq_visitors';
}
$count = 0;
$sum = 0;
$js = array();
$css_class = array();
if ( is_array( $response ) ) {
foreach ( $response as $row ) {
++$count;
$sum += isset( $row[ $unique ] ) ? $row[ $unique ] : 0;
if ( $count < $this->limit ) {
$table_body[ $row['label'] ] = array( $row['label'], $row[ $unique ], 0 );
} elseif ( ! isset( $table_body['Others'] ) ) {
$table_body['Others'] = array( $row['label'], $row[ $unique ], 0 );
$css_class['Others'] = 'wp-piwik-hideDetails';
$js['Others'] = '$j' . "( '.wp-piwik-hideDetails' ).toggle( 'hidden' );";
$table_body[ $row['label'] ] = array( $row['label'], $row[ $unique ], 0 );
$css_class[ $row['label'] ] = 'wp-piwik-hideDetails hidden';
$js[ $row['label'] ] = '$j' . "( '.wp-piwik-hideDetails' ).toggle( 'hidden' );";
} else {
$table_body['Others'][1] += $row[ $unique ];
$table_body[ $row['label'] ] = array( $row['label'], $row[ $unique ], 0 );
$css_class[ $row['label'] ] = 'wp-piwik-hideDetails hidden';
$js[ $row['label'] ] = '$j' . "( '.wp-piwik-hideDetails' ).toggle( 'hidden' );";
}
}
}
if ( $count > $this->limit ) {
$table_body['Others'][0] = __( 'Others', 'wp-piwik' );
}
foreach ( $table_body as $key => $row ) {
$table_body[ $key ][2] = number_format( $row[1] / $sum * 100, 2 ) . '%';
}
if ( ! empty( $table_body ) ) {
$this->pie_chart( $table_body );
}
$this->table( $table_head, $table_body, null, false, $js, $css_class );
}
}
}

View File

@ -0,0 +1,40 @@
<?php
namespace WP_Piwik\Widget;
class Search extends \WP_Piwik\Widget {
public $class_name = __CLASS__;
protected function configure( $prefix = '', $params = array() ) {
$time_settings = $this->get_time_settings();
$this->parameter = array(
'idSite' => self::$wp_piwik->get_piwik_site_id( $this->blog_id ),
'period' => $time_settings['period'],
'date' => $time_settings['date'],
);
$this->title = $prefix . __( 'Site Search', 'wp-piwik' ) . ' (' . $time_settings['description'] . ')';
$this->method = 'Actions.getSiteSearchKeywords';
}
public function show() {
$response = self::$wp_piwik->request( $this->api_id[ $this->method ] );
if ( ! empty( $response['result'] ) && 'error' === $response['result'] ) {
echo '<strong>' . esc_html__( 'Piwik error', 'wp-piwik' ) . ':</strong> ' . esc_html( $response['message'] );
} else {
$table_head = array( __( 'Keyword', 'wp-piwik' ), __( 'Requests', 'wp-piwik' ), __( 'Bounced', 'wp-piwik' ) );
$table_body = array();
$count = 0;
if ( is_array( $response ) ) {
foreach ( $response as $row ) {
++$count;
$table_body[] = array( $row['label'], $row['nb_visits'], $row['bounce_rate'] );
if ( 10 === $count ) {
break;
}
}
}
$this->table( $table_head, $table_body, null );
}
}
}

View File

@ -0,0 +1,33 @@
<?php
namespace WP_Piwik\Widget;
class Seo extends \WP_Piwik\Widget {
public $class_name = __CLASS__;
protected function configure( $prefix = '', $params = array() ) {
$this->parameter = array(
'url' => get_bloginfo( 'url' ),
);
$this->title = $prefix . __( 'SEO', 'wp-piwik' );
$this->method = 'SEO.getRank';
}
public function show() {
$response = self::$wp_piwik->request( $this->api_id[ $this->method ] );
if ( ! empty( $response['result'] ) && 'error' === $response['result'] ) {
echo '<strong>' . esc_html__( 'Piwik error', 'wp-piwik' ) . ':</strong> ' . esc_html( $response['message'] );
} else {
echo '<div class="table"><table class="widefat"><tbody>';
if ( is_array( $response ) ) {
foreach ( $response as $val ) {
echo '<tr><td>' . ( isset( $val['logo_link'] ) && ! empty( $val['logo_link'] ) ? '<a href="' . esc_attr( $val['logo_link'] ) . '" title="' . esc_attr( $val['logo_tooltip'] ) . '">' . esc_html( $val['label'] ) . '</a>' : esc_html( $val['label'] ) ) . '</td><td>' . esc_html( $val['rank'] ) . '</td></tr>';
}
} else {
echo '<tr><td>SEO module currently not available.</td></tr>';
}
echo '</tbody></table></div>';
}
}
}

View File

@ -0,0 +1,76 @@
<?php
namespace WP_Piwik\Widget;
class SystemDetails extends \WP_Piwik\Widget {
protected function configure( $prefix = '', $params = array() ) {
$time_settings = $this->get_time_settings();
$this->parameter = array(
'idSite' => self::$wp_piwik->get_piwik_site_id( $this->blog_id ),
'period' => $time_settings['period'],
'date' => $time_settings['date'],
);
$this->title = $prefix . __( 'Operation System Details', 'wp-piwik' ) . ' (' . $time_settings['description'] . ')';
$this->method = 'DevicesDetection.getOsVersions';
$this->context = 'normal';
$version = self::$wp_piwik->get_plugin_version();
wp_enqueue_script( 'wp-piwik', self::$wp_piwik->get_plugin_url() . 'js/wp-piwik.js', array(), $version, true );
wp_enqueue_script( 'wp-piwik-chartjs', self::$wp_piwik->get_plugin_url() . 'js/chartjs/chart.min.js', array(), $version, false );
wp_enqueue_style( 'wp-piwik', self::$wp_piwik->get_plugin_url() . 'css/wp-piwik.css', array(), $version );
}
public function show() {
$response = self::$wp_piwik->request( $this->api_id[ $this->method ] );
$table_body = array();
if ( ! empty( $response['result'] ) && 'error' === $response['result'] ) {
echo '<strong>' . esc_html__( 'Piwik error', 'wp-piwik' ) . ':</strong> ' . esc_html( $response['message'] );
} else {
$table_head = array( __( 'Operation System', 'wp-piwik' ), __( 'Unique', 'wp-piwik' ), __( 'Percent', 'wp-piwik' ) );
if ( isset( $response[0]['nb_uniq_visitors'] ) ) {
$unique = 'nb_uniq_visitors';
} else {
$unique = 'sum_daily_nb_uniq_visitors';
}
$count = 0;
$sum = 0;
$js = array();
$css_class = array();
if ( is_array( $response ) ) {
foreach ( $response as $row ) {
++$count;
$sum += isset( $row[ $unique ] ) ? $row[ $unique ] : 0;
if ( $count < $this->limit ) {
$table_body[ $row['label'] ] = array( $row['label'], $row[ $unique ], 0 );
} elseif ( ! isset( $table_body['Others'] ) ) {
$table_body['Others'] = array( $row['label'], $row[ $unique ], 0 );
$css_class['Others'] = 'wp-piwik-hideDetails';
$js['Others'] = '$j' . "( '.wp-piwik-hideDetails' ).toggle( 'hidden' );";
$table_body[ $row['label'] ] = array( $row['label'], $row[ $unique ], 0 );
$css_class[ $row['label'] ] = 'wp-piwik-hideDetails hidden';
$js[ $row['label'] ] = '$j' . "( '.wp-piwik-hideDetails' ).toggle( 'hidden' );";
} else {
$table_body['Others'][1] += $row[ $unique ];
$table_body[ $row['label'] ] = array( $row['label'], $row[ $unique ], 0 );
$css_class[ $row['label'] ] = 'wp-piwik-hideDetails hidden';
$js[ $row['label'] ] = '$j' . "( '.wp-piwik-hideDetails' ).toggle( 'hidden' );";
}
}
}
if ( $count > $this->limit ) {
$table_body['Others'][0] = __( 'Others', 'wp-piwik' );
}
foreach ( $table_body as $key => $row ) {
$table_body[ $key ][2] = number_format( $row[1] / $sum * 100, 2 ) . '%';
}
if ( ! empty( $table_body ) ) {
$this->pie_chart( $table_body );
}
$this->table( $table_head, $table_body, null, false, $js, $css_class );
}
}
}

View File

@ -0,0 +1,76 @@
<?php
namespace WP_Piwik\Widget;
class Systems extends \WP_Piwik\Widget {
protected function configure( $prefix = '', $params = array() ) {
$time_settings = $this->get_time_settings();
$this->parameter = array(
'idSite' => self::$wp_piwik->get_piwik_site_id( $this->blog_id ),
'period' => $time_settings['period'],
'date' => $time_settings['date'],
);
$this->title = $prefix . __( 'Operation Systems', 'wp-piwik' ) . ' (' . $time_settings['description'] . ')';
$this->method = 'DevicesDetection.getOsFamilies';
$this->context = 'normal';
$version = self::$wp_piwik->get_plugin_version();
wp_enqueue_script( 'wp-piwik', self::$wp_piwik->get_plugin_url() . 'js/wp-piwik.js', array(), $version, true );
wp_enqueue_script( 'wp-piwik-chartjs', self::$wp_piwik->get_plugin_url() . 'js/chartjs/chart.min.js', array(), $version, false );
wp_enqueue_style( 'wp-piwik', self::$wp_piwik->get_plugin_url() . 'css/wp-piwik.css', array(), $version );
}
public function show() {
$response = self::$wp_piwik->request( $this->api_id[ $this->method ] );
$table_body = array();
if ( ! empty( $response['result'] ) && 'error' === $response['result'] ) {
echo '<strong>' . esc_html__( 'Piwik error', 'wp-piwik' ) . ':</strong> ' . esc_html( $response['message'] );
} else {
$table_head = array( __( 'Operation System', 'wp-piwik' ), __( 'Unique', 'wp-piwik' ), __( 'Percent', 'wp-piwik' ) );
if ( isset( $response[0]['nb_uniq_visitors'] ) ) {
$unique = 'nb_uniq_visitors';
} else {
$unique = 'sum_daily_nb_uniq_visitors';
}
$count = 0;
$sum = 0;
$js = array();
$css_class = array();
if ( is_array( $response ) ) {
foreach ( $response as $row ) {
++$count;
$sum += isset( $row[ $unique ] ) ? $row[ $unique ] : 0;
if ( $count < $this->limit ) {
$table_body[ $row['label'] ] = array( $row['label'], $row[ $unique ], 0 );
} elseif ( ! isset( $table_body['Others'] ) ) {
$table_body['Others'] = array( $row['label'], $row[ $unique ], 0 );
$css_class['Others'] = 'wp-piwik-hideDetails';
$js['Others'] = '$j' . "( '.wp-piwik-hideDetails' ).toggle( 'hidden' );";
$table_body[ $row['label'] ] = array( $row['label'], $row[ $unique ], 0 );
$css_class[ $row['label'] ] = 'wp-piwik-hideDetails hidden';
$js[ $row['label'] ] = '$j' . "( '.wp-piwik-hideDetails' ).toggle( 'hidden' );";
} else {
$table_body['Others'][1] += $row[ $unique ];
$table_body[ $row['label'] ] = array( $row['label'], $row[ $unique ], 0 );
$css_class[ $row['label'] ] = 'wp-piwik-hideDetails hidden';
$js[ $row['label'] ] = '$j' . "( '.wp-piwik-hideDetails' ).toggle( 'hidden' );";
}
}
}
if ( $count > $this->limit ) {
$table_body['Others'][0] = __( 'Others', 'wp-piwik' );
}
foreach ( $table_body as $key => $row ) {
$table_body[ $key ][2] = number_format( $row[1] / $sum * 100, 2 ) . '%';
}
if ( ! empty( $table_body ) ) {
$this->pie_chart( $table_body );
}
$this->table( $table_head, $table_body, null, false, $js, $css_class );
}
}
}

View File

@ -0,0 +1,84 @@
<?php
namespace WP_Piwik\Widget;
use WP_Piwik\Widget;
class Types extends Widget {
public $class_name = __CLASS__;
protected function configure( $prefix = '', $params = array() ) {
$time_settings = $this->get_time_settings();
$this->parameter = array(
'idSite' => self::$wp_piwik->get_piwik_site_id( $this->blog_id ),
'period' => $time_settings['period'],
'date' => $time_settings['date'],
);
$this->title = $prefix . __( 'Types', 'wp-piwik' ) . ' (' . $time_settings['description'] . ')';
$this->method = 'DevicesDetection.getType';
$this->context = 'normal';
$version = self::$wp_piwik->get_plugin_version();
wp_enqueue_script( 'wp-piwik', self::$wp_piwik->get_plugin_url() . 'js/wp-piwik.js', array(), $version, true );
wp_enqueue_script( 'wp-piwik-chartjs', self::$wp_piwik->get_plugin_url() . 'js/chartjs/chart.min.js', array(), $version, false );
wp_enqueue_style( 'wp-piwik', self::$wp_piwik->get_plugin_url() . 'css/wp-piwik.css', array(), $version );
}
public function show() {
$response = self::$wp_piwik->request( $this->api_id[ $this->method ] );
$table_body = array();
if ( ! empty( $response['result'] ) && 'error' === $response['result'] ) {
echo '<strong>' . esc_html__( 'Piwik error', 'wp-piwik' ) . ':</strong> ' . esc_html( $response['message'] );
} else {
$table_head = array( __( 'Type', 'wp-piwik' ), __( 'Unique', 'wp-piwik' ), __( 'Percent', 'wp-piwik' ) );
if ( isset( $response[0]['nb_uniq_visitors'] ) ) {
$unique = 'nb_uniq_visitors';
} else {
$unique = 'sum_daily_nb_uniq_visitors';
}
$count = 0;
$sum = 0;
$js = array();
$css_class = array();
if ( is_array( $response ) ) {
foreach ( $response as $row ) {
$key = isset( $row[ $unique ] ) ? $unique : 'nb_visits';
++$count;
$sum += isset( $row[ $key ] ) ? $row[ $key ] : 0;
if ( $count < $this->limit ) {
$table_body[ $row['label'] ] = array( $row['label'], $row[ $key ], 0 );
} elseif ( ! isset( $table_body['Others'] ) ) {
$table_body['Others'] = array( $row['label'], $row[ $key ], 0 );
$css_class['Others'] = 'wp-piwik-hideDetails';
$js['Others'] = '$j' . "( '.wp-piwik-hideDetails' ).toggle( 'hidden' );";
$table_body[ $row['label'] ] = array( $row['label'], $row[ $key ], 0 );
$css_class[ $row['label'] ] = 'wp-piwik-hideDetails hidden';
$js[ $row['label'] ] = '$j' . "( '.wp-piwik-hideDetails' ).toggle( 'hidden' );";
} else {
$table_body['Others'][1] += $row[ $key ];
$table_body[ $row['label'] ] = array( $row['label'], $row[ $key ], 0 );
$css_class[ $row['label'] ] = 'wp-piwik-hideDetails hidden';
$js[ $row['label'] ] = '$j' . "( '.wp-piwik-hideDetails' ).toggle( 'hidden' );";
}
}
}
if ( $count > $this->limit ) {
$table_body['Others'][0] = __( 'Others', 'wp-piwik' );
} elseif ( $count === $this->limit ) {
$css_class['Others'] = '';
$js['Others'] = '';
}
foreach ( $table_body as $key => $row ) {
$table_body[ $key ][2] = number_format( $row[1] / $sum * 100, 2 ) . '%';
}
if ( ! empty( $table_body ) ) {
$this->pie_chart( $table_body );
}
$this->table( $table_head, $table_body, null, false, $js, $css_class );
}
}
}

View File

@ -0,0 +1,100 @@
<?php
namespace WP_Piwik\Widget;
use WP_Piwik\Widget;
class Visitors extends Widget {
public $class_name = __CLASS__;
protected function configure( $prefix = '', $params = array() ) {
$time_settings = $this->get_time_settings();
$this->parameter = array(
'idSite' => self::$wp_piwik->get_piwik_site_id( $this->blog_id ),
'period' => isset( $params['period'] ) ? $params['period'] : $time_settings['period'],
'date' => 'last' . ( 'day' === $time_settings['period'] ? '30' : '12' ),
'limit' => null,
);
$this->title = $prefix . __( 'Visitors', 'wp-piwik' ) . ' (' . $this->range_name() . ')';
$this->method = array( 'VisitsSummary.getVisits', 'VisitsSummary.getUniqueVisitors', 'VisitsSummary.getBounceCount', 'VisitsSummary.getActions' );
$this->context = 'normal';
$version = self::$wp_piwik->get_plugin_version();
wp_enqueue_script( 'wp-piwik', self::$wp_piwik->get_plugin_url() . 'js/wp-piwik.js', array(), $version, true );
wp_enqueue_script( 'wp-piwik-chartjs', self::$wp_piwik->get_plugin_url() . 'js/chartjs/chart.min.js', array(), $version, false );
wp_enqueue_style( 'wp-piwik', self::$wp_piwik->get_plugin_url() . 'css/wp-piwik.css', array(), $version );
}
public function request_data() {
$response = array();
$success = true;
foreach ( $this->method as $method ) {
$response[ $method ] = self::$wp_piwik->request( $this->api_id[ $method ] );
if ( ! empty( $response[ $method ]['result'] ) && 'error' === $response[ $method ]['result'] ) {
$success = false;
}
}
return array(
'response' => $response,
'success' => $success,
);
}
public function show() {
$result = $this->request_data();
$response = $result['response'];
if ( ! $result['success'] ) {
$message = '';
if ( is_array( $this->method ) ) {
foreach ( $this->method as $m ) {
if ( empty( $response[ $m ]['message'] ) ) {
continue;
}
$message .= ' ' . $m . ' - ' . $response[ $m ]['message'];
}
} else {
$message = $response[ $this->method ]['message'];
}
echo '<strong>' . esc_html__( 'Piwik error', 'wp-piwik' ) . ':</strong> ' . esc_html( $message );
} else {
$data = array();
if ( is_array( $response ) && is_array( $response['VisitsSummary.getVisits'] ) ) {
foreach ( $response['VisitsSummary.getVisits'] as $key => $value ) {
if ( 'week' === $this->parameter['period'] ) {
preg_match( '/[0-9]{4}-(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1])/', $key, $date_list );
$js_key = $date_list[0];
$text_key = $this->date_format( $js_key, 'week' );
} elseif ( 'month' === $this->parameter['period'] ) {
$js_key = $key . '-01';
$text_key = $key;
} else {
$js_key = $key;
$text_key = $key;
}
$data[] = array(
$text_key,
$value,
$response['VisitsSummary.getUniqueVisitors'][ $key ] ? $response['VisitsSummary.getUniqueVisitors'][ $key ] : '-',
$response['VisitsSummary.getBounceCount'][ $key ] ? $response['VisitsSummary.getBounceCount'][ $key ] : '-',
$response['VisitsSummary.getActions'][ $key ] ? $response['VisitsSummary.getActions'][ $key ] : '-',
);
$java_script[] = 'javascript:wp_piwik_datelink('
. wp_json_encode( rawurlencode( 'wp-piwik_stats' ) ) . ','
. wp_json_encode( str_replace( '-', '', $js_key ) ) . ','
. wp_json_encode( isset( $_GET['wpmu_show_stats'] ) ? (int) $_GET['wpmu_show_stats'] : '' )
. ');';
}
}
$this->table(
array( __( 'Date', 'wp-piwik' ), __( 'Visits', 'wp-piwik' ), __( 'Unique', 'wp-piwik' ), __( 'Bounced', 'wp-piwik' ), __( 'Page Views', 'wp-piwik' ) ),
array_reverse( $data ),
array(),
'clickable',
array_reverse( isset( $java_script ) ? $java_script : array() )
);
}
}
}