$post_type_object) { if (! in_array($post_type, (array) $settings['post_types'], true)) { continue; } add_filter('manage_' . $post_type . '_posts_columns', array($this, 'add_column')); add_filter('manage_edit-' . $post_type . '_sortable_columns', array($this, 'add_sortable_column')); add_action('manage_' . $post_type . '_posts_custom_column', array($this, 'render_column'), 10, 2); } } /** * Render onboarding notice after activation. * * @return void */ public function render_onboarding_notice() { if (! current_user_can('manage_options')) { return; } if ('1' !== (string) get_option('a360_insights_show_onboarding', '')) { return; } $screen = function_exists('get_current_screen') ? get_current_screen() : null; $screen_id = $screen ? (string) $screen->id : ''; $allowed_screens = array_merge(array('dashboard', 'plugins'), $this->admin_page_hooks); if (! in_array($screen_id, $allowed_screens, true)) { return; } $dismiss_url = wp_nonce_url( admin_url('admin-post.php?action=a360_insights_dismiss_onboarding'), 'a360_insights_dismiss_onboarding' ); ?>

string('views')) . '" aria-label="' . esc_attr($this->string('views')) . '">'; return $columns; } /** * Make views column sortable. * * @param array $columns Sortable columns. * @return array */ public function add_sortable_column($columns) { $columns['a360_insights_views'] = 'a360_insights_views'; return $columns; } /** * Render column. * * @param string $column Column. * @param int $post_id Post ID. * @return void */ public function render_column($column, $post_id) { if ('a360_insights_views' !== $column) { return; } $total = A360_Insights_DB::get_total_views($post_id); printf( '', absint($post_id), esc_attr(get_the_title($post_id)), absint($total) ); } /** * Handle sorting by views column. * * @param WP_Query $query Query object. * @return void */ public function handle_views_sorting($query) { if (! is_admin() || ! $query->is_main_query()) { return; } if ('a360_insights_views' !== $query->get('orderby')) { return; } add_filter('posts_clauses', array($this, 'sort_by_views_clauses'), 10, 2); } /** * Modify posts query to sort by total views. * * @param array $clauses Query clauses. * @param WP_Query $query Query object. * @return array */ public function sort_by_views_clauses($clauses, $query) { if ('a360_insights_views' !== $query->get('orderby')) { return $clauses; } global $wpdb; $table_name = A360_Insights_DB::table_name(); $order = 'ASC' === strtoupper((string) $query->get('order')) ? 'ASC' : 'DESC'; $clauses['join'] .= " LEFT JOIN ( SELECT post_id, COUNT(*) AS a360_views FROM {$table_name} GROUP BY post_id ) AS a360_counts ON {$wpdb->posts}.ID = a360_counts.post_id"; $clauses['orderby'] = "COALESCE(a360_counts.a360_views, 0) {$order}, {$wpdb->posts}.post_date DESC"; return $clauses; } /** * Enqueue admin assets. * * @param string $hook Hook. * @return void */ public function enqueue_assets($hook) { $is_posts_screen = 'edit.php' === $hook; $is_dashboard = 'index.php' === $hook; $is_settings_screen = in_array($hook, $this->admin_page_hooks, true); if (! $is_posts_screen && ! $is_dashboard && ! $is_settings_screen) { return; } wp_enqueue_script( 'chart-js', A360_INSIGHTS_URL . 'assets/chart.js', array(), '4.5.1', true ); $admin_css_path = A360_INSIGHTS_PATH . 'assets/admin.css'; $admin_js_path = A360_INSIGHTS_PATH . 'assets/admin.js'; $admin_css_version = file_exists($admin_css_path) ? A360_INSIGHTS_VERSION . '.' . filemtime($admin_css_path) : A360_INSIGHTS_VERSION; $admin_js_version = file_exists($admin_js_path) ? A360_INSIGHTS_VERSION . '.' . filemtime($admin_js_path) : A360_INSIGHTS_VERSION; wp_enqueue_style('a360-insights-admin', A360_INSIGHTS_URL . 'assets/admin.css', array(), $admin_css_version); wp_enqueue_script('a360-insights-admin', A360_INSIGHTS_URL . 'assets/admin.js', array('jquery', 'chart-js'), $admin_js_version, true); wp_localize_script( 'a360-insights-admin', 'a360Insights', array( 'ajaxUrl' => admin_url('admin-ajax.php'), 'nonce' => wp_create_nonce('a360_insights_stats'), 'sourceNonce' => wp_create_nonce('a360_insights_source_stats'), 'resetNonce' => wp_create_nonce('a360_insights_reset'), 'searchNonce' => wp_create_nonce('a360_insights_search_content'), 'trendNonce' => wp_create_nonce('a360_insights_dashboard_trend'), 'reportNonce' => wp_create_nonce('a360_insights_create_report_link'), 'reportLinksNonce' => wp_create_nonce('a360_insights_report_links'), 'revokeReportNonce' => wp_create_nonce('a360_insights_revoke_report_link'), 'deleteReportNonce' => wp_create_nonce('a360_insights_delete_report_link'), 'today' => current_time('Y-m-d'), 'i18n' => $this->i18n(), ) ); } /** * AJAX stats endpoint. * * @return void */ public function ajax_stats() { check_ajax_referer('a360_insights_stats', 'nonce'); if (! current_user_can('edit_posts')) { wp_send_json_error(array('message' => __('Permission denied.', 'a360-insights')), 403); } $post_id = isset($_POST['postId']) ? absint($_POST['postId']) : 0; $range = isset($_POST['range']) ? sanitize_key(wp_unslash($_POST['range'])) : 'month'; $anchor = isset($_POST['anchor']) ? sanitize_text_field(wp_unslash($_POST['anchor'])) : ''; if (! $post_id || ! current_user_can('edit_post', $post_id)) { wp_send_json_error(array('message' => __('Invalid post.', 'a360-insights')), 400); } wp_send_json_success( array( 'stats' => A360_Insights_DB::get_stats($post_id, $range, $anchor), 'exportUrl' => admin_url('admin-post.php'), 'export' => array( 'action' => 'a360_insights_export_csv', 'post_id' => $post_id, 'nonce' => wp_create_nonce('a360_insights_export_' . $post_id), ), ) ); } /** * AJAX source stats endpoint. * * @return void */ public function ajax_source_stats() { check_ajax_referer('a360_insights_source_stats', 'nonce'); if (! current_user_can('edit_posts')) { wp_send_json_error(array('message' => __('Permission denied.', 'a360-insights')), 403); } $source = isset($_POST['source']) ? sanitize_key(wp_unslash($_POST['source'])) : ''; $range = isset($_POST['range']) ? sanitize_key(wp_unslash($_POST['range'])) : 'month'; $anchor = isset($_POST['anchor']) ? sanitize_text_field(wp_unslash($_POST['anchor'])) : ''; if ('' === $source) { wp_send_json_error(array('message' => __('Invalid source.', 'a360-insights')), 400); } wp_send_json_success( array( 'stats' => A360_Insights_DB::get_source_stats($source, $range, $anchor), ) ); } /** * AJAX reset endpoint. * * @return void */ public function ajax_reset() { check_ajax_referer('a360_insights_reset', 'nonce'); $post_id = isset($_POST['postId']) ? absint($_POST['postId']) : 0; $scope = isset($_POST['scope']) ? sanitize_key(wp_unslash($_POST['scope'])) : 'post'; if ('all' === $scope) { if (! current_user_can('manage_options')) { wp_send_json_error(array('message' => __('Permission denied.', 'a360-insights')), 403); } A360_Insights_DB::reset_all_views(); wp_send_json_success( array( 'message' => __('All counters have been reset.', 'a360-insights'), ) ); } if (! $post_id || ! current_user_can('edit_post', $post_id)) { wp_send_json_error(array('message' => __('Invalid post.', 'a360-insights')), 400); } A360_Insights_DB::reset_post_views($post_id); wp_send_json_success( array( 'message' => __('Counter has been reset.', 'a360-insights'), ) ); } /** * AJAX content search for settings page. * * @return void */ public function ajax_search_content() { check_ajax_referer('a360_insights_search_content', 'nonce'); if (! current_user_can('manage_options')) { wp_send_json_error(array('message' => __('Permission denied.', 'a360-insights')), 403); } $term = isset($_GET['term']) ? sanitize_text_field(wp_unslash($_GET['term'])) : ''; if (strlen($term) < 2) { wp_send_json_success(array('items' => array())); } $query = new WP_Query( array( 'post_type' => array_keys(A360_Insights_Settings::public_post_types()), 'post_status' => array('publish', 'draft', 'pending', 'private'), 's' => $term, 'posts_per_page' => 20, 'orderby' => 'relevance', 'order' => 'DESC', 'no_found_rows' => true, 'update_post_meta_cache' => false, 'update_post_term_cache' => false, ) ); $items = array(); foreach ($query->posts as $post) { $items[] = $this->format_content_item($post); } wp_send_json_success(array('items' => $items)); } /** * AJAX dashboard trend endpoint. * * @return void */ public function ajax_dashboard_trend() { check_ajax_referer('a360_insights_dashboard_trend', 'nonce'); if (! current_user_can('manage_options')) { wp_send_json_error(array('message' => __('Permission denied.', 'a360-insights')), 403); } $range = isset($_POST['range']) ? sanitize_key(wp_unslash($_POST['range'])) : 'month'; $offset = isset($_POST['offset']) ? absint(wp_unslash($_POST['offset'])) : 0; $source_filter = isset($_POST['source']) ? sanitize_key(wp_unslash($_POST['source'])) : ''; $referrer_filter = isset($_POST['referrer']) ? sanitize_text_field(wp_unslash($_POST['referrer'])) : ''; $channel_filter = isset($_POST['channel']) ? sanitize_key(wp_unslash($_POST['channel'])) : ''; $allowed_ranges = array('day', 'week', 'month', 'year'); if (! in_array($range, $allowed_ranges, true)) { $range = 'month'; } wp_send_json_success( array( 'points' => A360_Insights_DB::get_traffic_trend($range, $offset, $source_filter, $referrer_filter, $channel_filter), 'chartType' => 'day' === $range ? 'bar' : 'line', 'filterLabel' => $this->dashboard_filter_label($source_filter, $referrer_filter, $channel_filter), ) ); } /** * AJAX create public report link for a post. * * @return void */ public function ajax_create_report_link() { check_ajax_referer('a360_insights_create_report_link', 'nonce'); if (! current_user_can('edit_posts')) { wp_send_json_error(array('message' => __('Permission denied.', 'a360-insights')), 403); } $post_id = isset($_POST['postId']) ? absint($_POST['postId']) : 0; $post = $post_id ? get_post($post_id) : null; if (! $post || ! current_user_can('edit_post', $post_id)) { wp_send_json_error(array('message' => __('Invalid post.', 'a360-insights'))); } $expires_at = isset($_POST['expiresAt']) ? sanitize_text_field(wp_unslash($_POST['expiresAt'])) : ''; $report = A360_Insights_DB::create_shared_report($post_id, get_the_title($post), $expires_at); if (! $report) { wp_send_json_error(array('message' => __('Could not create report link.', 'a360-insights'))); } wp_send_json_success(array( 'url' => esc_url_raw($report['url']), )); } /** * AJAX list public report links for a post. * * @return void */ public function ajax_report_links() { check_ajax_referer('a360_insights_report_links', 'nonce'); if (! current_user_can('edit_posts')) { wp_send_json_error(array('message' => __('Permission denied.', 'a360-insights')), 403); } $post_id = isset($_POST['postId']) ? absint($_POST['postId']) : 0; if (! $post_id) { if (! current_user_can('manage_options')) { wp_send_json_error(array('message' => __('Permission denied.', 'a360-insights')), 403); } wp_send_json_success(array( 'links' => $this->format_report_link_rows(A360_Insights_DB::get_shared_reports(50)), )); } if (! current_user_can('edit_post', $post_id)) { wp_send_json_error(array('message' => __('Invalid post.', 'a360-insights'))); } wp_send_json_success(array( 'links' => $this->format_report_link_rows(A360_Insights_DB::get_shared_reports_for_post($post_id)), )); } /** * AJAX revoke public report link. * * @return void */ public function ajax_revoke_report_link() { check_ajax_referer('a360_insights_revoke_report_link', 'nonce'); if (! current_user_can('edit_posts')) { wp_send_json_error(array('message' => __('Permission denied.', 'a360-insights')), 403); } $post_id = isset($_POST['postId']) ? absint($_POST['postId']) : 0; $report_id = isset($_POST['reportId']) ? absint($_POST['reportId']) : 0; if (! $post_id || ! $report_id || ! current_user_can('edit_post', $post_id)) { wp_send_json_error(array('message' => __('Invalid report link.', 'a360-insights'))); } $updated = A360_Insights_DB::revoke_shared_report($report_id, $post_id); if (false === $updated) { wp_send_json_error(array('message' => __('Could not disable report link.', 'a360-insights'))); } wp_send_json_success(array( 'links' => $this->format_report_link_rows(A360_Insights_DB::get_shared_reports_for_post($post_id)), )); } /** * AJAX permanently delete a public report link. * * @return void */ public function ajax_delete_report_link() { check_ajax_referer('a360_insights_delete_report_link', 'nonce'); if (! current_user_can('edit_posts')) { wp_send_json_error(array('message' => __('Permission denied.', 'a360-insights')), 403); } $post_id = isset($_POST['postId']) ? absint($_POST['postId']) : 0; $report_id = isset($_POST['reportId']) ? absint($_POST['reportId']) : 0; if (! $post_id || ! $report_id || ! current_user_can('edit_post', $post_id)) { wp_send_json_error(array('message' => __('Invalid report link.', 'a360-insights'))); } $deleted = A360_Insights_DB::delete_shared_report($report_id, $post_id); if (false === $deleted || 0 === $deleted) { wp_send_json_error(array('message' => __('Could not delete report link.', 'a360-insights'))); } wp_send_json_success(); } /** * Add display metadata to report link rows. * * @param array $rows Report rows. * @return array */ private function format_report_link_rows(array $rows) { $formatted = array(); $now = current_time('timestamp'); foreach ($rows as $row) { $post_id = absint($row['post_id'] ?? 0); $post_title = $post_id ? get_the_title($post_id) : ''; if ('' === $post_title) { $post_title = sprintf( /* translators: %d: post ID. */ __('Content #%d', 'a360-insights'), $post_id ); } $expires_at = (string) ($row['expires_at'] ?? ''); $is_expired = false; if ('' !== $expires_at && '0000-00-00 00:00:00' !== $expires_at) { $expires_timestamp = strtotime($expires_at); $is_expired = $expires_timestamp && $expires_timestamp < $now; } $row['post_title'] = html_entity_decode($post_title, ENT_QUOTES, get_bloginfo('charset')); $row['edit_url'] = $post_id ? get_edit_post_link($post_id, '') : ''; $row['is_expired'] = $is_expired ? 1 : 0; $row['url'] = ! empty($row['token']) ? add_query_arg('a360_report', rawurlencode($row['token']), home_url('/')) : ''; unset($row['token']); $formatted[] = $row; } return $formatted; } /** * Render a public report by token. * * @return void */ public function render_public_report() { // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Public read-only report token. if (empty($_GET['a360_report'])) { return; } // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Public read-only report token. $token = sanitize_text_field(wp_unslash($_GET['a360_report'])); $report = A360_Insights_DB::get_shared_report_by_token($token); if (! $report) { status_header(404); nocache_headers(); echo 'A360 Insights

Report not found

'; exit; } $post_id = absint($report['post_id'] ?? 0); $post = $post_id ? get_post($post_id) : null; if (! $post || 'publish' !== get_post_status($post)) { status_header(404); nocache_headers(); echo 'A360 Insights

Report not found

'; exit; } // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Public report range. $range = isset($_GET['range']) ? sanitize_key(wp_unslash($_GET['range'])) : 'month'; $stats = A360_Insights_DB::get_stats($post_id, $range, current_time('Y-m-d')); $title = get_the_title($post); nocache_headers(); status_header(200); $this->render_public_report_html($title, get_permalink($post), $stats, $range); exit; } /** * Render public report HTML. * * @param string $title Post title. * @param string $permalink Post permalink. * @param array $stats Stats data. * @param string $range Current range. * @return void */ private function render_public_report_html($title, $permalink, array $stats, $range) { $ranges = array( 'day' => __('Day', 'a360-insights'), 'week' => __('Week', 'a360-insights'), 'month' => __('Month', 'a360-insights'), 'year' => __('Year', 'a360-insights'), ); ?> > <?php echo esc_html(sprintf(__('Analytics report: %s', 'a360-insights'), $title)); ?>

render_public_report_kpi(__('Total views', 'a360-insights'), $stats['total'] ?? 0); ?> render_public_report_kpi(__('AI traffic', 'a360-insights'), $stats['ai_views'] ?? 0, ($stats['ai_percent'] ?? 0) . '%'); ?> render_public_report_kpi(__('Search traffic', 'a360-insights'), $stats['search_views'] ?? 0, ($stats['search_percent'] ?? 0) . '%'); ?> render_public_report_kpi(__('Referrals', 'a360-insights'), $stats['referral_views'] ?? 0, ($stats['referral_percent'] ?? 0) . '%'); ?> render_public_report_kpi(__('Sessions', 'a360-insights'), $stats['sessions'] ?? 0); ?> render_public_report_kpi(__('Engaged sessions', 'a360-insights'), $stats['engaged_sessions'] ?? 0, ($stats['engagement_rate'] ?? 0) . '%'); ?> render_public_report_kpi(__('Conversions', 'a360-insights'), $stats['conversions'] ?? 0, ($stats['conversion_rate'] ?? 0) . '%'); ?>
render_public_report_trend((array) ($stats['chart'] ?? array())); ?> render_public_report_channels((array) ($stats['sources'] ?? array()), (int) ($stats['total'] ?? 0)); ?>
render_public_report_visual_list(__('Top referrers', 'a360-insights'), (array) ($stats['top_referrers'] ?? array()), __('No referrers yet.', 'a360-insights'), true); ?> render_public_report_bar_card(__('Engagement', 'a360-insights'), (array) ($stats['engagement'] ?? array()), 'events', __('No engagement events yet.', 'a360-insights'), true, __('Engagement is tracked automatically: outbound links, file downloads, phone and email clicks, form starts, form submits and scroll depth.', 'a360-insights')); ?>
render_public_report_bar_card(__('Key events', 'a360-insights'), (array) ($stats['key_events'] ?? array()), 'events', __('No key events yet.', 'a360-insights'), true); ?> render_public_report_bar_card(__('Landing funnel', 'a360-insights'), (array) ($stats['funnel'] ?? array()), 'count', __('No funnel data yet.', 'a360-insights'), true, __('This funnel follows anonymous sessions from landing page view through scroll depth, CTA/link clicks and form actions.', 'a360-insights')); ?>
render_public_report_campaigns((array) ($stats['campaigns'] ?? array())); ?> render_public_report_table(__('Recent visits', 'a360-insights'), (array) ($stats['recent'] ?? array()), array('viewed_at' => __('Date', 'a360-insights'), 'label' => __('Source', 'a360-insights'), 'utm_campaign' => __('Campaign', 'a360-insights'))); ?>

$row) : ?> 0 ? ($views / $total) * $circumference : 0; $color = $colors[$index % count($colors)]; ?>
$row) : ?> 0 ? round(($views / $total) * 100, 1) : 0; $color = $colors[$index % count($colors)]; ?> %

