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 +117 -78 3.5.14.9.2 View file →
@@ -1,101 +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 $icon_position = 'after';
16 + public $icon_position = 'after';
12 17
13 - public function get_name() {
14 - return 'betterdocs_faq_list_modern';
15 - }
18 + public function get_name() {
19 + return 'betterdocs_faq_list_modern';
20 + }
16 21
17 - public function get_style_depends() {
18 - return ['betterdocs-faq'];
19 - }
22 + public function get_style_depends() {
23 + return [ 'betterdocs-faq' ];
24 + }
20 25
21 - public function get_script_depends() {
22 - return ['betterdocs-faq'];
23 - }
26 + public function get_script_depends() {
27 + return [ 'betterdocs-faq' ];
28 + }
24 29
25 - protected $map_view_vars = [
26 - 'class' => 'faq_heading_class'
27 - ];
30 + protected $map_view_vars = [
31 + 'class' => 'faq_heading_class'
32 + ];
28 33
29 - /**
30 - * Summary of default_attributes
31 - * @return array
32 - */
33 - public function default_attributes() {
34 - return [
35 - 'groups' => '',
36 - 'class' => '',
37 - 'group_exclude' => '',
38 - 'faq_heading' => __( 'Frequently Asked Questions', 'betterdocs' ),
39 - 'faq_schema' => false,
40 - 'faq_layout' => 'layout-1',
41 - 'faq_section_title_color' => null,
42 - 'include_faq_group' => '',
43 - 'exclude_faq_group' => '',
44 - 'faq_group_title_color' => null,
45 - 'faq_group_title_hover_color' => null,
46 - 'faq_list_color' => null,
47 - 'faq_content_color' => null,
48 - 'faq_icon_color' => null,
49 - 'faq_group_title_typography' => null,
50 - 'faq_per_page' => 9,
51 - 'show_button_icon' => true,
52 - 'button_icon_position' => 'after',
53 - 'button_color' => '#528ffe',
54 - 'is_gutenberg' => false
55 - ];
56 - }
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 + }
57 69
58 - public function icons() {
59 - $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="' . 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>';
60 - $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="' . 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>';
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' ];
61 76
62 - echo $faq_markup;
63 - }
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>';
64 80
65 - public function render( $atts, $content = null ) {
81 + echo $faq_markup; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
82 + }
66 83
67 - $this->icon_position = isset( $this->atts['button_icon_position'] ) ? $this->atts['button_icon_position'] : '';
84 + public function render( $atts, $content = null ) {
68 85
69 - if ( $this->attributes['is_gutenberg'] && $this->attributes['button_icon_position'] == 'before' && $this->attributes['show_button_icon'] ) {
70 - add_action( 'betterdocs_faq_post_before', [$this, 'icons'] );
71 - } else if ( $this->attributes['is_gutenberg'] && $this->attributes['button_icon_position'] == 'after' && $this->attributes['show_button_icon'] ) {
72 - add_action( 'betterdocs_faq_post_after', [$this, 'icons'] );
73 - } else {
74 - add_action( $this->icon_hook, [$this, 'icons'] );
75 - }
86 + $this->icon_position = isset( $this->atts['button_icon_position'] ) ? $this->atts['button_icon_position'] : '';
76 87
77 - $this->views( 'shortcodes/faq' );
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 + }
78 95
79 - remove_action( $this->icon_hook, [$this, 'icons'] );
80 - }
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 + }
81 107
82 - public function view_params() {
83 - $terms_query = $this->query->faq_terms_query_args( $this->attributes['groups'], $this->attributes['group_exclude'] );
108 + $this->views( 'shortcodes/faq' );
84 109
85 - $wrapper_attr = [
86 - 'class' => [
87 - 'betterdocs-faq-wrapper',
88 - 'layout-' . $this->layout,
89 - 'icon-' . $this->attributes['button_icon_position'],
90 - $this->attributes['class']
91 - ]
92 - ];
110 + if ( $order_filter ) {
111 + remove_filter( 'betterdocs_faq_order_key', $order_filter, 20 );
112 + }
93 113
94 - return wp_parse_args( [
95 - 'wrapper_attr' => $wrapper_attr,
96 - 'widget' => $this,
97 - 'layout' => 'list',
98 - 'terms_query_args' => $terms_query
99 - ] );
100 - }
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 + }
101 140 }