= self::SECOND_MILESTONE ) {
update_option( self::OPTION, 'due-again', false );
}
}
public static function state(): string {
$state = (string) get_option( self::OPTION, '' );
if ( '' === $state ) {
// The first look on a site whose orders with designs came before this request existed.
$ordered = get_posts(
array(
'post_type' => Design_Store::POST_TYPE,
'post_status' => 'private',
'numberposts' => 1,
'fields' => 'ids',
'meta_key' => Design_Store::META_ORDER, // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_key
)
);
$state = $ordered ? 'due' : 'waiting';
update_option( self::OPTION, $state, false );
}
return $state;
}
public static function notice(): void {
if ( ! current_user_can( 'manage_woocommerce' ) || 'own' !== Admin_Menu::surface() ) {
return;
}
echo wp_kses_post( self::notice_html() );
}
public static function notice_html(): string {
$state = self::state();
if ( ! in_array( $state, array( 'due', 'due-again' ), true ) ) {
return '';
}
$answer = static fn( string $answer ): string => Admin_Menu::action_url( 'printblob_review_request', array( 'answer' => $answer ) );
$later = 'due' === $state
? sprintf( ' %2$s %4$s', esc_url( $answer( 'dismiss' ) ), esc_html__( 'Dismiss', 'printblob' ), esc_url( $answer( 'never' ) ), esc_html__( 'Don’t ask again', 'printblob' ) )
: sprintf( ' %2$s', esc_url( $answer( 'never' ) ), esc_html__( 'Dismiss', 'printblob' ) );
return sprintf(
'
',
'due' === $state
? esc_html__( 'Your shop has its first order with a PrintBlob design. If PrintBlob is useful to you, a review on WordPress.org helps other shops find it.', 'printblob' )
/* translators: %d: number of orders with designs. */
: esc_html( sprintf( __( 'Your shop has had %d orders with PrintBlob designs. If PrintBlob is useful to you, a review on WordPress.org helps other shops find it.', 'printblob' ), self::SECOND_MILESTONE ) ),
esc_url( $answer( 'review' ) ),
esc_html__( 'Write a review', 'printblob' ),
$later
);
}
/**
* Records the admin's answer. Following a request, "Don't ask again" and dismissing the second request end it for
* good; dismissing the first waits for the second milestone, unless the shop has reached it already.
*
* @param string $answer 'review', 'dismiss' or 'never'.
*/
public static function answer( string $answer ): void {
if ( in_array( $answer, array( 'review', 'never' ), true ) ) {
update_option( self::OPTION, 'done', false );
} elseif ( 'dismiss' === $answer ) {
$first = 'due' === self::state() && Design_Store::order_count() < self::SECOND_MILESTONE;
update_option( self::OPTION, $first ? 'later' : 'done', false );
}
}
public static function handle(): void {
check_admin_referer( 'printblob_review_request' );
Admin_Menu::allow();
$answer = isset( $_GET['answer'] ) ? sanitize_key( wp_unslash( $_GET['answer'] ) ) : '';
self::answer( $answer );
if ( 'review' === $answer ) {
wp_redirect( self::REVIEW_URL ); // phpcs:ignore WordPress.Security.SafeRedirect.wp_redirect_wp_redirect -- PrintBlob's own page on WordPress.org.
exit;
}
Admin_Menu::back();
}
}