0 ? min(100, ($views / $max) * 100) : 0; ?>

$label) : ?>
post_type); $type_label = $post_type_object ? $post_type_object->labels->singular_name : $post->post_type; $title = get_the_title($post); if ('' === $title) { $title = __('(no title)', 'a360-insights'); } return array( 'id' => absint($post->ID), 'title' => html_entity_decode($title, ENT_QUOTES, get_bloginfo('charset')), 'type' => html_entity_decode($type_label, ENT_QUOTES, get_bloginfo('charset')), 'edit' => get_edit_post_link($post->ID, ''), ); } /** * Get selected content items for the settings page. * * @param array $ids Post IDs. * @return array */ private function get_selected_content_items($ids) { $items = array(); foreach (array_map('absint', (array) $ids) as $post_id) { $item = $this->format_content_item($post_id); if ($item) { $items[] = $item; } } return $items; } /** * Render report links manager. * * @param bool $standalone Whether this is rendered as a standalone admin page. * @return void */ private function render_report_links_manager($standalone = false) { $section_classes = $standalone ? 'a360-settings-card a360-report-manager-card' : 'a360-settings-card a360-report-manager-card'; ?>
>

__('Outbound clicks', 'a360-insights'), 'file_download' => __('File downloads', 'a360-insights'), 'phone_click' => __('Phone clicks', 'a360-insights'), 'email_click' => __('Email clicks', 'a360-insights'), 'form_start' => __('Form starts', 'a360-insights'), 'form_submit' => __('Form submits', 'a360-insights'), 'scroll_75' => __('Scroll 75%', 'a360-insights'), 'scroll_90' => __('Scroll 90%', 'a360-insights'), ); } /** * Register WordPress dashboard widget. * * @return void */ public function register_dashboard_widget() { if (! current_user_can('edit_posts')) { return; } wp_add_dashboard_widget( 'a360_insights_dashboard_widget', __('A360 Insights', 'a360-insights'), array($this, 'render_dashboard_widget') ); } /** * Render WordPress dashboard widget. * * @return void */ public function render_dashboard_widget() { if (! current_user_can('edit_posts')) { return; } $summary = A360_Insights_DB::get_dashboard_summary(); ?>
%

render_dashboard_list(__('Top AI sources', 'a360-insights'), $summary['top_ai_sources'] ?? array(), 'ai_sources'); ?>

empty_state_message($type)); ?>

