PluginProbe
WProofreader spell & grammar check plugin for WordPress / trunk
WProofreader spell & grammar check plugin for WordPress vtrunk
3.2.1 3.2.2 3.2.0 trunk 1.0 1.1 2.0 2.1 2.2 2.3 2.4 2.5 2.6 2.6.1 2.6.10 2.6.2 2.6.3 2.6.4 2.6.5 2.6.6 2.6.7 2.6.8 2.6.9 2.7.0 2.7.1 All 28 releases
webspellchecker / includes / class-wsc-settings.php

class-wsc-settings.php in WProofreader spell & grammar check plugin for WordPress trunk, at includes/class-wsc-settings.php

318 lines 8.9 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 if ( ! defined( 'ABSPATH' ) ) {
3 exit; // Exit if accessed directly.
4 }
5
6 /**
7 * Admin settings controller for WProofreader.
8 */
9 if ( ! class_exists( 'WSC_Settings' ) ) {
10
11 class WSC_Settings {
12 /** Option bag name for all plugin settings (single section). */
13 const OPTION_NAME = 'wsc_proofreader';
14
15 /** @var WSC_Settings_API */
16 private $settings_api;
17
18 /** @var string */
19 private $page_title;
20
21 /** @var string */
22 private $menu_title;
23
24 /** @var string */
25 private $menu_slug;
26
27 /**
28 * @param string $page_title Settings page title (H1).
29 * @param string $menu_title Menu label under Settings.
30 * @param string $menu_slug Menu slug.
31 */
32 public function __construct( $page_title, $menu_title, $menu_slug ) {
33 $this->settings_api = new WSC_Settings_API();
34 $this->menu_title = (string) $menu_title;
35 $this->menu_slug = (string) $menu_slug;
36 $this->page_title = (string) $page_title;
37
38 add_action( 'admin_init', array( $this, 'on_admin_init' ) );
39 add_action( 'admin_menu', array( $this, 'on_admin_menu' ) );
40 }
41
42 /**
43 * Register sections/fields and augment fields if e-commerce is active.
44 */
45 public function on_admin_init() {
46 // Field/section setup is only needed when rendering the settings page
47 // or when options.php is persisting this option group.
48 if ( ! $this->is_settings_request() ) {
49 return;
50 }
51
52 if ( $this->is_ecommerce_active() ) {
53 add_filter( 'wsc_admin_fields', array( $this, 'add_products_toggle_field' ), 1 );
54 }
55
56 $this->settings_api->set_sections( $this->get_settings_sections() );
57 $this->settings_api->set_fields( $this->get_settings_fields() );
58
59 $this->settings_api->admin_init();
60 }
61
62 /**
63 * Add the settings page under "Settings".
64 */
65 public function on_admin_menu() {
66 add_options_page(
67 $this->page_title,
68 $this->menu_title,
69 'manage_options',
70 $this->menu_slug,
71 array( $this, 'render_settings_page' )
72 );
73 }
74
75 /**
76 * Whether the current request renders or saves this settings page.
77 *
78 * @return bool
79 */
80 protected function is_settings_request(): bool {
81 global $pagenow;
82
83 if ( 'options.php' === $pagenow ) {
84 return true;
85 }
86
87 // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- read-only routing check.
88 $page = isset( $_GET['page'] ) ? sanitize_key( wp_unslash( $_GET['page'] ) ) : '';
89
90 return $this->menu_slug === $page;
91 }
92
93 /**
94 * Detect if WooCommerce or WP eCommerce is active.
95 *
96 * @return bool
97 */
98 protected function is_ecommerce_active(): bool {
99 return class_exists( 'WooCommerce' ) || class_exists( 'WP_eCommerce' );
100 }
101
102 /**
103 * Filter callback: insert "Check Products" field after "Check Pages".
104 *
105 * @param array $settings_fields
106 *
107 * @return array
108 */
109 public function add_products_toggle_field( array $settings_fields ): array {
110 if ( empty( $settings_fields[ self::OPTION_NAME ] ) || ! is_array( $settings_fields[ self::OPTION_NAME ] ) ) {
111 return $settings_fields;
112 }
113
114 $products_field = array(
115 'name' => 'enable_on_products',
116 'label' => __( 'Check Products', 'webspellchecker' ),
117 'type' => 'checkbox',
118 'default' => 'on',
119 );
120
121 $fields = $settings_fields[ self::OPTION_NAME ];
122 $new_fields = array();
123 $inserted = false;
124
125 foreach ( $fields as $field ) {
126 $new_fields[] = $field;
127
128 if ( ! $inserted && isset( $field['name'] ) && 'enable_on_pages' === $field['name'] ) {
129 $new_fields[] = $products_field;
130 $inserted = true;
131 }
132 }
133
134 // If we did not find "enable_on_pages", append before the last two tail fields (admin/frontend).
135 if ( ! $inserted ) {
136 $tail_count = 2;
137 if ( count( $new_fields ) > $tail_count ) {
138 $tail = array_splice( $new_fields, - $tail_count );
139 $new_fields[] = $products_field;
140 $new_fields = array_merge( $new_fields, $tail );
141 } else {
142 $new_fields[] = $products_field;
143 }
144 }
145
146 $settings_fields[ self::OPTION_NAME ] = $new_fields;
147
148 return $settings_fields;
149 }
150
151 /**
152 * Define the single settings section.
153 *
154 * @return array[]
155 */
156 protected function get_settings_sections(): array {
157 return array(
158 array(
159 'id' => self::OPTION_NAME,
160 'title' => '',
161 ),
162 );
163 }
164
165 /**
166 * Define all settings fields.
167 *
168 * @return array
169 */
170 protected function get_settings_fields(): array {
171 $language_options = $this->get_language_options();
172 if ( empty( $language_options ) ) {
173 $language_options = array(
174 'en_US' => 'English',
175 'en_GB' => 'British English',
176 'en_CA' => 'Canadian English',
177 'fr_FR' => 'French',
178 'fr_CA' => 'Canadian French',
179 'de_DE' => 'German',
180 'it_IT' => 'Italian',
181 'pt_PT' => 'Portuguese',
182 'pt_BR' => 'Brazilian Portuguese',
183 'da_DK' => 'Danish',
184 );
185 }
186
187 $fields = array(
188 self::OPTION_NAME => array(
189 array(
190 'name' => 'customer_id',
191 'label' => __( 'License Key', 'webspellchecker' ),
192 'desc' => __( 'Upgrade to WProofreader Pro to access the grammar/style checking, text autocomplete capabilities and lift the usage limits for your websites. Leave it empty if you prefer to use the Free version. <br><a href="https://webspellchecker.com/free-trial/" target="_blank">Try Pro for 14-days free ></a>.', 'webspellchecker' ),
193 'type' => 'text',
194 'default' => '',
195 'sanitize_callback' => 'sanitize_text_field',
196 ),
197 array(
198 'name' => 'slang',
199 'label' => __( 'Default Language', 'webspellchecker' ),
200 'type' => 'select',
201 'options' => $language_options,
202 'default' => 'en_US',
203 'sanitize_callback' => 'sanitize_text_field',
204 ),
205 array(
206 // Historical toggle: 'on' means "badge shown".
207 'name' => 'disable_badge_button',
208 'label' => __( 'Enable Badge', 'webspellchecker' ),
209 'type' => 'checkbox',
210 'default' => 'on',
211 ),
212 array(
213 'name' => 'enable_on_posts',
214 'label' => __( 'Check Posts', 'webspellchecker' ),
215 'type' => 'checkbox',
216 'default' => 'on',
217 ),
218 array(
219 'name' => 'enable_on_pages',
220 'label' => __( 'Check Pages', 'webspellchecker' ),
221 'type' => 'checkbox',
222 'default' => 'on',
223 ),
224 // "Check Products" may be injected here if e-commerce is active.
225 array(
226 'name' => 'enable_on_categories',
227 'label' => __( 'Check Categories', 'webspellchecker' ),
228 'type' => 'checkbox',
229 'default' => 'on',
230 ),
231 array(
232 'name' => 'enable_on_tags',
233 'label' => __( 'Check Tags', 'webspellchecker' ),
234 'type' => 'checkbox',
235 'default' => 'on',
236 ),
237 // Keep these at the end for predictable UI.
238 array(
239 'name' => 'enable_in_admin',
240 'label' => __( 'Enable in admin area', 'webspellchecker' ),
241 'desc' => __( 'Enable WProofreader in editable fields across the WordPress dashboard.', 'webspellchecker' ),
242 'type' => 'checkbox',
243 'default' => 'off',
244 ),
245 array(
246 'name' => 'enable_on_frontend',
247 'label' => __( 'Enable on public site', 'webspellchecker' ),
248 'desc' => __( 'Enable WProofreader in editable fields on the public site (e.g., contact forms, forums).', 'webspellchecker' ),
249 'type' => 'checkbox',
250 'default' => 'off',
251 ),
252 ),
253 );
254
255 return apply_filters( 'wsc_admin_fields', $fields );
256 }
257
258 /**
259 * Render the settings page.
260 */
261 public function render_settings_page() {
262 if ( ! current_user_can( 'manage_options' ) ) {
263 wp_die( esc_html__( 'You do not have sufficient permissions to access this page.', 'webspellchecker' ) );
264 }
265
266 echo '<div class="wrap">';
267 echo '<h1>' . esc_html( $this->page_title ) . '</h1>';
268 $this->settings_api->show_navigation();
269 $this->settings_api->show_forms();
270 echo '</div>';
271 }
272
273 /**
274 * Utility: return available languages from cached option.
275 *
276 * @return array<string,string> key => label
277 */
278 protected function get_language_options(): array {
279 $info = get_transient( 'wsc_proofreader_info_cache' );
280 if ( false === $info ) {
281 $info = get_option( 'wsc_proofreader_info' );
282 }
283
284 if ( ! is_array( $info ) || empty( $info['langList'] ) || ! is_array( $info['langList'] ) ) {
285 return array();
286 }
287
288 $lang_list = $info['langList'];
289
290 $ltr = array();
291 $rtl = array();
292
293 if ( isset( $lang_list['ltr'] ) && is_array( $lang_list['ltr'] ) ) {
294 $ltr = $lang_list['ltr'];
295 }
296 if ( isset( $lang_list['rtl'] ) && is_array( $lang_list['rtl'] ) ) {
297 $rtl = $lang_list['rtl'];
298 }
299
300 // Ensure strings and remove empties.
301 $sanitize_map = static function ( $arr ) {
302 $out = array();
303 foreach ( $arr as $code => $label ) {
304 $code = (string) $code;
305 $label = (string) $label;
306 if ( '' !== $code && '' !== $label ) {
307 $out[ $code ] = $label;
308 }
309 }
310
311 return $out;
312 };
313
314 return array_merge( $sanitize_map( $ltr ), $sanitize_map( $rtl ) );
315 }
316 }
317 }
318