PluginProbe
BetterDocs – AI Documentation, Knowledge Base, MCP Server, Docs, Wikis, FAQ & Chatbot / 4.9.5
BetterDocs – AI Documentation, Knowledge Base, MCP Server, Docs, Wikis, FAQ & Chatbot v4.9.5
4.9.5 4.9.4 4.9.3 4.9.2 4.9.1 4.9.0 4.8.2 4.8.1 4.8.0 4.7.0 4.6.2 4.6.1 4.6.0 4.5.6 4.5.5 4.5.4 4.5.3 4.5.2 4.5.1 4.5.0 4.4.1 4.4.0 3.3.4 3.4.0 3.4.1 All 203 releases
← All changes | includes/Core/Settings.php +312 -34 4.8.1 → 4.9.5 View file →
@@ -239,8 +239,12 @@
239 239 'category_slug' => 'docs-category',
240 240 'tag_slug' => 'docs-tag',
241 241 'permalink_structure' => 'docs/',
242 242 'enable_faq_schema' => false,
243 + 'analytics_from' => 'everyone',
244 + 'unique_visitor_count' => true,
245 + 'exclude_bot_analytics' => true,
246 + 'child_category_exclude' => false,
243 247 'live_search' => true,
244 248 'advance_search' => false,
245 249 'popular_keyword_limit' => 5,
246 250 'search_letter_limit' => 3,
@@ -283,8 +287,12 @@
283 287 'enable_breadcrumb_category' => true,
284 288 'enable_breadcrumb_title' => true,
285 289 'enable_sidebar_cat_list' => true,
286 290 'enable_print_icon' => true,
291 + 'print_enable_logo' => false,
292 + 'print_logo' => array(),
293 + 'print_enable_footer' => false,
294 + 'print_footer_text' => '',
287 295 'enable_tags' => true,
288 296 'email_feedback' => true,
289 297 'feedback_link_text' => __( 'Still stuck? How can we help?', 'betterdocs' ),
290 298 'reaction_feedback_text' => __( 'Thanks for your feedback', 'betterdocs' ),
@@ -343,9 +351,40 @@
343 351 'singular_estimated_reading_time_text' => __( 'min read', 'betterdocs' ),
344 352 'betterdocs_access_control_repeater' => array(),
345 353 'internal_knowledge_base_type' => 'basic',
346 354 'betterdocs_access_control_repeater_kb' => array(),
347 - 'enable_git_integration' => false
355 + 'enable_git_integration' => false,
356 + 'enable_ai_actions' => true,
357 + 'enable_markdown_endpoint' => true,
358 + 'ai_actions_button_label' => __( 'Copy page', 'betterdocs' ),
359 + 'ai_actions_prompt_template' => __( 'Read from {URL} so I can ask questions about it.', 'betterdocs' ),
360 + 'ai_actions_copy_page' => true,
361 + 'ai_actions_view_markdown' => true,
362 + 'ai_actions_chatgpt' => true,
363 + 'ai_actions_claude' => true,
364 + 'ai_actions_gemini' => true,
365 + 'ai_actions_perplexity' => false,
366 + 'ai_actions_grok' => false,
367 + 'enable_listen' => true,
368 + 'listen_button_label' => __( 'Listen', 'betterdocs' ),
369 + 'listen_show_speed' => true,
370 + // Words a synthetic voice gets through in a minute at rate 1.
371 + // Deliberately lower than the 200 the reading-time pill assumes — that
372 + // number describes silent reading. Only the player's duration estimate
373 + // uses this; see Core\Listen::WORDS_PER_MINUTE.
374 + 'listen_words_per_minute' => 180,
375 + /**
376 + * MCP master switch. Off by default; the toggle lives on the
377 + * BetterDocs → MCP page, not in the settings tree, and writes
378 + * through POST betterdocs/v1/settings.
379 + *
380 + * The key has to be listed here or `get()` cannot see it at all:
381 + * it answers `$default` for anything absent from the defaults
382 + * array, whatever the stored option holds.
383 + *
384 + * @since 4.9.0
385 + */
386 + 'enable_mcp' => ''
348 387 );
349 388
350 389 $_default = apply_filters( 'betterdocs_default_settings', $_default );
351 390 // $_default = apply_filters_deprecated(
@@ -717,21 +756,38 @@
717 756 betterdocs()->kbmigration->migrate();
718 757 }
719 758 $_settings = wp_parse_args( $_normalized_settings, $_old_settings );
720 759
721 - // Check if there are actual changes before saving.
722 - // update_option returns false when values serialize identically, which can happen
723 - // due to object caching or type normalization even when user made changes.
724 - $_has_changes = $_settings != $_old_settings;
760 + // Detect whether this save actually changes the effective settings.
761 + //
762 + // The stored option and the submitted payload are normalized differently:
763 + // an optional field can be ABSENT from storage yet arrive as '' (e.g.
764 + // Feedback URL), and array fields can be stored empty ( [] ) while their
765 + // normalized/default form is non-empty (e.g. Instant Answer's
766 + // display_ia_texonomy defaults to ['all']). Comparing the raw arrays
767 + // ( $_settings != $_old_settings ) therefore reported a phantom change on
768 + // every save, leaving the tab perpetually "dirty" and always toasting
769 + // "Changes Saved Successfully." instead of "There are no changes to be
770 + // saved." — see WPDevelopers/betterdocs-pro#78.
771 + //
772 + // Compare like-for-like instead: fill defaults on both sides and run both
773 + // through the same normalization, so semantically-equal states (absent vs
774 + // '', [] vs ['all'], 'on' vs true) collapse to identical values and only a
775 + // real edit registers. This is also more reliable than update_option()'s
776 + // return, which is false whenever values serialize identically under object
777 + // caching or type coercion even when the user did change something (#49).
778 + $_defaults = array_merge( $this->get_default(), $this->get_pro_defaults() );
779 + $_old_normalized = $this->get_normalized_values( wp_parse_args( $_old_settings, $_defaults ), $_defaults );
780 + $_new_normalized = $this->get_normalized_values( wp_parse_args( $_settings, $_defaults ), $_defaults );
781 + $_has_changes = $_new_normalized != $_old_normalized;
725 782
726 783 $_saved = $this->database->save( $this->base_key, $_settings );
727 784
728 785 do_action_ref_array( 'betterdocs::settings::saved', array( $_saved, $_settings, $_old_settings, &$this ) );
729 786
730 - // Return true if save succeeded OR if there were changes to attempt saving.
731 - // This handles cases where update_option returns false due to identical serialization
732 - // (e.g., object caching, type coercion during serialization).
733 - return $_saved || $_has_changes;
787 + // The success / no-changes toast reflects whether the user made a real
788 + // change, not update_option()'s (unreliable) return value.
789 + return $_has_changes;
734 790 }
735 791
736 792 public function views( $hook ) {
737 793 return betterdocs()->views->get( 'admin/settings' );
@@ -929,10 +985,9 @@
929 985 'guests' => __( 'Guests Only', 'betterdocs' ),
930 986 'registered_users' => __( 'Registered Users Only', 'betterdocs' )
931 987 ) ),
932 988 'default' => 'everyone',
933 - 'priority' => 13,
934 - 'is_pro' => true
989 + 'priority' => 13
935 990 ),
936 991 'unique_visitor_count' => array(
937 992 'name' => 'unique_visitor_count',
938 993 'type' => 'toggle',
@@ -937,11 +992,10 @@
937 992 'name' => 'unique_visitor_count',
938 993 'type' => 'toggle',
939 994 'label' => __( 'Unique Visitor Count', 'betterdocs' ),
940 995 'enable_disable_text_active' => true,
941 - 'default' => false,
942 - 'priority' => 14,
943 - 'is_pro' => true
996 + 'default' => true,
997 + 'priority' => 14
944 998 ),
945 999 'exclude_bot_analytics' => array(
946 1000 'name' => 'exclude_bot_analytics',
947 1001 'type' => 'toggle',
@@ -946,11 +1000,10 @@
946 1000 'name' => 'exclude_bot_analytics',
947 1001 'type' => 'toggle',
948 1002 'label' => __( 'Exclude Bot Analytics', 'betterdocs' ),
949 1003 'enable_disable_text_active' => true,
950 - 'default' => false,
951 - 'priority' => 15,
952 - 'is_pro' => true
1004 + 'default' => true,
1005 + 'priority' => 15
953 1006 )
954 1007
955 1008 )
956 1009 ) )
@@ -1173,11 +1226,10 @@
1173 1226 'name' => 'child_category_exclude',
1174 1227 'type' => 'toggle',
1175 1228 'label' => __( 'Exclude Child Terms In Category Search', 'betterdocs' ),
1176 1229 'enable_disable_text_active' => true,
1177 - 'default' => '',
1178 - 'priority' => 3,
1179 - 'is_pro' => true
1230 + 'default' => false,
1231 + 'priority' => 3
1180 1232 ) ),
1181 1233 'popular_keyword_limit' => apply_filters( 'betterdocs_popular_keyword_limit_settings', array(
1182 1234 'name' => 'popular_keyword_limit',
1183 1235 'type' => 'number',
@@ -1384,8 +1436,44 @@
1384 1436 'enable_disable_text_active' => true,
1385 1437 'default' => 1,
1386 1438 'priority' => 3
1387 1439 ),
1440 + 'print_enable_logo' => array(
1441 + 'name' => 'print_enable_logo',
1442 + 'type' => 'toggle',
1443 + 'label' => __( 'Logo on Printed Doc', 'betterdocs' ),
1444 + 'label_subtitle' => __( 'Show a logo at the top of the printed / PDF page', 'betterdocs' ),
1445 + 'enable_disable_text_active' => true,
1446 + 'default' => 0,
1447 + 'priority' => 4
1448 + ),
1449 + 'print_logo' => array(
1450 + 'name' => 'print_logo',
1451 + 'type' => 'media',
1452 + 'value' => '',
1453 + 'label' => __( 'Print Logo', 'betterdocs' ),
1454 + 'label_subtitle' => __( 'Leave empty to use your site logo, or the site icon when no site logo is set', 'betterdocs' ),
1455 + 'priority' => 5,
1456 + 'rules' => Rules::is( 'print_enable_logo', true )
1457 + ),
1458 + 'print_enable_footer' => array(
1459 + 'name' => 'print_enable_footer',
1460 + 'type' => 'toggle',
1461 + 'label' => __( 'Footer on Printed Doc', 'betterdocs' ),
1462 + 'label_subtitle' => __( 'Show a footer on every page of the printed / PDF document', 'betterdocs' ),
1463 + 'enable_disable_text_active' => true,
1464 + 'default' => 0,
1465 + 'priority' => 6
1466 + ),
1467 + 'print_footer_text' => array(
1468 + 'name' => 'print_footer_text',
1469 + 'type' => 'textarea',
1470 + 'label' => __( 'Print Footer Text', 'betterdocs' ),
1471 + 'label_subtitle' => __( 'Leave empty to use the site name and current year', 'betterdocs' ),
1472 + 'default' => '',
1473 + 'priority' => 7,
1474 + 'rules' => Rules::is( 'print_enable_footer', true )
1475 + ),
1388 1476 'enable_tags' => array(
1389 1477 'name' => 'enable_tags',
1390 1478 'type' => 'toggle',
1391 1479 'label' => __( 'Tags', 'betterdocs' ),
@@ -1390,9 +1478,9 @@
1390 1478 'type' => 'toggle',
1391 1479 'label' => __( 'Tags', 'betterdocs' ),
1392 1480 'enable_disable_text_active' => true,
1393 1481 'default' => 1,
1394 - 'priority' => 4
1482 + 'priority' => 8
1395 1483 ),
1396 1484 'show_last_update_time' => array(
1397 1485 'name' => 'show_last_update_time',
1398 1486 'type' => 'toggle',
@@ -1398,9 +1486,9 @@
1398 1486 'type' => 'toggle',
1399 1487 'label' => __( 'Last Update Time', 'betterdocs' ),
1400 1488 'enable_disable_text_active' => true,
1401 1489 'default' => 1,
1402 - 'priority' => 5
1490 + 'priority' => 9
1403 1491 ),
1404 1492 'enable_navigation' => array(
1405 1493 'name' => 'enable_navigation',
1406 1494 'type' => 'toggle',
@@ -1406,9 +1494,9 @@
1406 1494 'type' => 'toggle',
1407 1495 'label' => __( 'Navigation', 'betterdocs' ),
1408 1496 'enable_disable_text_active' => true,
1409 1497 'default' => 1,
1410 - 'priority' => 6
1498 + 'priority' => 10
1411 1499 ),
1412 1500 'enable_comment' => array(
1413 1501 'name' => 'enable_comment',
1414 1502 'type' => 'toggle',
@@ -1414,9 +1502,9 @@
1414 1502 'type' => 'toggle',
1415 1503 'label' => __( 'Comment', 'betterdocs' ),
1416 1504 'enable_disable_text_active' => true,
1417 1505 'default' => '',
1418 - 'priority' => 7
1506 + 'priority' => 11
1419 1507 ),
1420 1508 'enable_credit' => array(
1421 1509 'name' => 'enable_credit',
1422 1510 'type' => 'toggle',
@@ -1422,9 +1510,9 @@
1422 1510 'type' => 'toggle',
1423 1511 'label' => __( 'Show Powered by BetterDocs', 'betterdocs' ),
1424 1512 'enable_disable_text_active' => true,
1425 1513 'default' => '',
1426 - 'priority' => 8
1514 + 'priority' => 12
1427 1515 ),
1428 1516 'reaction_feedback_text' => array(
1429 1517 'name' => 'reaction_feedback_text',
1430 1518 'type' => 'text',
@@ -1429,9 +1517,9 @@
1429 1517 'name' => 'reaction_feedback_text',
1430 1518 'type' => 'text',
1431 1519 'label' => __( 'Reaction Feedback Text', 'betterdocs' ),
1432 1520 'default' => __( 'Thanks for your feedback.', 'betterdocs' ),
1433 - 'priority' => 9
1521 + 'priority' => 13
1434 1522 ),
1435 1523 'enable_estimated_reading_time' => array(
1436 1524 'name' => 'enable_estimated_reading_time',
1437 1525 'type' => 'toggle',
@@ -1437,9 +1525,9 @@
1437 1525 'type' => 'toggle',
1438 1526 'label' => __( 'Estimated Reading Time', 'betterdocs' ),
1439 1527 'enable_disable_text_active' => true,
1440 1528 'default' => 0,
1441 - 'priority' => 10
1529 + 'priority' => 14
1442 1530 ),
1443 1531 'estimated_reading_time_title' => array(
1444 1532 'name' => 'estimated_reading_time_title',
1445 1533 'type' => 'text',
@@ -1444,9 +1532,9 @@
1444 1532 'name' => 'estimated_reading_time_title',
1445 1533 'type' => 'text',
1446 1534 'label' => __( 'Estimated Reading Time Title', 'betterdocs' ),
1447 1535 'default' => '',
1448 - 'priority' => 11,
1536 + 'priority' => 15,
1449 1537 'rules' => Rules::is( 'enable_estimated_reading_time', true )
1450 1538 ),
1451 1539 'estimated_reading_time_text' => array(
1452 1540 'name' => 'estimated_reading_time_text',
@@ -1452,9 +1540,9 @@
1452 1540 'name' => 'estimated_reading_time_text',
1453 1541 'type' => 'text',
1454 1542 'label' => __( 'Estimated Reading Time Text', 'betterdocs' ),
1455 1543 'default' => __( 'min read', 'betterdocs' ),
1456 - 'priority' => 12,
1544 + 'priority' => 16,
1457 1545 'rules' => Rules::is( 'enable_estimated_reading_time', true )
1458 1546 ),
1459 1547 'singular_estimated_reading_time_text' => array(
1460 1548 'name' => 'singular_estimated_reading_time_text',
@@ -1460,9 +1548,9 @@
1460 1548 'name' => 'singular_estimated_reading_time_text',
1461 1549 'type' => 'text',
1462 1550 'label' => __( 'Estimated Reading Time Text Singular', 'betterdocs' ),
1463 1551 'default' => __( 'min read', 'betterdocs' ),
1464 - 'priority' => 13,
1552 + 'priority' => 17,
1465 1553 'rules' => Rules::is( 'enable_estimated_reading_time', true )
1466 1554 )
1467 1555 )
1468 1556 ),
@@ -1729,8 +1817,202 @@
1729 1817 'enable_disable_text_active' => true,
1730 1818 'default' => false
1731 1819 )
1732 1820 ) )
1821 + ),
1822 + 'layout_single_doc_ai_actions' => array(
1823 + 'id' => 'layout_single_doc_ai_actions',
1824 + 'name' => 'layout_single_doc_ai_actions',
1825 + 'type' => 'section',
1826 + 'label' => __( 'AI Actions', 'betterdocs' ),
1827 + 'priority' => 8,
1828 + 'fields' => apply_filters( 'betterdocs_single_doc_ai_actions', array(
1829 + 'enable_ai_actions' => array(
1830 + 'name' => 'enable_ai_actions',
1831 + 'type' => 'toggle',
1832 + 'priority' => 1,
1833 + 'label' => __( 'Enable AI Actions', 'betterdocs' ),
1834 + 'label_subtitle' => __( 'Show a "Copy page" button beside the doc title so readers can copy the page as Markdown or open it in an AI assistant.', 'betterdocs' ),
1835 + 'enable_disable_text_active' => true,
1836 + 'default' => true
1837 + ),
1838 + 'enable_markdown_endpoint' => array(
1839 + 'name' => 'enable_markdown_endpoint',
1840 + 'type' => 'toggle',
1841 + 'priority' => 2,
1842 + 'label' => __( 'Serve Docs as Markdown', 'betterdocs' ),
1843 + // Plain text, not `<doc-url>.md`: the subtitle is rendered as HTML, so an
1844 + // angle-bracketed placeholder is swallowed as an unknown tag and the
1845 + // sentence read "Publish every doc at .md".
1846 + 'label_subtitle' => __( 'Publish every doc as Markdown at its address plus .md (for example /docs/getting-started.md), so AI assistants can read a clean copy. The Listen player uses it too. Required by "Copy page", "View as Markdown", and the Claude and Google AI Studio actions.', 'betterdocs' ),
1847 + 'enable_disable_text_active' => true,
1848 + 'default' => true
1849 + ),
1850 + // AI Actions and the Markdown endpoint are deliberately independent: the
1851 + // `.md` copies also serve AI assistants directly and the Listen player.
1852 + // So switching AI Actions off leaves Markdown on — say so where the
1853 + // admin is looking, rather than leaving a lone "Enabled" toggle under a
1854 + // feature that reads as switched off.
1855 + 'ai_actions_markdown_notice' => array(
1856 + 'name' => 'ai_actions_markdown_notice',
1857 + 'type' => 'html',
1858 + 'priority' => 3,
1859 + 'html' => sprintf(
1860 + '<div class="betterdocs-ai-actions-markdown-notice" style="margin:8px 0 0;padding:12px 16px;background:#f0f6ff;border-left:4px solid #5a6bff;border-radius:4px;font-size:13px;color:#202223;line-height:1.5;">%s</div>',
1861 + esc_html__( 'AI Actions is off, but your docs are still published as Markdown (.md) for AI assistants and the Listen player. Turn off "Serve Docs as Markdown" above if you don\'t want that.', 'betterdocs' )
1862 + ),
1863 + 'rules' => Rules::logicalRule( array(
1864 + Rules::is( 'enable_ai_actions', false ),
1865 + Rules::is( 'enable_markdown_endpoint', true )
1866 + ), 'and' )
1867 + ),
1868 + 'ai_actions_button_label' => array(
1869 + 'name' => 'ai_actions_button_label',
1870 + 'type' => 'text',
1871 + 'priority' => 4,
1872 + 'label' => __( 'Button Label', 'betterdocs' ),
1873 + 'default' => __( 'Copy page', 'betterdocs' ),
1874 + 'rules' => Rules::is( 'enable_ai_actions', true )
1875 + ),
1876 + 'ai_actions_prompt_template' => array(
1877 + 'name' => 'ai_actions_prompt_template',
1878 + 'type' => 'text',
1879 + 'priority' => 5,
1880 + 'label' => __( 'AI Prompt Template', 'betterdocs' ),
1881 + 'label_subtitle' => __( 'Sent to the AI assistant when a reader opens this doc there. Use {URL} for the doc address.', 'betterdocs' ),
1882 + 'default' => __( 'Read from {URL} so I can ask questions about it.', 'betterdocs' ),
1883 + 'rules' => Rules::is( 'enable_ai_actions', true )
1884 + ),
1885 + 'ai_actions_copy_page' => array(
1886 + 'name' => 'ai_actions_copy_page',
1887 + 'type' => 'toggle',
1888 + 'priority' => 6,
1889 + 'label' => __( 'Copy Page', 'betterdocs' ),
1890 + 'enable_disable_text_active' => true,
1891 + 'default' => true,
1892 + 'rules' => Rules::logicalRule( array(
1893 + Rules::is( 'enable_ai_actions', true ),
1894 + Rules::is( 'enable_markdown_endpoint', true )
1895 + ), 'and' )
1896 + ),
1897 + 'ai_actions_view_markdown' => array(
1898 + 'name' => 'ai_actions_view_markdown',
1899 + 'type' => 'toggle',
1900 + 'priority' => 7,
1901 + 'label' => __( 'View as Markdown', 'betterdocs' ),
1902 + 'enable_disable_text_active' => true,
1903 + 'default' => true,
1904 + 'rules' => Rules::logicalRule( array(
1905 + Rules::is( 'enable_ai_actions', true ),
1906 + Rules::is( 'enable_markdown_endpoint', true )
1907 + ), 'and' )
1908 + ),
1909 + 'ai_actions_chatgpt' => array(
1910 + 'name' => 'ai_actions_chatgpt',
1911 + 'type' => 'toggle',
1912 + 'priority' => 8,
1913 + 'label' => __( 'Open in ChatGPT', 'betterdocs' ),
1914 + 'enable_disable_text_active' => true,
1915 + 'default' => true,
1916 + 'rules' => Rules::is( 'enable_ai_actions', true )
1917 + ),
1918 + 'ai_actions_claude' => array(
1919 + 'name' => 'ai_actions_claude',
1920 + 'type' => 'toggle',
1921 + 'priority' => 9,
1922 + 'label' => __( 'Open in Claude', 'betterdocs' ),
1923 + 'enable_disable_text_active' => true,
1924 + 'default' => true,
1925 + 'rules' => Rules::logicalRule( array(
1926 + Rules::is( 'enable_ai_actions', true ),
1927 + Rules::is( 'enable_markdown_endpoint', true )
1928 + ), 'and' )
1929 + ),
1930 + 'ai_actions_gemini' => array(
1931 + 'name' => 'ai_actions_gemini',
1932 + 'type' => 'toggle',
1933 + 'priority' => 10,
1934 + 'label' => __( 'Open in Google AI Studio', 'betterdocs' ),
1935 + 'label_subtitle' => __( 'Gemini has no way to receive a prompt from a link, so this opens Google AI Studio instead. A Google account is required.', 'betterdocs' ),
1936 + 'enable_disable_text_active' => true,
1937 + 'default' => true,
1938 + 'rules' => Rules::logicalRule( array(
1939 + Rules::is( 'enable_ai_actions', true ),
1940 + Rules::is( 'enable_markdown_endpoint', true )
1941 + ), 'and' )
1942 + ),
1943 + 'ai_actions_perplexity' => array(
1944 + 'name' => 'ai_actions_perplexity',
1945 + 'type' => 'toggle',
1946 + 'priority' => 11,
1947 + 'label' => __( 'Open in Perplexity', 'betterdocs' ),
1948 + 'enable_disable_text_active' => true,
1949 + 'default' => false,
1950 + 'rules' => Rules::logicalRule( array(
1951 + Rules::is( 'enable_ai_actions', true ),
1952 + Rules::is( 'enable_markdown_endpoint', true )
1953 + ), 'and' )
1954 + ),
1955 + 'ai_actions_grok' => array(
1956 + 'name' => 'ai_actions_grok',
1957 + 'type' => 'toggle',
1958 + 'priority' => 12,
1959 + 'label' => __( 'Open in Grok', 'betterdocs' ),
1960 + 'enable_disable_text_active' => true,
1961 + 'default' => false,
1962 + 'rules' => Rules::logicalRule( array(
1963 + Rules::is( 'enable_ai_actions', true ),
1964 + Rules::is( 'enable_markdown_endpoint', true )
1965 + ), 'and' )
1966 + )
1967 + ) )
1968 + ),
1969 + 'layout_single_doc_listen' => array(
1970 + 'id' => 'layout_single_doc_listen',
1971 + 'name' => 'layout_single_doc_listen',
1972 + 'type' => 'section',
1973 + 'label' => __( 'Listen', 'betterdocs' ),
1974 + 'priority' => 9,
1975 + 'fields' => apply_filters( 'betterdocs_single_doc_listen', array(
1976 + 'enable_listen' => array(
1977 + 'name' => 'enable_listen',
1978 + 'type' => 'toggle',
1979 + 'priority' => 1,
1980 + 'label' => __( 'Enable Listen', 'betterdocs' ),
1981 + 'label_subtitle' => __( 'Show a "Listen" button beside the reading time. Pressed, it turns into a small audio player that reads the doc aloud using the visitor\'s browser — no audio files and no third-party service.', 'betterdocs' ),
1982 + 'enable_disable_text_active' => true,
1983 + 'default' => true
1984 + ),
1985 + 'listen_button_label' => array(
1986 + 'name' => 'listen_button_label',
1987 + 'type' => 'text',
1988 + 'priority' => 2,
1989 + 'label' => __( 'Button Label', 'betterdocs' ),
1990 + 'default' => __( 'Listen', 'betterdocs' ),
1991 + 'rules' => Rules::is( 'enable_listen', true )
1992 + ),
1993 + 'listen_show_speed' => array(
1994 + 'name' => 'listen_show_speed',
1995 + 'type' => 'toggle',
1996 + 'priority' => 3,
1997 + 'label' => __( 'Speed Control', 'betterdocs' ),
1998 + 'label_subtitle' => __( 'Let readers cycle the playback speed between 0.75× and 2×.', 'betterdocs' ),
1999 + 'enable_disable_text_active' => true,
2000 + 'default' => true,
2001 + 'rules' => Rules::is( 'enable_listen', true )
2002 + ),
2003 + 'listen_words_per_minute' => array(
2004 + 'name' => 'listen_words_per_minute',
2005 + 'type' => 'number',
2006 + 'priority' => 4,
2007 + 'label' => __( 'Words Per Minute', 'betterdocs' ),
2008 + 'label_subtitle' => __( 'Used to estimate the total playing time the player shows. Browser voices read at roughly 180 words a minute at normal speed; raise this if the countdown finishes early.', 'betterdocs' ),
2009 + 'default' => 180,
2010 + 'min' => 60,
2011 + 'max' => 400,
2012 + 'rules' => Rules::is( 'enable_listen', true )
2013 + )
2014 + ) )
1733 2015 )
1734 2016 )
1735 2017 )
1736 2018 )
@@ -2691,15 +2973,11 @@
2691 2973 return array(
2692 2974 'multiple_kb' => false,
2693 2975 'enable_glossaries' => false,
2694 2976 'enable_encyclopedia' => false,
2695 - 'analytics_from' => false,
2696 - 'unique_visitor_count' => false,
2697 - 'exclude_bot_analytics' => false,
2698 2977 'show_attachment' => false,
2699 2978 'show_related_docs' => false,
2700 2979 'advance_search' => false,
2701 - 'child_category_exclude' => false,
2702 2980 'kb_based_search' => false,
2703 2981 'enable_disable' => false,
2704 2982 'enable_content_restriction' => false
2705 2983 );