__('AI visits will appear here when visitors arrive from ChatGPT, Copilot, Gemini and other AI assistants.', 'a360-insights'), 'content' => __('Top content will appear here after tracked pages or posts receive visits.', 'a360-insights'), 'campaigns' => __('Campaigns will appear here when UTM parameters are detected in incoming visits.', 'a360-insights'), 'sources' => __('Traffic channels will appear here as soon as A360 Insights records visits.', 'a360-insights'), 'referrers' => __('Referral domains will appear here when visitors come from external websites.', 'a360-insights'), ); return isset($messages[$type]) ? $messages[$type] : __('No data yet.', 'a360-insights'); } /** * Render dashboard empty state. * * @param string $title Empty state title. * @param string $message Empty state message. * @return void */ private function render_empty_state($title, $message) { ?>
admin_page_hooks[] = add_menu_page( __('A360 Insights', 'a360-insights'), __('A360 Insights', 'a360-insights'), 'manage_options', 'a360-insights', array($this, 'render_dashboard_page'), 'dashicons-chart-area', 25 ); $this->admin_page_hooks[] = add_submenu_page( 'a360-insights', __('Dashboard', 'a360-insights'), __('Dashboard', 'a360-insights'), 'manage_options', 'a360-insights', array($this, 'render_dashboard_page') ); $this->admin_page_hooks[] = add_submenu_page( 'a360-insights', __('Landing Pages', 'a360-insights'), __('Landing Pages', 'a360-insights'), 'manage_options', 'a360-insights-landing-pages', array($this, 'render_landing_pages_page') ); $this->admin_page_hooks[] = add_submenu_page( 'a360-insights', __('Sources / Channels', 'a360-insights'), __('Sources / Channels', 'a360-insights'), 'manage_options', 'a360-insights-sources', array($this, 'render_sources_page') ); $this->admin_page_hooks[] = add_submenu_page( 'a360-insights', __('Report Links', 'a360-insights'), __('Report Links', 'a360-insights'), 'manage_options', 'a360-insights-report-links', array($this, 'render_report_links_page') ); $this->admin_page_hooks[] = add_submenu_page( 'a360-insights', __('Settings', 'a360-insights'), __('Settings', 'a360-insights'), 'manage_options', 'a360-insights-settings', array($this, 'render_settings_page') ); } /** * Register settings. * * @return void */ public function register_settings() { register_setting( 'a360_insights_settings', A360_Insights_Settings::OPTION_NAME, array( 'type' => 'array', 'sanitize_callback' => array('A360_Insights_Settings', 'sanitize'), 'default' => A360_Insights_Settings::defaults(), ) ); } private function source_icon($source) { $source = strtolower((string) $source); if (false !== strpos($source, 'ai_crawler_') || 'ai_crawlers' === $source) { return 'AI'; } if ('likely_ai_direct' === $source) { return '?'; } if (false !== strpos($source, 'codex')) { return 'CX'; } if ('ai_traffic' === $source) { return 'AI'; } if (false !== strpos($source, 'chatgpt') || false !== strpos($source, 'openai')) { return 'AI'; } if (false !== strpos($source, 'gemini')) { return '✦'; } if (false !== strpos($source, 'copilot')) { return 'C'; } if (false !== strpos($source, 'perplexity')) { return 'P'; } if (false !== strpos($source, 'claude')) { return 'C'; } if (false !== strpos($source, 'meta_ai')) { return 'M'; } if (false !== strpos($source, 'mistral')) { return 'M'; } if ('you' === $source || false !== strpos($source, 'you.com')) { return 'Y'; } if (false !== strpos($source, 'poe')) { return 'P'; } if (false !== strpos($source, 'phind')) { return 'P'; } if (false !== strpos($source, 'deepseek')) { return 'D'; } if (false !== strpos($source, 'grok')) { return 'G'; } if (false !== strpos($source, 'google')) { return 'G'; } if ('organic_search' === $source) { return 'S'; } if ('social' === $source) { return '#'; } if ('campaign' === $source) { return 'C'; } if ('referral' === $source) { return 'R'; } if (false !== strpos($source, 'facebook')) { return 'f'; } if (false !== strpos($source, 'youtube')) { return '▶'; } if (false !== strpos($source, 'bing')) { return 'b'; } if (false !== strpos($source, 'direct')) { return '↗'; } return '•'; } /** * Render a consistent dashboard interface icon. * * @param string $icon Icon key. * @return string */ private function dashboard_icon($icon) { $icons = array( 'views' => '', 'ai' => '', 'search' => '', 'referral' => '', ); return $icons[$icon] ?? $icons['views']; } /** * Render landing pages report. * * @return void */ public function render_landing_pages_page() { if (! current_user_can('manage_options')) { return; } // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Read-only admin filters, no data is changed. $range = isset($_GET['range']) // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Read-only admin filters, no data is changed. ? sanitize_key(wp_unslash($_GET['range'])) : 'month'; // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Read-only admin filters, no data is changed. $offset = isset($_GET['offset']) // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Read-only admin filters, no data is changed. ? absint(wp_unslash($_GET['offset'])) : 0; $allowed_ranges = array('day', 'week', 'month', 'year'); if (! in_array($range, $allowed_ranges, true)) { $range = 'month'; } $settings = A360_Insights_Settings::get(); $business_landing_page_ids = array_values(array_filter(array_map('absint', (array) ($settings['business_landing_page_ids'] ?? array())))); // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Read-only admin filters, no data is changed. $landing_scope = isset($_GET['landing_scope']) // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Read-only admin filters, no data is changed. ? sanitize_key(wp_unslash($_GET['landing_scope'])) : 'all'; if (! in_array($landing_scope, array('all', 'selected'), true)) { $landing_scope = 'all'; } $selected_only = 'selected' === $landing_scope; $landing_pages = A360_Insights_DB::get_top_landing_pages(50, $range, $offset, $business_landing_page_ids, $selected_only); $period_label = A360_Insights_DB::get_period_label($range, $offset); $ranges = array( 'day' => __('Day', 'a360-insights'), 'week' => __('Week', 'a360-insights'), 'month' => __('Month', 'a360-insights'), 'year' => __('Year', 'a360-insights'), ); ?>

$range_label_item) : ?>
‹ 0) : ?> › ›





