PluginProbe
Yoast SEO – Advanced SEO with real-time guidance and built-in AI / 28.1
Yoast SEO – Advanced SEO with real-time guidance and built-in AI v28.1
28.6 28.5 28.4 28.3 28.2 28.1 28.0 27.9 27.8 27.7 27.6 27.5 trunk 18.0 18.1 18.2 18.3 18.4 18.4.1 18.5 18.5.1 18.6 18.7 18.8 18.9 All 130 releases
wordpress-seo / src / ai / content-planner / user-interface / banner-permanent-dismissal-route.php

banner-permanent-dismissal-route.php in Yoast SEO – Advanced SEO with real-time guidance and built-in AI 28.1, at src/ai/content-planner/user-interface/banner-permanent-dismissal-route.php

130 lines 3.2 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 // phpcs:disable Yoast.NamingConventions.NamespaceName.TooLong -- Needed in the folder structure.
4 // phpcs:disable Yoast.NamingConventions.NamespaceName.MaxExceeded
5
6 namespace Yoast\WP\SEO\AI\Content_Planner\User_Interface;
7
8 use WP_REST_Request;
9 use WP_REST_Response;
10 use Yoast\WP\SEO\Conditionals\AI_Conditional;
11 use Yoast\WP\SEO\Helpers\User_Helper;
12 use Yoast\WP\SEO\Main;
13 use Yoast\WP\SEO\Routes\Route_Interface;
14
15 /**
16 * Registers a route to permanently dismiss the AI Content Planner inline banner for the current user.
17 */
18 class Banner_Permanent_Dismissal_Route implements Route_Interface {
19
20 /**
21 * The user meta key used to store the permanent dismissal state.
22 *
23 * @var string
24 */
25 public const USER_META_KEY = '_yoast_wpseo_ai_content_planner_banner_permanently_dismissed';
26
27 /**
28 * The namespace for this route.
29 *
30 * @var string
31 */
32 public const ROUTE_NAMESPACE = Main::API_V1_NAMESPACE;
33
34 /**
35 * The prefix for this route.
36 *
37 * @var string
38 */
39 public const ROUTE_PREFIX = '/ai_content_planner/banner_permanent_dismissal';
40
41 /**
42 * Holds the user helper instance.
43 *
44 * @var User_Helper
45 */
46 private $user_helper;
47
48 /**
49 * Gets the conditionals required to load this class.
50 *
51 * @return array<string>
52 */
53 public static function get_conditionals() {
54 return [ AI_Conditional::class ];
55 }
56
57 /**
58 * Constructs the class.
59 *
60 * @param User_Helper $user_helper The user helper.
61 *
62 * @codeCoverageIgnore
63 */
64 public function __construct( User_Helper $user_helper ) {
65 $this->user_helper = $user_helper;
66 }
67
68 /**
69 * Registers routes with WordPress.
70 *
71 * @return void
72 */
73 public function register_routes() {
74 \register_rest_route(
75 self::ROUTE_NAMESPACE,
76 self::ROUTE_PREFIX,
77 [
78 [
79 'methods' => 'POST',
80 'callback' => [ $this, 'set_banner_permanent_dismissal' ],
81 'permission_callback' => [ $this, 'check_capabilities' ],
82 'args' => [
83 'is_dismissed' => [
84 'required' => true,
85 'type' => 'bool',
86 'sanitize_callback' => 'rest_sanitize_boolean',
87 ],
88 ],
89 ],
90 ],
91 );
92 }
93
94 /**
95 * Permanently dismisses the AI Content Planner banner for the current user.
96 *
97 * @param WP_REST_Request $request The request object.
98 *
99 * @return WP_REST_Response The success or failure response.
100 */
101 public function set_banner_permanent_dismissal( WP_REST_Request $request ) {
102 $is_dismissed = $request->get_param( 'is_dismissed' );
103 $user_id = $this->user_helper->get_current_user_id();
104 $result = $this->user_helper->update_meta( $user_id, self::USER_META_KEY, $is_dismissed );
105
106 // update_meta returns false both on failure and when the stored value is already identical.
107 // Check the existing value to distinguish the two cases and keep the endpoint idempotent.
108 if ( $result === false ) {
109 $existing = $this->user_helper->get_meta( $user_id, self::USER_META_KEY, true );
110 $result = ( (bool) $existing === (bool) $is_dismissed );
111 }
112
113 return new WP_REST_Response(
114 [
115 'success' => (bool) $result,
116 ],
117 ( $result !== false ) ? 200 : 400,
118 );
119 }
120
121 /**
122 * Checks if the current user has the required capabilities.
123 *
124 * @return bool
125 */
126 public function check_capabilities() {
127 return \current_user_can( 'edit_posts' );
128 }
129 }
130