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
betterdocs / includes / Editors / BlockEditor / Blocks / CategoryGrid.php

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

239 lines 8.6 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 // phpcs:disable WordPress.DB.SlowDBQuery.slow_db_query_meta_query,WordPress.DB.SlowDBQuery.slow_db_query_meta_key,WordPress.DB.SlowDBQuery.slow_db_query_tax_query -- core block query; meta/tax filtering required.
3 // phpcs:disable WordPressVIPMinimum.Performance.WPQueryParams.PostNotIn_exclude -- block exposes user-driven exclusion controls.
4 namespace WPDeveloper\BetterDocs\Editors\BlockEditor\Blocks;
5
6 use WPDeveloper\BetterDocs\Editors\BlockEditor\Block;
7
8 class CategoryGrid extends Block {
9 protected $editor_scripts = [
10 'betterdocs-blocks-editor',
11 'betterdocs-categorygrid'
12 ];
13
14 protected $editor_styles = [
15 'betterdocs-blocks-editor',
16 'betterdocs-fontawesome',
17 'betterdocs-blocks-category-grid'
18 ];
19
20 protected $frontend_scripts = [
21 'betterdocs-category-grid'
22 ];
23 protected $frontend_styles = [
24 'betterdocs-fontawesome',
25 'betterdocs-blocks-category-grid'
26 ];
27
28 /**
29 * unique name of block
30 * @return string
31 */
32 public function get_name() {
33 return 'categorygrid';
34 }
35
36 public function register_scripts() {
37 //when thrive editor mode is active, do not enqueue this script, this causes an issue with thrive edit mode
38 // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- read-only editor detection.
39 $check_for_thrive = isset( $_GET['action'] ) ? sanitize_text_field( wp_unslash( $_GET['action'] ) ) : '';
40 if ( $check_for_thrive === 'architect' ) {
41 return;
42 }
43
44 $this->assets_manager->enqueue(
45 'betterdocs-categorygrid',
46 'blocks/categorygrid/frontend.js',
47 [ 'masonry' ]
48 );
49 }
50
51 public function get_default_attributes() {
52 return [
53 'blockId' => '',
54 'categories' => [],
55 'includeCategories' => '',
56 'excludeCategories' => '',
57 'gridPerPage' => 9,
58 'subCategoryPerGrid' => 2,
59 'orderBy' => 'doc_category_order',
60 'order' => 'asc',
61 'layout' => 'default',
62 'showTitle' => true,
63 'titleTag' => 'h2',
64 'showCount' => true,
65 'showIcon' => true,
66 'showList' => true,
67 'layoutMode' => 'grid',
68 'showHeader' => true,
69 'showButton' => true,
70 'listIcon' => 'far fa-file-alt',
71 'postsPerPage' => 5,
72 'postsOrderBy' => 'betterdocs_order',
73 'postsOrder' => 'asc',
74 'enableNestedSubcategory' => false,
75 // Default follows the global "Lazy Load Sidebar Docs & Subcategories"
76 // setting, mirroring the Elementor sidebar widget's control default, so
77 // enabling the setting lazy-loads the block too unless overridden.
78 'enableLazyLoad' => (bool) betterdocs()->settings->get( 'archive_lazy_load_descendants' ),
79 'postPerSubcategory' => 3,
80 'buttonIconPosition' => 'after',
81 'buttonIcon' => 'fas fa-angle-right',
82 'buttonPosition' => 'after',
83 'showButtonIcon' => true,
84 'colRange' => 3,
85 'TABcolRange' => 2,
86 'MOBcolRange' => 1,
87 'gridSpaceRange' => 10,
88 'TABgridSpaceRange' => 10,
89 'MOBgridSpaceRange' => 10,
90 'buttonText' => __( 'Explore More', 'betterdocs' ),
91 'categoryTitleLink' => false,
92 'selectKB' => '',
93 'listIconImageUrl' => '',
94 'prefix' => '',
95 'suffix' => '',
96 'suffixSingular' => ''
97 ];
98 }
99
100 public function render( $attributes, $content ) {
101 $this->views( 'layouts/base' );
102 }
103
104 public function view_params() {
105 $attributes = &$this->attributes;
106
107 // Sanitize the layout attribute to prevent path traversal (LFI).
108 $attributes['layout'] = sanitize_file_name( $attributes['layout'] );
109
110 $terms_object = [
111 'taxonomy' => 'doc_category',
112 'order' => $attributes['order'],
113 'orderby' => $attributes['orderBy'],
114 'number' => isset( $attributes['gridPerPage'] ) ? $attributes['gridPerPage'] : 5,
115 'hide_empty' => true
116 ];
117
118 if ( 'doc_category_order' === $attributes['orderBy'] ) {
119 // Use betterdocs_order which handles fallback logic automatically
120 $terms_object['orderby'] = 'betterdocs_order';
121 }
122
123 if ( $attributes['enableNestedSubcategory'] ) {
124 $terms_object['parent'] = 0;
125 }
126
127 $includes = $this->string_to_array( $attributes['includeCategories'] );
128 $excludes = $this->string_to_array( $attributes['excludeCategories'] );
129
130 if ( ! empty( $includes ) ) {
131 $terms_object['include'] = array_diff( $includes, (array) $excludes );
132 }
133
134 if ( ! empty( $excludes ) ) {
135 $terms_object['exclude'] = $excludes;
136 }
137
138 $_wrapper_classes = [
139 'betterdocs-category-grid-wrapper',
140 'betterdocs-blocks-grid'
141 ];
142
143 $layout_class = ( $attributes['layout'] === 'default' ) ? 'layout-1' : $attributes['layout'];
144
145 $_inner_wrapper_classes = [
146 'betterdocs-category-grid-inner-wrapper',
147 'layout-flex',
148 $layout_class,
149 $attributes['layoutMode'],
150 'betterdocs-column-' . $attributes['colRange'],
151 'betterdocs-column-tablet-' . $attributes['TABcolRange'],
152 'betterdocs-column-mobile-' . $attributes['MOBcolRange']
153 ];
154
155 $wrapper_attr = [
156 'class' => $_wrapper_classes
157 ];
158
159 $inner_wrapper_attr = [
160 'class' => $_inner_wrapper_classes,
161 'data-column_desktop' => $attributes['colRange'],
162 'data-column_tab' => $attributes['TABcolRange'],
163 'data-column_mobile' => $attributes['MOBcolRange'],
164 'data-column_space_desktop' => $attributes['gridSpaceRange'],
165 'data-colomn_space_tab' => $attributes['TABgridSpaceRange'],
166 'data-colomn_space_mobile' => $attributes['MOBgridSpaceRange']
167 ];
168
169 $docs_query = [
170 'orderby' => $attributes['postsOrderBy'],
171 'order' => $attributes['postsOrder'],
172 'posts_per_page' => $attributes['postsPerPage'],
173 'nested_subcategory' => $attributes['enableNestedSubcategory']
174 ];
175
176 $default_multiple_kb = betterdocs()->settings->get( 'multiple_kb' );
177
178 $select_kb = isset( $attributes['selectKB'] ) ? $attributes['selectKB'] : '';
179 if ( is_string( $select_kb ) && $select_kb !== '' ) {
180 $decoded = json_decode( $select_kb, true );
181 $select_kb = is_array( $decoded ) ? $decoded : [];
182 }
183 $kb_slug = is_array( $select_kb ) && isset( $select_kb['value'] ) ? $select_kb['value'] : '';
184
185 if ( is_tax( 'knowledge_base' ) && $default_multiple_kb == 1 ) {
186 $object = get_queried_object();
187 $kb_slug = $object->slug;
188 }
189
190 if ( ! empty( $kb_slug ) && $default_multiple_kb == 1 ) {
191 $terms_object['meta_query'] = [
192 'relation' => 'OR',
193 [
194 'key' => 'doc_category_knowledge_base',
195 'value' => $kb_slug,
196 'compare' => 'LIKE'
197 ]
198 ];
199 }
200
201 /**
202 * Add This Attribute When Using Outside Betterdocs Templates Only
203 */
204 if ( $default_multiple_kb == 1 && ( ! empty( $kb_slug ) ) && ( ! betterdocs()->helper->is_templates() ) ) {
205 $inner_wrapper_attr['data-mkb-slug'] = $kb_slug;
206 }
207
208 return [
209 'wrapper_attr' => $wrapper_attr,
210 'inner_wrapper_attr' => $inner_wrapper_attr,
211 'terms_query_args' => betterdocs()->query->terms_query( $terms_object ),
212 'docs_query_args' => $docs_query,
213 'widget_type' => 'category-grid',
214 'multiple_knowledge_base' => ( $default_multiple_kb && ! empty( $kb_slug ) ) ? true : false,
215 'kb_slug' => $kb_slug,
216 'nested_terms_query' => [
217 'number' => $attributes['subCategoryPerGrid']
218 ],
219 'list_icon_url' => '', // not needed for blocks, provided the prop for formality
220 'layout_type' => 'block',
221 'nested_docs_query_args' => [
222 'orderby' => $attributes['postsOrderBy'],
223 'order' => $attributes['postsOrder'],
224 'posts_per_page' => $attributes['postPerSubcategory']
225 ],
226 'list_icon_name' => ! empty( $attributes['listIconImageUrl'] ) ? [ 'value' => [ 'url' => str_replace( 'blob:', '', $attributes['listIconImageUrl'] ) ] ] : ( ! empty( $attributes['listIcon'] ) ? [ 'value' => [ 'url' => $attributes['listIcon'] ] ] : ( ! empty( betterdocs()->settings->get( 'docs_list_icon' ) ) ? [ 'value' => [ 'url' => betterdocs()->settings->get( 'docs_list_icon' )['url'] ] ] : [] ) ),
227 'button_icon' => [
228 'value' => $attributes['buttonIcon']
229 ],
230 'category_title_link' => $attributes['categoryTitleLink'],
231 'count_prefix' => $attributes['prefix'],
232 'count_suffix' => $attributes['suffix'],
233 'count_suffix_singular' => $attributes['suffixSingular'],
234 'title_tag' => $attributes['titleTag'],
235 'lazy_load' => ! empty( $attributes['enableLazyLoad'] )
236 ];
237 }
238 }
239