source_icon($top_source)); ?> % %
render_empty_state( __('No landing page sessions yet', 'a360-insights'), __('Landing pages will appear after tracked visitors start new anonymous sessions.', 'a360-insights') ); ?>
__('Day', 'a360-insights'), 'week' => __('Week', 'a360-insights'), 'month' => __('Month', 'a360-insights'), 'year' => __('Year', 'a360-insights'), ); ?>

$range_label_item) : ?>
‹ 0) : ?> › ›
source_icon($source)); ?> % % —
render_empty_state( __('No source sessions yet', 'a360-insights'), __('Sources and channels will appear after tracked visitors start anonymous sessions.', 'a360-insights') ); ?>

render_report_links_manager(true); ?>
0 ? round(($ai_views / $total_views) * 100, 1) : 0; $search_percent = $total_views > 0 ? round(($search_views / $total_views) * 100, 1) : 0; $referral_percent = $total_views > 0 ? round(($referral_views / $total_views) * 100, 1) : 0; $daily_views = A360_Insights_DB::get_traffic_trend($range, $offset, $source_filter, $referrer_filter, $channel_filter); // $site_trend = A360_Insights_DB::get_daily_views_by_type('site', $range, $offset); // $ai_trend = A360_Insights_DB::get_daily_views_by_type('ai', $range, $offset); // $search_trend = A360_Insights_DB::get_daily_views_by_type('search', $range, $offset); // $referral_trend = A360_Insights_DB::get_daily_views_by_type('referral', $range, $offset); $trend_label = array( 'day' => __('Today by hour', 'a360-insights'), 'week' => __('Last 7 days', 'a360-insights'), 'month' => __('Last 30 days', 'a360-insights'), 'year' => __('Last 365 days', 'a360-insights'), ); $trend_label = isset($trend_label[$range]) ? $trend_label[$range] : __('Last 30 days', 'a360-insights'); $trend_granularity_label = array( 'day' => __('Hourly views', 'a360-insights'), 'week' => __('Daily views', 'a360-insights'), 'month' => __('Daily views', 'a360-insights'), 'year' => __('Monthly totals', 'a360-insights'), ); $trend_granularity_label = isset($trend_granularity_label[$range]) ? $trend_granularity_label[$range] : __('Daily views', 'a360-insights'); $period_label = A360_Insights_DB::get_period_label($range, $offset); ?>

