PluginProbe
BetterDocs – AI Documentation, Knowledge Base, MCP Server, Docs, Wikis, FAQ & Chatbot / 4.9.2
BetterDocs – AI Documentation, Knowledge Base, MCP Server, Docs, Wikis, FAQ & Chatbot v4.9.2
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 3.4.2 3.5.0 3.5.1 All 200 releases
← All changes | includes/Shortcodes/FaqList.php +120 -54 3.3.44.9.2 View file →
@@ -1,74 +1,140 @@
1 1 <?php
2 +namespace WPDeveloper\BetterDocs\Shortcodes;
2 3
3 -namespace WPDeveloper\BetterDocs\Shortcodes;
4 +if ( ! defined( 'ABSPATH' ) ) {
5 + exit;
6 +}
4 7
8 +
5 9 use WPDeveloper\BetterDocs\Core\Shortcode;
10 +use WPDeveloper\BetterDocs\Utils\Helper;
6 11
7 12 class FaqList extends Shortcode {
8 - protected $layout = 'modern';
9 - protected $icon_hook = 'betterdocs_faq_post_after';
13 + protected $layout = 'modern';
14 + protected $icon_hook = 'betterdocs_faq_post_after';
10 15
11 - public function get_name() {
12 - return 'betterdocs_faq_list_modern';
13 - }
16 + public $icon_position = 'after';
14 17
15 - public function get_style_depends() {
16 - return ['betterdocs-faq'];
17 - }
18 + public function get_name() {
19 + return 'betterdocs_faq_list_modern';
20 + }
18 21
19 - public function get_script_depends() {
20 - return ['betterdocs-faq'];
21 - }
22 + public function get_style_depends() {
23 + return [ 'betterdocs-faq' ];
24 + }
22 25
23 - protected $map_view_vars = [
24 - 'class' => 'faq_heading_class'
25 - ];
26 + public function get_script_depends() {
27 + return [ 'betterdocs-faq' ];
28 + }
26 29
27 - /**
28 - * Summary of default_attributes
29 - * @return array
30 - */
31 - public function default_attributes() {
32 - return [
33 - 'groups' => '',
34 - 'class' => '',
35 - 'group_exclude' => '',
36 - 'faq_heading' => __( 'Frequently Asked Questions', 'betterdocs' ),
37 - 'faq_schema' => false
38 - ];
39 - }
30 + protected $map_view_vars = [
31 + 'class' => 'faq_heading_class'
32 + ];
40 33
41 - public function icons() {
42 - $faq_markup = '<svg class="betterdocs-faq-iconminus" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" stroke-width="2"><g fill="none" stroke="#528ffe" stroke-linecap="round" stroke-miterlimit="10" stroke-linejoin="round"><path d="M17 12H7"></path><circle cx="12" cy="12" r="11"></circle></g></svg>';
43 - $faq_markup .= '<svg class="betterdocs-faq-iconplus" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><g stroke-width="2" fill="none" stroke="#528ffe" stroke-linecap="square" stroke-miterlimit="10"><path d="M12 7v10M17 12H7"></path><circle cx="12" cy="12" r="11"></circle></g></svg>';
34 + /**
35 + * Summary of default_attributes
36 + * @return array
37 + */
38 + public function default_attributes() {
39 + return [
40 + 'groups' => '',
41 + 'class' => '',
42 + 'group_exclude' => '',
43 + 'faq_heading' => __( 'Frequently Asked Questions', 'betterdocs' ),
44 + 'faq_section_title_tag' => 'h2',
45 + 'faq_group_title_tag' => 'h3',
46 + 'faq_schema' => false,
47 + 'faq_layout' => 'layout-1',
48 + 'faq_section_title_color' => null,
49 + 'include_faq_group' => '',
50 + 'exclude_faq_group' => '',
51 + 'faq_group_title_color' => null,
52 + 'faq_group_title_hover_color' => null,
53 + 'faq_list_color' => null,
54 + 'faq_content_color' => null,
55 + 'faq_icon_color' => null,
56 + 'faq_group_title_typography' => null,
57 + 'faq_per_page' => 9,
58 + 'show_button_icon' => true,
59 + 'button_icon_position' => 'after',
60 + 'button_color' => '#528ffe',
61 + 'is_gutenberg' => false,
62 + 'faq_taxonomy' => 'betterdocs_faq_category',
63 + // Per-placement order override. Empty = use the global FAQ Builder
64 + // order (`betterdocs_faq_order` option). One of: default,
65 + // most_recent, least_recent, a_to_z, z_to_a, most_questions.
66 + 'order' => ''
67 + ];
68 + }
44 69
45 - echo $faq_markup;
46 - }
70 + /**
71 + * Allowed per-placement order keys, mirroring the FAQ Builder header dropdown.
72 + *
73 + * @var string[]
74 + */
75 + protected $allowed_order_keys = [ 'default', 'most_recent', 'least_recent', 'a_to_z', 'z_to_a', 'most_questions' ];
47 76
48 - public function render( $atts, $content = null ) {
49 - add_action( $this->icon_hook, [$this, 'icons'] );
77 + public function icons( $faq_toggle ) {
78 + $faq_markup = '<svg class="betterdocs-faq-iconminus" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"' .($faq_toggle ? " style='display:inline;'" : ""). 'stroke-width="2"><g fill="none" stroke="' . esc_attr( $this->attributes['button_color'] ) . '" stroke-linecap="round" stroke-miterlimit="10" stroke-linejoin="round"><path d="M17 12H7"></path><circle cx="12" cy="12" r="11"></circle></g></svg>';
79 + $faq_markup .= '<svg class="betterdocs-faq-iconplus" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"'.($faq_toggle ? " style='display:none;'" : "").'><g stroke-width="2" fill="none" stroke="' . esc_attr( $this->attributes['button_color'] ) . '" stroke-linecap="square" stroke-miterlimit="10"><path d="M12 7v10M17 12H7"></path><circle cx="12" cy="12" r="11"></circle></g></svg>';
50 80
51 - $this->views( 'shortcodes/faq' );
81 + echo $faq_markup; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
82 + }
52 83
53 - remove_action( $this->icon_hook, [$this, 'icons'] );
54 - }
84 + public function render( $atts, $content = null ) {
55 85
56 - public function view_params() {
57 - $terms_query = $this->query->faq_terms_query_args( $this->attributes['groups'], $this->attributes['group_exclude'] );
86 + $this->icon_position = isset( $this->atts['button_icon_position'] ) ? $this->atts['button_icon_position'] : '';
58 87
59 - $wrapper_attr = [
60 - 'class' => [
61 - 'betterdocs-faq-wrapper',
62 - 'layout-' . $this->layout,
63 - $this->attributes['class'],
64 - ]
65 - ];
88 + if ( $this->attributes['is_gutenberg'] && $this->attributes['button_icon_position'] == 'before' && $this->attributes['show_button_icon'] ) {
89 + add_action( 'betterdocs_faq_post_before', [ $this, 'icons' ] );
90 + } elseif ( $this->attributes['is_gutenberg'] && $this->attributes['button_icon_position'] == 'after' && $this->attributes['show_button_icon'] ) {
91 + add_action( 'betterdocs_faq_post_after', [ $this, 'icons' ] );
92 + } else {
93 + add_action( $this->icon_hook, [ $this, 'icons' ] );
94 + }
66 95
67 - return wp_parse_args( [
68 - 'wrapper_attr' => $wrapper_attr,
69 - 'widget' => $this,
70 - 'layout' => 'list',
71 - 'terms_query_args' => $terms_query
72 - ] );
73 - }
96 + // When this placement sets a valid `order`, scope it to this render only
97 + // (via the existing `betterdocs_faq_order_key` filter) so it overrides
98 + // the global FAQ Builder order without affecting other placements.
99 + $order_override = is_string( $this->attributes['order'] ) ? trim( $this->attributes['order'] ) : '';
100 + $order_filter = null;
101 + if ( $order_override && in_array( $order_override, $this->allowed_order_keys, true ) ) {
102 + $order_filter = function () use ( $order_override ) {
103 + return $order_override;
104 + };
105 + add_filter( 'betterdocs_faq_order_key', $order_filter, 20 );
106 + }
107 +
108 + $this->views( 'shortcodes/faq' );
109 +
110 + if ( $order_filter ) {
111 + remove_filter( 'betterdocs_faq_order_key', $order_filter, 20 );
112 + }
113 +
114 + remove_action( $this->icon_hook, [ $this, 'icons' ] );
115 + }
116 +
117 + public function view_params() {
118 + $taxonomy = sanitize_key( $this->attributes['faq_taxonomy'] );
119 + $terms_query = $this->query->faq_terms_query_args( $this->attributes['groups'], $this->attributes['group_exclude'], [], $taxonomy );
120 +
121 + $wrapper_attr = [
122 + 'class' => [
123 + 'betterdocs-faq-wrapper',
124 + 'layout-' . $this->layout,
125 + 'icon-' . $this->attributes['button_icon_position'],
126 + $this->attributes['class']
127 + ]
128 + ];
129 +
130 + return wp_parse_args(
131 + [
132 + 'wrapper_attr' => $wrapper_attr,
133 + 'widget' => $this,
134 + 'layout' => 'list',
135 + 'terms_query_args' => $terms_query,
136 + 'faq_schema' => $this->attributes['faq_schema'] && ! Helper::seo_plugin_outputs_faq_schema()
137 + ]
138 + );
139 + }
74 140 }