PluginProbe ʕ •ᴥ•ʔ
Post Views Counter / trunk
Post Views Counter vtrunk
1.7.13 1.7.12 1.7.11 trunk 1.0.0 1.0.1 1.0.10 1.0.11 1.0.12 1.0.2 1.0.3 1.0.4 1.0.5 1.0.6 1.0.7 1.0.8 1.0.9 1.1.0 1.1.1 1.1.2 1.1.3 1.1.4 1.2.0 1.2.1 1.2.10 1.2.11 1.2.12 1.2.13 1.2.14 1.2.2 1.2.3 1.2.4 1.2.5 1.2.6 1.2.7 1.2.8 1.2.9 1.3 1.3.1 1.3.10 1.3.11 1.3.12 1.3.13 1.3.2 1.3.2.1 1.3.3 1.3.4 1.3.5 1.3.6 1.3.7 1.3.8 1.3.9 1.4 1.4.1 1.4.2 1.4.3 1.4.4 1.4.5 1.4.6 1.4.7 1.4.8 1.5.0 1.5.1 1.5.2 1.5.3 1.5.4 1.5.5 1.5.6 1.5.7 1.5.8 1.5.9 1.6.0 1.6.1 1.7.0 1.7.1 1.7.10 1.7.2 1.7.3 1.7.4 1.7.5 1.7.6 1.7.7 1.7.8 1.7.9
post-views-counter / includes / class-settings-other.php
post-views-counter / includes Last commit date
class-admin.php 3 months ago class-columns-modal.php 1 month ago class-columns.php 2 weeks ago class-counter.php 2 months ago class-crawler-detect.php 7 months ago class-cron.php 1 month ago class-dashboard.php 1 month ago class-emails-mailer.php 1 month ago class-emails-period.php 1 month ago class-emails-query.php 1 month ago class-emails-scheduler.php 1 month ago class-emails-template.php 1 month ago class-emails.php 1 month ago class-frontend.php 2 weeks ago class-functions.php 1 year ago class-import.php 2 months ago class-integration-gutenberg.php 6 months ago class-integrations.php 2 months ago class-query.php 2 months ago class-settings-api.php 1 month ago class-settings-display.php 4 months ago class-settings-emails.php 1 month ago class-settings-general.php 1 month ago class-settings-integrations.php 5 months ago class-settings-other.php 1 month ago class-settings-reports.php 1 month ago class-settings.php 1 month ago class-toolbar.php 3 months ago class-traffic-signals.php 2 months ago class-update.php 1 month ago class-widgets.php 1 month ago functions.php 1 month ago
class-settings-other.php
465 lines
1 <?php
2 // exit if accessed directly
3 if ( ! defined( 'ABSPATH' ) )
4 exit;
5
6 /**
7 * Post_Views_Counter_Settings_Other class.
8 *
9 * @class Post_Views_Counter_Settings_Other
10 */
11 class Post_Views_Counter_Settings_Other {
12
13 private $pvc;
14 private $settings;
15
16 /**
17 * Class constructor.
18 *
19 * @param Post_Views_Counter_Settings $settings
20 * @return void
21 */
22 public function __construct( $settings = null ) {
23 $this->pvc = Post_Views_Counter();
24 $this->settings = $settings;
25 }
26
27 /**
28 * Get sections for other tab.
29 *
30 * @return array
31 */
32 public function get_sections() {
33 return [
34 'post_views_counter_other_status' => [
35 'tab' => 'other',
36 'title' => __( 'Plugin Status', 'post-views-counter' ),
37 'callback' => [ $this, 'section_other_status' ]
38 ],
39 'post_views_counter_other_import' => [
40 'tab' => 'other',
41 'title' => __( 'Data Import', 'post-views-counter' ),
42 'callback' => [ $this, 'section_other_import' ]
43 ],
44 'post_views_counter_other_management' => [
45 'tab' => 'other',
46 'title' => __( 'Data Removal', 'post-views-counter' ),
47 'callback' => [ $this, 'section_other_management' ]
48 ]
49 ];
50 }
51
52 /**
53 * Get fields for other tab.
54 *
55 * @return array
56 */
57 public function get_fields() {
58 return [
59 'license' => [
60 'tab' => 'other',
61 'title' => __( 'License Key', 'post-views-counter' ),
62 'section' => 'post_views_counter_other_status',
63 'disabled' => true,
64 'value' => $this->pvc->options['other']['license'],
65 'type' => 'input',
66 'description' => sprintf( __( 'Enter your %s license key (requires Pro version to be installed and active).', 'post-views-counter' ), '<a href="' . esc_url( $this->pvc->get_postviewscounter_url( '/upgrade/', 'link', 'license', 'license-field-pro-link', 'free' ) ) . '" target="_blank">Post Views Counter Pro</a>' ),
67 'subclass' => 'regular-text',
68 'validate' => [ $this, 'validate_license' ],
69 'append' => '<span class="pvc-status-icon"></span>'
70 ],
71 'import_from' => [
72 'tab' => 'other',
73 'title' => __( 'Import From', 'post-views-counter' ),
74 'section' => 'post_views_counter_other_import',
75 'type' => 'custom',
76 'skip_saving' => true,
77 'callback' => [ $this, 'setting_import_from' ]
78 ],
79 'import_strategy' => [
80 'tab' => 'other',
81 'title' => __( 'Import Strategy', 'post-views-counter' ),
82 'section' => 'post_views_counter_other_import',
83 'class' => 'pvc-pro-extended',
84 'type' => 'custom',
85 'skip_saving' => true,
86 'callback' => [ $this, 'setting_import_strategy' ]
87 ],
88 'import_actions' => [
89 'tab' => 'other',
90 'title' => '',
91 'section' => 'post_views_counter_other_import',
92 'type' => 'custom',
93 'description' => __( 'Click Analyse Views to check how many views are available for import, or Import Views to begin the import process.', 'post-views-counter' ),
94 'skip_saving' => true,
95 'callback' => [ $this, 'setting_import_actions' ]
96 ],
97 'delete_views' => [
98 'tab' => 'other',
99 'title' => __( 'Delete Views', 'post-views-counter' ),
100 'section' => 'post_views_counter_other_management',
101 'type' => 'custom',
102 'description' => __( 'Delete ALL the existing post views data. Note that this is an irreversible process!', 'post-views-counter' ),
103 'skip_saving' => true,
104 'callback' => [ $this, 'setting_delete_views' ]
105 ],
106 'deactivation_delete' => [
107 'tab' => 'other',
108 'title' => __( 'Delete on Deactivation', 'post-views-counter' ),
109 'section' => 'post_views_counter_other_management',
110 'type' => 'boolean',
111 'description' => __( 'When enabled, deactivating the plugin will delete all plugin data from the database, including all content view counts.', 'post-views-counter' ),
112 'label' => __( 'Delete all plugin data on deactivation.', 'post-views-counter' )
113 ]
114 ];
115 }
116
117 /**
118 * Validate license.
119 *
120 * @param array $input
121 * @param array $field
122 * @return array
123 */
124 public function validate_license( $input, $field ) {
125 // save value from database
126 return $field['value'];
127 }
128
129 /**
130 * Setting: import from.
131 *
132 * @return string
133 */
134 public function setting_import_from() {
135 // get all providers (not just available ones)
136 $all_providers = $this->pvc->import->get_all_providers();
137
138 // get currently selected provider
139 $selected_provider = isset( $this->pvc->options['other']['import_provider_settings']['provider'] ) ? $this->pvc->options['other']['import_provider_settings']['provider'] : 'custom_meta_key';
140
141 // if selected provider is not available, fallback to custom_meta_key
142 if ( isset( $all_providers[$selected_provider] ) ) {
143 $is_selected_available = is_callable( $all_providers[$selected_provider]['is_available'] ) && call_user_func( $all_providers[$selected_provider]['is_available'] );
144 if ( ! $is_selected_available ) {
145 $selected_provider = 'custom_meta_key';
146 }
147 }
148
149 $html = '<div class="pvc-import-provider-selection">';
150 $html .= '<div class="pvc-field-group pvc-radio-group">';
151
152 foreach ( $all_providers as $slug => $provider ) {
153 $is_available = is_callable( $provider['is_available'] ) && call_user_func( $provider['is_available'] );
154 $is_checked = ( $selected_provider === $slug );
155 $disabled_attr = ! $is_available ? ' disabled="disabled"' : '';
156 $disabled_class = ! $is_available ? ' class="pvc-disabled"' : '';
157 $tooltip = ! $is_available ? ' title="' . esc_attr( sprintf( __( '%s is not currently available. Please install and activate the required plugin.', 'post-views-counter' ), $provider['label'] ) ) . '"' : '';
158
159 $html .= '
160 <label' . $disabled_class . $tooltip . '>
161 <input type="radio" id="pvc-other-import-from-' . esc_attr( $slug ) . '" name="pvc_import_provider" value="' . esc_attr( $slug ) . '" ' . checked( $is_checked, true, false ) . $disabled_attr . ' />
162 ' . esc_html( $provider['label'] ) . '
163 </label>';
164 }
165
166 $html .= '</div>';
167 $html .= '<p class="description">' . esc_html__( 'Choose a data source to import existing view counts from.', 'post-views-counter' ) . '</p>';
168
169 $html .= '</div><div class="pvc-import-provider-fields">';
170
171 foreach ( $all_providers as $slug => $provider ) {
172 $is_available = is_callable( $provider['is_available'] ) && call_user_func( $provider['is_available'] );
173 $is_active = ( $selected_provider === $slug );
174 $provider_html = '';
175
176 if ( $is_available && is_callable( $provider['render'] ) ) {
177 $provider_html = call_user_func( $provider['render'] );
178 } elseif ( ! $is_available ) {
179 $provider_html = '<p class="description pvc-provider-unavailable">' . sprintf( __( '%s is not available. Please install and activate the required plugin to use this import source.', 'post-views-counter' ), '<strong>' . esc_html( $provider['label'] ) . '</strong>' ) . '</p>';
180 }
181
182 $logic = [ [ 'field' => 'pvc-other-import-from', 'operator' => 'is', 'value' => $slug, 'container' => 'self' ] ];
183
184 $html .= '
185 <div class="pvc-provider-content pvc-provider-' . esc_attr( $slug ) . '" data-pvc-logic="' . esc_attr( wp_json_encode( $logic ) ) . '" data-pvc-animation="slide">
186 ' . $provider_html . '
187 </div>';
188 }
189
190 $html .= '</div>';
191
192 return $html;
193 }
194
195 /**
196 * Setting: import strategy.
197 *
198 * @return string
199 */
200 public function setting_import_strategy() {
201 // get import strategy
202 $import_strategy = isset( $this->pvc->options['other']['import_provider_settings']['strategy'] ) ? $this->pvc->import->normalize_strategy( $this->pvc->options['other']['import_provider_settings']['strategy'] ) : $this->pvc->import->get_default_strategy();
203 $strategies = $this->pvc->import->get_import_strategies();
204
205 $html = '<div class="pvc-field-group pvc-radio-group">';
206
207 foreach ( $strategies as $slug => $strategy ) {
208 $label = isset( $strategy['label'] ) ? $strategy['label'] : ucwords( str_replace( '_', ' ', $slug ) );
209 $description = isset( $strategy['description'] ) ? $strategy['description'] : '';
210 $is_enabled = $this->pvc->import->is_strategy_enabled( $slug );
211 $input_id = 'pvc-other-import-strategy-' . $slug;
212 $is_pro = ! empty( $strategy['pro_only'] ) && $strategy['pro_only'];
213 $pro_unavailable = $is_pro && ! $is_enabled;
214
215 if ( $slug === $import_strategy ) {
216 $current_description = $description;
217 }
218
219 $label_classes = [ 'pvc-import-strategy-option' ];
220 if ( $pro_unavailable ) {
221 $label_classes[] = 'pvc-pro';
222 $label_classes[] = 'pvc-disabled';
223 }
224
225 $html .= '<label for="' . esc_attr( $input_id ) . '" class="' . esc_attr( implode( ' ', $label_classes ) ) . '" data-description="' . esc_attr( $description ) . '">
226 <input type="radio" id="' . esc_attr( $input_id ) . '" name="pvc_import_strategy" value="' . esc_attr( $slug ) . '" ' . checked( $import_strategy, $slug, false ) . ' ' . disabled( ! $is_enabled, true, false ) . ' />
227 ' . esc_html( $label );
228
229 $html .= '</label>';
230 }
231
232 $html .= '</div>';
233
234 $html .= '</div>';
235
236 $html .= '<p class="description">' . esc_html__( 'Choose how to handle existing view counts when importing.', 'post-views-counter' ) . '</p>';
237
238 $html .= '<div class="pvc-provider-fields pvc-import-strategy-details">';
239
240 foreach ( $strategies as $slug => $strategy ) {
241 $description = isset( $strategy['description'] ) ? $strategy['description'] : '';
242 $is_active = ( $slug === $import_strategy );
243
244 $logic = [ [ 'field' => 'pvc-other-import-strategy', 'operator' => 'is', 'value' => $slug, 'container' => 'self' ] ];
245 $html .= '<div class="pvc-strategy-content pvc-strategy-' . esc_attr( $slug ) . '" data-pvc-logic="' . esc_attr( wp_json_encode( $logic ) ) . '" data-pvc-animation="slide">
246 <p class="description">' . esc_html( $description ) . '</p>
247 </div>';
248 }
249
250 $html .= '</div>';
251
252 return $html;
253 }
254
255 /**
256 * Setting: import actions.
257 *
258 * @return string
259 */
260 public function setting_import_actions() {
261 $html = '<input type="submit" class="button outline" name="post_views_counter_analyse_views" value="' . esc_attr__( 'Analyse Views', 'post-views-counter' ) . '" />
262 <input type="submit" class="button outline" name="post_views_counter_import_views" value="' . esc_attr__( 'Import Views', 'post-views-counter' ) . '" />';
263
264 return $html;
265 }
266
267 /**
268 * Setting: delete views.
269 *
270 * @return string
271 */
272 public function setting_delete_views() {
273 $html = '
274 <input type="submit" class="button outline" name="post_views_counter_reset_views" value="' . esc_attr__( 'Delete Views', 'post-views-counter' ) . '" />';
275
276 return $html;
277 }
278
279 /**
280 * Section description: other - status.
281 *
282 * @return void
283 */
284 public function section_other_status() {
285 echo '<p class="description">' . esc_html__( 'View license details and other status information.', 'post-views-counter' ) . '</p>';
286
287 // render plugin status rows
288 $rows = $this->get_plugin_status_rows();
289
290 echo '<table class="form-table pvc-status-table"><tbody>';
291 foreach ( (array) $rows as $row ) {
292 $label = isset( $row['label'] ) ? $row['label'] : '';
293 $value = isset( $row['value'] ) ? $row['value'] : '';
294 $active = isset( $row['active'] ) ? (bool) $row['active'] : null;
295 $tables = isset( $row['tables'] ) ? $row['tables'] : null;
296
297 echo '<tr>';
298 echo '<th scope="row">' . esc_html( $label ) . '</th>';
299 echo '<td>';
300
301 // handle tables structure with individual badges
302 if ( is_array( $tables ) && ! empty( $tables ) ) {
303 foreach ( $tables as $table ) {
304 $table_name = isset( $table['name'] ) ? esc_html( $table['name'] ) : '';
305 $table_label = isset( $table['label'] ) ? esc_html( $table['label'] ) : $table_name;
306 $table_exists = isset( $table['exists'] ) ? (bool) $table['exists'] : false;
307
308 echo '<p>';
309 echo $table_label;
310 if ( $table_exists ) {
311 echo ' <span class="pvc-status pvc-status-active">&#10003;</span>';
312 } else {
313 echo ' <span class="pvc-status pvc-status-missing">&#10007;</span>';
314 }
315 echo '</p>';
316 }
317 // handle lines array
318 } elseif ( isset( $row['lines'] ) && is_array( $row['lines'] ) ) {
319 foreach ( $row['lines'] as $line ) {
320 echo '<p>' . wp_kses( $line, [ 'span' => [ 'class' => [] ] ] ) . '</p>';
321 }
322 // handle boolean active status
323 } elseif ( $active === true ) {
324 echo '<span class="pvc-status pvc-status-active">&#10003; ' . esc_html__( 'Active', 'post-views-counter' ) . '</span>';
325 } elseif ( $active === false ) {
326 echo '<span class="pvc-status pvc-status-missing">&#10007; ' . esc_html__( 'Not Detected', 'post-views-counter' ) . '</span>';
327 // handle plain text value
328 } else {
329 echo wp_kses( $value, [ 'br' => [] ] );
330 } echo '</td>';
331 echo '</tr>';
332 }
333 echo '</tbody></table>';
334 }
335
336 /**
337 * Prepare an array with plugin status rows.
338 *
339 * Rows should be associative arrays with: label, value (string) and optional active (bool) key.
340 * The returned rows will be filtered by 'pvc_plugin_status_rows' which allows extensions to add/modify rows.
341 *
342 * @return array
343 */
344 protected function get_plugin_status_rows() {
345 global $wpdb;
346
347 $version = isset( $this->pvc->defaults['version'] ) ? $this->pvc->defaults['version'] : '';
348
349 if ( empty( $version ) ) {
350 $version = esc_html__( 'unknown', 'post-views-counter' );
351 }
352
353 // detect companion plugin activation status
354 $pvc_pro_active = class_exists( 'Post_Views_Counter_Pro' );
355
356 // get companion plugin version
357 $pro_version = $pvc_pro_active ? get_option( 'post_views_counter_pro_version', '1.0.0' ) : '<span class="pvc-status pvc-status-missing">✗</span>';
358
359 // get database tables via filter
360 $tables = $this->get_plugin_status_tables();
361
362 $rows = [
363 [
364 'label' => __( 'Plugin Version', 'post-views-counter' ),
365 'lines' => [ 'Post Views Counter: ' . $version, 'Post Views Counter Pro: ' . $pro_version ]
366 ]
367 ];
368
369 // add database tables row if any tables are defined
370 if ( ! empty( $tables ) ) {
371 $rows[] = [
372 'label' => __( 'Database Tables', 'post-views-counter' ),
373 'tables' => $tables
374 ];
375 }
376
377 /**
378 * Filter the plugin status rows.
379 *
380 * Allows extensions to add or modify status rows displayed in the settings page.
381 *
382 * @since 1.5.9
383 * @param array $rows Status rows
384 * @param Post_Views_Counter_Settings $this Instance of settings class
385 */
386 $rows = apply_filters( 'pvc_plugin_status_rows', $rows, $this->settings );
387
388 return $rows;
389 }
390
391 /**
392 * Get database tables for status display.
393 *
394 * Collects table definitions via filter, validates that table names contain 'post_views',
395 * checks actual existence in database, and returns formatted array.
396 *
397 * @return array
398 */
399 protected function get_plugin_status_tables() {
400 global $wpdb;
401
402 /**
403 * Filter the database tables to check for plugin status.
404 *
405 * @since 1.5.9
406 * @param array $table_definitions Array of table definitions
407 * @param Post_Views_Counter_Settings $this Instance of settings class
408 */
409 $table_definitions = apply_filters( 'pvc_plugin_status_tables', [], $this->settings );
410
411 if ( empty( $table_definitions ) || ! is_array( $table_definitions ) ) {
412 return [];
413 }
414
415 $validated_tables = [];
416
417 foreach ( $table_definitions as $table_def ) {
418 // validate structure
419 if ( ! is_array( $table_def ) || empty( $table_def['name'] ) ) {
420 continue;
421 }
422
423 $table_name = sanitize_key( $table_def['name'] );
424
425 // security: only allow tables with 'post_views' in the name
426 if ( strpos( $table_name, 'post_views' ) === false ) {
427 continue;
428 }
429
430 // check if table exists
431 $full_table_name = $wpdb->prefix . $table_name;
432 $exists = (bool) $wpdb->get_var( $wpdb->prepare( "SHOW TABLES LIKE %s", $full_table_name ) );
433
434 // use provided label or fallback to table name
435 $label = ! empty( $table_def['label'] ) ? $table_def['label'] : $table_name;
436
437 $validated_tables[] = [
438 'name' => $table_name,
439 'label' => $label,
440 'exists' => $exists
441 ];
442 }
443
444 return $validated_tables;
445 }
446
447 /**
448 * Section description: other - data import.
449 *
450 * @return void
451 */
452 public function section_other_import() {
453 echo '<p class="description">' . esc_html__( 'Import view counts when migrating from custom meta key or other analytics plugins.', 'post-views-counter' ) . '</p>';
454 }
455
456 /**
457 * Section description: other - admin & cleanup.
458 *
459 * @return void
460 */
461 public function section_other_management() {
462 echo '<p class="description">' . esc_html__( 'Choose what happens to stored view data on uninstall, and manage other removal-related tools.', 'post-views-counter' ) . '</p>';
463 }
464 }
465