__('Day', 'a360-insights'), 'week' => __('Week', 'a360-insights'), 'month' => __('Month', 'a360-insights'), 'year' => __('Year', 'a360-insights'), ); foreach ($ranges as $range_key => $range_label_item) : $url = add_query_arg( array( 'page' => 'a360-insights', 'range' => $range_key, 'offset' => 0, 'source' => $source_filter ? $source_filter : false, 'referrer' => $referrer_filter ? $referrer_filter : false, 'channel' => $channel_filter ? $channel_filter : false, ), admin_url('admin.php') ); ?>
‹ 0) : ?> › ›
'a360-insights', 'range' => $range, 'offset' => $offset, ), admin_url('admin.php') ); $ai_traffic_url = add_query_arg( array( 'page' => 'a360-insights', 'range' => $range, 'offset' => $offset, 'source' => false, 'referrer' => false, 'channel' => 'ai_traffic', ), admin_url('admin.php') ); $search_traffic_url = add_query_arg( array( 'page' => 'a360-insights', 'range' => $range, 'offset' => $offset, 'source' => false, 'referrer' => false, 'channel' => 'organic_search', ), admin_url('admin.php') ); $referrals_url = add_query_arg( array( 'page' => 'a360-insights', 'range' => $range, 'offset' => $offset, 'source' => false, 'referrer' => false, 'channel' => 'referral', ), admin_url('admin.php') ); ?>
dashboard_icon('views'); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Static internal SVG. ?>
dashboard_icon('ai'); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Static internal SVG. ?>
%
dashboard_icon('search'); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Static internal SVG. ?>
%
dashboard_icon('referral'); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Static internal SVG. ?>
%

'a360-insights', 'range' => $range, 'offset' => $offset, 'source' => false, 'referrer' => false, 'channel' => $channel_key, ), admin_url('admin.php') ); ?>
source_icon($channel_key)); ?> %
render_empty_state( __('No channel data yet', 'a360-insights'), $this->empty_state_message('sources') ); ?>

dashboard_icon('referral'); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Static internal SVG. ?>

source_icon($row['source'])); ?>
render_empty_state( __('No referrers yet', 'a360-insights'), $this->empty_state_message('referrers') ); ?>

render_empty_state( __('No content views yet', 'a360-insights'), $this->empty_state_message('content') ); ?>
> dashboard_filter_label($source_filter, $referrer_filter, $channel_filter)); ?>

%
render_empty_state( __('No landing page sessions yet', 'a360-insights'), $this->empty_state_message('content') ); ?>

·

render_empty_state( __('No technology data yet', 'a360-insights'), __('Technology categories will appear after new browser sessions are tracked.', 'a360-insights') ); ?>
get_selected_content_items((array) $settings['selected_post_ids']); $selected_ids = implode(',', array_map('absint', (array) $settings['selected_post_ids'])); $business_landing_items = $this->get_selected_content_items((array) ($settings['business_landing_page_ids'] ?? array())); $business_landing_ids = implode(',', array_map('absint', (array) ($settings['business_landing_page_ids'] ?? array()))); $selected_post_type_count = count((array) $settings['post_types']); $selected_content_count = count((array) $settings['selected_post_ids']); $status_item_label = __('Selected items', 'a360-insights'); $status_item_count = $selected_content_count; if ('all' === $settings['tracking_mode']) { $status_item_label = __('Tracked post types', 'a360-insights'); $status_item_count = $selected_post_type_count; } elseif ('exclude' === $settings['tracking_mode']) { $status_item_label = __('Excluded items', 'a360-insights'); $status_item_count = $selected_content_count; } ?>

