$choice ) ); } /** * Published dates, without the generated children of recurring events (filtered through threecal_thanks_count). * * @return int */ public static function count() { global $wpdb; // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching -- Small count on the plugin's own table, only on its own admin page. $count = (int) $wpdb->get_var( 'SELECT COUNT(*) FROM `' . esc_sql( $wpdb->prefix . 'threecal_events' ) . "` WHERE status = 'published' AND ( parent_id IS NULL OR parent_id = 0 )" ); /** * Number of published dates the thank-you card refers to. * * @param int $count Published dates. */ return (int) apply_filters( 'threecal_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_DATES ) { return ''; } $html = '
'; $html .= ''; /* translators: %d: number of published dates. */ $html .= '

' . esc_html( sprintf( _n( '%d date is in your calendar. Thank you for using 3task Calendar.', '%d dates are in your calendar. Thank you for using 3task Calendar.', $count, '3task-calendar' ), $count ) ) . '

'; $html .= '

' . esc_html__( 'A calendar only helps when people find it. A short, honest review works the same way: it helps the next site owner find a calendar that fits.', '3task-calendar' ) . '

'; $html .= '

' . esc_html__( 'I am Frank, and I build 3task Calendar 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-calendar' ) . '

'; $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-calendar' ) . '

'; $html .= '

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

' . esc_html__( 'This note appears at most twice and only on the Dashboard and Events tabs of 3task Calendar. Nothing changes in the plugin, whatever you choose.', '3task-calendar' ) . '

'; 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, ); } }