← All changes
|
_inc/lib/core-api/wpcom-endpoints/class-wpcom-rest-api-v2-endpoint-guidelines-banner-dismissed.php
+131
-0
16.2-beta
→
16.3
View file →
| @@ -1,0 +1,131 @@ | ||
| 1 | +<?php | |
| 2 | +/** | |
| 3 | + * REST API endpoint for the Content Guidelines AI empty-state banner. | |
| 4 | + * | |
| 5 | + * Stores a per-user flag (so it persists across the user's devices/browsers) | |
| 6 | + * for whether the banner has been dismissed, instead of relying on per-browser | |
| 7 | + * localStorage. Modeled on the wpcom block-editor "recommended tags modal | |
| 8 | + * dismissed" flow, but scoped to the user via user meta. | |
| 9 | + * | |
| 10 | + * @package automattic/jetpack | |
| 11 | + */ | |
| 12 | + | |
| 13 | +if ( ! defined( 'ABSPATH' ) ) { | |
| 14 | + exit( 0 ); | |
| 15 | +} | |
| 16 | + | |
| 17 | +// Load before the class definition, not in the constructor: META_KEY below | |
| 18 | +// delegates to a Jetpack_AI_Helper constant, and PHP resolves class constant | |
| 19 | +// expressions at first instantiation, before the constructor body runs. | |
| 20 | +if ( ! class_exists( 'Jetpack_AI_Helper' ) ) { | |
| 21 | + require_once JETPACK__PLUGIN_DIR . '_inc/lib/class-jetpack-ai-helper.php'; | |
| 22 | +} | |
| 23 | + | |
| 24 | +/** | |
| 25 | + * Class WPCOM_REST_API_V2_Endpoint_Guidelines_Banner_Dismissed | |
| 26 | + * | |
| 27 | + * @since 16.0 | |
| 28 | + */ | |
| 29 | +class WPCOM_REST_API_V2_Endpoint_Guidelines_Banner_Dismissed extends WP_REST_Controller { | |
| 30 | + /** | |
| 31 | + * User meta key storing the dismissed flag. | |
| 32 | + * | |
| 33 | + * The canonical key lives on Jetpack_AI_Helper (required at the top of | |
| 34 | + * this file) because this class is not loaded during admin page loads on | |
| 35 | + * Simple sites, while the admin-page preload in | |
| 36 | + * _inc/content-guidelines-ai.php needs the key there. | |
| 37 | + * | |
| 38 | + * @var string | |
| 39 | + */ | |
| 40 | + const META_KEY = Jetpack_AI_Helper::GUIDELINES_BANNER_DISMISSED_META_KEY; | |
| 41 | + | |
| 42 | + /** | |
| 43 | + * Namespace prefix. | |
| 44 | + * | |
| 45 | + * @var string | |
| 46 | + */ | |
| 47 | + public $namespace = 'wpcom/v2'; | |
| 48 | + | |
| 49 | + /** | |
| 50 | + * Endpoint base route. | |
| 51 | + * | |
| 52 | + * @var string | |
| 53 | + */ | |
| 54 | + public $rest_base = 'jetpack-ai/guidelines-banner-dismissed'; | |
| 55 | + | |
| 56 | + /** | |
| 57 | + * Constructor. | |
| 58 | + */ | |
| 59 | + public function __construct() { | |
| 60 | + $this->is_wpcom = true; | |
| 61 | + $this->wpcom_is_wpcom_only_endpoint = true; | |
| 62 | + | |
| 63 | + // Match the suggest-guidelines endpoint: register on Simple, Atomic, | |
| 64 | + // and WordPress VIP sites only. | |
| 65 | + if ( ! \Jetpack_AI_Helper::is_enabled_for_content_guidelines() ) { | |
| 66 | + return; | |
| 67 | + } | |
| 68 | + | |
| 69 | + add_action( 'rest_api_init', array( $this, 'register_routes' ) ); | |
| 70 | + } | |
| 71 | + | |
| 72 | + /** | |
| 73 | + * Register routes. | |
| 74 | + */ | |
| 75 | + public function register_routes() { | |
| 76 | + register_rest_route( | |
| 77 | + $this->namespace, | |
| 78 | + '/' . $this->rest_base, | |
| 79 | + array( | |
| 80 | + array( | |
| 81 | + 'methods' => WP_REST_Server::EDITABLE, | |
| 82 | + 'callback' => array( $this, 'set_dismissed' ), | |
| 83 | + 'permission_callback' => array( $this, 'permission_callback' ), | |
| 84 | + ), | |
| 85 | + ) | |
| 86 | + ); | |
| 87 | + } | |
| 88 | + | |
| 89 | + /** | |
| 90 | + * Permission check. | |
| 91 | + * | |
| 92 | + * Gated to the same capability as the Content Guidelines page (and the | |
| 93 | + * suggest-guidelines endpoint): only admins ever see the banner, so only | |
| 94 | + * they need to dismiss it. | |
| 95 | + * | |
| 96 | + * @return bool | |
| 97 | + */ | |
| 98 | + public function permission_callback() { | |
| 99 | + return current_user_can( 'manage_options' ); | |
| 100 | + } | |
| 101 | + | |
| 102 | + /** | |
| 103 | + * Whether the current user has dismissed the banner. | |
| 104 | + * | |
| 105 | + * Back-compat alias: the admin-page preload reads the flag via | |
| 106 | + * Jetpack_AI_Helper::is_guidelines_banner_dismissed() instead, because | |
| 107 | + * this class is not loaded during admin page loads on Simple sites. | |
| 108 | + * | |
| 109 | + * @return bool | |
| 110 | + */ | |
| 111 | + public static function is_dismissed() { | |
| 112 | + return Jetpack_AI_Helper::is_guidelines_banner_dismissed(); | |
| 113 | + } | |
| 114 | + | |
| 115 | + /** | |
| 116 | + * Mark the banner as dismissed for the current user. | |
| 117 | + * | |
| 118 | + * Dismissal is one-way — the banner has no "show again" control — so this | |
| 119 | + * only ever sets the flag. | |
| 120 | + * | |
| 121 | + * @return WP_REST_Response | |
| 122 | + */ | |
| 123 | + public function set_dismissed() { | |
| 124 | + update_user_meta( get_current_user_id(), self::META_KEY, '1' ); | |
| 125 | + | |
| 126 | + // Just set above — return it directly instead of re-reading the meta. | |
| 127 | + return rest_ensure_response( array( 'dismissed' => true ) ); | |
| 128 | + } | |
| 129 | +} | |
| 130 | + | |
| 131 | +wpcom_rest_api_v2_load_plugin( 'WPCOM_REST_API_V2_Endpoint_Guidelines_Banner_Dismissed' ); | |