render_report_links_manager(false); ?>
'a360-insights', 'a360_reset' => 'success', ), admin_url('options-general.php') ) ); exit; } /** * Get translated UI string. * * @param string $key String key. * @return string */ private function string($key) { $strings = $this->strings(); return isset($strings[$key]) ? $strings[$key] : $key; } /** * UI strings. * * Uses plugin-side fallback translations because JS/localized strings * require compiled language files on WordPress.org installations. * * @return array */ private function i18n() { return $this->strings(); } /** * Get UI strings for supported locales. * * @return array */ private function strings() { $locale = function_exists('determine_locale') ? determine_locale() : get_locale(); $lang = strtolower(substr((string) $locale, 0, 2)); $en = array( 'title' => 'Post statistics', 'sourceTitle' => 'Source statistics', 'total' => 'Total views', 'totalViews' => 'Total Views', 'allTrackedViews' => 'All tracked views', 'aiTraffic' => 'AI Traffic', 'ofAiTraffic' => 'of AI traffic', 'noAiTrafficText' => 'AI assistants will appear here after this content receives visits from AI sources.', 'searchTraffic' => 'Search Traffic', 'ofSearchTraffic' => 'of search traffic', 'noSearchTrafficText' => 'Search engines will appear here after this content receives search traffic.', 'searchLandingPages' => 'Landing pages from search', 'noSearchLandingPagesText' => 'Landing pages will appear here after search visits are recorded.', 'utmTerms' => 'UTM terms', 'noUtmTermsText' => 'UTM terms will appear here when search visits include utm_term.', 'referrals' => 'Referrals', 'ofReferralTraffic' => 'of referral traffic', 'noReferralTrafficText' => 'Referral sources will appear here after visitors arrive from external websites.', 'overview' => 'Overview', 'sources' => 'Sources', 'technology' => 'Technology', 'campaigns' => 'Campaigns', 'engagement' => 'Engagement', 'funnel' => 'Funnel', 'funnelHelp' => 'Landing funnel by anonymous sessions: page view, 75% scroll, CTA/link click, form start and form submit.', 'keyEvents' => 'Key events', 'keyEventsHelp' => 'Configured conversion events for this content. Edit key events in Settings.', 'conversions' => 'Conversions', 'conversionRate' => 'conversion rate', 'ofEngagedSessions' => 'of engaged sessions', 'ofConversions' => 'of conversions', 'noSessionsText' => 'Sessions will appear here after anonymous browser sessions are recorded.', 'noEngagedSessionsText' => 'Engaged sessions will appear here after visitors interact with this content.', 'noConversionsText' => 'Conversions will appear here after configured key events are recorded.', 'step' => 'Step', 'sessions' => 'Sessions', 'pageSessions' => 'Page sessions', 'anonymousSessions' => 'Anonymous browser sessions', 'engagedSessions' => 'Engaged sessions', 'engagedPageSessions' => 'Engaged page sessions', 'pageConversions' => 'Page conversions', 'engagementRate' => 'engagement rate', 'engagementHelp' => 'Tracked automatically: outbound links, file downloads, phone and email clicks, form starts, form submits and scroll depth. The rate compares each event count with page views in the selected period.', 'event' => 'Event', 'events' => 'Events', 'rate' => 'Rate', 'medium' => 'Medium', 'trafficChannels' => 'Traffic channels', 'channelTypes' => 'Channel Types', 'channelType' => 'Channel Type', 'visitorTechnology' => 'Visitor Technology', 'technologySummary' => 'Anonymous technology categories from %s sessions in the selected period.', 'deviceTypes' => 'Device Types', 'browsers' => 'Browsers', 'operatingSystems' => 'Operating Systems', 'ofSessions' => 'of sessions', 'campaignsHint' => 'UTM campaigns detected for this content in the selected period.', 'day' => 'Day', 'week' => 'Week', 'month' => 'Month', 'year' => 'Year', 'topReferrers' => 'Top referrers', 'topContent' => 'Top content', 'recent' => 'Recent visits', 'source' => 'Source', 'contentTitle' => 'Title', 'views' => 'Views', 'date' => 'Date', 'campaign' => 'Campaign', 'exportCsv' => 'Export CSV', 'createReportLink' => 'Create client report link', 'reportLink' => 'Client report link', 'expiresAt' => 'Expires at', 'created' => 'Created', 'status' => 'Status', 'actions' => 'Actions', 'active' => 'Active', 'disabled' => 'Disabled', 'expired' => 'Expired', 'disable' => 'Disable', 'delete' => 'Delete', 'copyLink' => 'Copy link', 'openLink' => 'Open', 'copied' => 'Copied', 'linkUnavailable' => 'Link unavailable', 'confirmDeleteReport' => 'Permanently delete this report link? This cannot be undone.', 'noData' => 'No data yet.', 'noCampaignsTitle' => 'No campaigns yet', 'noCampaignsText' => 'UTM campaigns will appear here when incoming visits include campaign parameters.', 'noReferrersTitle' => 'No referrers yet', 'noReferrersText' => 'Referral domains will appear here when visitors come from external websites.', 'noChannelTypesTitle' => 'No channel data yet', 'noChannelTypesText' => 'Channel types will appear after tracked visitors start anonymous sessions.', 'noTechnologyText' => 'Technology categories will appear after new browser sessions are tracked.', 'noRecentTitle' => 'No recent visits yet', 'noRecentText' => 'Recent visits will appear here after A360 Insights records traffic for this period.', 'noSourceContentTitle' => 'No content yet', 'noSourceContentText' => 'Top content for this source will appear here after matching visits are recorded.', 'close' => 'Close', 'loading' => 'Loading…', 'previous' => 'Previous', 'next' => 'Next', 'today' => 'Today', 'thisWeek' => 'This week', 'thisMonth' => 'This month', 'resetPost' => 'Reset this counter', 'resetAll' => 'Reset all counters', 'confirmPost' => 'Reset counter for this post? This cannot be undone.', 'confirmAll' => 'Reset counters for all posts and pages? This cannot be undone.', 'resetDone' => 'Counter reset completed.', ); $translations = array( 'pl' => array( 'title' => 'Statystyki wpisu', 'sourceTitle' => 'Statystyki źródła', 'total' => 'Łączna liczba odsłon', 'totalViews' => 'Łączne odsłony', 'allTrackedViews' => 'Wszystkie śledzone odsłony', 'aiTraffic' => 'Ruch AI', 'ofAiTraffic' => 'ruchu AI', 'noAiTrafficText' => 'Asystenci AI pojawią się tutaj, gdy ta treść otrzyma wejścia ze źródeł AI.', 'searchTraffic' => 'Ruch z wyszukiwarek', 'ofSearchTraffic' => 'ruchu z wyszukiwarek', 'noSearchTrafficText' => 'Wyszukiwarki pojawią się tutaj, gdy ta treść otrzyma ruch z wyników wyszukiwania.', 'searchLandingPages' => 'Landing pages z wyszukiwarek', 'noSearchLandingPagesText' => 'Landing pages pojawią się tutaj po zarejestrowaniu wejść z wyszukiwarek.', 'utmTerms' => 'Frazy UTM', 'noUtmTermsText' => 'Frazy UTM pojawią się tutaj, gdy wejścia z wyszukiwarek zawierają utm_term.', 'referrals' => 'Odesłania', 'ofReferralTraffic' => 'ruchu z odesłań', 'noReferralTrafficText' => 'Źródła odesłań pojawią się tutaj, gdy odwiedzający przyjdą z zewnętrznych stron.', 'overview' => 'Przegląd', 'sources' => 'Źródła', 'technology' => 'Technologia', 'campaigns' => 'Kampanie', 'engagement' => 'Zaangażowanie', 'funnel' => 'Lejek', 'funnelHelp' => 'Lejek landing page według anonimowych sesji: odsłona, scroll 75%, klik CTA/linku, rozpoczęcie formularza i wysłanie formularza.', 'keyEvents' => 'Kluczowe zdarzenia', 'keyEventsHelp' => 'Wybrane zdarzenia konwersji dla tej treści. Kluczowe zdarzenia ustawisz w Settings.', 'conversions' => 'Konwersje', 'conversionRate' => 'współczynnik konwersji', 'ofEngagedSessions' => 'zaangażowanych sesji', 'ofConversions' => 'konwersji', 'noSessionsText' => 'Sesje pojawią się tutaj po zarejestrowaniu anonimowych sesji przeglądarki.', 'noEngagedSessionsText' => 'Zaangażowane sesje pojawią się tutaj, gdy odwiedzający wejdą w interakcję z tą treścią.', 'noConversionsText' => 'Konwersje pojawią się tutaj po zarejestrowaniu skonfigurowanych kluczowych zdarzeń.', 'step' => 'Krok', 'sessions' => 'Sesje', 'pageSessions' => 'Sesje strony', 'anonymousSessions' => 'Anonimowe sesje przeglądarki', 'engagedSessions' => 'Zaangażowane sesje', 'engagedPageSessions' => 'Zaangażowane sesje strony', 'pageConversions' => 'Konwersje strony', 'engagementRate' => 'wskaźnik zaangażowania', 'engagementHelp' => 'Mierzone automatycznie: linki wychodzące, pobrania plików, kliknięcia telefonu i e-maila, rozpoczęcia formularzy, wysłania formularzy oraz głębokość przewijania. Wskaźnik porównuje liczbę zdarzeń z odsłonami w wybranym okresie.', 'event' => 'Zdarzenie', 'events' => 'Zdarzenia', 'rate' => 'Wskaźnik', 'medium' => 'Medium', 'trafficChannels' => 'Kanały ruchu', 'channelTypes' => 'Typy kanałów', 'channelType' => 'Typ kanału', 'visitorTechnology' => 'Technologia odwiedzających', 'technologySummary' => 'Anonimowe kategorie technologii z %s sesji w wybranym okresie.', 'deviceTypes' => 'Typy urządzeń', 'browsers' => 'Przeglądarki', 'operatingSystems' => 'Systemy operacyjne', 'ofSessions' => 'sesji', 'campaignsHint' => 'Kampanie UTM wykryte dla tej treści w wybranym okresie.', 'day' => 'Dzień', 'week' => 'Tydzień', 'month' => 'Miesiąc', 'year' => 'Rok', 'topReferrers' => 'Najlepsze źródła', 'topContent' => 'Najlepsze treści', 'recent' => 'Ostatnie wejścia', 'source' => 'Źródło', 'contentTitle' => 'Tytuł', 'views' => 'Odsłony', 'date' => 'Data', 'campaign' => 'Kampania', 'exportCsv' => 'Eksport CSV', 'createReportLink' => 'Utwórz link raportu dla klienta', 'reportLink' => 'Link raportu dla klienta', 'expiresAt' => 'Wygasa', 'created' => 'Utworzono', 'status' => 'Status', 'actions' => 'Akcje', 'active' => 'Aktywny', 'disabled' => 'Wyłączony', 'expired' => 'Wygasł', 'disable' => 'Wyłącz', 'delete' => 'Usuń', 'copyLink' => 'Kopiuj link', 'openLink' => 'Otwórz', 'copied' => 'Skopiowano', 'linkUnavailable' => 'Adres niedostępny', 'confirmDeleteReport' => 'Trwale usunąć ten link raportu? Tej operacji nie można cofnąć.', 'noData' => 'Brak danych.', 'noCampaignsTitle' => 'Brak kampanii', 'noCampaignsText' => 'Kampanie UTM pojawią się tutaj, gdy wejścia będą zawierać parametry kampanii.', 'noReferrersTitle' => 'Brak źródeł', 'noReferrersText' => 'Domeny odsyłające pojawią się tutaj, gdy odwiedzający przyjdą z zewnętrznych stron.', 'noChannelTypesTitle' => 'Brak danych kanałów', 'noChannelTypesText' => 'Typy kanałów pojawią się tutaj, gdy odwiedzający rozpoczną anonimowe sesje.', 'noTechnologyText' => 'Kategorie technologii pojawią się tutaj po zarejestrowaniu nowych sesji przeglądarki.', 'noRecentTitle' => 'Brak ostatnich wejść', 'noRecentText' => 'Ostatnie wejścia pojawią się tutaj po zarejestrowaniu ruchu dla wybranego okresu.', 'noSourceContentTitle' => 'Brak treści', 'noSourceContentText' => 'Najlepsze treści dla tego źródła pojawią się tutaj po zarejestrowaniu pasujących wejść.', 'close' => 'Zamknij', 'loading' => 'Ładowanie…', 'previous' => 'Poprzedni', 'next' => 'Następny', 'today' => 'Dzisiaj', 'thisWeek' => 'Ten tydzień', 'thisMonth' => 'Ten miesiąc', 'resetPost' => 'Resetuj ten licznik', 'resetAll' => 'Resetuj wszystkie liczniki', 'confirmPost' => 'Zresetować licznik dla tego wpisu? Tej operacji nie można cofnąć.', 'confirmAll' => 'Zresetować liczniki dla wszystkich wpisów i stron? Tej operacji nie można cofnąć.', 'resetDone' => 'Reset licznika zakończony.', ), 'de' => array( 'title' => 'Beitragsstatistiken', 'sourceTitle' => 'Quellenstatistiken', 'total' => 'Aufrufe insgesamt', 'overview' => 'Übersicht', 'sources' => 'Quellen', 'campaigns' => 'Kampagnen', 'medium' => 'Medium', 'trafficChannels' => 'Traffic-Kanäle', 'campaignsHint' => 'UTM-Kampagnen für diesen Inhalt im ausgewählten Zeitraum.', 'day' => 'Tag', 'week' => 'Woche', 'month' => 'Monat', 'year' => 'Jahr', 'topReferrers' => 'Top-Referrer', 'topContent' => 'Top-Inhalte', 'recent' => 'Letzte Besuche', 'source' => 'Quelle', 'contentTitle' => 'Titel', 'views' => 'Aufrufe', 'date' => 'Datum', 'campaign' => 'Kampagne', 'exportCsv' => 'CSV exportieren', 'noData' => 'Noch keine Daten.', 'noCampaignsTitle' => 'Noch keine Kampagnen', 'noCampaignsText' => 'UTM-Kampagnen erscheinen hier, sobald Besuche Kampagnenparameter enthalten.', 'noReferrersTitle' => 'Noch keine Referrer', 'noReferrersText' => 'Verweisende Domains erscheinen hier, wenn Besucher von externen Websites kommen.', 'noRecentTitle' => 'Noch keine letzten Besuche', 'noRecentText' => 'Letzte Besuche erscheinen hier, sobald A360 Insights Traffic für diesen Zeitraum erfasst.', 'noSourceContentTitle' => 'Noch keine Inhalte', 'noSourceContentText' => 'Top-Inhalte für diese Quelle erscheinen hier, sobald passende Besuche erfasst werden.', 'close' => 'Schließen', 'loading' => 'Wird geladen…', 'previous' => 'Zurück', 'next' => 'Weiter', 'today' => 'Heute', 'thisWeek' => 'Diese Woche', 'thisMonth' => 'Dieser Monat', 'resetPost' => 'Diesen Zähler zurücksetzen', 'resetAll' => 'Alle Zähler zurücksetzen', 'confirmPost' => 'Zähler für diesen Beitrag zurücksetzen? Dies kann nicht rückgängig gemacht werden.', 'confirmAll' => 'Zähler für alle Beiträge und Seiten zurücksetzen? Dies kann nicht rückgängig gemacht werden.', 'resetDone' => 'Zähler wurde zurückgesetzt.', ), 'fr' => array( 'title' => 'Statistiques de l’article', 'sourceTitle' => 'Statistiques de la source', 'total' => 'Vues totales', 'overview' => 'Vue d’ensemble', 'sources' => 'Sources', 'campaigns' => 'Campagnes', 'medium' => 'Medium', 'trafficChannels' => 'Canaux de trafic', 'campaignsHint' => 'Campagnes UTM détectées pour ce contenu sur la période sélectionnée.', 'day' => 'Jour', 'week' => 'Semaine', 'month' => 'Mois', 'year' => 'Année', 'topReferrers' => 'Principaux référents', 'topContent' => 'Contenus principaux', 'recent' => 'Visites récentes', 'source' => 'Source', 'contentTitle' => 'Titre', 'views' => 'Vues', 'date' => 'Date', 'campaign' => 'Campagne', 'exportCsv' => 'Exporter CSV', 'noData' => 'Aucune donnée.', 'noCampaignsTitle' => 'Aucune campagne pour le moment', 'noCampaignsText' => 'Les campagnes UTM apparaîtront ici lorsque les visites entrantes contiendront des paramètres de campagne.', 'noReferrersTitle' => 'Aucun référent pour le moment', 'noReferrersText' => 'Les domaines référents apparaîtront ici lorsque les visiteurs viendront de sites externes.', 'noRecentTitle' => 'Aucune visite récente', 'noRecentText' => 'Les visites récentes apparaîtront ici après l’enregistrement du trafic pour cette période.', 'noSourceContentTitle' => 'Aucun contenu pour le moment', 'noSourceContentText' => 'Les contenus principaux pour cette source apparaîtront ici après l’enregistrement de visites correspondantes.', 'close' => 'Fermer', 'loading' => 'Chargement…', 'previous' => 'Précédent', 'next' => 'Suivant', 'today' => 'Aujourd’hui', 'thisWeek' => 'Cette semaine', 'thisMonth' => 'Ce mois-ci', 'resetPost' => 'Réinitialiser ce compteur', 'resetAll' => 'Réinitialiser tous les compteurs', 'confirmPost' => 'Réinitialiser le compteur de cet article ? Cette action est irréversible.', 'confirmAll' => 'Réinitialiser les compteurs de tous les articles et pages ? Cette action est irréversible.', 'resetDone' => 'Compteur réinitialisé.', ), 'es' => array( 'title' => 'Estadísticas de la entrada', 'sourceTitle' => 'Estadísticas de la fuente', 'total' => 'Vistas totales', 'overview' => 'Resumen', 'sources' => 'Fuentes', 'campaigns' => 'Campañas', 'medium' => 'Medio', 'trafficChannels' => 'Canales de tráfico', 'campaignsHint' => 'Campañas UTM detectadas para este contenido en el periodo seleccionado.', 'day' => 'Día', 'week' => 'Semana', 'month' => 'Mes', 'year' => 'Año', 'topReferrers' => 'Principales referentes', 'topContent' => 'Contenido principal', 'recent' => 'Visitas recientes', 'source' => 'Fuente', 'contentTitle' => 'Título', 'views' => 'Vistas', 'date' => 'Fecha', 'campaign' => 'Campaña', 'exportCsv' => 'Exportar CSV', 'noData' => 'Sin datos todavía.', 'noCampaignsTitle' => 'Aún no hay campañas', 'noCampaignsText' => 'Las campañas UTM aparecerán aquí cuando las visitas entrantes incluyan parámetros de campaña.', 'noReferrersTitle' => 'Aún no hay referentes', 'noReferrersText' => 'Los dominios de referencia aparecerán aquí cuando los visitantes lleguen desde sitios externos.', 'noRecentTitle' => 'Aún no hay visitas recientes', 'noRecentText' => 'Las visitas recientes aparecerán aquí después de que A360 Insights registre tráfico para este periodo.', 'noSourceContentTitle' => 'Aún no hay contenido', 'noSourceContentText' => 'El contenido principal para esta fuente aparecerá aquí después de registrar visitas coincidentes.', 'close' => 'Cerrar', 'loading' => 'Cargando…', 'previous' => 'Anterior', 'next' => 'Siguiente', 'today' => 'Hoy', 'thisWeek' => 'Esta semana', 'thisMonth' => 'Este mes', 'resetPost' => 'Restablecer este contador', 'resetAll' => 'Restablecer todos los contadores', 'confirmPost' => '¿Restablecer el contador de esta entrada? Esta acción no se puede deshacer.', 'confirmAll' => '¿Restablecer los contadores de todas las entradas y páginas? Esta acción no se puede deshacer.', 'resetDone' => 'Contador restablecido.', ), 'nl' => array( 'title' => 'Berichtstatistieken', 'sourceTitle' => 'Bronstatistieken', 'total' => 'Totaal aantal weergaven', 'overview' => 'Overzicht', 'sources' => 'Bronnen', 'campaigns' => 'Campagnes', 'medium' => 'Medium', 'trafficChannels' => 'Verkeerskanalen', 'campaignsHint' => 'UTM-campagnes die voor deze inhoud in de geselecteerde periode zijn gedetecteerd.', 'day' => 'Dag', 'week' => 'Week', 'month' => 'Maand', 'year' => 'Jaar', 'topReferrers' => 'Topverwijzers', 'topContent' => 'Topinhoud', 'recent' => 'Recente bezoeken', 'source' => 'Bron', 'contentTitle' => 'Titel', 'views' => 'Weergaven', 'date' => 'Datum', 'campaign' => 'Campagne', 'exportCsv' => 'CSV exporteren', 'noData' => 'Nog geen gegevens.', 'noCampaignsTitle' => 'Nog geen campagnes', 'noCampaignsText' => 'UTM-campagnes verschijnen hier wanneer inkomende bezoeken campagneparameters bevatten.', 'noReferrersTitle' => 'Nog geen verwijzers', 'noReferrersText' => 'Verwijzende domeinen verschijnen hier wanneer bezoekers vanaf externe websites komen.', 'noRecentTitle' => 'Nog geen recente bezoeken', 'noRecentText' => 'Recente bezoeken verschijnen hier nadat A360 Insights verkeer voor deze periode heeft geregistreerd.', 'noSourceContentTitle' => 'Nog geen inhoud', 'noSourceContentText' => 'Topinhoud voor deze bron verschijnt hier nadat overeenkomende bezoeken zijn geregistreerd.', 'close' => 'Sluiten', 'loading' => 'Laden…', 'previous' => 'Vorige', 'next' => 'Volgende', 'today' => 'Vandaag', 'thisWeek' => 'Deze week', 'thisMonth' => 'Deze maand', 'resetPost' => 'Deze teller resetten', 'resetAll' => 'Alle tellers resetten', 'confirmPost' => 'Teller voor dit bericht resetten? Dit kan niet ongedaan worden gemaakt.', 'confirmAll' => 'Tellers voor alle berichten en pagina’s resetten? Dit kan niet ongedaan worden gemaakt.', 'resetDone' => 'Teller gereset.', ), 'pt' => array( 'title' => 'Estatísticas do post', 'sourceTitle' => 'Estatísticas da fonte', 'total' => 'Total de visualizações', 'overview' => 'Visão geral', 'sources' => 'Fontes', 'campaigns' => 'Campanhas', 'medium' => 'Meio', 'trafficChannels' => 'Canais de tráfego', 'campaignsHint' => 'Campanhas UTM detectadas para este conteúdo no período selecionado.', 'day' => 'Dia', 'week' => 'Semana', 'month' => 'Mês', 'year' => 'Ano', 'topReferrers' => 'Principais referenciadores', 'topContent' => 'Conteúdo principal', 'recent' => 'Visitas recentes', 'source' => 'Fonte', 'contentTitle' => 'Título', 'views' => 'Visualizações', 'date' => 'Data', 'campaign' => 'Campanha', 'exportCsv' => 'Exportar CSV', 'noData' => 'Ainda sem dados.', 'noCampaignsTitle' => 'Ainda sem campanhas', 'noCampaignsText' => 'As campanhas UTM aparecerão aqui quando as visitas recebidas incluírem parâmetros de campanha.', 'noReferrersTitle' => 'Ainda sem referenciadores', 'noReferrersText' => 'Os domínios referenciadores aparecerão aqui quando os visitantes vierem de sites externos.', 'noRecentTitle' => 'Ainda sem visitas recentes', 'noRecentText' => 'As visitas recentes aparecerão aqui depois que o A360 Insights registrar tráfego para este período.', 'noSourceContentTitle' => 'Ainda sem conteúdo', 'noSourceContentText' => 'O conteúdo principal desta fonte aparecerá aqui depois que visitas correspondentes forem registradas.', 'close' => 'Fechar', 'loading' => 'Carregando…', 'previous' => 'Anterior', 'next' => 'Próximo', 'today' => 'Hoje', 'thisWeek' => 'Esta semana', 'thisMonth' => 'Este mês', 'resetPost' => 'Redefinir este contador', 'resetAll' => 'Redefinir todos os contadores', 'confirmPost' => 'Redefinir o contador deste post? Esta ação não pode ser desfeita.', 'confirmAll' => 'Redefinir os contadores de todos os posts e páginas? Esta ação não pode ser desfeita.', 'resetDone' => 'Contador redefinido.', ), 'it' => array( 'title' => 'Statistiche dell’articolo', 'sourceTitle' => 'Statistiche della fonte', 'total' => 'Visualizzazioni totali', 'overview' => 'Panoramica', 'sources' => 'Fonti', 'campaigns' => 'Campagne', 'medium' => 'Mezzo', 'trafficChannels' => 'Canali di traffico', 'campaignsHint' => 'Campagne UTM rilevate per questo contenuto nel periodo selezionato.', 'day' => 'Giorno', 'week' => 'Settimana', 'month' => 'Mese', 'year' => 'Anno', 'topReferrers' => 'Referrer principali', 'topContent' => 'Contenuti principali', 'recent' => 'Visite recenti', 'source' => 'Fonte', 'contentTitle' => 'Titolo', 'views' => 'Visualizzazioni', 'date' => 'Data', 'campaign' => 'Campagna', 'exportCsv' => 'Esporta CSV', 'noData' => 'Ancora nessun dato.', 'noCampaignsTitle' => 'Ancora nessuna campagna', 'noCampaignsText' => 'Le campagne UTM appariranno qui quando le visite in ingresso includeranno parametri di campagna.', 'noReferrersTitle' => 'Ancora nessun referrer', 'noReferrersText' => 'I domini referrer appariranno qui quando i visitatori arriveranno da siti esterni.', 'noRecentTitle' => 'Ancora nessuna visita recente', 'noRecentText' => 'Le visite recenti appariranno qui dopo che A360 Insights avrà registrato traffico per questo periodo.', 'noSourceContentTitle' => 'Ancora nessun contenuto', 'noSourceContentText' => 'I contenuti principali per questa fonte appariranno qui dopo la registrazione di visite corrispondenti.', 'close' => 'Chiudi', 'loading' => 'Caricamento…', 'previous' => 'Precedente', 'next' => 'Successivo', 'today' => 'Oggi', 'thisWeek' => 'Questa settimana', 'thisMonth' => 'Questo mese', 'resetPost' => 'Reimposta questo contatore', 'resetAll' => 'Reimposta tutti i contatori', 'confirmPost' => 'Reimpostare il contatore per questo articolo? L’azione non può essere annullata.', 'confirmAll' => 'Reimpostare i contatori per tutti gli articoli e le pagine? L’azione non può essere annullata.', 'resetDone' => 'Contatore reimpostato.', ), ); if (isset($translations[$lang])) { return array_merge($en, $translations[$lang]); } return $en; } }