email_options = $options; $this->hooks(); if ( ! $disable_email_summaries && ! wp_next_scheduled( 'userfeedback_email_summaries_cron' ) ) { wp_schedule_event( $this->get_first_cron_date(), 'userfeedback_email_summaries_weekly', 'userfeedback_email_summaries_cron' ); } } /** * Email Summaries hooks. * * @since 1.0.0 */ public function hooks() { add_action( 'admin_enqueue_scripts', array( $this, 'admin_scripts' ) ); if ( $this->email_options['email_summaries'] ) { add_action( 'init', array( $this, 'preview' ) ); add_filter( 'userfeedback_email_template_paths', array( $this, 'add_email_template_path' ) ); add_filter( 'userfeedback_emails_templates_set_initial_args', array( $this, 'set_template_args' ) ); add_filter( 'cron_schedules', array( $this, 'add_weekly_cron_schedule' ) ); add_action( 'userfeedback_email_summaries_cron', array( $this, 'cron' ) ); add_action( 'wp_ajax_userfeedback_send_test_summary_email', array( $this, 'send_test_email' ) ); } } /** * Load required scripts for email summaries features * * @since 1.0.0 * * @return void */ public function admin_scripts() { if ( userfeedback_screen_is_settings() ) { // This will load the required dependencies for the WordPress media uploader wp_enqueue_media(); } } /** * Preview Email Summary. * * @since 1.0.0 */ public function preview() { if ( ! current_user_can( 'userfeedback_save_settings' ) ) { return; } if ( ! $this->is_preview() ) { return; } // initiate email class. $emails = new UserFeedback_WP_Emails( $this->email_template ); // check if html template option is enabled if ( ! $this->is_enabled_html_template() ) { $emails->__set( 'html', false ); } $content = $emails->build_email(); if ( ! $this->is_enabled_html_template() ) { $content = wpautop( $content ); } echo $content; // phpcs:ignore exit; } /** * Check whether it's in preview mode * * @since 1.0.0 * * @return boolean */ public function is_preview() { if ( isset( $_GET['userfeedback_email_preview'], $_GET['userfeedback_email_template'] ) && 'summary' === $_GET['userfeedback_email_template'] ) { // phpcs:ignore return true; } return false; } /** * Get the email header image. * * @since 1.0.0 * * @return string The email from address. */ public function get_header_image() { // set default header image $img = array( 'url' => plugins_url( 'assets/img/emails/userfeedback-logo-white.png', USERFEEDBACK_PLUGIN_FILE ), '2x' => '', // plugins_url( "assets/img/emails/logo-MonsterInsights@2x.png", USERFEEDBACK_PLUGIN_FILE ), ); if ( userfeedback_is_pro_version() && userfeedback_is_licensed() && ! empty( $this->email_options['summaries_header_image'] ) ) { $img['url'] = $this->email_options['summaries_header_image']; $img['2x'] = ''; } return apply_filters( 'userfeedback_email_header_image', $img ); } /** * Get the email footer image. * * @since 1.10.0 * * @return string The email from address. */ public function get_footer_image() { // set default footer image $img = array( 'url' => plugins_url( 'assets/img/emails/userfeedback-logo.png', USERFEEDBACK_PLUGIN_FILE ), '2x' => '', // plugins_url( "assets/img/emails/logo-MonsterInsights@2x.png", USERFEEDBACK_PLUGIN_FILE ), ); return apply_filters( 'userfeedback_email_footer_image', $img ); } /** * Get next cron occurrence date. * * @since 1.0.0 * * @return int */ protected function get_first_cron_date() { $schedule = array(); $schedule['day'] = wp_rand( 0, 1 ); $schedule['hour'] = wp_rand( 0, 23 ); $schedule['minute'] = wp_rand( 0, 59 ); $schedule['second'] = wp_rand( 0, 59 ); $schedule['offset'] = ( $schedule['day'] * DAY_IN_SECONDS ) + ( $schedule['hour'] * HOUR_IN_SECONDS ) + ( $schedule['minute'] * MINUTE_IN_SECONDS ) + $schedule['second']; $date = strtotime( 'next saturday' ) + $schedule['offset']; return $date; } /** * Add summaries email template path * * @since 1.0.0 * * @param array $schedules WP cron schedules. * * @return array */ public function add_email_template_path( $file_paths ) { // $file_paths['1000'] = USERFEEDBACK_PLUGIN_DIR . 'pro/includes/emails/templates'; return $file_paths; } /** * Add custom Email Summaries cron schedule. * * @since 1.0.0 * * @param array $schedules WP cron schedules. * * @return array */ public function add_weekly_cron_schedule( $schedules ) { $schedules['userfeedback_email_summaries_weekly'] = array( 'interval' => WEEK_IN_SECONDS, 'display' => esc_html__( 'Weekly UserFeedback Email Summaries', 'userfeedback-lite' ), ); return $schedules; } /** * Get email subject * * @since 1.0.0 */ public function get_email_subject() { $site_url = get_site_url(); $site_url_parsed = wp_parse_url( $site_url ); $site_url = isset( $site_url_parsed['host'] ) ? $site_url_parsed['host'] : $site_url; // Translators: The domain of the site is appended to the subject. $subject = sprintf( __( 'UserFeedback Summary - %s', 'userfeedback-lite' ), $site_url ); return apply_filters( 'userfeedback_emails_summaries_cron_subject', $subject ); } /** * Get email addresses to send * * @since 1.0.0 */ public function get_email_addresses() { $emails = array(); $email_addresses = explode( ',', $this->email_options[ 'summaries_email_addresses' ] ); if ( ! empty( $email_addresses ) && is_array( $email_addresses ) ) { foreach ( $email_addresses as $email_address ) { if ( ! empty( $email_address ) && is_email( $email_address ) ) { $emails[] = $email_address; } } } return apply_filters( 'userfeedback_email_addresses_to_send', $emails ); } /** * check if carbon copy option is enabled * * @since 1.0.0 */ public function is_cc_enabled() { $value = false; if ( 'yes' === $this->email_options['summaries_carbon_copy'] ) { $value = true; } return apply_filters( 'userfeedback_email_cc_enabled', $value, $this ); } /** * Check if html template option is turned on * * @since 1.0.0 * * @return bool */ public function is_enabled_html_template() { $value = true; if ( false === $this->email_options['summaries_html_template'] ) { $value = false; } return apply_filters( 'userfeedback_email_html_template', $value, $this ); } /** * Email Summaries cron callback. * * @since 1.0.0 */ public function cron() { $disable_email_summaries = userfeedback_get_option( 'summaries_disabled' ); if ( $disable_email_summaries ) { return; } $email = array(); $email['subject'] = $this->get_email_subject(); $email['address'] = $this->get_email_addresses(); $email['address'] = array_map( 'sanitize_email', $email['address'] ); // Create new email. $emails = new UserFeedback_WP_Emails( $this->email_template ); // Maybe include CC. if ( $this->is_cc_enabled() ) { $emails->__set( 'cc', implode( ',', $this->get_email_addresses() ) ); } // check if html template option is enabled if ( ! $this->is_enabled_html_template() ) { $emails->__set( 'html', false ); } // Go. foreach ( $email['address'] as $address ) { $emails->send( trim( $address ), $email['subject'] ); } } /** * Send test email * * @since 1.0.0 */ public function send_test_email() { // Run a security check first. check_ajax_referer( 'uf-admin-nonce', 'nonce' ); if ( ! current_user_can( 'userfeedback_save_settings' ) ) { return; } $email = array(); $email['subject'] = '[Test email] UserFeedback Summary'; $email['address'] = $this->get_email_addresses(); $email['address'] = array_map( 'sanitize_email', $email['address'] ); // Create new email. $emails = new Userfeedback_WP_Emails( $this->test_email_template ); // Maybe include CC. if ( $this->is_cc_enabled() ) { $emails->__set( 'cc', implode( ',', $this->get_email_addresses() ) ); } // check if html template option is enabled if ( ! $this->is_enabled_html_template() ) { $emails->__set( 'html', false ); } // Go. foreach ( $email['address'] as $address ) { if ( ! $emails->send( trim( $address ), $email['subject'] ) ) { wp_send_json_error(); } } wp_send_json_success(); } /** * Email summaries template arguments * * @since 1.0.0 */ public function set_template_args( $args ) { $start_date = $this->get_summaries_start_date(); $end_date = $this->get_summaries_end_date(); $args['body']['preview_title'] = $this->get_email_subject(); $args['body']['header_image'] = $this->get_header_image(); $args['body']['footer_image'] = $this->get_footer_image(); $args['body']['title'] = esc_html__( 'Hi there!', 'userfeedback-lite' ); $args['body']['blogs'] = $this->get_latest_blog_posts_from_feed(); $args['body']['description'] = sprintf( // translators: %s is the date range of the week (e.g. "January 1, 2024 - January 7, 2024"). esc_html__( 'Below is the total number of survey responses for each active survey from the week of %s ', 'userfeedback-lite' ), wp_date( 'F j, Y', strtotime( $start_date ) ) . ' - ' . wp_date( 'F j, Y', strtotime( $end_date ) ) ); $summaries = $this->get_summaries(); $args['body']['summaries'] = $summaries; if ( empty( $summaries ) ) { $args['body']['description'] = sprintf( // translators: %s is the date range of the week (e.g. "January 1, 2024 - January 7, 2024"). esc_html__( 'No responses were recorded in any of your UserFeedback surveys the week of %s ', 'userfeedback-lite' ), wp_date( 'F j, Y', strtotime( $start_date ) ) . ' - ' . wp_date( 'F j, Y', strtotime( $end_date ) ) ); } $args['body']['survey_results_url'] = admin_url( 'admin.php?page=userfeedback_results' ); $args['body']['settings_tab_url'] = esc_url( admin_url( 'admin.php?page=userfeedback_settings#/email' ) ); return apply_filters( 'userfeedback_email_summaries_template_args', $args ); } /** * get the start date from the last week * * @since 1.0.0 */ public function get_summaries_start_date() { return wp_date( 'Y-m-d', strtotime( '-1 day, last week', current_time( 'timestamp' ) ) ); // sunday of last week } /** * get the end date from the last week * * @since 1.0.0 */ public function get_summaries_end_date() { return wp_date( 'Y-m-d', strtotime( 'last saturday', current_time( 'timestamp' ) ) ); // last saturday } /** * data for email template * * @throws Exception * @since 1.0.0 */ public function get_summaries() { $start_date = new DateTime( $this->get_summaries_start_date() ); $end_date = new DateTime( $this->get_summaries_end_date() ); $start_date = $start_date->format( 'Y-m-d' ); $end_date = $end_date->format( 'Y-m-d' ); $where_config = array( array( 'submitted_at', '>=', $start_date, ), array( 'submitted_at', '<=', $end_date, ), ); $responses = UserFeedback_Response::where( $where_config ) ->select( array( 'id', 'survey_id', 'submitted_at' ) ) ->with( array( 'survey' ) ) ->group_by( 'survey_id' ) ->get(); $surveys_with_count = array_map( function( $result ) { return array( 'name' => $result->survey->title, 'responses' => $result->count, 'result_link' => admin_url( 'admin.php?page=userfeedback_results#/survey/' . $result->survey_id ), ); }, $responses ); usort( $surveys_with_count, function ($survey_a, $survey_b) { if ($survey_a['responses'] == $survey_b['responses']) return 0; return ($survey_a['responses'] > $survey_b['responses']) ? -1 : 1; }); return $surveys_with_count; } /** * Get the latest blog posts from the UserFeedback RSS feed. * * Fetches the RSS feed from userfeedback.com and extracts the titles and links * of the last 3 blog posts. * * @since 1.10.0 * @access private * * @return array Array of the latest 3 blog posts with title and link, or empty array on failure. */ private function get_latest_blog_posts_from_feed() { $source = 'https://userfeedback.com'; $rest_url = $source . '/wp-json/wp/v2/posts?per_page=3&_embed=wp:featuredmedia&_fields=title,excerpt,link,_embedded,_links'; // Fetch last 3 posts and embed media $response = wp_remote_get( $rest_url ); if ( is_wp_error( $response ) ) { return array(); // Return empty array on error } $body = wp_remote_retrieve_body( $response ); $posts_data = json_decode( $body, true ); $posts = array(); if ( empty( $posts_data ) || ! is_array( $posts_data ) ) { return array(); } foreach ( $posts_data as $post_item ) { $featured_image_url = ''; if ( isset( $post_item['_embedded']['wp:featuredmedia'] ) && ! empty( $post_item['_embedded']['wp:featuredmedia'] ) ) { $featured_media = $post_item['_embedded']['wp:featuredmedia'][0]; if ( isset( $featured_media['media_details']['sizes']['medium']['source_url'] ) ) { $featured_image_url = $featured_media['media_details']['sizes']['medium']['source_url']; } } if ( empty( $post_item['title']['rendered'] ) || empty( $post_item['link'] ) ) { continue; } $new = array( 'title' => esc_html( $post_item['title']['rendered'] ), 'link' => esc_url( $post_item['link'] ), 'excerpt' => '' ); if ( ! empty( $post_item['excerpt']['rendered'] ) ) { $new['excerpt'] = esc_html( wp_trim_words( wp_strip_all_tags( $post_item['excerpt']['rendered'] ), 15, '...' ) ); } if ( ! empty( $featured_image_url ) ) { $new['featured_image'] = esc_url_raw( $featured_image_url ); } $posts[] = $new; } return $posts; } } new UserFeedback_Email_Summaries();