| 1 |
<?php |
| 2 |
/** |
| 3 |
* Asks why, on the way out. |
| 4 |
* |
| 5 |
* The moment someone deactivates is the one moment they definitely have an |
| 6 |
* opinion, and it is the last one we get. So we ask — but the rules are strict, |
| 7 |
* because this pattern is easy to abuse: |
| 8 |
* |
| 9 |
* - Deactivation is never blocked or delayed. "Just deactivate" is always one |
| 10 |
* click away and is the default if anything goes wrong with the dialog. |
| 11 |
* - Nothing is transmitted from here. Choosing a reason opens the feedback form |
| 12 |
* in a new tab with that reason pre-selected; the user still decides whether |
| 13 |
* to send it. |
| 14 |
* - It appears once. Dismissing it, or deactivating without answering, sets a flag. |
| 15 |
*/ |
| 16 |
|
| 17 |
namespace forge12\contactform7\CF7DoubleOptIn; |
| 18 |
|
| 19 |
if ( ! defined( 'ABSPATH' ) ) { |
| 20 |
exit; |
| 21 |
} |
| 22 |
|
| 23 |
add_action( 'admin_footer-plugins.php', __NAMESPACE__ . '\render_deactivation_survey' ); |
| 24 |
add_action( 'wp_ajax_f12_doi_dismiss_survey', __NAMESPACE__ . '\dismiss_deactivation_survey' ); |
| 25 |
|
| 26 |
/** |
| 27 |
* Remember that the dialog has run its course. |
| 28 |
*/ |
| 29 |
function dismiss_deactivation_survey(): void { |
| 30 |
check_ajax_referer( 'f12_doi_survey' ); |
| 31 |
|
| 32 |
if ( ! current_user_can( 'activate_plugins' ) ) { |
| 33 |
wp_send_json_error( null, 403 ); |
| 34 |
} |
| 35 |
|
| 36 |
update_option( 'f12_doi_survey_done', 1, false ); |
| 37 |
wp_send_json_success(); |
| 38 |
} |
| 39 |
|
| 40 |
/** |
| 41 |
* The reasons offered, in the order they are shown. |
| 42 |
* |
| 43 |
* @return array<string, string> slug => label |
| 44 |
*/ |
| 45 |
function get_deactivation_reasons(): array { |
| 46 |
return array( |
| 47 |
'temporary' => __( 'Only switching it off for a moment', 'double-opt-in' ), |
| 48 |
'not_sending' => __( 'Confirmation emails did not arrive', 'double-opt-in' ), |
| 49 |
'complicated' => __( 'I could not get it configured', 'double-opt-in' ), |
| 50 |
'conflict' => __( 'It clashed with another plugin or my theme', 'double-opt-in' ), |
| 51 |
'form_plugin' => __( 'It did not work with my form plugin', 'double-opt-in' ), |
| 52 |
'other_plugin' => __( 'I switched to something else', 'double-opt-in' ), |
| 53 |
); |
| 54 |
} |
| 55 |
|
| 56 |
/** |
| 57 |
* Print the dialog on the plugins screen. |
| 58 |
*/ |
| 59 |
function render_deactivation_survey(): void { |
| 60 |
if ( ! current_user_can( 'activate_plugins' ) ) { |
| 61 |
return; |
| 62 |
} |
| 63 |
|
| 64 |
if ( (int) get_option( 'f12_doi_survey_done', 0 ) === 1 ) { |
| 65 |
return; |
| 66 |
} |
| 67 |
|
| 68 |
$reasons = get_deactivation_reasons(); |
| 69 |
$feedback = get_feedback_url( 'deactivation' ); |
| 70 |
$nonce = wp_create_nonce( 'f12_doi_survey' ); |
| 71 |
?> |
| 72 |
<div id="f12-doi-survey" style="display:none;position:fixed;inset:0;z-index:100000;background:rgba(0,0,0,.6);"> |
| 73 |
<div style="max-width:460px;margin:10vh auto;background:#fff;border-radius:4px;padding:24px;box-shadow:0 4px 24px rgba(0,0,0,.3);"> |
| 74 |
<h2 style="margin-top:0;"> |
| 75 |
<?php esc_html_e( 'Before you go — what went wrong?', 'double-opt-in' ); ?> |
| 76 |
</h2> |
| 77 |
<p style="color:#666;"> |
| 78 |
<?php esc_html_e( 'Optional. Picking a reason opens our feedback form; nothing is sent from this page.', 'double-opt-in' ); ?> |
| 79 |
</p> |
| 80 |
<ul style="list-style:none;margin:16px 0;padding:0;"> |
| 81 |
<?php foreach ( $reasons as $slug => $label ) : ?> |
| 82 |
<li style="margin-bottom:8px;"> |
| 83 |
<a href="<?php echo esc_url( add_query_arg( 'reason', $slug, $feedback ) ); ?>" |
| 84 |
target="_blank" rel="noopener" |
| 85 |
class="f12-doi-survey-reason" |
| 86 |
style="display:block;padding:8px 12px;border:1px solid #ddd;border-radius:3px;text-decoration:none;color:#1d2327;"> |
| 87 |
<?php echo esc_html( $label ); ?> |
| 88 |
</a> |
| 89 |
</li> |
| 90 |
<?php endforeach; ?> |
| 91 |
</ul> |
| 92 |
<p style="margin-bottom:0;display:flex;gap:8px;align-items:center;"> |
| 93 |
<a href="#" class="button button-primary f12-doi-survey-skip"> |
| 94 |
<?php esc_html_e( 'Just deactivate', 'double-opt-in' ); ?> |
| 95 |
</a> |
| 96 |
<a href="#" class="f12-doi-survey-cancel" style="color:#666;"> |
| 97 |
<?php esc_html_e( 'Cancel', 'double-opt-in' ); ?> |
| 98 |
</a> |
| 99 |
</p> |
| 100 |
</div> |
| 101 |
</div> |
| 102 |
<script> |
| 103 |
(function () { |
| 104 |
var overlay = document.getElementById('f12-doi-survey'); |
| 105 |
var link = document.querySelector('tr[data-slug="double-opt-in"] .deactivate a'); |
| 106 |
if (!overlay || !link) { return; } |
| 107 |
|
| 108 |
var target = link.href; |
| 109 |
|
| 110 |
function done() { |
| 111 |
// Record that we asked, then let the deactivation proceed. A failed |
| 112 |
// request must never strand the user on this screen, so navigation |
| 113 |
// happens either way. |
| 114 |
var body = new FormData(); |
| 115 |
body.append('action', 'f12_doi_dismiss_survey'); |
| 116 |
body.append('_wpnonce', <?php echo wp_json_encode( $nonce ); ?>); |
| 117 |
fetch(ajaxurl, { method: 'POST', body: body, credentials: 'same-origin' }) |
| 118 |
.catch(function () {}) |
| 119 |
.finally(function () { window.location.href = target; }); |
| 120 |
} |
| 121 |
|
| 122 |
link.addEventListener('click', function (e) { |
| 123 |
e.preventDefault(); |
| 124 |
overlay.style.display = 'block'; |
| 125 |
}); |
| 126 |
|
| 127 |
overlay.querySelectorAll('.f12-doi-survey-reason').forEach(function (a) { |
| 128 |
// The reason opens in a new tab; this one carries on with the deactivation. |
| 129 |
a.addEventListener('click', function () { setTimeout(done, 150); }); |
| 130 |
}); |
| 131 |
|
| 132 |
overlay.querySelector('.f12-doi-survey-skip').addEventListener('click', function (e) { |
| 133 |
e.preventDefault(); |
| 134 |
done(); |
| 135 |
}); |
| 136 |
|
| 137 |
overlay.querySelector('.f12-doi-survey-cancel').addEventListener('click', function (e) { |
| 138 |
e.preventDefault(); |
| 139 |
overlay.style.display = 'none'; |
| 140 |
}); |
| 141 |
})(); |
| 142 |
</script> |
| 143 |
<?php |
| 144 |
} |
| 145 |
|