| @@ -7,13 +7,12 @@ | ||
| 7 | 7 | */ |
| 8 | 8 | |
| 9 | 9 | namespace SRFM\Inc\Global_Settings; |
| 10 | 10 | |
| 11 | +use SRFM\Inc\Helper; | |
| 12 | +use SRFM\Inc\Traits\Get_Instance; | |
| 13 | +use WP_REST_Request; | |
| 11 | 14 | use WP_REST_Response; |
| 12 | -use WP_REST_Request; | |
| 13 | -use WP_Query; | |
| 14 | -use SRFM\Inc\Traits\Get_Instance; | |
| 15 | -use SRFM\Inc\Helper; | |
| 16 | 15 | |
| 17 | 16 | /** |
| 18 | 17 | * Email Summary Class. |
| 19 | 18 | * |
| @@ -64,9 +63,15 @@ | ||
| 64 | 63 | |
| 65 | 64 | $email_send_to = ''; |
| 66 | 65 | |
| 67 | 66 | if ( is_array( $data ) && isset( $data['srfm_email_sent_to'] ) && is_string( $data['srfm_email_sent_to'] ) ) { |
| 68 | - $email_send_to = $data['srfm_email_sent_to']; | |
| 67 | + $email_send_to = sanitize_email( $data['srfm_email_sent_to'] ); | |
| 68 | + if ( ! is_email( $email_send_to ) ) { | |
| 69 | + return new \WP_REST_Response( | |
| 70 | + [ 'data' => __( 'Invalid email address.', 'sureforms' ) ], | |
| 71 | + 400 | |
| 72 | + ); | |
| 73 | + } | |
| 69 | 74 | } |
| 70 | 75 | |
| 71 | 76 | $get_email_summary_options = [ |
| 72 | 77 | 'srfm_email_sent_to' => $email_send_to, |
| @@ -81,90 +86,430 @@ | ||
| 81 | 86 | ); |
| 82 | 87 | } |
| 83 | 88 | |
| 84 | 89 | /** |
| 90 | + * Get or copy image to uploads folder. | |
| 91 | + * | |
| 92 | + * @param string $filename The image filename. | |
| 93 | + * @param string $source_path The source path relative to plugin directory. | |
| 94 | + * @return string The public URL of the image. | |
| 95 | + * | |
| 96 | + * @since 1.10.1 | |
| 97 | + */ | |
| 98 | + public static function get_public_image_url( $filename, $source_path ) { | |
| 99 | + // Sanitize filename. | |
| 100 | + $filename = basename( $filename ); | |
| 101 | + | |
| 102 | + // Validate allowed extensions. | |
| 103 | + $allowed_ext = [ 'png', 'jpg', 'jpeg', 'gif', 'svg' ]; | |
| 104 | + $ext = strtolower( pathinfo( $filename, PATHINFO_EXTENSION ) ); | |
| 105 | + if ( ! in_array( $ext, $allowed_ext, true ) ) { | |
| 106 | + return ''; | |
| 107 | + } | |
| 108 | + | |
| 109 | + // Whitelist or sanitize source_path if possible. | |
| 110 | + $source_path = trailingslashit( ltrim( $source_path, '/' ) ); | |
| 111 | + | |
| 112 | + // Upload directory info. | |
| 113 | + $upload_dir = wp_upload_dir(); | |
| 114 | + $sureforms_upload_dir = trailingslashit( $upload_dir['basedir'] ) . 'sureforms/images/'; | |
| 115 | + $sureforms_upload_url = trailingslashit( $upload_dir['baseurl'] ) . 'sureforms/images/'; | |
| 116 | + | |
| 117 | + // Create directory if it doesn't exist. | |
| 118 | + if ( ! file_exists( $sureforms_upload_dir ) && ! wp_mkdir_p( $sureforms_upload_dir ) ) { | |
| 119 | + // Fallback URL. | |
| 120 | + return esc_url( SRFM_URL . $source_path . $filename ); | |
| 121 | + } | |
| 122 | + | |
| 123 | + $target_file = $sureforms_upload_dir . $filename; | |
| 124 | + $target_url = $sureforms_upload_url . $filename; | |
| 125 | + | |
| 126 | + // Copy if doesn't exist. | |
| 127 | + if ( ! file_exists( $target_file ) ) { | |
| 128 | + $source_file = SRFM_DIR . $source_path . $filename; | |
| 129 | + if ( ! file_exists( $source_file ) || ! copy( $source_file, $target_file ) ) { | |
| 130 | + // Fallback URL. | |
| 131 | + return esc_url( SRFM_URL . $source_path . $filename ); | |
| 132 | + } | |
| 133 | + } | |
| 134 | + | |
| 135 | + return esc_url( $target_url ); | |
| 136 | + } | |
| 137 | + | |
| 138 | + /** | |
| 85 | 139 | * Function to get the total number of entries for the last week. |
| 86 | 140 | * |
| 141 | + * @param array<array{form_id:int,title:string,count:int}>|null $forms_data Optional. Forms data with entry counts. If null, fetches from database. | |
| 142 | + * | |
| 87 | 143 | * @since 0.0.2 |
| 88 | 144 | * @return string HTML table with entries count. |
| 89 | 145 | */ |
| 90 | - public static function get_total_entries_for_week() { | |
| 91 | - $args = [ | |
| 92 | - 'post_type' => SRFM_FORMS_POST_TYPE, | |
| 93 | - 'posts_per_page' => -1, | |
| 146 | + public static function get_total_entries_for_week( $forms_data = null ) { | |
| 147 | + // Calculate timestamp for 7 days ago (last week). | |
| 148 | + $week_ago_timestamp = strtotime( '-7 days' ); | |
| 149 | + | |
| 150 | + if ( null === $forms_data ) { | |
| 151 | + // Use the helper function to get forms with entry counts. | |
| 152 | + $forms_data = Helper::get_forms_with_entry_counts( $week_ago_timestamp ); | |
| 153 | + } | |
| 154 | + | |
| 155 | + $logs_url = admin_url( 'admin.php?page=sureforms_entries' ); | |
| 156 | + | |
| 157 | + ob_start(); | |
| 158 | + ?> | |
| 159 | + <!DOCTYPE html> | |
| 160 | + <html lang="en"> | |
| 161 | + <head> | |
| 162 | + <meta charset="UTF-8"> | |
| 163 | + <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| 164 | + <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> | |
| 165 | + <meta http-equiv="X-UA-Compatible" content="IE=edge"> | |
| 166 | + <title><?php esc_html_e( 'Weekly Summary', 'sureforms' ); ?></title> | |
| 167 | + <?php | |
| 168 | + // phpcs:ignore WordPress.WP.EnqueuedResources.NonEnqueuedStylesheet -- Required in email HTML; wp_enqueue_style() can't be used for emails. | |
| 169 | + echo '<link href="https://fonts.googleapis.com/css2?family=Figtree:wght@400;500;600&display=swap" rel="stylesheet">'; | |
| 170 | + ?> | |
| 171 | + <style> | |
| 172 | + /* Mobile-specific styles */ | |
| 173 | + @media only screen and (max-width: 600px) { | |
| 174 | + .email-greeting { | |
| 175 | + font-size: 16px !important; | |
| 176 | + } | |
| 177 | + | |
| 178 | + /* Padding reductions */ | |
| 179 | + .pad-32 { padding: 32px !important; } | |
| 180 | + .pad-24 { padding: 24px !important; } | |
| 181 | + .pad-16 { padding: 16px !important; } | |
| 182 | + .margin-mob { margin: 24px 16px !important; } | |
| 183 | + } | |
| 184 | + </style> | |
| 185 | + </head> | |
| 186 | + <body class="pad-24" style="font-family:Figtree,Arial,sans-serif;background-color:#F1F5F9;margin:0;padding:32px;"> | |
| 187 | + <div style="max-width:640px;margin:0 auto;"> | |
| 188 | + <div style="margin-bottom:24px;text-align:left;"> | |
| 189 | + <img | |
| 190 | + src="<?php echo esc_url( self::get_public_image_url( 'sureforms-logo-full.png', 'admin/assets/' ) ); ?>" | |
| 191 | + alt="<?php esc_attr_e( 'SureForms Logo', 'sureforms' ); ?>" | |
| 192 | + width="192" height="32" | |
| 193 | + style="display:block;"> | |
| 194 | + </div> | |
| 195 | + <div style="background-color:#FFFFFF;padding-bottom:40px;"> | |
| 196 | + <div class="pad-16" style="padding:24px;"> | |
| 197 | + <p class="email-greeting" style="font-size:18px;font-weight:600;color:#111827;margin:0 0 8px;"> | |
| 198 | + <?php | |
| 199 | + echo esc_html__( 'Hey There,', 'sureforms' ); | |
| 200 | + ?> | |
| 201 | + </p> | |
| 202 | + <p style="font-size:14px;color:#4B5563;margin:0 0 16px;line-height:20px;"> | |
| 203 | + <?php | |
| 204 | + $site_url = home_url(); | |
| 205 | + $site_name = get_bloginfo( 'name' ) ? get_bloginfo( 'name' ) : $site_url; | |
| 206 | + printf( | |
| 207 | + /* translators: 1: site URL, 2: site name */ | |
| 208 | + esc_html__( "Here's your SureForms report for the last 7 days of %s.", 'sureforms' ), | |
| 209 | + sprintf( | |
| 210 | + '<a href="%1$s" target="_blank" rel="noopener noreferrer" style="color:#4B5563;text-decoration:underline;">%2$s</a>', | |
| 211 | + esc_url( $site_url ), | |
| 212 | + esc_html( $site_name ) | |
| 213 | + ) | |
| 214 | + ); | |
| 215 | + ?> | |
| 216 | + </p> | |
| 217 | + | |
| 218 | + <?php | |
| 219 | + ob_start(); | |
| 220 | + ?> | |
| 221 | + <table style="border:1px solid #E5E7EB;border-radius:8px;box-shadow:0 1px 1px rgba(0,0,0,0.05);margin-top:16px;width:100%;border-collapse:separate;border-spacing:0;table-layout:fixed;"> | |
| 222 | + <thead> | |
| 223 | + <tr style="background-color:#F9FAFB;"> | |
| 224 | + <th style="padding:8px 12px;font-size:14px;font-weight:500;color:#111827;text-align:left;border-top-left-radius:8px;border-bottom:0.5px solid #E5E7EB;white-space:nowrap;width:auto;"><?php esc_html_e( 'Form Name', 'sureforms' ); ?></th> | |
| 225 | + <th style="padding:8px 12px;font-size:14px;font-weight:500;color:#111827;text-align:right;width:80px;border-top-right-radius:8px;border-bottom:0.5px solid #E5E7EB;white-space:nowrap;"><?php esc_html_e( 'Entries', 'sureforms' ); ?></th> | |
| 226 | + </tr> | |
| 227 | + </thead> | |
| 228 | + <tbody> | |
| 229 | + <?php | |
| 230 | + $table_html = ob_get_clean(); | |
| 231 | + | |
| 232 | + $total_entries = 0; | |
| 233 | + | |
| 234 | + if ( ! empty( $forms_data ) ) { | |
| 235 | + foreach ( $forms_data as $form ) { | |
| 236 | + if ( $form['count'] <= 0 ) { | |
| 237 | + continue; | |
| 238 | + } | |
| 239 | + | |
| 240 | + $total_entries += $form['count']; | |
| 241 | + | |
| 242 | + ob_start(); | |
| 243 | + ?> | |
| 244 | + <tr style="background-color:#FFFFFF;"> | |
| 245 | + <td style="padding:12px;font-size:14px;color:#4B5563;border-bottom:0.5px solid #E5E7EB;overflow-wrap:anywhere;white-space:normal;word-break: break-word;"><?php echo esc_html( $form['title'] ); ?></td> | |
| 246 | + <td style="padding:12px;font-size:14px;color:#4B5563;text-align:right;border-bottom:0.5px solid #E5E7EB;white-space:nowrap;width:80px;"><?php echo esc_html( Helper::get_string_value( $form['count'] ) ); ?></td> | |
| 247 | + </tr> | |
| 248 | + <?php | |
| 249 | + $table_html .= ob_get_clean(); | |
| 250 | + } | |
| 251 | + | |
| 252 | + ob_start(); | |
| 253 | + ?> | |
| 254 | + </tbody> | |
| 255 | + <tfoot> | |
| 256 | + <tr style="background-color:#F9FAFB;font-weight:bold;"> | |
| 257 | + <td style="padding:8px 12px;font-size:14px;color:#111827;border-bottom-left-radius:8px;white-space:nowrap;"><?php echo esc_html__( 'Total Entries', 'sureforms' ); ?></td> | |
| 258 | + <td style="padding:8px 12px;font-size:14px;color:#111827;text-align:right;border-bottom-right-radius:8px;white-space:nowrap;width:80px;"><?php echo esc_html( Helper::get_string_value( $total_entries ) ); ?></td> | |
| 259 | + </tr> | |
| 260 | + </tfoot> | |
| 261 | + <?php | |
| 262 | + $table_html .= ob_get_clean(); | |
| 263 | + } | |
| 264 | + | |
| 265 | + ob_start(); | |
| 266 | + ?> | |
| 267 | + </table> | |
| 268 | + <?php | |
| 269 | + $table_html .= ob_get_clean(); | |
| 270 | + | |
| 271 | + echo wp_kses_post( $table_html ); | |
| 272 | + ?> | |
| 273 | + | |
| 274 | + <a href="<?php echo esc_url( $logs_url ); ?>" | |
| 275 | + style="display:inline-block;background-color:#2563EB;color:#FFFFFF;padding:8px 12px;border-radius:4px;text-decoration:none;font-size:12px;font-weight:600;margin-top:16px;"> | |
| 276 | + <?php esc_html_e( 'View Entries', 'sureforms' ); ?> | |
| 277 | + </a> | |
| 278 | + </div> | |
| 279 | + | |
| 280 | + <hr style="border:none;border-top:1px solid #eee;"> | |
| 281 | + | |
| 282 | + <!-- Promotion Section --> | |
| 283 | + <?php | |
| 284 | + if ( ! Helper::has_pro() ) { | |
| 285 | + $plugin_key = self::get_next_promo_plugin(); | |
| 286 | + self::render_promo_banner( $plugin_key ); | |
| 287 | + self::mark_promo_sent( $plugin_key ); | |
| 288 | + } | |
| 289 | + ?> | |
| 290 | + | |
| 291 | + <p style="font-size:12px;color:#9CA3AF;text-align:center;margin:16px 16px;"> | |
| 292 | + <?php | |
| 293 | + printf( | |
| 294 | + /* translators: %s: opening and closing anchor tag for SureForms settings link */ | |
| 295 | + esc_html__( 'Manage Email Summaries from your %1$sSureForms settings%2$s', 'sureforms' ), | |
| 296 | + '<a href="' . esc_url( admin_url( 'admin.php?page=sureforms_form_settings&tab=general-settings' ) ) . '" style="color:#9CA3AF;text-decoration:underline;">', | |
| 297 | + '</a>' | |
| 298 | + ); | |
| 299 | + ?> | |
| 300 | + </p> | |
| 301 | + | |
| 302 | + <hr style="margin:16px 24px;border:none;border-top:1px solid #eee;"> | |
| 303 | + | |
| 304 | + <div style="text-align:center;margin-top:16px;"> | |
| 305 | + <img src="<?php echo esc_url( self::get_public_image_url( 'sureforms-logo-full.png', 'admin/assets/' ) ); ?>" alt="<?php esc_attr_e( 'SureForms Logo', 'sureforms' ); ?>" height="20" style="display:block;margin:0 auto;"> | |
| 306 | + </div> | |
| 307 | + </div> | |
| 308 | + </div> | |
| 309 | + </body> | |
| 310 | + </html> | |
| 311 | + <?php | |
| 312 | + $content = ob_get_clean(); | |
| 313 | + return false !== $content ? $content : ''; | |
| 314 | + } | |
| 315 | + | |
| 316 | + /** | |
| 317 | + * Retrieve all available promo banners. | |
| 318 | + * | |
| 319 | + * Returns an associative array of promo plugin data, | |
| 320 | + * including logo, title, description, and link info. | |
| 321 | + * | |
| 322 | + * @since 1.12.1 | |
| 323 | + * | |
| 324 | + * @return array List of promo banners with details. | |
| 325 | + */ | |
| 326 | + public static function get_promo_banners() { | |
| 327 | + return [ | |
| 328 | + 'ottokit' => [ | |
| 329 | + 'logo' => 'ottokit.png', | |
| 330 | + 'title' => __( 'Automate Workflows with OttoKit', 'sureforms' ), | |
| 331 | + 'description' => __( 'Connect your apps and automate repetitive tasks with ease. Build workflows that save time, reduce errors, and keep your business running smoothly around the clock.', 'sureforms' ), | |
| 332 | + 'link' => 'https://ottokit.com?utm_medium=sureforms-email-summary', | |
| 333 | + 'link_text' => __( 'Explore OttoKit', 'sureforms' ), | |
| 334 | + 'plugin_path' => 'suretriggers/suretriggers.php', | |
| 335 | + ], | |
| 336 | + 'surerank' => [ | |
| 337 | + 'logo' => 'surerank.png', | |
| 338 | + 'title' => __( 'Optimize Your Site with SureRank', 'sureforms' ), | |
| 339 | + 'description' => __( 'Fix common SEO issues and make your site search-friendly without the clutter. Check pages, add titles, meta, and schema — all in one simple plugin.', 'sureforms' ), | |
| 340 | + 'link' => 'https://surerank.com?utm_medium=sureforms-email-summary', | |
| 341 | + 'link_text' => __( 'Explore SureRank', 'sureforms' ), | |
| 342 | + 'plugin_path' => 'surerank/surerank.php', | |
| 343 | + ], | |
| 344 | + 'suremail' => [ | |
| 345 | + 'logo' => 'suremail.png', | |
| 346 | + 'title' => __( 'Send Emails Reliably with SureMail', 'sureforms' ), | |
| 347 | + 'description' => __( 'Make sure every WordPress email gets delivered. View logs, debug errors, and send with confidence using a lightweight SMTP solution.', 'sureforms' ), | |
| 348 | + 'link' => 'https://suremails.com?utm_medium=sureforms-email-summary', | |
| 349 | + 'link_text' => __( 'Explore SureMail', 'sureforms' ), | |
| 350 | + 'plugin_path' => 'suremails/suremails.php', | |
| 351 | + ], | |
| 352 | + 'surecart' => [ | |
| 353 | + 'logo' => 'surecart.png', | |
| 354 | + 'title' => __( 'Sell with Ease using SureCart', 'sureforms' ), | |
| 355 | + 'description' => __( 'Run your online store on WordPress with a modern checkout, subscriptions, and payments. Fast, flexible, and built for growth.', 'sureforms' ), | |
| 356 | + 'link' => 'https://surecart.com?utm_medium=sureforms-email-summary', | |
| 357 | + 'link_text' => __( 'Explore SureCart', 'sureforms' ), | |
| 358 | + 'plugin_path' => 'surecart/surecart.php', | |
| 359 | + ], | |
| 360 | + 'suredash' => [ | |
| 361 | + 'logo' => 'suredash.png', | |
| 362 | + 'title' => __( 'Build Your Community with SureDash', 'sureforms' ), | |
| 363 | + 'description' => __( 'Create a central hub where members can connect, share, and grow together. Manage discussions, courses, and events — all from your own WordPress site.', 'sureforms' ), | |
| 364 | + 'link' => 'https://suredash.com?utm_medium=sureforms-email-summary', | |
| 365 | + 'link_text' => __( 'Explore SureDash', 'sureforms' ), | |
| 366 | + 'plugin_path' => 'suredash/suredash.php', | |
| 367 | + ], | |
| 94 | 368 | ]; |
| 369 | + } | |
| 95 | 370 | |
| 96 | - $query = new WP_Query( $args ); | |
| 371 | + /** | |
| 372 | + * Check if a plugin is installed. | |
| 373 | + * | |
| 374 | + * @param string $plugin_path The plugin path (e.g., 'plugin-folder/plugin-file.php'). | |
| 375 | + * @return bool True if plugin is installed, false otherwise. | |
| 376 | + * @since 2.3.0 | |
| 377 | + */ | |
| 378 | + public static function is_plugin_installed( $plugin_path ) { | |
| 379 | + return '' !== Helper::get_plugin_if_installed( [ $plugin_path ] ); | |
| 380 | + } | |
| 97 | 381 | |
| 98 | - $admin_user_name = get_user_by( 'id', 1 ) ? get_user_by( 'id', 1 )->display_name : 'Admin'; | |
| 382 | + /** | |
| 383 | + * Render a promo banner for a given plugin. | |
| 384 | + * | |
| 385 | + * Outputs the banner HTML for the specified plugin key. | |
| 386 | + * If the key is invalid, nothing is rendered. | |
| 387 | + * | |
| 388 | + * @since 1.12.1 | |
| 389 | + * | |
| 390 | + * @param string $plugin_key The key of the promo plugin to render. | |
| 391 | + * | |
| 392 | + * @return void | |
| 393 | + */ | |
| 394 | + public static function render_promo_banner( $plugin_key ) { | |
| 395 | + $banners = self::get_promo_banners(); | |
| 99 | 396 | |
| 100 | - $table_html = '<b>' . __( 'Hello', 'sureforms' ) . ' ' . $admin_user_name . ',</b><br><br>'; | |
| 101 | - $table_html .= '<span>' . __( 'Let\'s see how your forms performed in the last week', 'sureforms' ) . '</span><br><br>'; | |
| 102 | - $table_html .= '<table style="width: 100%; border-collapse: collapse; margin-bottom: 20px;">'; | |
| 103 | - $table_html .= '<thead>'; | |
| 104 | - $table_html .= '<tr style="background-color: #333; color: #fff; text-align: left;">'; | |
| 105 | - $table_html .= '<th style="padding: 10px;">' . __( 'Form Name', 'sureforms' ) . '</th>'; | |
| 106 | - $table_html .= '<th style="padding: 10px;">' . __( 'Entries', 'sureforms' ) . '</th>'; | |
| 107 | - $table_html .= '</tr>'; | |
| 108 | - $table_html .= '</thead>'; | |
| 109 | - $table_html .= '<tbody>'; | |
| 397 | + if ( ! isset( $banners[ $plugin_key ] ) ) { | |
| 398 | + return; | |
| 399 | + } | |
| 110 | 400 | |
| 111 | - if ( $query->have_posts() ) { | |
| 112 | - $row_index = 0; | |
| 113 | - while ( $query->have_posts() ) { | |
| 114 | - $query->the_post(); | |
| 115 | - global $post; | |
| 401 | + $args = $banners[ $plugin_key ]; | |
| 116 | 402 | |
| 117 | - $post_id_formatted = strval( $post->ID ); | |
| 403 | + if ( isset( $args['plugin_path'] ) && self::is_plugin_installed( $args['plugin_path'] ) ) { | |
| 404 | + return; | |
| 405 | + } | |
| 118 | 406 | |
| 119 | - $previous_week_start = gmdate( 'Y-m-d', strtotime( '-1 week last monday' ) ); | |
| 120 | - $previous_week_end = gmdate( 'Y-m-d', strtotime( '-1 week next sunday' ) ); | |
| 407 | + ?> | |
| 408 | + <div class="margin-mob" style="margin:32px 24px;padding:16px;border:0.5px solid #E5E7EB;border-radius:8px;background:#FFFFFF;text-align:left;"> | |
| 409 | + <div style="margin-bottom:4px;"> | |
| 410 | + <img | |
| 411 | + src="<?php echo esc_url( self::get_public_image_url( $args['logo'], 'admin/assets/' ) ); ?>" | |
| 412 | + alt="<?php echo esc_attr( $args['title'] ); ?> Logo" | |
| 413 | + width="20" height="20" | |
| 414 | + style="display:block;"> | |
| 415 | + </div> | |
| 121 | 416 | |
| 122 | - $taxonomy = 'sureforms_tax'; | |
| 123 | - $entries_args = [ | |
| 124 | - 'post_type' => SRFM_ENTRIES_POST_TYPE, | |
| 125 | - 'tax_query' => [ // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_tax_query. --We require tax_query for this function to work. | |
| 126 | - [ | |
| 127 | - 'taxonomy' => $taxonomy, | |
| 128 | - 'field' => 'slug', | |
| 129 | - 'terms' => $post_id_formatted, | |
| 130 | - ], | |
| 131 | - ], | |
| 132 | - 'date_query' => [ | |
| 133 | - [ | |
| 134 | - 'after' => $previous_week_start, | |
| 135 | - 'before' => $previous_week_end, | |
| 136 | - 'inclusive' => true, | |
| 137 | - ], | |
| 138 | - ], | |
| 139 | - ]; | |
| 140 | - $entries_query = new WP_Query( $entries_args ); | |
| 141 | - $entry_count = $entries_query->post_count; | |
| 417 | + <p style="font-size:14px;line-height:20px;font-weight:600;color:#111827;margin:0 0 4px;"> | |
| 418 | + <?php echo esc_html( $args['title'] ); ?> | |
| 419 | + </p> | |
| 420 | + <p style="font-size:12px;color:#4B5563;margin:0 0 4px;line-height:16px;font-weight:400;"> | |
| 421 | + <?php echo esc_html( $args['description'] ); ?> | |
| 422 | + </p> | |
| 423 | + <a href="<?php echo esc_url( $args['link'] ); ?>" target="_blank" rel="noopener noreferrer" | |
| 424 | + style="font-size:12px;font-weight:600;color:#EF4444;text-decoration:none;line-height:16px;"> | |
| 425 | + <?php echo esc_html( $args['link_text'] ); ?> → | |
| 426 | + </a> | |
| 427 | + </div> | |
| 428 | + <?php | |
| 429 | + } | |
| 142 | 430 | |
| 143 | - $bg_color = 0 === $row_index % 2 ? '#ffffff' : '#f2f2f2;'; | |
| 431 | + /** | |
| 432 | + * Get the next promo plugin. | |
| 433 | + * | |
| 434 | + * @return string The plugin key for the next promo banner. | |
| 435 | + * @since 1.12.1 | |
| 436 | + */ | |
| 437 | + public static function get_next_promo_plugin() { | |
| 438 | + $all_banners = self::get_promo_banners(); | |
| 439 | + $all_plugins = array_keys( $all_banners ); | |
| 144 | 440 | |
| 145 | - $table_html .= '<tr style="background-color: ' . $bg_color . ';">'; | |
| 146 | - $table_html .= '<td style="padding: 10px;">' . esc_html( get_the_title() ) . '</td>'; | |
| 147 | - $table_html .= '<td style="padding: 10px;">' . esc_html( Helper::get_string_value( $entry_count ) ) . '</td>'; | |
| 148 | - $table_html .= '</tr>'; | |
| 441 | + $remaining = Helper::get_array_value( Helper::get_srfm_option( 'remaining_promos', [] ) ); | |
| 149 | 442 | |
| 150 | - $row_index++; | |
| 443 | + if ( empty( $remaining ) ) { | |
| 444 | + $remaining = $all_plugins; | |
| 445 | + } | |
| 446 | + | |
| 447 | + foreach ( $remaining as $key ) { | |
| 448 | + if ( ! isset( $all_banners[ $key ] ) ) { | |
| 449 | + $remaining = array_diff( $remaining, [ $key ] ); | |
| 450 | + continue; | |
| 151 | 451 | } |
| 152 | - } else { | |
| 153 | - $table_html .= '<tr>'; | |
| 154 | - $table_html .= '<td colspan="2" style="padding: 10px;">' . __( 'No forms found.', 'sureforms' ) . '</td>'; | |
| 155 | - $table_html .= '</tr>'; | |
| 452 | + | |
| 453 | + $banner = $all_banners[ $key ]; | |
| 454 | + | |
| 455 | + if ( isset( $banner['plugin_path'] ) && self::is_plugin_installed( $banner['plugin_path'] ) ) { | |
| 456 | + $remaining = array_diff( $remaining, [ $key ] ); | |
| 457 | + Helper::update_srfm_option( 'remaining_promos', $remaining ); | |
| 458 | + continue; | |
| 459 | + } | |
| 460 | + | |
| 461 | + return $key; | |
| 156 | 462 | } |
| 157 | 463 | |
| 158 | - $table_html .= '</tbody>'; | |
| 159 | - $table_html .= '</table>'; | |
| 464 | + if ( empty( $remaining ) ) { | |
| 465 | + $remaining = $all_plugins; | |
| 466 | + Helper::update_srfm_option( 'remaining_promos', $remaining ); | |
| 160 | 467 | |
| 161 | - wp_reset_postdata(); | |
| 468 | + foreach ( $remaining as $key ) { | |
| 469 | + if ( ! isset( $all_banners[ $key ] ) ) { | |
| 470 | + continue; | |
| 471 | + } | |
| 162 | 472 | |
| 163 | - return $table_html; | |
| 473 | + $banner = $all_banners[ $key ]; | |
| 474 | + | |
| 475 | + if ( isset( $banner['plugin_path'] ) && self::is_plugin_installed( $banner['plugin_path'] ) ) { | |
| 476 | + $remaining = array_diff( $remaining, [ $key ] ); | |
| 477 | + Helper::update_srfm_option( 'remaining_promos', $remaining ); | |
| 478 | + continue; | |
| 479 | + } | |
| 480 | + | |
| 481 | + return $key; | |
| 482 | + } | |
| 483 | + } | |
| 484 | + | |
| 485 | + return ''; | |
| 164 | 486 | } |
| 165 | 487 | |
| 166 | 488 | /** |
| 489 | + * Mark a promo as sent by removing it from the remaining list. | |
| 490 | + * | |
| 491 | + * @param string $plugin_key The plugin key to mark as sent. | |
| 492 | + * @return void | |
| 493 | + * @since 1.12.1 | |
| 494 | + */ | |
| 495 | + public static function mark_promo_sent( $plugin_key ) { | |
| 496 | + if ( '' === $plugin_key ) { | |
| 497 | + return; | |
| 498 | + } | |
| 499 | + | |
| 500 | + $remaining = Helper::get_array_value( Helper::get_srfm_option( 'remaining_promos', [] ) ); | |
| 501 | + | |
| 502 | + if ( empty( $remaining ) ) { | |
| 503 | + $remaining = array_keys( self::get_promo_banners() ); | |
| 504 | + } | |
| 505 | + | |
| 506 | + $remaining = array_diff( $remaining, [ $plugin_key ] ); | |
| 507 | + | |
| 508 | + Helper::update_srfm_option( 'remaining_promos', $remaining ); | |
| 509 | + } | |
| 510 | + | |
| 511 | + /** | |
| 167 | 512 | * Function to send the entries to admin mail. |
| 168 | 513 | * |
| 169 | 514 | * @param array<mixed>|bool $email_summary_options Email Summary Options. |
| 170 | 515 | * @since 0.0.2 |
| @@ -170,10 +515,23 @@ | ||
| 170 | 515 | * @since 0.0.2 |
| 171 | 516 | * @return void |
| 172 | 517 | */ |
| 173 | 518 | public static function send_entries_to_admin( $email_summary_options ) { |
| 174 | - $entries_count_table = self::get_total_entries_for_week(); | |
| 519 | + // Calculate timestamp for 7 days ago (last week). | |
| 520 | + $week_ago_timestamp = strtotime( '-7 days' ); | |
| 175 | 521 | |
| 522 | + $forms_data = Helper::get_forms_with_entry_counts( $week_ago_timestamp ); | |
| 523 | + | |
| 524 | + // Calculate total entries. | |
| 525 | + $total_entries = array_sum( wp_list_pluck( $forms_data, 'count' ) ); | |
| 526 | + | |
| 527 | + // If no entries at all, don't send the email. | |
| 528 | + if ( $total_entries <= 0 ) { | |
| 529 | + return; | |
| 530 | + } | |
| 531 | + | |
| 532 | + $entries_count_table = self::get_total_entries_for_week( $forms_data ); | |
| 533 | + | |
| 176 | 534 | $recipients_string = ''; |
| 177 | 535 | |
| 178 | 536 | if ( is_array( $email_summary_options ) && isset( $email_summary_options['srfm_email_sent_to'] ) && is_string( $email_summary_options['srfm_email_sent_to'] ) ) { |
| 179 | 537 | $recipients_string = $email_summary_options['srfm_email_sent_to']; |
| @@ -180,11 +538,13 @@ | ||
| 180 | 538 | } |
| 181 | 539 | |
| 182 | 540 | $recipients = $recipients_string ? explode( ',', $recipients_string ) : []; |
| 183 | 541 | |
| 184 | - $site_title = get_bloginfo( 'name' ); | |
| 542 | + $from_date = date_i18n( 'F j, Y', $week_ago_timestamp ); | |
| 543 | + $to_date = date_i18n( 'F j, Y' ); | |
| 185 | 544 | |
| 186 | - $subject = __( 'SureForms Email Summary - ', 'sureforms' ) . $site_title; | |
| 545 | + // Translators: %1$s: From Date, %2$s: To Date. | |
| 546 | + $subject = sprintf( __( 'Email Summary of your last week - %1$s to %2$s', 'sureforms' ), $from_date, $to_date ); | |
| 187 | 547 | $message = $entries_count_table; |
| 188 | 548 | $headers = [ |
| 189 | 549 | 'Content-Type: text/html; charset=UTF-8', |
| 190 | 550 | 'From: ' . get_option( 'admin_email' ), |
| @@ -220,9 +580,9 @@ | ||
| 220 | 580 | if ( ! preg_match( '/^([01][0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9])$/', $time ) ) { |
| 221 | 581 | $time = '09:00:00'; |
| 222 | 582 | } |
| 223 | 583 | |
| 224 | - $next_day_user_timezone = Helper::get_integer_value( strtotime( "next $day $time", $current_time_user_timezone ) ); | |
| 584 | + $next_day_user_timezone = Helper::get_integer_value( strtotime( "next {$day} {$time}", $current_time_user_timezone ) ); | |
| 225 | 585 | |
| 226 | 586 | $scheduled_time = Helper::get_integer_value( strtotime( gmdate( 'Y-m-d H:i:s', $next_day_user_timezone ) ) ); |
| 227 | 587 | |
| 228 | 588 | if ( false === as_has_scheduled_action( 'srfm_weekly_scheduled_events' ) ) { |