is_profile_builder_page(); } /** * Check if current page is a Profile Builder admin page * * @return bool */ private function is_profile_builder_page() { if ( ! is_admin() ) { return false; } $screen = get_current_screen(); if ( ! $screen ) { return false; } // Check for PB pages $pb_pages = array( 'profile-builder', 'profile-builder-dashboard', 'profile-builder-basic-info', 'profile-builder-general-settings', 'profile-builder-add-ons', 'manage-fields', ); foreach ( $pb_pages as $page ) { if ( strpos( $screen->id, $page ) !== false ) { return true; } } // Include PB form/userlisting CPT admin screens. if ( ! empty( $screen->post_type ) ) { $pb_cpt_pages = array( 'wppb-ul-cpt', 'wppb-rf-cpt', 'wppb-epf-cpt' ); if ( in_array( $screen->post_type, $pb_cpt_pages, true ) ) { return true; } } return false; } /** * Enqueue assets */ public function enqueue_assets() { if ( ! $this->should_show_widget() ) { return; } wp_enqueue_style( 'wppb-support-chat', WPPB_PLUGIN_URL . 'assets/css/wppb-support-chat.css', array(), PROFILE_BUILDER_VERSION ); wp_enqueue_script( 'wppb-support-chat', WPPB_PLUGIN_URL . 'assets/js/wppb-support-chat.js', array(), PROFILE_BUILDER_VERSION, true ); // Compute new post count from cached data, fetching if needed on first visit. $new_count = 0; $last_viewed = (int) get_user_meta( get_current_user_id(), self::LAST_VIEWED_META_KEY, true ); $cached_posts = get_transient( self::CACHE_KEY ); if ( false === $cached_posts ) { $cached_posts = $this->get_forum_posts(); } if ( is_array( $cached_posts ) ) { foreach ( $cached_posts as $post ) { if ( ! empty( $post['timestamp'] ) && $post['timestamp'] > $last_viewed ) { $new_count++; } } } wp_localize_script( 'wppb-support-chat', 'wppbSupportChat', array( 'ajaxUrl' => admin_url( 'admin-ajax.php' ), 'nonce' => wp_create_nonce( 'wppb_support_chat' ), 'forumUrl' => self::FORUM_URL, 'newTopicUrl' => self::NEW_TOPIC_URL, 'newCount' => $new_count, 'lastViewed' => $last_viewed, 'strings' => array( 'title' => __( 'Need Help?', 'profile-builder' ), 'subtitle' => __( 'Recent community discussions', 'profile-builder' ), 'loading' => __( 'Loading...', 'profile-builder' ), 'error' => __( 'Unable to load forum posts', 'profile-builder' ), 'askQuestion' => __( 'Ask a Question', 'profile-builder' ), 'viewAll' => __( 'View All Topics', 'profile-builder' ), 'postedBy' => __( 'by', 'profile-builder' ), 'encourageTitle' => __( 'Have a question?', 'profile-builder' ), 'encourageText' => __( 'Get help directly from the plugin developers, suggest improvements, or share your feedback!', 'profile-builder' ), 'tipTitle' => __( 'Tip for faster help:', 'profile-builder' ), 'tipText' => __( 'Include what you tried, what you expected, and what happened. Screenshots help!', 'profile-builder' ), ), ) ); } /** * Render chat widget HTML */ public function render_chat_widget() { if ( ! $this->should_show_widget() ) { return; } ?>
__( 'Unauthorized', 'profile-builder' ) ) ); } $posts = $this->get_forum_posts(); if ( is_wp_error( $posts ) ) { wp_send_json_error( array( 'message' => $posts->get_error_message() ) ); } wp_send_json_success( array( 'posts' => $posts ) ); } /** * AJAX handler to mark forum posts as read */ public function ajax_mark_forum_posts_read() { check_ajax_referer( 'wppb_support_chat', 'nonce' ); if ( ! current_user_can( 'manage_options' ) ) { wp_send_json_error( array( 'message' => __( 'Unauthorized', 'profile-builder' ) ) ); } update_user_meta( get_current_user_id(), self::LAST_VIEWED_META_KEY, time() ); wp_send_json_success(); } /** * Get forum posts from RSS feed * * @return array|WP_Error */ private function get_forum_posts() { // Try to get from cache $cached = get_transient( self::CACHE_KEY ); if ( false !== $cached ) { return $cached; } // Fetch RSS feed $response = wp_remote_get( self::FEED_URL, array( 'timeout' => 4, 'sslverify' => true, ) ); if ( is_wp_error( $response ) ) { set_transient( self::CACHE_KEY, array(), self::CACHE_DURATION ); return $response; } $body = wp_remote_retrieve_body( $response ); if ( empty( $body ) ) { set_transient( self::CACHE_KEY, array(), self::CACHE_DURATION ); return new WP_Error( 'empty_feed', __( 'Empty feed response', 'profile-builder' ) ); } // Parse XML libxml_use_internal_errors( true ); $xml = simplexml_load_string( $body ); if ( false === $xml ) { set_transient( self::CACHE_KEY, array(), self::CACHE_DURATION ); return new WP_Error( 'parse_error', __( 'Unable to parse feed', 'profile-builder' ) ); } $posts = array(); $count = 0; if ( isset( $xml->channel->item ) ) { foreach ( $xml->channel->item as $item ) { if ( $count >= self::POSTS_COUNT ) { break; } // Get dc:creator namespace $dc = $item->children( 'http://purl.org/dc/elements/1.1/' ); // Clean up title - strip HTML tags and decode entities $title = (string) $item->title; $title = strip_tags( $title ); $title = html_entity_decode( $title, ENT_QUOTES, 'UTF-8' ); $title = trim( $title ); $posts[] = array( 'title' => $title, 'link' => (string) $item->link, 'date' => $this->format_date( (string) $item->pubDate ), 'timestamp' => (int) strtotime( (string) $item->pubDate ), 'author' => isset( $dc->creator ) ? (string) $dc->creator : '', ); $count++; } } // Cache the results set_transient( self::CACHE_KEY, $posts, self::CACHE_DURATION ); return $posts; } /** * Format date for display * * @param string $date_string * @return string */ private function format_date( $date_string ) { $timestamp = strtotime( $date_string ); if ( ! $timestamp ) { return ''; } $now = time(); $diff = $now - $timestamp; // Less than a day ago if ( $diff < DAY_IN_SECONDS ) { $hours = floor( $diff / HOUR_IN_SECONDS ); if ( $hours < 1 ) { return __( 'Just now', 'profile-builder' ); } /* translators: %d: number of hours */ return sprintf( _n( '%d hour ago', '%d hours ago', $hours, 'profile-builder' ), $hours ); } // Less than a week ago if ( $diff < WEEK_IN_SECONDS ) { $days = floor( $diff / DAY_IN_SECONDS ); /* translators: %d: number of days */ return sprintf( _n( '%d day ago', '%d days ago', $days, 'profile-builder' ), $days ); } // More than a week, show date return date_i18n( get_option( 'date_format' ), $timestamp ); } } // Initialize add_action( 'admin_init', array( 'WPPB_Support_Chat', 'get_instance' ) );