PluginProbe
Polylang / 3.7.1
Polylang v3.7.1
3.8.9 3.8.8 3.8.7 3.8.6 3.8.5 3.8.4 3.8.3 2.7 2.7.0.1 2.7.1 2.7.2 2.7.3 2.7.4 2.8 2.8.1 2.8.2 2.8.3 2.8.4 2.9 2.9.1 2.9.2 3.0 3.0.1 3.0.2 3.0.3 All 233 releases
polylang / admin / admin-notices.php

admin-notices.php in Polylang 3.7.1, at admin/admin-notices.php

297 lines 7.6 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * @package Polylang
4 */
5
6 /**
7 * A class to manage admin notices
8 * displayed only to admin, based on 'manage_options' capability
9 * and only on dashboard, plugins and Polylang admin pages
10 *
11 * @since 2.3.9
12 * @since 2.7 Dismissed notices are stored in an option instead of a user meta
13 */
14 class PLL_Admin_Notices {
15 /**
16 * Stores the plugin options.
17 *
18 * @var array
19 */
20 protected $options;
21
22 /**
23 * Stores custom notices.
24 *
25 * @var string[]
26 */
27 private static $notices = array();
28
29 /**
30 * Constructor
31 * Setup actions
32 *
33 * @since 2.3.9
34 *
35 * @param object $polylang The Polylang object.
36 */
37 public function __construct( $polylang ) {
38 $this->options = &$polylang->options;
39
40 add_action( 'admin_init', array( $this, 'hide_notice' ) );
41 add_action( 'admin_notices', array( $this, 'display_notices' ) );
42 }
43
44 /**
45 * Add a custom notice
46 *
47 * @since 2.3.9
48 *
49 * @param string $name Notice name
50 * @param string $html Content of the notice
51 * @return void
52 */
53 public static function add_notice( $name, $html ) {
54 self::$notices[ $name ] = $html;
55 }
56
57 /**
58 * Get custom notices.
59 *
60 * @since 2.3.9
61 *
62 * @return string[]
63 */
64 public static function get_notices() {
65 return self::$notices;
66 }
67
68 /**
69 * Has a notice been dismissed?
70 *
71 * @since 2.3.9
72 *
73 * @param string $notice Notice name
74 * @return bool
75 */
76 public static function is_dismissed( $notice ) {
77 $dismissed = get_option( 'pll_dismissed_notices', array() );
78
79 // Handle legacy user meta
80 $dismissed_meta = get_user_meta( get_current_user_id(), 'pll_dismissed_notices', true );
81 if ( is_array( $dismissed_meta ) ) {
82 if ( array_diff( $dismissed_meta, $dismissed ) ) {
83 $dismissed = array_merge( $dismissed, $dismissed_meta );
84 update_option( 'pll_dismissed_notices', $dismissed );
85 }
86 if ( ! is_multisite() ) {
87 // Don't delete on multisite to avoid the notices to appear in other sites.
88 delete_user_meta( get_current_user_id(), 'pll_dismissed_notices' );
89 }
90 }
91
92 return in_array( $notice, $dismissed );
93 }
94
95 /**
96 * Should we display notices on this screen?
97 *
98 * @since 2.3.9
99 *
100 * @param string $notice The notice name.
101 * @param array $allowed_screens The screens allowed to display the notice.
102 * If empty, default screens are used, i.e. dashboard, plugins, languages, strings and settings.
103 *
104 * @return bool
105 */
106 protected function can_display_notice( string $notice, array $allowed_screens = array() ) {
107 $screen = get_current_screen();
108
109 if ( empty( $screen ) ) {
110 return false;
111 }
112
113 if ( empty( $allowed_screens ) ) {
114 $screen_id = sanitize_title( __( 'Languages', 'polylang' ) );
115 $allowed_screens = array(
116 'dashboard',
117 'plugins',
118 'toplevel_page_mlang',
119 $screen_id . '_page_mlang_strings',
120 $screen_id . '_page_mlang_settings',
121 );
122 }
123
124 /**
125 * Filters admin notices which can be displayed.
126 *
127 * @since 2.7.0
128 *
129 * @param bool $display Whether the notice should be displayed or not.
130 * @param string $notice The notice name.
131 */
132 return apply_filters( 'pll_can_display_notice', in_array( $screen->id, $allowed_screens, true ), $notice );
133 }
134
135 /**
136 * Stores a dismissed notice in the database.
137 *
138 * @since 2.3.9
139 *
140 * @param string $notice Notice name.
141 * @return void
142 */
143 public static function dismiss( $notice ) {
144 $dismissed = get_option( 'pll_dismissed_notices', array() );
145
146 if ( ! in_array( $notice, $dismissed ) ) {
147 $dismissed[] = $notice;
148 update_option( 'pll_dismissed_notices', array_unique( $dismissed ) );
149 }
150 }
151
152 /**
153 * Handle a click on the dismiss button
154 *
155 * @since 2.3.9
156 *
157 * @return void
158 */
159 public function hide_notice() {
160 if ( isset( $_GET['pll-hide-notice'], $_GET['_pll_notice_nonce'] ) ) {
161 $notice = sanitize_key( $_GET['pll-hide-notice'] );
162 check_admin_referer( $notice, '_pll_notice_nonce' );
163 self::dismiss( $notice );
164 wp_safe_redirect( remove_query_arg( array( 'pll-hide-notice', '_pll_notice_nonce' ), wp_get_referer() ) );
165 exit;
166 }
167 }
168
169 /**
170 * Displays notices
171 *
172 * @since 2.3.9
173 *
174 * @return void
175 */
176 public function display_notices() {
177 if ( current_user_can( 'manage_options' ) ) {
178 // Core notices
179 if ( defined( 'WOOCOMMERCE_VERSION' ) && ! defined( 'PLLWC_VERSION' ) && $this->can_display_notice( 'pllwc' ) && ! static::is_dismissed( 'pllwc' ) ) {
180 $this->pllwc_notice();
181 }
182
183 if ( ! defined( 'POLYLANG_PRO' ) && $this->can_display_notice( 'review' ) && ! static::is_dismissed( 'review' ) && ! empty( $this->options['first_activation'] ) && time() > $this->options['first_activation'] + 15 * DAY_IN_SECONDS ) {
184 $this->review_notice();
185 }
186
187 $allowed_screen = sanitize_title( __( 'Languages', 'polylang' ) ) . '_page_mlang_strings';
188 if (
189 ( ! empty( $this->options['previous_version'] ) && version_compare( $this->options['previous_version'], '3.7.0', '<' ) )
190 && $this->can_display_notice( 'empty-strings-translations', (array) $allowed_screen )
191 && ! static::is_dismissed( 'empty-strings-translations' )
192 ) {
193 $this->empty_strings_translations_notice();
194 }
195
196 // Custom notices
197 foreach ( static::get_notices() as $notice => $html ) {
198 if ( $this->can_display_notice( $notice ) && ! static::is_dismissed( $notice ) ) {
199 ?>
200 <div class="pll-notice notice notice-info">
201 <?php
202 $this->dismiss_button( $notice );
203 echo wp_kses_post( $html );
204 ?>
205 </div>
206 <?php
207 }
208 }
209 }
210 }
211
212 /**
213 * Displays a dismiss button
214 *
215 * @since 2.3.9
216 *
217 * @param string $name Notice name
218 * @return void
219 */
220 public function dismiss_button( $name ) {
221 printf(
222 '<a class="notice-dismiss" href="%s"><span class="screen-reader-text">%s</span></a>',
223 esc_url( wp_nonce_url( add_query_arg( 'pll-hide-notice', $name ), $name, '_pll_notice_nonce' ) ),
224 /* translators: accessibility text */
225 esc_html__( 'Dismiss this notice.', 'polylang' )
226 );
227 }
228
229 /**
230 * Displays a notice if WooCommerce is activated without Polylang for WooCommerce
231 *
232 * @since 2.3.9
233 *
234 * @return void
235 */
236 private function pllwc_notice() {
237 ?>
238 <div class="pll-notice notice notice-warning">
239 <?php $this->dismiss_button( 'pllwc' ); ?>
240 <p>
241 <?php
242 printf(
243 /* translators: %1$s is link start tag, %2$s is link end tag. */
244 esc_html__( 'We have noticed that you are using Polylang with WooCommerce. To ensure compatibility, we recommend you use %1$sPolylang for WooCommerce%2$s.', 'polylang' ),
245 '<a href="https://polylang.pro/downloads/polylang-for-woocommerce/">',
246 '</a>'
247 );
248 ?>
249 </p>
250 </div>
251 <?php
252 }
253
254 /**
255 * Displays a notice asking for a review
256 *
257 * @since 2.3.9
258 *
259 * @return void
260 */
261 private function review_notice() {
262 ?>
263 <div class="pll-notice notice notice-info">
264 <?php $this->dismiss_button( 'review' ); ?>
265 <p>
266 <?php
267 printf(
268 /* translators: %1$s is link start tag, %2$s is link end tag. */
269 esc_html__( 'We have noticed that you have been using Polylang for some time. We hope you love it, and we would really appreciate it if you would %1$sgive us a 5 stars rating%2$s.', 'polylang' ),
270 '<a href="https://wordpress.org/support/plugin/polylang/reviews/?rate=5#new-post">',
271 '</a>'
272 );
273 ?>
274 </p>
275 </div>
276 <?php
277 }
278
279 /**
280 * Displays a notice about the empty strings translations.
281 *
282 * @since 3.7
283 *
284 * @return void
285 */
286 private function empty_strings_translations_notice() {
287 ?>
288 <div class="pll-notice notice notice-info">
289 <?php $this->dismiss_button( 'empty-strings-translations' ); ?>
290 <p>
291 <?php esc_html_e( 'Translations matching the original string are shown as empty in the table. Untranslated content remains unchanged.', 'polylang' ); ?>
292 </p>
293 </div>
294 <?php
295 }
296 }
297