PluginProbe
BetterDocs – AI Documentation, Knowledge Base, MCP Server, Docs, Wikis, FAQ & Chatbot / 4.8.0
BetterDocs – AI Documentation, Knowledge Base, MCP Server, Docs, Wikis, FAQ & Chatbot v4.8.0
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 3.5.2 All 199 releases
betterdocs / includes / Editors / BlockEditor / Blocks / FAQ.php

FAQ.php in BetterDocs – AI Documentation, Knowledge Base, MCP Server, Docs, Wikis, FAQ & Chatbot 4.8.0, at includes/Editors/BlockEditor/Blocks/FAQ.php

170 lines 5.7 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 namespace WPDeveloper\BetterDocs\Editors\BlockEditor\Blocks;
3
4 if ( ! defined( 'ABSPATH' ) ) {
5 exit;
6 }
7
8
9 use WPDeveloper\BetterDocs\Editors\BlockEditor\Block;
10 use WPDeveloper\BetterDocs\FrontEnd\WooProductFAQ as WooFAQRenderer;
11
12 class FAQ extends Block {
13 protected $editor_scripts = [
14 'betterdocs-faq',
15 'betterdocs-blocks-editor'
16 ];
17
18 protected $editor_styles = [
19 'betterdocs-faq',
20 'betterdocs-blocks-editor'
21 ];
22
23 protected $frontend_styles = [
24 'betterdocs-faq'
25 ];
26
27 protected $frontend_scripts = [
28 'betterdocs-faq'
29 ];
30
31 /**
32 * unique name of block
33 * @return string
34 */
35 public function get_name() {
36 return 'faq';
37 }
38
39 public function get_default_attributes() {
40 return [
41 'blockId' => '',
42 'resOption' => 'Desktop',
43 'blockRoot' => 'better_docs',
44 'blockMeta' => null,
45 'faqLayout' => 'layout-1',
46 'faqSectionText' => 'Frequently Asked Questions',
47 'faqSectionTitleTag' => 'h2',
48 'faqGroupTitleTag' => 'h3',
49 'faqSectionTitleColor' => null,
50 'includeFaqGroup' => '',
51 'excludeFaqGroup' => '',
52 'faqGroupTitleColor' => null,
53 'faqGroupTitleHoverColor' => null,
54 'faqListColor' => null,
55 'faqContentColor' => null,
56 'faqIconColor' => null,
57 'faqGroupTitleTypography' => null,
58 'faqPerPage' => 9,
59
60 'showButtonIcon' => true,
61 'buttonColor' => '#528ffe',
62 'faqTaxonomy' => 'betterdocs_faq_category'
63 ];
64 }
65
66 public function render( $attributes, $content ) {
67 if ( ( $this->attributes['faqTaxonomy'] ?? '' ) === 'product_assignments' ) {
68 $this->render_product_assignments();
69 return;
70 }
71
72 add_filter( 'betterdocs_header_layout_sequence', [ $this, 'header_sequence' ], 10, 4 );
73 $this->views( 'layouts/faq' );
74 remove_filter( 'betterdocs_header_layout_sequence', [ $this, 'header_sequence' ], 10 );
75 }
76
77 private function render_product_assignments() {
78 if ( ! class_exists( 'WooCommerce' ) || ! is_product() ) {
79 return;
80 }
81
82 // In FSE templates, top-level blocks render outside the loop, so
83 // get_the_ID() can be 0 — fall back to the queried product.
84 $product_id = get_the_ID();
85 if ( ! $product_id ) {
86 $product_id = get_queried_object_id();
87 }
88 if ( ! $product_id ) {
89 return;
90 }
91
92 /** @var WooFAQRenderer $renderer */
93 $renderer = betterdocs()->container->get( WooFAQRenderer::class );
94
95 // This block is the explicit placement; don't also inject into the tab/summary.
96 $renderer->suppress_auto_placement();
97 $renderer->render_for_product( $product_id, $this->attributes['faqLayout'] ?? null );
98 }
99
100 public function get_groups_ids( $json ) {
101 $data = json_decode( $json, true );
102 $ids = '';
103 if ( $data !== null ) {
104 $ids = implode( ',', array_column( $data, 'value' ) );
105 }
106
107 return $ids;
108 }
109
110 public function view_params() {
111 $attributes = &$this->attributes;
112
113 // Sanitize the layout attribute to prevent path traversal (LFI).
114 $attributes['faqLayout'] = sanitize_file_name( $attributes['faqLayout'] );
115 $exclude = $this->get_groups_ids( $attributes['excludeFaqGroup'] );
116 $include = $this->get_groups_ids( $attributes['includeFaqGroup'] );
117 $taxonomy = sanitize_key( $attributes['faqTaxonomy'] ?? 'betterdocs_faq_category' );
118
119 $terms_query = betterdocs()->query->faq_terms_query_args( $include, $exclude, [], $taxonomy );
120
121 return wp_parse_args(
122 [
123 'enable' => true,
124 'have_posts' => true,
125 'widget' => $this,
126 'layout' => $attributes['faqLayout'],
127 'terms_query_args' => $terms_query,
128 'shortcode_attr' => [
129 'group_exclude' => $exclude,
130 'class' => 'betterdocs-faq-' . $attributes['faqLayout'] . ' ' . $attributes['blockId'],
131 'groups' => $include,
132 'is_gutenberg' => true,
133 'faq_heading' => $attributes['faqSectionText'],
134 'faq_section_title_tag' => $attributes['faqSectionTitleTag'],
135 'faq_group_title_tag' => $attributes['faqGroupTitleTag'],
136 'faq_section_title_color' => $attributes['faqSectionTitleColor'],
137 'include_faq_group' => $this->string_to_array( $attributes['includeFaqGroup'] ),
138 'exclude_faq_group' => $this->string_to_array( $attributes['excludeFaqGroup'] ),
139 'faq_group_title_color' => $attributes['faqGroupTitleColor'],
140 'faq_group_title_hover_color' => $attributes['faqGroupTitleHoverColor'],
141 'faq_list_color' => $attributes['faqListColor'],
142 'faq_content_color' => $attributes['faqContentColor'],
143 'faq_icon_color' => $attributes['faqIconColor'],
144 'faq_group_title_typography' => $attributes['faqGroupTitleTypography'],
145 'faq_per_page' => $attributes['faqPerPage'],
146 'show_button_icon' => $attributes['showButtonIcon'],
147 'button_icon_position' => $attributes['faqLayout'] == 'layout-1' || $attributes['faqLayout'] == 'layout-3' || $attributes['faqLayout'] == 'layout-4' ? 'after' : 'before',
148 'button_color' => $attributes['buttonColor'],
149 'faq_taxonomy' => $taxonomy,
150 // Per-block order; empty falls back to the global FAQ order.
151 'order' => isset( $attributes['faqOrder'] ) ? $attributes['faqOrder'] : ''
152 ]
153
154 ]
155 );
156 }
157
158 public function header_sequence( $_layout_sequence, $layout, $widget_type, $_defined_vars ) {
159 $_new_layout_sequence = [
160 [
161 'class' => 'betterdocs-category-title-counts',
162 'sequence' => [ 'category_title', 'category_counts' ]
163 ],
164 'category_description'
165 ];
166
167 return $_new_layout_sequence;
168 }
169 }
170