client = $client; $this->textDomain = $client->get_text_domain(); } /** * Initialize the deactivation functionality * * @return void */ public function init(): void { add_action( 'admin_footer', array( $this, 'add_deactivation_feedback_modal' ) ); add_filter( 'plugin_action_links_' . plugin_basename($this->client->get_plugin_file()), array( $this, 'filter_plugin_action_links' ) ); add_action( 'wp_ajax_' . $this->client->get_slug() . '_submit_deactivation_reason', array( $this, 'submit_deactivation_reason' ) ); } /** * Filter the plugin action links * * @param array $links * @return array */ public function filter_plugin_action_links( array $links ): array { if ( isset( $links['deactivate'] ) ) { $links['deactivate'] = str_replace( 'deactivation_modal_styles(); $reasons = $this->get_uninstall_reasons(); ?>

textDomain ); ?>

client->get_slug() . '-deactivation-nonce' ) ) { wp_send_json_error( 'Nonce verification failed' ); } if ( ! current_user_can( 'manage_options' ) ) { wp_send_json_error( 'You are not allowed for this task' ); } $reason_id = isset( $_POST['reason_id'] ) ? sanitize_text_field( wp_unslash( $_POST['reason_id'] ) ) : 'none'; $reason_info = isset( $_POST['reason_info'] ) ? sanitize_text_field( wp_unslash( $_POST['reason_info'] ) ) : ''; $this->track_deactivation( $reason_id, $reason_info ); wp_send_json_success(); } /** * Track the deactivation event * * @param string $reason_id * @param string $reason_info * @return void */ private function track_deactivation( string $reason_id, string $reason_info ): void { $payload = array( 'site_url' => get_site_url(), 'reason' => $reason_id, 'reason_key' => $reason_id, 'reason_info' => $reason_info, ); // Plugins hook here to add any extra properties (e.g. time_since_install_minutes). // reason and reason_key are global — plugins should not override them here. $payload = apply_filters( $this->client->get_slug() . '_deactivation_payload', $payload, $reason_id, $reason_info ); $this->client->track_lifecycle_event( 'activation/plugin_deactivated', $payload ); // Set a transient to indicate that a deactivation event has been sent from the feedback form. // This prevents the generic deactivation hook from sending another one. set_transient( $this->client->get_slug() . '_deactivation_event_sent', 'yes', MINUTE_IN_SECONDS ); } /** * Get the uninstall reasons * * @return array */ private function get_uninstall_reasons(): array { $reasons = [ [ 'id' => 'could-not-understand', 'text' => __( "Couldn't understand", 'text-domain' ), 'placeholder' => __( 'Would you like us to assist you?', 'text-domain' ), 'icon' => '', ], [ 'id' => 'found-better-plugin', 'text' => __( 'Found a better plugin', 'text-domain' ), 'placeholder' => __( 'Which plugin?', 'text-domain' ), 'icon' => '', ], [ 'id' => 'not-have-that-feature', 'text' => __( 'Missing a specific feature', 'text-domain' ), 'placeholder' => __( 'Could you tell us more about that feature?', 'text-domain' ), 'icon' => '', ], [ 'id' => 'is-not-working', 'text' => __( 'Not working', 'text-domain' ), 'placeholder' => __( 'Could you tell us a bit more whats not working?', 'text-domain' ), 'icon' => '', ], [ 'id' => 'looking-for-other', 'text' => __( 'Not what I was looking', 'text-domain' ), 'placeholder' => __( 'Could you tell us a bit more?', 'text-domain' ), 'icon' => '', ], [ 'id' => 'did-not-work-as-expected', 'text' => __( "Didn't work as expected", 'text-domain' ), 'placeholder' => __( 'What did you expect?', 'text-domain' ), 'icon' => '', ], [ 'id' => 'other', 'text' => __( 'Others', 'text-domain' ), 'placeholder' => __( 'Could you tell us a bit more?', 'text-domain' ), 'icon' => '', ], ]; return apply_filters( $this->client->get_slug() . '_telemetry_deactivation_reasons', $reasons ); } }