'POST', 'callback' => array( __CLASS__, 'rest_choice' ), 'permission_callback' => function () { return current_user_can( 'manage_options' ); }, 'args' => array( 'choice' => array( 'type' => 'string', 'enum' => array( 'done', 'later', 'never' ), 'required' => true, ), ), ) ); } /** * REST response. * * @param WP_REST_Request $request Request. * @return WP_REST_Response */ public static function rest_choice( $request ) { $state = self::state( get_current_user_id() ); $choice = (string) $request['choice']; if ( 'later' === $choice ) { $state['until'] = time() + self::LATER_DAYS * DAY_IN_SECONDS; } $state['state'] = $choice; ++$state['asked']; update_user_meta( get_current_user_id(), self::META, $state ); return rest_ensure_response( array( 'state' => $choice ) ); } /** * Requests turned away in the last 30 days, from the learning mode counters (filtered through threedoor_thanks_count). * * @return int */ public static function count() { $count = 0; foreach ( ThreeDoor_Learn::summary( 30 ) as $row ) { if ( ! empty( $row['denied'] ) ) { $count += (int) $row['hits']; } } /** * Number of refused requests the thank-you card refers to. * * @param int $count Refused requests in the last 30 days. */ return (int) apply_filters( 'threedoor_thanks_count', $count ); } /** * Card for one tab of the plugin page, or an empty string. * * @param string $tab Current tab. * @return string */ public static function card( $tab ) { if ( ! in_array( $tab, self::TABS, true ) || ! current_user_can( 'manage_options' ) ) { return ''; } $installed = (int) get_option( self::INSTALLED, 0 ); if ( $installed < 1 ) { update_option( self::INSTALLED, time(), false ); return ''; } if ( time() - $installed < self::WAIT_DAYS * DAY_IN_SECONDS ) { return ''; } $state = self::state( get_current_user_id() ); if ( in_array( $state['state'], array( 'done', 'never' ), true ) || $state['asked'] >= self::MAX_ASKS || ( 'later' === $state['state'] && time() < $state['until'] ) ) { return ''; } $count = self::count(); if ( $count < self::MIN_REFUSALS ) { return ''; } $html = '
'; $html .= ''; /* translators: %d: number of refused REST API requests in the last 30 days. */ $html .= '

' . esc_html( sprintf( _n( 'Doorman turned away %d unwanted request in the last 30 days. Thank you for using it.', 'Doorman turned away %d unwanted requests in the last 30 days. Thank you for using it.', $count, '3task-doorman' ), $count ) ) . '

'; $html .= '

' . esc_html__( 'A door only protects when someone looks after it. A short, honest review does a similar job: it tells the next site owner whether Doorman is worth a try.', '3task-doorman' ) . '

'; $html .= '

' . esc_html__( 'I am Frank, and I build 3task Doorman myself, without ads and without tracking. Nobody has to pay for it. What keeps it going is hearing from the people who use it.', '3task-doorman' ) . '

'; $html .= '

' . esc_html__( 'Would you leave a short review on WordPress.org? One honest sentence is enough, good or critical. If something is missing, tell me in the support forum and I will look at it.', '3task-doorman' ) . '

'; $html .= '

'; $html .= '' . esc_html__( 'Write a review on WordPress.org', '3task-doorman' ) . ' '; $html .= '' . esc_html__( 'Something is missing? Tell me', '3task-doorman' ) . ' '; $html .= ' '; $html .= ''; $html .= '

' . esc_html__( 'This note appears at most twice and only on the Overview and Learning mode tabs of 3task Doorman. Nothing changes in the plugin, whatever you choose.', '3task-doorman' ) . '

'; // Every choice is stored, the card disappears at once. Doorman has no admin script of its own, so the few lines sit here. $html .= wp_get_inline_script_tag( "document.querySelectorAll('.threedoor-danke [data-wahl]').forEach(function(el){el.addEventListener('click',function(){var c=el.closest('.threedoor-danke');fetch(c.getAttribute('data-url'),{method:'POST',credentials:'same-origin',headers:{'Content-Type':'application/json','X-WP-Nonce':c.getAttribute('data-nonce')},body:JSON.stringify({choice:el.getAttribute('data-wahl')})}).catch(function(){});c.remove();});});" ); return $html; } /** * Stored choice of one user. * * @param int $user_id User ID. * @return array{state:string, until:int, asked:int} */ private static function state( $user_id ) { $raw = get_user_meta( (int) $user_id, self::META, true ); $raw = is_array( $raw ) ? $raw : array(); return array( 'state' => isset( $raw['state'] ) && in_array( $raw['state'], array( 'done', 'later', 'never' ), true ) ? $raw['state'] : '', 'until' => isset( $raw['until'] ) ? (int) $raw['until'] : 0, 'asked' => isset( $raw['asked'] ) ? max( 0, (int) $raw['asked'] ) : 0, ); } }