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 '
';
echo '
SIGE Analytics Extended
';
// Add custom styles
echo '';
echo '
';
echo '
About
';
echo '
Development Team:
';
echo '
- Leandro Geraldo da Costa - Lead Developer
';
echo '
';
echo '
';
echo '
Functions and Functionalities
';
echo '
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.
';
echo '
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.
';
echo '
';
echo '
';
echo '
Shortcodes and Their Uses
';
echo '
[page_views_counter] - Displays the total number of page views.
[file_downloads_counter] - Displays the total number of file downloads.
[average_screen_articles_views] - Shows the average number of screen views per article.
[average_file_articles_downloads] - Shows the average number of file downloads per article.
[average_screen_posters_views] - Shows the average number of screen views per poster.
[average_file_posters_downloads] - Shows the average number of file downloads per poster.
[total_views_of_works] - Displays the total number of views across all works.
[sige_analytics_graphs] - Displays the analytics graphs on the front-end.
';
echo '
Use these shortcodes in your posts or pages to display the corresponding analytics data.
';
echo '
';
echo '
';
}
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 "";
}
echo "";
}
// 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 '';
echo '
';
// First chart
echo '
';
// Second chart
echo '
';
// Third chart
echo '
';
echo '
'; // Close dashboard-grid
echo '
'; // 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 "";
// Return the output buffer content
return ob_get_clean();
}
add_shortcode('sige_analytics_graphs', 'sige_analytics_graphs_shortcode');