Files

1032 lines
52 KiB
PHP
Executable File
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?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 its 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');