1032 lines
52 KiB
PHP
Executable File
1032 lines
52 KiB
PHP
Executable File
<?php
|
||
/*
|
||
Plugin Name: SIGE Analytics Extended
|
||
Plugin URI: https://www.sige.ita.br
|
||
Description: Google Analytics Extended
|
||
Author: Leandro Geraldo da Costa
|
||
Version: 1.2
|
||
*/
|
||
|
||
require 'vendor/autoload.php';
|
||
|
||
use Google\Analytics\Data\V1beta\Client\BetaAnalyticsDataClient;
|
||
use Google\Analytics\Data\V1beta\DateRange;
|
||
use Google\Analytics\Data\V1beta\Dimension;
|
||
use Google\Analytics\Data\V1beta\Metric;
|
||
use Google\Analytics\Data\V1beta\RunReportRequest;
|
||
|
||
$service_account_key_file_path = __DIR__ . '/key.json';
|
||
|
||
// Activation hook to create the database table
|
||
register_activation_hook(__FILE__, 'sige_analytics_install');
|
||
function sige_analytics_install() {
|
||
global $wpdb;
|
||
$table_name = $wpdb->prefix . 'sige_analytics_data';
|
||
|
||
$charset_collate = $wpdb->get_charset_collate();
|
||
|
||
$sql = "CREATE TABLE $table_name (
|
||
id bigint(20) unsigned NOT NULL AUTO_INCREMENT,
|
||
function_name varchar(255) NOT NULL,
|
||
data longtext NOT NULL,
|
||
last_updated datetime NOT NULL,
|
||
PRIMARY KEY (id),
|
||
UNIQUE KEY function_name (function_name)
|
||
) $charset_collate;";
|
||
|
||
require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
|
||
dbDelta($sql);
|
||
|
||
// Schedule cron events at 6 AM and 6 PM
|
||
if (!wp_next_scheduled('sige_analytics_update_data_6am')) {
|
||
$timestamp = strtotime('today 6:00');
|
||
if (time() > $timestamp) {
|
||
$timestamp = strtotime('tomorrow 6:00');
|
||
}
|
||
wp_schedule_event($timestamp, 'daily', 'sige_analytics_update_data_6am');
|
||
}
|
||
|
||
if (!wp_next_scheduled('sige_analytics_update_data_6pm')) {
|
||
$timestamp = strtotime('today 18:00');
|
||
if (time() > $timestamp) {
|
||
$timestamp = strtotime('tomorrow 18:00');
|
||
}
|
||
wp_schedule_event($timestamp, 'daily', 'sige_analytics_update_data_6pm');
|
||
}
|
||
}
|
||
|
||
// Deactivation hook to remove scheduled events
|
||
register_deactivation_hook(__FILE__, 'sige_analytics_deactivate');
|
||
function sige_analytics_deactivate() {
|
||
wp_clear_scheduled_hook('sige_analytics_update_data_6am');
|
||
wp_clear_scheduled_hook('sige_analytics_update_data_6pm');
|
||
}
|
||
|
||
// Add action hooks for the cron events
|
||
add_action('sige_analytics_update_data_6am', 'sige_analytics_update_cached_data');
|
||
add_action('sige_analytics_update_data_6pm', 'sige_analytics_update_cached_data');
|
||
|
||
|
||
// Function to update cached data during cron jobs
|
||
function sige_analytics_update_cached_data() {
|
||
global $service_account_key_file_path;
|
||
|
||
// Force update the cached data
|
||
calculate_average_metrics_articles($service_account_key_file_path, true);
|
||
calculate_average_metrics_posters($service_account_key_file_path, true);
|
||
calculate_total_views_of_works($service_account_key_file_path, true);
|
||
}
|
||
|
||
// Uninstall hook to remove the database table
|
||
register_uninstall_hook(__FILE__, 'sige_analytics_uninstall');
|
||
function sige_analytics_uninstall() {
|
||
global $wpdb;
|
||
$table_name = $wpdb->prefix . 'sige_analytics_data';
|
||
|
||
$sql = "DROP TABLE IF EXISTS $table_name;";
|
||
$wpdb->query($sql);
|
||
}
|
||
|
||
// Add the "SIGE Analytics" menu page
|
||
add_action('admin_menu', 'sige_analytics_add_admin_menu');
|
||
function sige_analytics_add_admin_menu() {
|
||
add_menu_page(
|
||
'SIGE Analytics About', // Page title
|
||
'SIGE Analytics', // Menu title
|
||
'manage_options', // Capability
|
||
'sige-analytics-about', // Menu slug
|
||
'sige_analytics_about_page', // Function to display the page content
|
||
'dashicons-chart-area', // Icon URL or Dashicon class
|
||
6 // Position in the menu
|
||
);
|
||
}
|
||
|
||
// Function to display the content of the "About" page with custom styles
|
||
function sige_analytics_about_page() {
|
||
echo '<div class="wrap">';
|
||
echo '<h1>SIGE Analytics Extended</h1>';
|
||
|
||
// Add custom styles
|
||
echo '<style>
|
||
.sige-box {
|
||
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
|
||
background: #f9f9f9;
|
||
border: 1px solid #ccc;
|
||
padding: 20px;
|
||
border-radius: 8px;
|
||
margin-bottom: 20px;
|
||
}
|
||
.sige-box h2 {
|
||
margin-top: 0;
|
||
}
|
||
.sige-box ul {
|
||
list-style-type: disc;
|
||
margin-left: 20px;
|
||
}
|
||
</style>';
|
||
|
||
echo '<div class="sige-box">';
|
||
echo '<h2>About</h2>';
|
||
echo '<p><strong>Development Team:</strong></p>';
|
||
echo '<ul>
|
||
<li>Leandro Geraldo da Costa - Lead Developer</li>
|
||
<!-- Add more team members as needed -->
|
||
</ul>';
|
||
echo '</div>';
|
||
|
||
echo '<div class="sige-box">';
|
||
echo '<h2>Functions and Functionalities</h2>';
|
||
echo '<p>This plugin extends Google Analytics functionalities by providing real-time metrics and statistics directly within your WordPress site. It retrieves data such as page views, file downloads, average views per article/poster, and total views of works.</p>';
|
||
echo '<p>The plugin uses Google Analytics Data API to fetch the metrics and stores them in the database for quick retrieval. Data is updated twice a day at 6 AM and 6 PM via scheduled cron jobs.</p>';
|
||
echo '</div>';
|
||
|
||
echo '<div class="sige-box">';
|
||
echo '<h2>Shortcodes and Their Uses</h2>';
|
||
echo '<ul>
|
||
<li><code>[page_views_counter]</code> - Displays the total number of page views.</li>
|
||
<li><code>[file_downloads_counter]</code> - Displays the total number of file downloads.</li>
|
||
<li><code>[average_screen_articles_views]</code> - Shows the average number of screen views per article.</li>
|
||
<li><code>[average_file_articles_downloads]</code> - Shows the average number of file downloads per article.</li>
|
||
<li><code>[average_screen_posters_views]</code> - Shows the average number of screen views per poster.</li>
|
||
<li><code>[average_file_posters_downloads]</code> - Shows the average number of file downloads per poster.</li>
|
||
<li><code>[total_views_of_works]</code> - Displays the total number of views across all works.</li>
|
||
<li><code>[sige_analytics_graphs]</code> - Displays the analytics graphs on the front-end.</li>
|
||
</ul>';
|
||
echo '<p>Use these shortcodes in your posts or pages to display the corresponding analytics data.</p>';
|
||
echo '</div>';
|
||
|
||
echo '</div>';
|
||
}
|
||
|
||
add_action('template_redirect', 'disable_cache_for_analytics_page');
|
||
|
||
function disable_cache_for_analytics_page() {
|
||
// Check if the current page is the analytics page and if the user is not an administrator
|
||
if (is_page('analytics') && !current_user_can('administrator')) {
|
||
// Disable cache headers for non-administrator users
|
||
nocache_headers();
|
||
|
||
// Calculate the nearest 30-minute interval for cache busting
|
||
$time_interval = floor(time() / 1800) * 1800; // 1800 seconds = 30 minutes
|
||
|
||
// Append a nocache query parameter if it’s not already set to the current interval
|
||
if (!isset($_GET['nocache']) || $_GET['nocache'] != $time_interval) {
|
||
// Generate a new URL with the 30-minute interval as a query parameter
|
||
$new_url = add_query_arg('nocache', $time_interval, get_permalink());
|
||
wp_redirect($new_url);
|
||
exit();
|
||
}
|
||
}
|
||
}
|
||
|
||
function fetch_ga_metrics($service_account_key_file_path) {
|
||
static $metrics_cache = null;
|
||
|
||
if ($metrics_cache !== null) {
|
||
return $metrics_cache;
|
||
}
|
||
|
||
$property_id = '436681896';
|
||
$metrics_cache = [];
|
||
|
||
try {
|
||
$client = new BetaAnalyticsDataClient(['credentials' => $service_account_key_file_path]);
|
||
|
||
if ($_SERVER['HTTP_HOST'] === 'www.sige.ita.br' &&
|
||
($_SERVER['REQUEST_URI'] === '/' || $_SERVER['REQUEST_URI'] === '/home-en/')) {
|
||
$request = (new RunReportRequest())
|
||
->setProperty('properties/' . $property_id)
|
||
->setDateRanges([new DateRange(['start_date' => '2020-03-31', 'end_date' => 'today'])])
|
||
->setMetrics([
|
||
new Metric(['name' => 'totalUsers']),
|
||
new Metric(['name' => 'screenPageViews']),
|
||
new Metric(['name' => 'engagementRate']),
|
||
new Metric(['name' => 'eventCount'])
|
||
])
|
||
->setDimensions([new Dimension(['name' => 'eventName'])]);
|
||
|
||
$response = $client->runReport($request);
|
||
|
||
$metrics_cache['totalUsers'] = $response->getRows()[0]->getMetricValues()[0]->getValue();
|
||
$metrics_cache['screenPageViews'] = $response->getRows()[0]->getMetricValues()[1]->getValue();
|
||
$metrics_cache['engagementRate'] = round($response->getRows()[0]->getMetricValues()[2]->getValue() * 100);
|
||
$metrics_cache['fileDownloads'] = $response->getRows()[4]->getMetricValues()[3]->getValue();
|
||
}
|
||
|
||
if (strpos($_SERVER['REQUEST_URI'], '/aiovg_videos/') !== false) {
|
||
$currentPagePath = $_SERVER['REQUEST_URI'];
|
||
|
||
$page_request = (new RunReportRequest())
|
||
->setProperty('properties/' . $property_id)
|
||
->setDateRanges([new DateRange(['start_date' => '2024-01-01', 'end_date' => '2025-01-01'])])
|
||
->setMetrics([
|
||
new Metric(['name' => 'screenPageViews']),
|
||
new Metric(['name' => 'eventCount'])
|
||
])
|
||
->setDimensions([new Dimension(['name' => 'pagePath']), new Dimension(['name' => 'eventName'])])
|
||
->setDimensionFilter(new \Google\Analytics\Data\V1beta\FilterExpression([
|
||
'filter' => new \Google\Analytics\Data\V1beta\Filter([
|
||
'field_name' => 'pagePath',
|
||
'string_filter' => new \Google\Analytics\Data\V1beta\Filter\StringFilter([
|
||
'match_type' => \Google\Analytics\Data\V1beta\Filter\StringFilter\MatchType::EXACT,
|
||
'value' => $currentPagePath
|
||
])
|
||
])
|
||
]));
|
||
|
||
$page_response = $client->runReport($page_request);
|
||
|
||
foreach ($page_response->getRows() as $row) {
|
||
$eventName = $row->getDimensionValues()[1]->getValue();
|
||
if ($eventName === 'page_view') {
|
||
$metrics_cache['screenPageViews'] = $row->getMetricValues()[0]->getValue();
|
||
}
|
||
if ($eventName === 'file_download') {
|
||
$metrics_cache['fileDownloads'] = $row->getMetricValues()[1]->getValue();
|
||
}
|
||
}
|
||
}
|
||
|
||
} catch (Exception $e) {
|
||
return null;
|
||
}
|
||
|
||
return $metrics_cache;
|
||
}
|
||
|
||
// Shortcode for Page Views Counter
|
||
function page_views_counter_shortcode() {
|
||
global $service_account_key_file_path;
|
||
$metrics = fetch_ga_metrics($service_account_key_file_path);
|
||
return $metrics['screenPageViews'] ?? 0;
|
||
}
|
||
add_shortcode('page_views_counter', 'page_views_counter_shortcode');
|
||
|
||
// Shortcode for File Downloads Counter
|
||
function file_downloads_counter_shortcode() {
|
||
global $service_account_key_file_path;
|
||
$metrics = fetch_ga_metrics($service_account_key_file_path);
|
||
return $metrics['fileDownloads'] ?? 0;
|
||
}
|
||
add_shortcode('file_downloads_counter', 'file_downloads_counter_shortcode');
|
||
|
||
add_action('wp_enqueue_scripts', 'enqueue_inline_ga_metrics_script');
|
||
|
||
function enqueue_inline_ga_metrics_script() {
|
||
global $service_account_key_file_path;
|
||
$metrics = fetch_ga_metrics($service_account_key_file_path);
|
||
|
||
if ($metrics) {
|
||
echo "<script>
|
||
document.addEventListener('DOMContentLoaded', function() {
|
||
var metrics = " . json_encode($metrics) . ";
|
||
//console.log('Loaded metrics:', metrics);
|
||
|
||
var counter3 = document.querySelector('.et_pb_number_counter_3');
|
||
if (counter3 && metrics.totalUsers) {
|
||
counter3.setAttribute('data-number-value', metrics.totalUsers);
|
||
var percentValue3 = counter3.querySelector('.percent-value');
|
||
if (percentValue3) {
|
||
percentValue3.textContent = metrics.totalUsers;
|
||
}
|
||
//console.log('Updated counter 3 with totalUsers:', metrics.totalUsers);
|
||
}
|
||
|
||
var counter4 = document.querySelector('.et_pb_number_counter_4');
|
||
if (counter4 && metrics.screenPageViews) {
|
||
counter4.setAttribute('data-number-value', metrics.screenPageViews);
|
||
var percentValue4 = counter4.querySelector('.percent-value');
|
||
if (percentValue4) {
|
||
percentValue4.textContent = metrics.screenPageViews;
|
||
}
|
||
//console.log('Updated counter 4 with screenPageViews:', metrics.screenPageViews);
|
||
}
|
||
|
||
var counter5 = document.querySelector('.et_pb_number_counter_5');
|
||
if (counter5 && metrics.engagementRate) {
|
||
counter5.setAttribute('data-number-value', metrics.engagementRate);
|
||
var percentValue5 = counter5.querySelector('.percent-value');
|
||
if (percentValue5) {
|
||
percentValue5.textContent = metrics.engagementRate + '%';
|
||
}
|
||
//console.log('Updated counter 5 with engagementRate:', metrics.engagementRate);
|
||
}
|
||
|
||
var counter6 = document.querySelector('.et_pb_number_counter_6');
|
||
if (counter6 && metrics.fileDownloads) {
|
||
counter6.setAttribute('data-number-value', metrics.fileDownloads);
|
||
var percentValue6 = counter6.querySelector('.percent-value');
|
||
if (percentValue6) {
|
||
percentValue6.textContent = metrics.fileDownloads;
|
||
}
|
||
// console.log('Updated counter 6 with fileDownloads:', metrics.fileDownloads);
|
||
}
|
||
});
|
||
</script>";
|
||
}
|
||
|
||
echo "<style>
|
||
.et_pb_number_counter .percent-value {
|
||
font-size: 0.8em;
|
||
line-height: 1.2;
|
||
}
|
||
@media (max-width: 1200px) {
|
||
.et_pb_number_counter .percent-value { font-size: 0.7em; }
|
||
}
|
||
@media (max-width: 992px) {
|
||
.et_pb_number_counter .percent-value { font-size: 0.9em; }
|
||
}
|
||
@media (max-width: 768px) {
|
||
.et_pb_number_counter .percent-value { font-size: 0.9em; }
|
||
}
|
||
@media (max-width: 576px) {
|
||
.et_pb_number_counter .percent-value { font-size: 0.8em; }
|
||
}
|
||
</style>";
|
||
}
|
||
|
||
|
||
// Function to calculate averages for articles with database storage
|
||
function calculate_average_metrics_articles($service_account_key_file_path, $force_update = false) {
|
||
error_log("calculate_average_metrics_articles function called.");
|
||
|
||
global $wpdb;
|
||
$table_name = $wpdb->prefix . 'sige_analytics_data';
|
||
|
||
$function_name = 'calculate_average_metrics_articles';
|
||
|
||
$row = $wpdb->get_row($wpdb->prepare("SELECT data FROM $table_name WHERE function_name = %s", $function_name), ARRAY_A);
|
||
|
||
if ($row && !$force_update) {
|
||
$data = maybe_unserialize($row['data']);
|
||
error_log("Cached calculate_average_metrics_articles retrieved: " . print_r($data, true)); // Using print_r to convert array to string
|
||
return $data;
|
||
}
|
||
|
||
$urls = [
|
||
'/aiovg_videos/iniciativa-em-redes-quanticas-e-suas-aplicacoes-no-instituto-tecnologico-de-aeronautica/',
|
||
'/aiovg_videos/superconducting-quantum-interference-devices-potential-applications-in-air-defense/',
|
||
'/aiovg_videos/estimating-changes-in-radiation-exposure-and-the-risk-zones-size-during-an-urban-release-event/',
|
||
'/aiovg_videos/modelo-de-estimativa-de-forca-para-interdicao-de-alvos-lineares-por-sistemas-de-armas-ar-superficie/',
|
||
'/aiovg_videos/metodologia-para-estimativa-de-pico-de-sobrepressao-a-partir-de-video-em-alta-velocidade-por-diferenciacao-numerica/',
|
||
'/aiovg_videos/probabilidade-de-impacto-de-tiro-unico-em-alvo-poligonal/',
|
||
'/aiovg_videos/digital-twins-in-military-operations-optimizing-logistics-and-responsiveness-in-conflict-zones/',
|
||
'/aiovg_videos/construcao-de-um-modelo-de-simulacao-integrada-com-ontologias-para-manutencao-prescritiva/',
|
||
'/aiovg_videos/otimizacao-da-probabilidade-de-sucesso-em-missoes-de-busca-por-aeronaves-desaparecidas/',
|
||
'/aiovg_videos/reference-values-for-damage-predictions-of-reinforced-concrete-slabs-subjected-to-blast-from-field-tests/',
|
||
'/aiovg_videos/simulacao-da-decomposicao-termica-por-rmd-da-substituicao-total-do-pblh-por-oleo-de-mamona-em-formulacoes-propelentes-a-base-de-boro/',
|
||
'/aiovg_videos/ativacao-mecanoquimica-do-sistema-mgo-al2o3-sio2-diferentes-precurso-res-de-aluminio-diferentes-caminhos-reacionais/',
|
||
'/aiovg_videos/sensoriamento-remoto-utilizando-radares-sar-embarcados-em-satelites-principios-basicos-tecnologias-desempenho-e-aplicacoes-em-satelites-que-operam-em-bandas-l-c-e-x/',
|
||
'/aiovg_videos/breve-discussao-sobre-as-diferentes-abordagens-de-utilizacao-das-tecnicas-fmea-e-fta-em-processos-aplicados-nas-industrias-espacial-e-aeronautica/',
|
||
'/aiovg_videos/enhancing-satellite-operations-through-datasat-a-study-on-noise-mitigation-systems-within-the-ada-framework/',
|
||
'/aiovg_videos/selecao-de-pilotos-para-missoes-das-unidades-aereas-da-fab-proposta-multimetodologica/',
|
||
'/aiovg_videos/decisao-estrategica-e-complexidade-aplicacao-da-soft-systems-methodology-ssm-na-aquisicao-de-aeronaves-para-a-forca-aerea/',
|
||
'/aiovg_videos/a-crise-yanomami-uma-abordagem-do-sistema-logistico-com-o-value-focused-thinking-vft/',
|
||
'/aiovg_videos/otimizacao-do-planejamento-de-download-de-imagens-obtidas-por-satelites-de-observacao-da-terra-utilizando-simulated-annealing/',
|
||
'/aiovg_videos/ucas-doa-with-reduced-number-of-sensors-and-small-sample-support-via-beamspace-harmonics-decomposition-and-root-music-algorithm/',
|
||
'/aiovg_videos/arma-laser-para-destruicao-de-rpas-analise-experimental-da-interacao-das-fibras-de-carbono-de-aramida-e-de-vidro-com-irradiacao-laser-de-107-%c2%b5m/',
|
||
'/aiovg_videos/estudo-de-um-composito-magnetico-poroso-para-alta-absorcao-em-micro-ondas-para-a-banda-ka/',
|
||
'/aiovg_videos/enhancing-brazilian-aerospace-systems-lifecycle-directive/',
|
||
'/aiovg_videos/pesquisa-comparativa-de-sistemas-militares-aplicada-a-sistemas-de-aeronaves-remotamente-pilotadas/',
|
||
'/aiovg_videos/requisitos-para-um-sistema-de-aeronave-remotamente-pilotada-de-ataque/',
|
||
'/aiovg_videos/modeling-of-a-data-modification-cyber-attack-in-an-iec-61850-scenario-using-stochastic-colored-petri-nets/',
|
||
'/aiovg_videos/desenvolvimento-de-um-sistema-de-comando-e-controle-de-conceito-expandido-com-deteccao-sensorial-automatica/',
|
||
'/aiovg_videos/autenticacao-de-usuarios-com-wi-fi-csi-uma-fonte-estrategica-para-inteligencia/',
|
||
'/aiovg_videos/otimizacao-logistica-em-operacoes-militares-remotas-um-modelo-para-os-pelotoes-especiais-de-fronteira/',
|
||
'/aiovg_videos/proposta-de-framework-para-o-desenvolvimento-integrado-de-sistemas-de-defesa-de-alta-complexidade-tecnologica/',
|
||
'/aiovg_videos/proposta-de-framework-para-o-desenvolvimento-integrado-de-sistemas-de-defesa-de-alta-complexidade-tecnologica/',
|
||
'/aiovg_videos/analysis-of-digital-radio-frequency-memory-signals-in-radar-receivers/',
|
||
'/aiovg_videos/single-antenna-passive-synthetic-aperture-doa-estimation/',
|
||
'/aiovg_videos/emprego-da-stft-e-da-cnn-na-classificacao-automatica-de-sinais-radar-de-baixa-probabilidade-de-interceptacao/',
|
||
'/aiovg_videos/estudo-do-desempenho-aerodinamico-de-scramjets-usando-redes-neurais-profundas/',
|
||
'/aiovg_videos/modelo-para-a-transferencia-de-tecnologia-em-offset-de-defesa-uma-revisao-integrativa-e-o-uso-da-linguagem-uml/',
|
||
'/aiovg_videos/sistema-de-aprendizado-de-maquina-como-apoio-ao-monitoramento-da-saude-estrutural-de-aeronaves/',
|
||
'/aiovg_videos/avaliacao-dimensional-de-pecas-fabricadas-por-manufatura-aditiva-para-aplicacao-em-veiculos-autonomos/',
|
||
'/aiovg_videos/simulacao-de-blindagem-contra-radiacao-ionizante-em-satelites-de-orbita-baixa-leo/',
|
||
'/aiovg_videos/model-based-design-methodology-applied-to-software-defined-radio-based-ew-receiver/',
|
||
'/aiovg_videos/calibracao-radiometrica-de-sensor-eletro-optico-em-laboratorio/',
|
||
'/aiovg_videos/prototipagem-de-um-concentrador-de-sinais-seriais-para-integracao-de-sistemas-navais/',
|
||
'/aiovg_videos/optimized-simulation-for-radio-transmission-project/',
|
||
'/aiovg_videos/improving-data-center-efficiency-a-combinatorial-optimization-framework-for-resource-allocation/',
|
||
'/aiovg_videos/avaliacao-da-safe-escape-manoeuvre-de-aeronaves-lancando-armamentos-ar-superficie/',
|
||
'/aiovg_videos/manobra-winding-defesa-contra-misseis-passivos-e-semiativos-superficie-ar/',
|
||
'/aiovg_videos/avaliacao-de-ameacas-com-decisao-em-tres-vias-no-combate-aereo-alem-do-alcance-visual/',
|
||
'/aiovg_videos/nova-metodologia-hibrida-a-partir-dos-metodos-de-decisao-multicriterio-merec-e-spotis-para-ordenacao-das-melhores-aeronaves-de-patrulha-maritima-nas-operacoes-antissubmarino-do-mundo/',
|
||
'/aiovg_videos/evaluation-of-a-u-net-based-method-for-segmenting-unauthorized-airstrips-in-the-amazon-rainforest-using-sar-imagery/',
|
||
'/aiovg_videos/analise-da-interacao-entre-o-tamanho-do-alvo-e-desempenho-na-deteccao-automatica-de-embarcacoes-em-imagens-sar-utilizando-yolov8-modificada/',
|
||
'/aiovg_videos/deteccao-automatica-de-pistas-de-pouso-clandestinas-na-amazonia-utilizando-tecnicas-de-aprendizado-de-maquina/'
|
||
];
|
||
|
||
$client = new BetaAnalyticsDataClient(['credentials' => $service_account_key_file_path]);
|
||
$property_id = '436681896';
|
||
|
||
$total_screen_views = 0;
|
||
$total_file_downloads = 0;
|
||
$count = count($urls);
|
||
|
||
foreach ($urls as $url) {
|
||
$request = (new RunReportRequest())
|
||
->setProperty('properties/' . $property_id)
|
||
->setDateRanges([new DateRange(['start_date' => '2024-01-01', 'end_date' => '2025-01-01'])])
|
||
->setMetrics([
|
||
new Metric(['name' => 'screenPageViews']),
|
||
new Metric(['name' => 'eventCount'])
|
||
])
|
||
->setDimensions([new Dimension(['name' => 'pagePath']), new Dimension(['name' => 'eventName'])])
|
||
->setDimensionFilter(new \Google\Analytics\Data\V1beta\FilterExpression([
|
||
'filter' => new \Google\Analytics\Data\V1beta\Filter([
|
||
'field_name' => 'pagePath',
|
||
'string_filter' => new \Google\Analytics\Data\V1beta\Filter\StringFilter([
|
||
'match_type' => \Google\Analytics\Data\V1beta\Filter\StringFilter\MatchType::EXACT,
|
||
'value' => $url
|
||
])
|
||
])
|
||
]));
|
||
|
||
$response = $client->runReport($request);
|
||
foreach ($response->getRows() as $row) {
|
||
$eventName = $row->getDimensionValues()[1]->getValue();
|
||
if ($eventName === 'page_view') {
|
||
$total_screen_views += $row->getMetricValues()[0]->getValue();
|
||
}
|
||
if ($eventName === 'file_download') {
|
||
$total_file_downloads += $row->getMetricValues()[1]->getValue();
|
||
}
|
||
}
|
||
}
|
||
|
||
$average_screen_views = $count > 0 ? $total_screen_views / $count : 0;
|
||
$average_file_downloads = $count > 0 ? $total_file_downloads / $count : 0;
|
||
|
||
$metrics = [
|
||
'average_screen_views' => $average_screen_views,
|
||
'average_file_downloads' => $average_file_downloads
|
||
];
|
||
|
||
// Save to database
|
||
$serialized_data = maybe_serialize($metrics);
|
||
$wpdb->replace(
|
||
$table_name,
|
||
[
|
||
'function_name' => $function_name,
|
||
'data' => $serialized_data,
|
||
'last_updated' => current_time('mysql')
|
||
],
|
||
[
|
||
'%s',
|
||
'%s',
|
||
'%s'
|
||
]
|
||
);
|
||
|
||
return $metrics;
|
||
}
|
||
|
||
// Shortcode for Average Screen Views
|
||
function average_screen_views_articles_shortcode() {
|
||
global $service_account_key_file_path;
|
||
$metrics = calculate_average_metrics_articles($service_account_key_file_path);
|
||
return isset($metrics['average_screen_views']) ? round($metrics['average_screen_views']) : 0;
|
||
}
|
||
add_shortcode('average_screen_articles_views', 'average_screen_views_articles_shortcode');
|
||
|
||
// Shortcode for Average File Downloads
|
||
function average_file_downloads_articles_shortcode() {
|
||
global $service_account_key_file_path;
|
||
$metrics = calculate_average_metrics_articles($service_account_key_file_path);
|
||
return isset($metrics['average_file_downloads']) ? round($metrics['average_file_downloads']) : 0;
|
||
}
|
||
add_shortcode('average_file_articles_downloads', 'average_file_downloads_articles_shortcode');
|
||
|
||
// Function to calculate averages for posters with database storage
|
||
// Function to calculate averages for posters with database storage
|
||
function calculate_average_metrics_posters($service_account_key_file_path, $force_update = false) {
|
||
error_log("calculate_average_metrics_posters function called.");
|
||
|
||
global $wpdb;
|
||
$table_name = $wpdb->prefix . 'sige_analytics_data';
|
||
|
||
$function_name = 'calculate_average_metrics_posters';
|
||
|
||
$row = $wpdb->get_row($wpdb->prepare("SELECT data FROM $table_name WHERE function_name = %s", $function_name), ARRAY_A);
|
||
|
||
if ($row && !$force_update) {
|
||
$data = maybe_unserialize($row['data']);
|
||
error_log("Cached calculate_average_metrics_posters retrieved: " . print_r($data, true)); // Using print_r to convert array to string
|
||
return $data;
|
||
}
|
||
|
||
$urls = [
|
||
'/aiovg_videos/processing-and-technologies-applied-to-oxidizers-and-strategic-particles-for-rocket-propulsion/',
|
||
'/aiovg_videos/insarsight-um-banco-de-dados-para-operacoes-de-busca-e-salvamento-focado-em-destrocos-de-aeronaves/',
|
||
'/aiovg_videos/influencia-da-porosidade-nas-propriedades-eletromagneticas-de-ceramicas-zirconia-titania/',
|
||
'/aiovg_videos/estudo-do-potencial-de-atenuacao-eletromagnetico-de-compositos-hibridos-a-base-de-ferrita-de-cobre-e-titanio-na-banda-ka-parte-ii/',
|
||
'/aiovg_videos/avaliacao-de-desempenho-do-middleware-de-codigo-aberto-portico-para-simulacoes-distribuidas-de-tempo-real-utilizando-hla/',
|
||
'/aiovg_videos/large-language-models-llms-aplicados-a-atividade-de-inteligencia-militar/',
|
||
'/aiovg_videos/planejamento-da-mobilizacao-de-pessoal-para-a-missao-excon-tapio-utilizando-pesquisa-operacional/',
|
||
'/aiovg_videos/estudo-de-intermediarios-na-sintese-do-oxidante-dinitramida-de-amonio/',
|
||
'/aiovg_videos/monitoramento-de-radiacao-ionizante-com-drones-metodologia-utilizando-sensores-comerciais/',
|
||
'/aiovg_videos/estimativa-de-doses-radiologicas-em-aeronaves-expostas-a-plumas-radioativas/',
|
||
'/aiovg_videos/insights-sobre-o-mecanismo-de-sintese-do-dinitramida-de-amonio-adn-via-calculos-dft/',
|
||
'/aiovg_videos/avaliacao_eletromagnetica_do_radome_do_telescopio_pierre_kauffman/',
|
||
'/aiovg_videos/saete-c2-sistema-digital-operativo-aplicado-ao-comando-e-controle/',
|
||
'/aiovg_videos/desenvolvimento-de-uma-raia-virtual-de-tiro-para-a-marinha-do-brasil/',
|
||
'/aiovg_videos/integrating-theory-and-experimental-insights-into-g-c3n4-structures-for-enhanced-photocatalysis/',
|
||
'/aiovg_videos/avaliacao-da-distribuicao-de-dose-de-radiacao-cosmica-em-tripulantes-aeronauticos/',
|
||
'/aiovg_videos/anylogic-based-simulation-improving-fighter-aircraft-fleet-management/',
|
||
'/aiovg_videos/avaliacao-da-distribuicao-de-dose-de-radiacao-cosmica-em-tripulantes-aeronauticos-2/',
|
||
'/aiovg_videos/dosimetria-da-radiacao-cosmica-em-tripulacoes-por-meio-da-tecnica-de-dosimetria-termoluminescente-tl/',
|
||
'/aiovg_videos/deteccao-proativa-de-intrusos-em-redes-wi-fi-utilizando-csi-e-machine-learning/'
|
||
];
|
||
|
||
$client = new BetaAnalyticsDataClient(['credentials' => $service_account_key_file_path]);
|
||
$property_id = '436681896';
|
||
|
||
$total_screen_views = 0;
|
||
$total_file_downloads = 0;
|
||
$count = count($urls);
|
||
|
||
foreach ($urls as $url) {
|
||
$request = (new RunReportRequest())
|
||
->setProperty('properties/' . $property_id)
|
||
->setDateRanges([new DateRange(['start_date' => '2024-01-01', 'end_date' => '2025-01-01'])])
|
||
->setMetrics([
|
||
new Metric(['name' => 'screenPageViews']),
|
||
new Metric(['name' => 'eventCount'])
|
||
])
|
||
->setDimensions([new Dimension(['name' => 'pagePath']), new Dimension(['name' => 'eventName'])])
|
||
->setDimensionFilter(new \Google\Analytics\Data\V1beta\FilterExpression([
|
||
'filter' => new \Google\Analytics\Data\V1beta\Filter([
|
||
'field_name' => 'pagePath',
|
||
'string_filter' => new \Google\Analytics\Data\V1beta\Filter\StringFilter([
|
||
'match_type' => \Google\Analytics\Data\V1beta\Filter\StringFilter\MatchType::EXACT,
|
||
'value' => $url
|
||
])
|
||
])
|
||
]));
|
||
|
||
$response = $client->runReport($request);
|
||
foreach ($response->getRows() as $row) {
|
||
$eventName = $row->getDimensionValues()[1]->getValue();
|
||
if ($eventName === 'page_view') {
|
||
$total_screen_views += $row->getMetricValues()[0]->getValue();
|
||
}
|
||
if ($eventName === 'file_download') {
|
||
$total_file_downloads += $row->getMetricValues()[1]->getValue();
|
||
}
|
||
}
|
||
}
|
||
|
||
$average_screen_views = $count > 0 ? $total_screen_views / $count : 0;
|
||
$average_file_downloads = $count > 0 ? $total_file_downloads / $count : 0;
|
||
|
||
$metrics = [
|
||
'average_screen_views' => $average_screen_views,
|
||
'average_file_downloads' => $average_file_downloads
|
||
];
|
||
|
||
// Save to database
|
||
$serialized_data = maybe_serialize($metrics);
|
||
$wpdb->replace(
|
||
$table_name,
|
||
[
|
||
'function_name' => $function_name,
|
||
'data' => $serialized_data,
|
||
'last_updated' => current_time('mysql')
|
||
],
|
||
[
|
||
'%s',
|
||
'%s',
|
||
'%s'
|
||
]
|
||
);
|
||
|
||
return $metrics;
|
||
}
|
||
|
||
// Shortcode for Average Screen Views for Posters
|
||
function average_screen_views_posters_shortcode() {
|
||
global $service_account_key_file_path;
|
||
$metrics = calculate_average_metrics_posters($service_account_key_file_path);
|
||
return isset($metrics['average_screen_views']) ? round($metrics['average_screen_views']) : 0;
|
||
}
|
||
add_shortcode('average_screen_posters_views', 'average_screen_views_posters_shortcode');
|
||
|
||
// Shortcode for Average File Downloads for Posters
|
||
function average_file_downloads_posters_shortcode() {
|
||
global $service_account_key_file_path;
|
||
$metrics = calculate_average_metrics_posters($service_account_key_file_path);
|
||
return isset($metrics['average_file_downloads']) ? round($metrics['average_file_downloads']) : 0;
|
||
}
|
||
add_shortcode('average_file_posters_downloads', 'average_file_downloads_posters_shortcode');
|
||
|
||
// Function to calculate total views with database storage
|
||
// Function to calculate total views with database storage
|
||
function calculate_total_views_of_works($service_account_key_file_path, $force_update = false) {
|
||
|
||
error_log("calculate_total_views_of_works function called.");
|
||
|
||
global $wpdb;
|
||
$table_name = $wpdb->prefix . 'sige_analytics_data';
|
||
|
||
$function_name = 'calculate_total_views_of_works';
|
||
|
||
$row = $wpdb->get_row($wpdb->prepare("SELECT data FROM $table_name WHERE function_name = %s", $function_name), ARRAY_A);
|
||
|
||
if ($row && !$force_update) {
|
||
$total_screen_views = maybe_unserialize($row['data']);
|
||
error_log("Cached total_screen_views retrieved: " . $total_screen_views);
|
||
|
||
return $total_screen_views;
|
||
} else {
|
||
error_log("No cached data found or force_update is true. Recalculating total_screen_views.");
|
||
}
|
||
|
||
$urls = [
|
||
'/aiovg_videos/iniciativa-em-redes-quanticas-e-suas-aplicacoes-no-instituto-tecnologico-de-aeronautica/',
|
||
'/aiovg_videos/superconducting-quantum-interference-devices-potential-applications-in-air-defense/',
|
||
'/aiovg_videos/estimating-changes-in-radiation-exposure-and-the-risk-zones-size-during-an-urban-release-event/',
|
||
'/aiovg_videos/modelo-de-estimativa-de-forca-para-interdicao-de-alvos-lineares-por-sistemas-de-armas-ar-superficie/',
|
||
'/aiovg_videos/metodologia-para-estimativa-de-pico-de-sobrepressao-a-partir-de-video-em-alta-velocidade-por-diferenciacao-numerica/',
|
||
'/aiovg_videos/probabilidade-de-impacto-de-tiro-unico-em-alvo-poligonal/',
|
||
'/aiovg_videos/digital-twins-in-military-operations-optimizing-logistics-and-responsiveness-in-conflict-zones/',
|
||
'/aiovg_videos/construcao-de-um-modelo-de-simulacao-integrada-com-ontologias-para-manutencao-prescritiva/',
|
||
'/aiovg_videos/otimizacao-da-probabilidade-de-sucesso-em-missoes-de-busca-por-aeronaves-desaparecidas/',
|
||
'/aiovg_videos/reference-values-for-damage-predictions-of-reinforced-concrete-slabs-subjected-to-blast-from-field-tests/',
|
||
'/aiovg_videos/simulacao-da-decomposicao-termica-por-rmd-da-substituicao-total-do-pblh-por-oleo-de-mamona-em-formulacoes-propelentes-a-base-de-boro/',
|
||
'/aiovg_videos/ativacao-mecanoquimica-do-sistema-mgo-al2o3-sio2-diferentes-precurso-res-de-aluminio-diferentes-caminhos-reacionais/',
|
||
'/aiovg_videos/sensoriamento-remoto-utilizando-radares-sar-embarcados-em-satelites-principios-basicos-tecnologias-desempenho-e-aplicacoes-em-satelites-que-operam-em-bandas-l-c-e-x/',
|
||
'/aiovg_videos/breve-discussao-sobre-as-diferentes-abordagens-de-utilizacao-das-tecnicas-fmea-e-fta-em-processos-aplicados-nas-industrias-espacial-e-aeronautica/',
|
||
'/aiovg_videos/enhancing-satellite-operations-through-datasat-a-study-on-noise-mitigation-systems-within-the-ada-framework/',
|
||
'/aiovg_videos/selecao-de-pilotos-para-missoes-das-unidades-aereas-da-fab-proposta-multimetodologica/',
|
||
'/aiovg_videos/decisao-estrategica-e-complexidade-aplicacao-da-soft-systems-methodology-ssm-na-aquisicao-de-aeronaves-para-a-forca-aerea/',
|
||
'/aiovg_videos/a-crise-yanomami-uma-abordagem-do-sistema-logistico-com-o-value-focused-thinking-vft/',
|
||
'/aiovg_videos/otimizacao-do-planejamento-de-download-de-imagens-obtidas-por-satelites-de-observacao-da-terra-utilizando-simulated-annealing/',
|
||
'/aiovg_videos/ucas-doa-with-reduced-number-of-sensors-and-small-sample-support-via-beamspace-harmonics-decomposition-and-root-music-algorithm/',
|
||
'/aiovg_videos/arma-laser-para-destruicao-de-rpas-analise-experimental-da-interacao-das-fibras-de-carbono-de-aramida-e-de-vidro-com-irradiacao-laser-de-107-%c2%b5m/',
|
||
'/aiovg_videos/estudo-de-um-composito-magnetico-poroso-para-alta-absorcao-em-micro-ondas-para-a-banda-ka/',
|
||
'/aiovg_videos/enhancing-brazilian-aerospace-systems-lifecycle-directive/',
|
||
'/aiovg_videos/pesquisa-comparativa-de-sistemas-militares-aplicada-a-sistemas-de-aeronaves-remotamente-pilotadas/',
|
||
'/aiovg_videos/requisitos-para-um-sistema-de-aeronave-remotamente-pilotada-de-ataque/',
|
||
'/aiovg_videos/modeling-of-a-data-modification-cyber-attack-in-an-iec-61850-scenario-using-stochastic-colored-petri-nets/',
|
||
'/aiovg_videos/desenvolvimento-de-um-sistema-de-comando-e-controle-de-conceito-expandido-com-deteccao-sensorial-automatica/',
|
||
'/aiovg_videos/autenticacao-de-usuarios-com-wi-fi-csi-uma-fonte-estrategica-para-inteligencia/',
|
||
'/aiovg_videos/otimizacao-logistica-em-operacoes-militares-remotas-um-modelo-para-os-pelotoes-especiais-de-fronteira/',
|
||
'/aiovg_videos/proposta-de-framework-para-o-desenvolvimento-integrado-de-sistemas-de-defesa-de-alta-complexidade-tecnologica/',
|
||
'/aiovg_videos/proposta-de-framework-para-o-desenvolvimento-integrado-de-sistemas-de-defesa-de-alta-complexidade-tecnologica/',
|
||
'/aiovg_videos/analysis-of-digital-radio-frequency-memory-signals-in-radar-receivers/',
|
||
'/aiovg_videos/single-antenna-passive-synthetic-aperture-doa-estimation/',
|
||
'/aiovg_videos/emprego-da-stft-e-da-cnn-na-classificacao-automatica-de-sinais-radar-de-baixa-probabilidade-de-interceptacao/',
|
||
'/aiovg_videos/estudo-do-desempenho-aerodinamico-de-scramjets-usando-redes-neurais-profundas/',
|
||
'/aiovg_videos/modelo-para-a-transferencia-de-tecnologia-em-offset-de-defesa-uma-revisao-integrativa-e-o-uso-da-linguagem-uml/',
|
||
'/aiovg_videos/sistema-de-aprendizado-de-maquina-como-apoio-ao-monitoramento-da-saude-estrutural-de-aeronaves/',
|
||
'/aiovg_videos/avaliacao-dimensional-de-pecas-fabricadas-por-manufatura-aditiva-para-aplicacao-em-veiculos-autonomos/',
|
||
'/aiovg_videos/simulacao-de-blindagem-contra-radiacao-ionizante-em-satelites-de-orbita-baixa-leo/',
|
||
'/aiovg_videos/model-based-design-methodology-applied-to-software-defined-radio-based-ew-receiver/',
|
||
'/aiovg_videos/calibracao-radiometrica-de-sensor-eletro-optico-em-laboratorio/',
|
||
'/aiovg_videos/prototipagem-de-um-concentrador-de-sinais-seriais-para-integracao-de-sistemas-navais/',
|
||
'/aiovg_videos/optimized-simulation-for-radio-transmission-project/',
|
||
'/aiovg_videos/improving-data-center-efficiency-a-combinatorial-optimization-framework-for-resource-allocation/',
|
||
'/aiovg_videos/avaliacao-da-safe-escape-manoeuvre-de-aeronaves-lancando-armamentos-ar-superficie/',
|
||
'/aiovg_videos/manobra-winding-defesa-contra-misseis-passivos-e-semiativos-superficie-ar/',
|
||
'/aiovg_videos/avaliacao-de-ameacas-com-decisao-em-tres-vias-no-combate-aereo-alem-do-alcance-visual/',
|
||
'/aiovg_videos/nova-metodologia-hibrida-a-partir-dos-metodos-de-decisao-multicriterio-merec-e-spotis-para-ordenacao-das-melhores-aeronaves-de-patrulha-maritima-nas-operacoes-antissubmarino-do-mundo/',
|
||
'/aiovg_videos/evaluation-of-a-u-net-based-method-for-segmenting-unauthorized-airstrips-in-the-amazon-rainforest-using-sar-imagery/',
|
||
'/aiovg_videos/analise-da-interacao-entre-o-tamanho-do-alvo-e-desempenho-na-deteccao-automatica-de-embarcacoes-em-imagens-sar-utilizando-yolov8-modificada/',
|
||
'/aiovg_videos/deteccao-automatica-de-pistas-de-pouso-clandestinas-na-amazonia-utilizando-tecnicas-de-aprendizado-de-maquina/',
|
||
'/aiovg_videos/processing-and-technologies-applied-to-oxidizers-and-strategic-particles-for-rocket-propulsion/',
|
||
'/aiovg_videos/insarsight-um-banco-de-dados-para-operacoes-de-busca-e-salvamento-focado-em-destrocos-de-aeronaves/',
|
||
'/aiovg_videos/influencia-da-porosidade-nas-propriedades-eletromagneticas-de-ceramicas-zirconia-titania/',
|
||
'/aiovg_videos/estudo-do-potencial-de-atenuacao-eletromagnetico-de-compositos-hibridos-a-base-de-ferrita-de-cobre-e-titanio-na-banda-ka-parte-ii/',
|
||
'/aiovg_videos/avaliacao-de-desempenho-do-middleware-de-codigo-aberto-portico-para-simulacoes-distribuidas-de-tempo-real-utilizando-hla/',
|
||
'/aiovg_videos/large-language-models-llms-aplicados-a-atividade-de-inteligencia-militar/',
|
||
'/aiovg_videos/planejamento-da-mobilizacao-de-pessoal-para-a-missao-excon-tapio-utilizando-pesquisa-operacional/',
|
||
'/aiovg_videos/estudo-de-intermediarios-na-sintese-do-oxidante-dinitramida-de-amonio/',
|
||
'/aiovg_videos/monitoramento-de-radiacao-ionizante-com-drones-metodologia-utilizando-sensores-comerciais/',
|
||
'/aiovg_videos/estimativa-de-doses-radiologicas-em-aeronaves-expostas-a-plumas-radioativas/',
|
||
'/aiovg_videos/insights-sobre-o-mecanismo-de-sintese-do-dinitramida-de-amonio-adn-via-calculos-dft/',
|
||
'/aiovg_videos/avaliacao_eletromagnetica_do_radome_do_telescopio_pierre_kauffman/',
|
||
'/aiovg_videos/saete-c2-sistema-digital-operativo-aplicado-ao-comando-e-controle/',
|
||
'/aiovg_videos/desenvolvimento-de-uma-raia-virtual-de-tiro-para-a-marinha-do-brasil/',
|
||
'/aiovg_videos/integrating-theory-and-experimental-insights-into-g-c3n4-structures-for-enhanced-photocatalysis/',
|
||
'/aiovg_videos/avaliacao-da-distribuicao-de-dose-de-radiacao-cosmica-em-tripulantes-aeronauticos/',
|
||
'/aiovg_videos/anylogic-based-simulation-improving-fighter-aircraft-fleet-management/',
|
||
'/aiovg_videos/avaliacao-da-distribuicao-de-dose-de-radiacao-cosmica-em-tripulantes-aeronauticos-2/',
|
||
'/aiovg_videos/dosimetria-da-radiacao-cosmica-em-tripulacoes-por-meio-da-tecnica-de-dosimetria-termoluminescente-tl/',
|
||
'/aiovg_videos/deteccao-proativa-de-intrusos-em-redes-wi-fi-utilizando-csi-e-machine-learning/'
|
||
];
|
||
|
||
$client = new BetaAnalyticsDataClient(['credentials' => $service_account_key_file_path]);
|
||
$property_id = '436681896';
|
||
|
||
$total_screen_views = 0;
|
||
|
||
foreach ($urls as $url) {
|
||
$request = (new RunReportRequest())
|
||
->setProperty('properties/' . $property_id)
|
||
->setDateRanges([new DateRange(['start_date' => '2024-01-01', 'end_date' => '2025-01-01'])])
|
||
->setMetrics([new Metric(['name' => 'screenPageViews'])])
|
||
->setDimensions([new Dimension(['name' => 'pagePath']), new Dimension(['name' => 'eventName'])])
|
||
->setDimensionFilter(new \Google\Analytics\Data\V1beta\FilterExpression([
|
||
'filter' => new \Google\Analytics\Data\V1beta\Filter([
|
||
'field_name' => 'pagePath',
|
||
'string_filter' => new \Google\Analytics\Data\V1beta\Filter\StringFilter([
|
||
'match_type' => \Google\Analytics\Data\V1beta\Filter\StringFilter\MatchType::EXACT,
|
||
'value' => $url
|
||
])
|
||
])
|
||
]));
|
||
|
||
$response = $client->runReport($request);
|
||
foreach ($response->getRows() as $row) {
|
||
$eventName = $row->getDimensionValues()[1]->getValue();
|
||
if ($eventName === 'page_view') {
|
||
$total_screen_views += $row->getMetricValues()[0]->getValue();
|
||
}
|
||
}
|
||
}
|
||
|
||
// Save to database
|
||
$serialized_data = maybe_serialize($total_screen_views);
|
||
$wpdb->replace(
|
||
$table_name,
|
||
[
|
||
'function_name' => $function_name,
|
||
'data' => $serialized_data,
|
||
'last_updated' => current_time('mysql')
|
||
],
|
||
[
|
||
'%s',
|
||
'%s',
|
||
'%s'
|
||
]
|
||
);
|
||
|
||
return $total_screen_views;
|
||
error_log("Total screen views saved to database: " . $total_screen_views);
|
||
|
||
}
|
||
|
||
// Shortcode for Total Screen Views
|
||
function total_views_of_works_shortcode() {
|
||
global $service_account_key_file_path;
|
||
error_log("total_views_of_works_shortcode called.");
|
||
|
||
$total_screen_views = calculate_total_views_of_works($service_account_key_file_path);
|
||
return $total_screen_views;
|
||
}
|
||
add_shortcode('total_views_of_works', 'total_views_of_works_shortcode');
|
||
|
||
// Shortcode to display the graphs
|
||
function sige_analytics_graphs_shortcode() {
|
||
global $wpdb;
|
||
|
||
// Fetch data for the first graph (unique users by region)
|
||
$query1 = "
|
||
SELECT um.meta_value as regiao_do_brasil, COUNT(DISTINCT e.user_id) as count
|
||
FROM {$wpdb->prefix}sige_enrollments e
|
||
LEFT JOIN {$wpdb->prefix}usermeta um ON e.user_id = um.user_id AND um.meta_key = 'regiao_do_brasil'
|
||
GROUP BY um.meta_value
|
||
";
|
||
$results1 = $wpdb->get_results($query1, ARRAY_A);
|
||
|
||
// Prepare data for the first chart
|
||
$regions = ['Norte', 'Nordeste', 'Centro-Oeste', 'Sudeste', 'Sul'];
|
||
$data1 = array_fill_keys($regions, 0);
|
||
|
||
foreach ($results1 as $row) {
|
||
if (in_array($row['regiao_do_brasil'], $regions)) {
|
||
$data1[$row['regiao_do_brasil']] = (int) $row['count'];
|
||
}
|
||
}
|
||
|
||
// Convert data to arrays for Chart.js
|
||
$labels1 = array_keys($data1);
|
||
$counts1 = array_values($data1);
|
||
|
||
// Fetch data for the second graph (formacao_academica by region)
|
||
$query2 = "
|
||
SELECT
|
||
fa.meta_value as formacao_academica,
|
||
rb.meta_value as regiao_do_brasil,
|
||
COUNT(DISTINCT e.user_id) as count
|
||
FROM {$wpdb->prefix}sige_enrollments e
|
||
LEFT JOIN {$wpdb->prefix}usermeta fa ON e.user_id = fa.user_id AND fa.meta_key = 'formacao_academica'
|
||
LEFT JOIN {$wpdb->prefix}usermeta rb ON e.user_id = rb.user_id AND rb.meta_key = 'regiao_do_brasil'
|
||
GROUP BY fa.meta_value, rb.meta_value
|
||
";
|
||
$results2 = $wpdb->get_results($query2, ARRAY_A);
|
||
|
||
// Prepare data for the second chart
|
||
$formacoes = ['Aluno de Graduação', 'Aluno de Pós-Graduação', 'Professor da Educação Básica', 'Professor/Pesquisador', 'Outros'];
|
||
$regions = ['Norte', 'Nordeste', 'Centro-Oeste', 'Sudeste', 'Sul'];
|
||
$data2 = [];
|
||
foreach ($formacoes as $formacao) {
|
||
$data2[$formacao] = array_fill_keys($regions, 0);
|
||
}
|
||
|
||
foreach ($results2 as $row) {
|
||
if (in_array($row['formacao_academica'], $formacoes)) {
|
||
$region = $row['regiao_do_brasil'];
|
||
if (array_key_exists($region, $data2[$row['formacao_academica']])) {
|
||
$data2[$row['formacao_academica']][$region] += (int) $row['count'];
|
||
}
|
||
}
|
||
}
|
||
|
||
// Prepare datasets for the second chart
|
||
$labels2 = array_keys($data2[$formacoes[0]]); // Regions
|
||
$datasets2 = [];
|
||
foreach ($data2 as $formacao => $counts) {
|
||
$datasets2[] = [
|
||
'label' => $formacao,
|
||
'data' => array_values($counts),
|
||
'backgroundColor' => 'rgba(' . rand(0, 255) . ',' . rand(0, 255) . ',' . rand(0, 255) . ',0.2)',
|
||
'borderColor' => 'rgba(' . rand(0, 255) . ',' . rand(0, 255) . ',' . rand(0, 255) . ',1)',
|
||
'borderWidth' => 1
|
||
];
|
||
}
|
||
|
||
// Fetch data for the third graph (In-person vs Online Enrollment)
|
||
$query3_in_person = "
|
||
SELECT DISTINCT e.user_id
|
||
FROM {$wpdb->prefix}sige_enrollments e
|
||
LEFT JOIN {$wpdb->prefix}sige_activities a ON e.activity_id = a.id
|
||
WHERE a.modality IN ('In-person', 'Hybrid')
|
||
AND e.status NOT IN ('Not Approved', 'Enrollment Canceled by User','Waiting List','Under Analysis')
|
||
";
|
||
$query3_online = "
|
||
SELECT COUNT(DISTINCT e.user_id) as count
|
||
FROM {$wpdb->prefix}sige_enrollments e
|
||
LEFT JOIN {$wpdb->prefix}sige_activities a ON e.activity_id = a.id
|
||
WHERE e.user_id NOT IN (
|
||
SELECT DISTINCT e.user_id
|
||
FROM {$wpdb->prefix}sige_enrollments e
|
||
LEFT JOIN {$wpdb->prefix}sige_activities a ON e.activity_id = a.id
|
||
WHERE a.modality IN ('In-person', 'Hybrid')
|
||
AND e.status NOT IN ('Not Approved', 'Enrollment Canceled by User','Waiting List','Under Analysis')
|
||
)
|
||
AND e.status NOT IN ('Not Approved', 'Enrollment Canceled by User', 'Waiting List','Under Analysis')
|
||
";
|
||
$in_person_users = $wpdb->get_col($query3_in_person);
|
||
$online_count = $wpdb->get_var($query3_online);
|
||
|
||
// Prepare data for the third chart
|
||
$in_person_count = count($in_person_users);
|
||
$labels3 = ['In-person Enrollment', 'Online Enrollment'];
|
||
$counts3 = [$in_person_count, (int) $online_count];
|
||
|
||
// Enqueue Chart.js
|
||
wp_enqueue_script('chart-js', 'https://cdn.jsdelivr.net/npm/chart.js', [], null, true);
|
||
|
||
// Start output buffering
|
||
ob_start();
|
||
|
||
// Generate the HTML for the charts
|
||
echo '<div class="sige-analytics-graphs">';
|
||
echo '<div class="dashboard-grid" style="display: flex; flex-wrap: wrap; overflow-x: auto; gap: 20px;">';
|
||
|
||
// First chart
|
||
echo '<div class="dashboard-item" style="flex: 1 1 30%; min-width: 300px; background-color: #f0f0f0;
|
||
border: 1px solid #ccc; box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); padding: 20px;">
|
||
<canvas id="regionChart" width="400" height="300"></canvas>
|
||
</div>';
|
||
|
||
// Second chart
|
||
echo '<div class="dashboard-item" style="flex: 1 1 30%; min-width: 300px; background-color: #f0f0f0;
|
||
border: 1px solid #ccc; box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); padding: 20px;">
|
||
<canvas id="formacaoChart" width="400" height="300"></canvas>
|
||
</div>';
|
||
|
||
// Third chart
|
||
echo '<div class="dashboard-item" style="flex: 1 1 30%; min-width: 300px; background-color: #f0f0f0;
|
||
border: 1px solid #ccc; box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); padding: 20px;">
|
||
<canvas id="enrollmentChart" width="400" height="300"></canvas>
|
||
</div>';
|
||
|
||
echo '</div>'; // Close dashboard-grid
|
||
echo '</div>'; // Close sige-analytics-graphs
|
||
|
||
// Prepare data for JavaScript
|
||
$chart_data = [
|
||
'labels1' => $labels1,
|
||
'counts1' => $counts1,
|
||
'labels2' => $labels2,
|
||
'datasets2' => $datasets2,
|
||
'labels3' => $labels3,
|
||
'counts3' => $counts3,
|
||
];
|
||
|
||
// Localize the script with data
|
||
wp_register_script('sige-analytics-charts', '', [], null, true);
|
||
wp_enqueue_script('sige-analytics-charts');
|
||
wp_add_inline_script('sige-analytics-charts', 'var sigeChartData = ' . json_encode($chart_data) . ';');
|
||
|
||
// Output the JavaScript to render the charts
|
||
echo "<script>
|
||
document.addEventListener('DOMContentLoaded', function() {
|
||
// First chart
|
||
var ctx1 = document.getElementById('regionChart').getContext('2d');
|
||
var regionChart = new Chart(ctx1, {
|
||
type: 'bar',
|
||
data: {
|
||
labels: sigeChartData.labels1,
|
||
datasets: [{
|
||
label: 'Users by Region',
|
||
data: sigeChartData.counts1,
|
||
backgroundColor: [
|
||
'rgba(255, 99, 132, 0.2)',
|
||
'rgba(54, 162, 235, 0.2)',
|
||
'rgba(255, 206, 86, 0.2)',
|
||
'rgba(75, 192, 192, 0.2)',
|
||
'rgba(153, 102, 255, 0.2)'
|
||
],
|
||
borderColor: [
|
||
'rgba(255, 99, 132, 1)',
|
||
'rgba(54, 162, 235, 1)',
|
||
'rgba(255, 206, 86, 1)',
|
||
'rgba(75, 192, 192, 1)',
|
||
'rgba(153, 102, 255, 1)'
|
||
],
|
||
borderWidth: 1
|
||
}]
|
||
},
|
||
options: {
|
||
plugins: {
|
||
title: {
|
||
display: true,
|
||
text: 'Total In-Person Enrollments by Regions of Brazil'
|
||
}
|
||
},
|
||
scales: {
|
||
y: {
|
||
beginAtZero: true
|
||
}
|
||
}
|
||
}
|
||
});
|
||
|
||
// Second chart
|
||
var ctx2 = document.getElementById('formacaoChart').getContext('2d');
|
||
var formacaoChart = new Chart(ctx2, {
|
||
type: 'bar',
|
||
data: {
|
||
labels: sigeChartData.labels2,
|
||
datasets: sigeChartData.datasets2
|
||
},
|
||
options: {
|
||
plugins: {
|
||
title: {
|
||
display: true,
|
||
text: 'Total In-Person Enrollments by Academic Background'
|
||
}
|
||
},
|
||
scales: {
|
||
y: {
|
||
beginAtZero: true
|
||
}
|
||
}
|
||
}
|
||
});
|
||
|
||
// Third chart
|
||
var ctx3 = document.getElementById('enrollmentChart').getContext('2d');
|
||
var enrollmentChart = new Chart(ctx3, {
|
||
type: 'bar',
|
||
data: {
|
||
labels: sigeChartData.labels3,
|
||
datasets: [{
|
||
label: 'Enrollment Types',
|
||
data: sigeChartData.counts3,
|
||
backgroundColor: [
|
||
'rgba(75, 192, 192, 0.2)',
|
||
'rgba(153, 102, 255, 0.2)'
|
||
],
|
||
borderColor: [
|
||
'rgba(75, 192, 192, 1)',
|
||
'rgba(153, 102, 255, 1)'
|
||
],
|
||
borderWidth: 1
|
||
}]
|
||
},
|
||
options: {
|
||
plugins: {
|
||
title: {
|
||
display: true,
|
||
text: 'Total In-Person and Online Enrollments (Unique Users - Status: Approved)'
|
||
}
|
||
},
|
||
scales: {
|
||
y: {
|
||
beginAtZero: true
|
||
}
|
||
}
|
||
}
|
||
});
|
||
});
|
||
</script>";
|
||
|
||
// Return the output buffer content
|
||
return ob_get_clean();
|
||
}
|
||
add_shortcode('sige_analytics_graphs', 'sige_analytics_graphs_shortcode'); |