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