Admin
4 years ago
Builder
4 years ago
Helpers
5 years ago
CFF_Autolink.php
5 years ago
CFF_Blocks.php
4 years ago
CFF_Cache.php
4 years ago
CFF_Education.php
5 years ago
CFF_Elementor_Base.php
4 years ago
CFF_Elementor_Widget.php
4 years ago
CFF_Error_Reporter.php
4 years ago
CFF_FB_Settings.php
4 years ago
CFF_Feed_Elementor_Control.php
4 years ago
CFF_Feed_Locator.php
4 years ago
CFF_Feed_Pro.php
4 years ago
CFF_GDPR_Integrations.php
4 years ago
CFF_Group_Posts.php
5 years ago
CFF_HTTP_Request.php
4 years ago
CFF_Oembed.php
5 years ago
CFF_Parse.php
4 years ago
CFF_Resizer.php
4 years ago
CFF_Response.php
4 years ago
CFF_Shortcode.php
4 years ago
CFF_Shortcode_Display.php
4 years ago
CFF_SiteHealth.php
4 years ago
CFF_Utils.php
4 years ago
CFF_View.php
4 years ago
Custom_Facebook_Feed.php
4 years ago
CFF_Error_Reporter.php
737 lines
| 1 | <?php |
| 2 | /** |
| 3 | * Class CFF_Error_Reporter |
| 4 | * |
| 5 | * Set as a global object to record and report errors |
| 6 | * |
| 7 | * @since |
| 8 | */ |
| 9 | |
| 10 | namespace CustomFacebookFeed; |
| 11 | if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly |
| 12 | |
| 13 | if ( ! defined( 'ABSPATH' ) ) { |
| 14 | die( '-1' ); |
| 15 | } |
| 16 | |
| 17 | class CFF_Error_Reporter |
| 18 | { |
| 19 | /** |
| 20 | * @var array |
| 21 | */ |
| 22 | var $errors; |
| 23 | |
| 24 | /** |
| 25 | * @var array |
| 26 | */ |
| 27 | var $frontend_error; |
| 28 | |
| 29 | /** |
| 30 | * @var string |
| 31 | */ |
| 32 | var $reporter_key; |
| 33 | |
| 34 | /** |
| 35 | * @var array |
| 36 | */ |
| 37 | var $display_error; |
| 38 | |
| 39 | |
| 40 | /** |
| 41 | * CFF_Error_Reporter constructor. |
| 42 | */ |
| 43 | public function __construct() { |
| 44 | $this->reporter_key = 'cff_error_reporter'; |
| 45 | $this->errors = get_option( $this->reporter_key, [] ); |
| 46 | if ( ! isset( $this->errors['connection'] ) ) { |
| 47 | $this->errors = array( |
| 48 | 'connection' => [], |
| 49 | 'resizing' => [], |
| 50 | 'database_create' => [], |
| 51 | 'upload_dir' => [], |
| 52 | 'accounts' => [], |
| 53 | 'error_log' => [], |
| 54 | 'action_log' => [] |
| 55 | ); |
| 56 | } |
| 57 | |
| 58 | |
| 59 | $this->display_error = []; |
| 60 | $this->frontend_error = ''; |
| 61 | |
| 62 | add_action( 'cff_feed_issue_email', [ $this, 'maybe_trigger_report_email_send'] ); |
| 63 | add_action( 'wp_ajax_cff_dismiss_critical_notice', [ $this, 'dismiss_critical_notice'] ); |
| 64 | add_action( 'wp_footer', [ $this, 'critical_error_notice'] , 300 ); |
| 65 | add_action( 'cff_admin_notices', [ $this, 'admin_error_notices'] ); |
| 66 | } |
| 67 | |
| 68 | /** |
| 69 | * @return array |
| 70 | * |
| 71 | * @since 2.0/4.0 |
| 72 | */ |
| 73 | public function get_errors() { |
| 74 | return $this->errors; |
| 75 | } |
| 76 | |
| 77 | /** |
| 78 | * @param $type |
| 79 | * @param $message_array |
| 80 | * |
| 81 | * @since 2.0/4.0 |
| 82 | */ |
| 83 | public function add_error( $type, $args, $connected_account_term = false ) { |
| 84 | $connected_account = false; |
| 85 | |
| 86 | $log_item = date( 'm-d H:i:s' ) . ' - '; |
| 87 | |
| 88 | if( $connected_account_term !== false ){ |
| 89 | if ( ! is_array( $connected_account_term ) ) { |
| 90 | $connected_account = CFF_Utils::cff_get_account( $connected_account_term ); |
| 91 | } else { |
| 92 | $connected_account = $connected_account_term; |
| 93 | } |
| 94 | $log_item .= $args['error']['message']; |
| 95 | $this->add_connected_account_error( $connected_account, $type, $args ); |
| 96 | } |
| 97 | |
| 98 | //Access Token Error |
| 99 | if( $type === 'accesstoken' ){ |
| 100 | $accesstoken_error_exists = false; |
| 101 | if ( isset( $this->errors['accounts'] ) ) { |
| 102 | foreach ($this->errors['accounts'] as $account ) { |
| 103 | if ( $args['accesstoken'] === $account['accesstoken'] ) { |
| 104 | $accesstoken_error_exists = true; |
| 105 | } |
| 106 | } |
| 107 | } |
| 108 | if ( !$accesstoken_error_exists ) { |
| 109 | $this->errors['accounts'][ $connected_account['id'] ][] = array( |
| 110 | 'accesstoken' => $args['accesstoken'], |
| 111 | 'post_id' => $args['post_id'], |
| 112 | 'critical' => true, |
| 113 | 'type' => $type, |
| 114 | 'errorno' => $args['errorno'] |
| 115 | ); |
| 116 | |
| 117 | } |
| 118 | } |
| 119 | |
| 120 | //Connection Error API & WP REMOTE CALL |
| 121 | if( $type === 'api' || $type === 'wp_remote_get' ){ |
| 122 | $connection_details = array( |
| 123 | 'error_id' => '' |
| 124 | ); |
| 125 | $connection_details['critical'] = false; |
| 126 | |
| 127 | if( isset( $args['error']['code'] ) ){ |
| 128 | $connection_details['error_id'] = $args['error']['code']; |
| 129 | if ( $this->is_critical_error( $args ) ) { |
| 130 | $connection_details['critical'] = true; |
| 131 | } |
| 132 | |
| 133 | }elseif( isset( $args['response'] ) && is_wp_error( $args['response'] )){ |
| 134 | foreach ( $args['response']->errors as $key => $item ) { |
| 135 | $connection_details['error_id'] = $key; |
| 136 | } |
| 137 | $connection_details['critical'] = true; |
| 138 | } |
| 139 | |
| 140 | $connection_details['error_message'] = $this->generate_error_message( $args, $connected_account ); |
| 141 | $log_item .= $connection_details['error_message']['admin_message']; |
| 142 | $this->errors['connection'] = $connection_details; |
| 143 | #var_dump($connection_details); |
| 144 | } |
| 145 | |
| 146 | if ( $type === 'image_editor' |
| 147 | || $type === 'storage' ) { |
| 148 | |
| 149 | $this->errors['resizing'] = $args; |
| 150 | $log_item .= $args; |
| 151 | } |
| 152 | |
| 153 | if ( $type === 'database_create' ) { |
| 154 | $this->errors['database_create'] = $args; |
| 155 | $log_item .= $args; |
| 156 | } |
| 157 | |
| 158 | if ( $type === 'upload_dir' ) { |
| 159 | $this->errors['upload_dir'] = $args; |
| 160 | $log_item .= $args; |
| 161 | } |
| 162 | |
| 163 | $current_log = $this->errors['error_log']; |
| 164 | if ( is_array( $current_log ) && count( $current_log ) >= 10 ) { |
| 165 | reset( $current_log ); |
| 166 | unset( $current_log[ key( $current_log ) ] ); |
| 167 | } |
| 168 | $current_log[] = $log_item; |
| 169 | $this->errors['error_log'] = $current_log; |
| 170 | update_option( $this->reporter_key, $this->errors, false ); |
| 171 | |
| 172 | } |
| 173 | |
| 174 | |
| 175 | /** |
| 176 | * Stores information about an encountered error related to a connected account |
| 177 | * |
| 178 | * @param $connected_account array |
| 179 | * @param $error_type string |
| 180 | * @param $details mixed/array/string |
| 181 | * |
| 182 | * @since 2.19 |
| 183 | */ |
| 184 | public function add_connected_account_error( $connected_account, $error_type, $details ) { |
| 185 | $account_id = $connected_account['id']; |
| 186 | $this->errors['accounts'][ $account_id ][ $error_type ] = $details; |
| 187 | |
| 188 | if ( $error_type === 'api' || $error_type === 'accesstoken' ) { |
| 189 | $this->errors['accounts'][ $account_id ][ $error_type ]['clear_time'] = time() + 60 * 3; |
| 190 | } |
| 191 | |
| 192 | if ( isset( $details['error']['code'] ) |
| 193 | && (int)$details['error']['code'] === 18 ) { |
| 194 | $this->errors['accounts'][ $account_id ][ $error_type ]['clear_time'] = time() + 60 * 15; |
| 195 | } |
| 196 | |
| 197 | \CustomFacebookFeed\Builder\CFF_Source::add_error( $account_id, $details ); |
| 198 | } |
| 199 | |
| 200 | /** |
| 201 | * @return mixed |
| 202 | * |
| 203 | * @since 2.19 |
| 204 | */ |
| 205 | public function get_error_log() { |
| 206 | return $this->errors['error_log']; |
| 207 | } |
| 208 | |
| 209 | |
| 210 | |
| 211 | /** |
| 212 | * Creates an array of information for easy display of API errors |
| 213 | * |
| 214 | * @param $response |
| 215 | * @param array $connected_account |
| 216 | * |
| 217 | * @return array |
| 218 | * |
| 219 | * @since 2.19 |
| 220 | */ |
| 221 | public function generate_error_message( $response, $connected_account = array( 'username' => '' ) ) { |
| 222 | $error_message_return = array( |
| 223 | 'public_message' => '', |
| 224 | 'admin_message' => '', |
| 225 | 'frontend_directions' => '', |
| 226 | 'backend_directions' => '', |
| 227 | 'post_id' => get_the_ID(), |
| 228 | 'errorno' => '', |
| 229 | 'time' => time() |
| 230 | ); |
| 231 | |
| 232 | if( isset( $response['error']['code'] ) ){ |
| 233 | $error_code = (int)$response['error']['code']; |
| 234 | $api_error_number_message = sprintf( __( 'API Error %s:', 'custom-facebook-feed' ), $error_code ); |
| 235 | $error_message_return['public_message'] = __( 'Error connecting to the Facebook API.', 'custom-facebook-feed' ) . ' ' . $api_error_number_message; |
| 236 | $ppca_error = ( strpos($response['error']['message'], 'Public Content Access') !== false ) ? true : false; |
| 237 | |
| 238 | $error_message_return['admin_message'] = ( $ppca_error) |
| 239 | ? '<B>PPCA Error:</b> Due to Facebook API changes it is no longer possible to display a feed from a Facebook Page you are not an admin of. Please use the button below for more information on how to fix this.' |
| 240 | : '<strong>' . $api_error_number_message . '</strong><br>' . $response['error']['message']; |
| 241 | |
| 242 | $error_message_return['frontend_directions'] = ( $ppca_error ) |
| 243 | ? '<p class="cff-error-directions"><a href="https://smashballoon.com/facebook-api-changes-september-4-2020/" target="_blank" rel="noopener">' . __( 'Directions on How to Resolve This Issue', 'custom-facebook-feed' ) . '</a></p>' |
| 244 | : '<p class="cff-error-directions"><a href="https://smashballoon.com/custom-facebook-feed/docs/errors/" target="_blank" rel="noopener">' . __( 'Directions on How to Resolve This Issue', 'custom-facebook-feed' ) . '</a></p>'; |
| 245 | |
| 246 | $error_message_return['backend_directions'] = ( $ppca_error ) |
| 247 | ? '<a class="cff-notice-btn cff-btn-blue" href="https://smashballoon.com/facebook-api-changes-september-4-2020/" target="_blank" rel="noopener">' . __( 'Directions on How to Resolve This Issue', 'custom-facebook-feed' ) . '</a>' |
| 248 | : '<a class="cff-notice-btn cff-btn-blue" href="https://smashballoon.com/custom-facebook-feed/docs/errors/" target="_blank" rel="noopener">' . __( 'Directions on How to Resolve This Issue', 'custom-facebook-feed' ) . '</a>'; |
| 249 | |
| 250 | $error_message_return['errorno'] = $error_code; |
| 251 | |
| 252 | }else{ |
| 253 | $error_message_return['error_message'] = __( 'An unknown error has occurred.', 'custom-facebook-feed' ); |
| 254 | $error_message_return['admin_message'] = json_encode( $response ); |
| 255 | } |
| 256 | |
| 257 | return $error_message_return; |
| 258 | |
| 259 | } |
| 260 | |
| 261 | |
| 262 | |
| 263 | |
| 264 | /** |
| 265 | * Certain API errors are considered critical and will trigger |
| 266 | * the various notifications to users to correct them. |
| 267 | * |
| 268 | * @param $details |
| 269 | * |
| 270 | * @return bool |
| 271 | * |
| 272 | * @since 2.7/5.10 |
| 273 | */ |
| 274 | public function is_critical_error( $details ) { |
| 275 | $error_code = (int)$details['error']['code']; |
| 276 | |
| 277 | $critical_codes = array( |
| 278 | 10, |
| 279 | 100, |
| 280 | 200, |
| 281 | 190, |
| 282 | 104 |
| 283 | ); |
| 284 | |
| 285 | return in_array( $error_code, $critical_codes, true ); |
| 286 | } |
| 287 | |
| 288 | /** |
| 289 | * @param $type |
| 290 | * |
| 291 | * @since 2.19 |
| 292 | */ |
| 293 | public function remove_error( $type, $connected_account = false ) { |
| 294 | $update = false; |
| 295 | if ( ! empty( $this->errors[ $type ] ) ) { |
| 296 | $this->errors[ $type ] = array(); |
| 297 | $this->add_action_log( 'Cleared ' . $type .' error.' ); |
| 298 | $update = true; |
| 299 | } |
| 300 | |
| 301 | if ( $update ) { |
| 302 | update_option( $this->reporter_key, $this->errors, false ); |
| 303 | } |
| 304 | |
| 305 | } |
| 306 | |
| 307 | public function remove_all_errors() { |
| 308 | delete_option( $this->reporter_key ); |
| 309 | } |
| 310 | |
| 311 | /** |
| 312 | * @param $type |
| 313 | * @param $message |
| 314 | * |
| 315 | * @since 2.0/5.0 |
| 316 | */ |
| 317 | public function add_frontend_error( $message, $directions ) { |
| 318 | $this->frontend_error = $message . $directions; |
| 319 | } |
| 320 | |
| 321 | public function remove_frontend_error() { |
| 322 | $this->frontend_error = ''; |
| 323 | } |
| 324 | |
| 325 | /** |
| 326 | * @return string |
| 327 | * |
| 328 | * @since 2.0/5.0 |
| 329 | */ |
| 330 | public function get_frontend_error() { |
| 331 | return $this->frontend_error; |
| 332 | } |
| 333 | |
| 334 | public function get_critical_errors() { |
| 335 | if ( ! $this->are_critical_errors() ) { |
| 336 | return ''; |
| 337 | } |
| 338 | $error_message = $directions = false; |
| 339 | if ( isset( $this->errors['connection']['critical'] ) ) { |
| 340 | $errors = $this->get_errors(); |
| 341 | $error = $errors['connection']; |
| 342 | $error_message_array = $error['error_message']; |
| 343 | |
| 344 | $error_message = $error_message_array['admin_message']; |
| 345 | |
| 346 | $directions = '<p class="cff-error-directions">'; |
| 347 | $directions .= $error_message_array['backend_directions']; |
| 348 | $directions .= '<button data-url="'.get_the_permalink( $error_message_array['post_id'] ).'" class="cff-clear-errors-visit-page cff-space-left cff-btn cff-notice-btn cff-btn-grey">' . __( 'View Feed and Retry', 'custom-facebook-feed' ) . '</button>'; |
| 349 | $directions .= '</p>'; |
| 350 | }else{ |
| 351 | |
| 352 | } |
| 353 | |
| 354 | |
| 355 | return [ |
| 356 | 'error_message' => $error_message, |
| 357 | 'directions' => $directions |
| 358 | ]; |
| 359 | } |
| 360 | |
| 361 | public function are_critical_errors() { |
| 362 | $are_errors = false; |
| 363 | $errors = $this->get_errors(); |
| 364 | if( isset( $errors['connection']['critical'] ) && $errors['connection']['critical'] === true){ |
| 365 | return true; |
| 366 | }else{ |
| 367 | $connected_accounts = CFF_Utils::cff_get_connected_accounts(); |
| 368 | foreach ( $connected_accounts as $connected_account ) { |
| 369 | $connected_account = (array)$connected_account; |
| 370 | if ( isset( $this->errors['accounts'][ $connected_account['id' ] ]['api'] ) ) { |
| 371 | if ( isset( $this->errors['accounts'][ $connected_account['id'] ]['api']['error'] ) ) { |
| 372 | return $this->is_critical_error( $this->errors['accounts'][ $connected_account['id'] ]['api'] ); |
| 373 | } |
| 374 | } |
| 375 | } |
| 376 | } |
| 377 | |
| 378 | |
| 379 | return $are_errors; |
| 380 | } |
| 381 | |
| 382 | /** |
| 383 | * Stores a time stamped string of information about |
| 384 | * actions that might lead to correcting an error |
| 385 | * |
| 386 | * @param string $log_item |
| 387 | * |
| 388 | * @since 2.19 |
| 389 | */ |
| 390 | public function add_action_log( $log_item ) { |
| 391 | $current_log = $this->errors['action_log']; |
| 392 | |
| 393 | if ( is_array( $current_log ) && count( $current_log ) >= 10 ) { |
| 394 | reset( $current_log ); |
| 395 | unset( $current_log[ key( $current_log ) ] ); |
| 396 | } |
| 397 | $current_log[] = date( 'm-d H:i:s' ) . ' - ' . $log_item; |
| 398 | |
| 399 | $this->errors['action_log'] = $current_log; |
| 400 | update_option( $this->reporter_key, $this->errors, false ); |
| 401 | } |
| 402 | |
| 403 | /** |
| 404 | * @return mixed |
| 405 | * |
| 406 | * @since 2.19 |
| 407 | */ |
| 408 | public function get_action_log() { |
| 409 | return $this->errors['action_log']; |
| 410 | } |
| 411 | |
| 412 | |
| 413 | /** |
| 414 | * Load the critical notice for logged in users. |
| 415 | */ |
| 416 | function critical_error_notice() { |
| 417 | // Don't do anything for guests. |
| 418 | if ( ! is_user_logged_in() ) { |
| 419 | return; |
| 420 | } |
| 421 | |
| 422 | // Only show this to users who are not tracked. |
| 423 | if ( ! current_user_can( 'edit_posts' ) ) { |
| 424 | return; |
| 425 | } |
| 426 | |
| 427 | if ( ! $this->are_critical_errors() ) { |
| 428 | return; |
| 429 | } |
| 430 | |
| 431 | |
| 432 | // Don't show if already dismissed. |
| 433 | if ( get_option( 'cff_dismiss_critical_notice', false ) ) { |
| 434 | return; |
| 435 | } |
| 436 | |
| 437 | /** TODO: Match real option */ |
| 438 | $options = get_option('cff_settings' ); |
| 439 | if ( isset( $options['disable_admin_notice'] ) && $options['disable_admin_notice'] === 'on' ) { |
| 440 | return; |
| 441 | } |
| 442 | |
| 443 | ?> |
| 444 | <div class="cff-critical-notice cff-critical-notice-hide"> |
| 445 | <div class="cff-critical-notice-icon"> |
| 446 | <img src="<?php echo CFF_PLUGIN_URL . 'admin/assets/img/cff-icon.png'; ?>" width="45" alt="Custom Facebook Feed icon" /> |
| 447 | </div> |
| 448 | <div class="cff-critical-notice-text"> |
| 449 | <h3><?php esc_html_e( 'Facebook Feed Critical Issue', 'custom-facebook-feed' ); ?></h3> |
| 450 | <p> |
| 451 | <?php |
| 452 | $doc_url = admin_url() . 'admin.php?page=cff-settings'; |
| 453 | // Translators: %s is the link to the article where more details about critical are listed. |
| 454 | printf( esc_html__( 'An issue is preventing your Custom Facebook Feeds from updating. %1$sResolve this issue%2$s.', 'custom-facebook-feed' ), '<a href="' . esc_url( $doc_url ) . '" target="_blank">', '</a>' ); |
| 455 | ?> |
| 456 | </p> |
| 457 | </div> |
| 458 | <div class="cff-critical-notice-close">×</div> |
| 459 | </div> |
| 460 | <style type="text/css"> |
| 461 | .cff-critical-notice { |
| 462 | position: fixed; |
| 463 | bottom: 20px; |
| 464 | right: 15px; |
| 465 | font-family: Arial, Helvetica, "Trebuchet MS", sans-serif; |
| 466 | background: #fff; |
| 467 | box-shadow: 0 0 10px 0 #dedede; |
| 468 | padding: 10px 10px; |
| 469 | display: flex; |
| 470 | align-items: center; |
| 471 | justify-content: center; |
| 472 | width: 325px; |
| 473 | max-width: calc( 100% - 30px ); |
| 474 | border-radius: 6px; |
| 475 | transition: bottom 700ms ease; |
| 476 | z-index: 10000; |
| 477 | } |
| 478 | |
| 479 | .cff-critical-notice h3 { |
| 480 | font-size: 13px; |
| 481 | color: #222; |
| 482 | font-weight: 700; |
| 483 | margin: 0 0 4px; |
| 484 | padding: 0; |
| 485 | line-height: 1; |
| 486 | border: none; |
| 487 | } |
| 488 | |
| 489 | .cff-critical-notice p { |
| 490 | font-size: 12px; |
| 491 | color: #7f7f7f; |
| 492 | font-weight: 400; |
| 493 | margin: 0; |
| 494 | padding: 0; |
| 495 | line-height: 1.2; |
| 496 | border: none; |
| 497 | } |
| 498 | |
| 499 | .cff-critical-notice p a { |
| 500 | color: #7f7f7f; |
| 501 | font-size: 12px; |
| 502 | line-height: 1.2; |
| 503 | margin: 0; |
| 504 | padding: 0; |
| 505 | text-decoration: underline; |
| 506 | font-weight: 400; |
| 507 | } |
| 508 | |
| 509 | .cff-critical-notice p a:hover { |
| 510 | color: #666; |
| 511 | } |
| 512 | |
| 513 | .cff-critical-notice-icon img { |
| 514 | height: auto; |
| 515 | display: block; |
| 516 | margin: 0; |
| 517 | } |
| 518 | |
| 519 | .cff-critical-notice-icon { |
| 520 | padding: 0; |
| 521 | border-radius: 4px; |
| 522 | flex-grow: 0; |
| 523 | flex-shrink: 0; |
| 524 | margin-right: 12px; |
| 525 | overflow: hidden; |
| 526 | } |
| 527 | |
| 528 | .cff-critical-notice-close { |
| 529 | padding: 10px; |
| 530 | margin: -12px -9px 0 0; |
| 531 | border: none; |
| 532 | box-shadow: none; |
| 533 | border-radius: 0; |
| 534 | color: #7f7f7f; |
| 535 | background: transparent; |
| 536 | line-height: 1; |
| 537 | align-self: flex-start; |
| 538 | cursor: pointer; |
| 539 | font-weight: 400; |
| 540 | } |
| 541 | .cff-critical-notice-close:hover, |
| 542 | .cff-critical-notice-close:focus{ |
| 543 | color: #111; |
| 544 | } |
| 545 | |
| 546 | .cff-critical-notice.cff-critical-notice-hide { |
| 547 | bottom: -200px; |
| 548 | } |
| 549 | </style> |
| 550 | <?php |
| 551 | |
| 552 | if ( ! wp_script_is( 'jquery', 'queue' ) ) { |
| 553 | wp_enqueue_script( 'jquery' ); |
| 554 | } |
| 555 | ?> |
| 556 | <script> |
| 557 | if ( 'undefined' !== typeof jQuery ) { |
| 558 | jQuery( document ).ready( function ( $ ) { |
| 559 | /* Don't show the notice if we don't have a way to hide it (no js, no jQuery). */ |
| 560 | $( document.querySelector( '.cff-critical-notice' ) ).removeClass( 'cff-critical-notice-hide' ); |
| 561 | $( document.querySelector( '.cff-critical-notice-close' ) ).on( 'click', function ( e ) { |
| 562 | e.preventDefault(); |
| 563 | $( this ).closest( '.cff-critical-notice' ).addClass( 'cff-critical-notice-hide' ); |
| 564 | $.ajax( { |
| 565 | url: '<?php echo esc_url( admin_url( 'admin-ajax.php' ) ); ?>', |
| 566 | method: 'POST', |
| 567 | data: { |
| 568 | action: 'cff_dismiss_critical_notice', |
| 569 | nonce: '<?php echo esc_js( wp_create_nonce( 'cff-critical-notice' ) ); ?>', |
| 570 | } |
| 571 | } ); |
| 572 | } ); |
| 573 | } ); |
| 574 | } |
| 575 | </script> |
| 576 | <?php |
| 577 | } |
| 578 | |
| 579 | /** |
| 580 | * Ajax handler to hide the critical notice. |
| 581 | */ |
| 582 | public function dismiss_critical_notice() { |
| 583 | |
| 584 | check_ajax_referer( 'cff-critical-notice', 'nonce' ); |
| 585 | |
| 586 | update_option( 'cff_dismiss_critical_notice', 1, false ); |
| 587 | |
| 588 | wp_die(); |
| 589 | |
| 590 | } |
| 591 | |
| 592 | public function send_report_email() { |
| 593 | $options = get_option( 'cff_style_settings', array() ); |
| 594 | |
| 595 | $to_string = ! empty( $options['email_notification_addresses'] ) ? str_replace( ' ', '', $options['email_notification_addresses'] ) : get_option( 'admin_email', '' ); |
| 596 | |
| 597 | $to_array_raw = explode( ',', $to_string ); |
| 598 | $to_array = array(); |
| 599 | |
| 600 | foreach ( $to_array_raw as $email ) { |
| 601 | if ( is_email( $email ) ) { |
| 602 | $to_array[] = $email; |
| 603 | } |
| 604 | } |
| 605 | |
| 606 | if ( empty( $to_array ) ) { |
| 607 | return false; |
| 608 | } |
| 609 | $from_name = esc_html( wp_specialchars_decode( get_bloginfo( 'name' ) ) ); |
| 610 | $email_from = $from_name . ' <' . get_option( 'admin_email', $to_array[0] ) . '>'; |
| 611 | $header_from = "From: " . $email_from; |
| 612 | |
| 613 | $headers = array( 'Content-Type: text/html; charset=utf-8', $header_from ); |
| 614 | |
| 615 | $header_image = CFF_PLUGIN_URL . 'admin/assets/img/balloon-120.png'; |
| 616 | $title = __( 'Custom Facebook Feed Report for ' . home_url() ); |
| 617 | $link = admin_url( 'admin.php?page=cff-settings'); |
| 618 | //&tab=customize-advanced |
| 619 | $footer_link = admin_url('admin.php?page=cff-style&tab=misc&flag=emails'); |
| 620 | $bold = __( 'There\'s an Issue with a Facebook Feed on Your Website', 'custom-facebook-feed' ); |
| 621 | $details = '<p>' . __( 'A Custom Facebook Feed on your website is currently unable to connect to Facebook to retrieve new posts. Don\'t worry, your feed is still being displayed using a cached version, but is no longer able to display new posts.', 'custom-facebook-feed' ) . '</p>'; |
| 622 | $details .= '<p>' . sprintf( __( 'This is caused by an issue with your Facebook account connecting to the Facebook API. For information on the exact issue and directions on how to resolve it, please visit the %sCustom Facebook Feed settings page%s on your website.', 'custom-facebook-feed' ), '<a href="' . esc_url( $link ) . '">', '</a>' ). '</p>'; |
| 623 | $message_content = '<h6 style="padding:0;word-wrap:normal;font-family:\'Helvetica Neue\',Helvetica,Arial,sans-serif;font-weight:bold;line-height:130%;font-size: 16px;color:#444444;text-align:inherit;margin:0 0 20px 0;Margin:0 0 20px 0;">' . $bold . '</h6>' . $details; |
| 624 | include_once CFF_PLUGIN_DIR . 'class-cff-education.php'; |
| 625 | $educator = new CFF_Education(); |
| 626 | $dyk_message = $educator->dyk_display(); |
| 627 | ob_start(); |
| 628 | include CFF_PLUGIN_DIR . 'email.php'; |
| 629 | $email_body = ob_get_contents(); |
| 630 | ob_get_clean(); |
| 631 | $sent = wp_mail( $to_array, $title, $email_body, $headers ); |
| 632 | |
| 633 | return $sent; |
| 634 | } |
| 635 | |
| 636 | public function maybe_trigger_report_email_send() { |
| 637 | if ( ! $this->are_critical_errors() ) { |
| 638 | return; |
| 639 | } |
| 640 | /** TODO: Match real option */ |
| 641 | $options = get_option('cff_settings' ); |
| 642 | |
| 643 | if ( isset( $options['enable_email_report'] ) && empty( $options['enable_email_report'] ) ) { |
| 644 | return; |
| 645 | } |
| 646 | |
| 647 | $this->send_report_email(); |
| 648 | } |
| 649 | |
| 650 | public function admin_error_notices() { |
| 651 | |
| 652 | if ( isset( $_GET['page'] ) && in_array( $_GET['page'], array( 'cff-settings' )) ) { |
| 653 | $errors = $this->get_errors(); |
| 654 | if ( ! empty( $errors ) && (! empty( $errors['database_create'] ) || ! empty( $errors['upload_dir'] )) ) : ?> |
| 655 | <div class="cff-admin-notices cff-critical-error-notice"> |
| 656 | <?php if ( ! empty( $errors['database_create'] ) ) echo '<p>' . $errors['database_create'] . '</p>'; ?> |
| 657 | <?php if ( ! empty( $errors['upload_dir'] ) ) echo '<p>' . $errors['upload_dir'] . '</p>'; ?> |
| 658 | <p><?php _e( sprintf( 'Visit our %s page for help', '<a href="https://smashballoon.com/custom-facebook-feed/faq/" class="cff-notice-btn cff-btn-grey" target="_blank">FAQ</a>' ), 'custom-facebook-feed' ); ?></p> |
| 659 | </div> |
| 660 | |
| 661 | <?php endif; |
| 662 | $errors = $this->get_critical_errors(); |
| 663 | if ( $this->are_critical_errors() && is_array( $errors ) && $errors['error_message'] !== false && $errors['directions'] !== false ) : |
| 664 | ?> |
| 665 | <div class="cff-admin-notices cff-critical-error-notice"> |
| 666 | <span class="sb-notice-icon sb-error-icon"> |
| 667 | <svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg"> |
| 668 | <path d="M10 0C4.48 0 0 4.48 0 10C0 15.52 4.48 20 10 20C15.52 20 20 15.52 20 10C20 4.48 15.52 0 10 0ZM11 15H9V13H11V15ZM11 11H9V5H11V11Z" fill="#D72C2C"/> |
| 669 | </svg> |
| 670 | </span> |
| 671 | <div class="cff-notice-body"> |
| 672 | <h3 class="sb-notice-title"> |
| 673 | <?php echo esc_html__( 'Custom Facebook Feed is encountering an error and your feeds may not be updating due to the following reasons:', 'custom-facebook-feed') ; ?> |
| 674 | </h3> |
| 675 | |
| 676 | <p><?php echo $errors['error_message']; ?></p> |
| 677 | |
| 678 | <div class="license-action-btns"> |
| 679 | <?php echo $errors['directions']; ?> |
| 680 | </div> |
| 681 | </div> |
| 682 | </div> |
| 683 | <?php |
| 684 | endif; |
| 685 | |
| 686 | /* |
| 687 | $errors = $this->get_critical_errors(); |
| 688 | if ( $this->are_critical_errors() && ! empty( $errors ) ) : |
| 689 | if ( isset( $errors['wp_remote_get'] ) ) { |
| 690 | $error = $errors['wp_remote_get']; |
| 691 | $error_message = $error['admin_message']; |
| 692 | $button = $error['backend_directions']; |
| 693 | $post_id = $error['post_id']; |
| 694 | $directions = '<p class="cff-error-directions">'; |
| 695 | $directions .= $button; |
| 696 | $directions .= '<button data-url="'.get_the_permalink( $post_id ).'" class="cff-clear-errors-visit-page cff-space-left button button-secondary">' . __( 'View Feed and Retry', 'custom-facebook-feed' ) . '</button>'; |
| 697 | $directions .= '</p>'; |
| 698 | } elseif ( isset( $errors['api'] ) ) { |
| 699 | $error = $errors['api']; |
| 700 | $error_message = $error['admin_message']; |
| 701 | $button = $error['backend_directions']; |
| 702 | $post_id = $error['post_id']; |
| 703 | $directions = '<p class="cff-error-directions">'; |
| 704 | $directions .= $button; |
| 705 | $directions .= '<button data-url="'.get_the_permalink( $post_id ).'" class="cff-clear-errors-visit-page cff-space-left button button-secondary">' . __( 'View Feed and Retry', 'custom-facebook-feed' ) . '</button>'; |
| 706 | $directions .= '</p>'; |
| 707 | } else { |
| 708 | $error = $errors['accesstoken']; |
| 709 | |
| 710 | $tokens = array(); |
| 711 | $post_id = false; |
| 712 | foreach ( $error as $token ) { |
| 713 | $tokens[] = $token['accesstoken']; |
| 714 | $post_id = $token['post_id']; |
| 715 | } |
| 716 | $error_message = sprintf( __( 'The access token %s is invalid or has expired.', 'custom-facebook-feed' ), implode( ', ', $tokens ) ); |
| 717 | $directions = '<p class="cff-error-directions">'; |
| 718 | $directions .= '<button class="button button-primary cff-reconnect">' . __( 'Reconnect Your Account', 'custom-facebook-feed' ) . '</button>'; |
| 719 | $directions .= '<button data-url="'.get_the_permalink( $post_id ).'" class="cff-clear-errors-visit-page cff-space-left button button-secondary">' . __( 'View Feed and Retry', 'custom-facebook-feed' ) . '</button>'; |
| 720 | $directions .= '</p>'; |
| 721 | } |
| 722 | ?> |
| 723 | <div class="notice notice-warning is-dismissible cff-admin-notice"> |
| 724 | <p><strong><?php echo esc_html__( 'Custom Facebook Feed is encountering an error and your feeds may not be updating due to the following reasons:', 'custom-facebook-feed') ; ?></strong></p> |
| 725 | |
| 726 | <?php echo $error_message; ?> |
| 727 | |
| 728 | <?php echo $directions; ?> |
| 729 | </div> |
| 730 | <?php endif; |
| 731 | */ |
| 732 | |
| 733 | } |
| 734 | |
| 735 | } |
| 736 | |
| 737 | } |