PluginProbe
weDocs: AI Powered Knowledge Base, Docs, Documentation, Wiki & AI Chatbot / trunk
weDocs: AI Powered Knowledge Base, Docs, Documentation, Wiki & AI Chatbot vtrunk
2.5.0 2.4.1 2.4.0 2.3.1 2.3.0 2.2.5 2.2.6 2.2.7 2.2.2 2.2.3 2.2.4 1.3.0 1.3.1 1.3.2 1.3.3 1.4 1.4.1 1.5 1.6 1.6.1 1.6.2 1.6.3 1.7 1.7.1 1.7.2 All 54 releases
wedocs / includes / Shortcode.php

Shortcode.php in weDocs: AI Powered Knowledge Base, Docs, Documentation, Wiki & AI Chatbot trunk, at includes/Shortcode.php

312 lines 9.2 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace WeDevs\WeDocs;
4
5 /**
6 * Shortcode.
7 */
8 class Shortcode {
9
10 /**
11 * Initialize the class
12 */
13 public function __construct() {
14 add_shortcode( 'wedocs', [ $this, 'shortcode' ] );
15 add_shortcode( 'wedocs_faq', [ $this, 'faq_shortcode' ] );
16 }
17
18 /**
19 * Shortcode handler.
20 *
21 * @param array $atts
22 * @param string $content
23 *
24 * @return string
25 */
26 public function shortcode( $atts, $content = '' ) {
27 Frontend::enqueue_assets();
28
29 ob_start();
30 self::wedocs( $atts );
31 $content .= ob_get_clean();
32
33 return $content;
34 }
35
36 /**
37 * Generic function for displaying docs.
38 *
39 * @param array $args
40 *
41 * @return void
42 */
43 public static function wedocs( $args = [] ) {
44 $defaults = [
45 'col' => '2',
46 'include' => 'any',
47 'exclude' => '',
48 'items' => 10,
49 'more' => __( 'View Details', 'wedocs' ),
50 'paginate' => '',
51 ];
52
53 $args = wp_parse_args( $args, $defaults );
54 $arranged = [];
55
56 $parent_args = [
57 'parent' => 0,
58 'post_type' => 'docs',
59 'sort_column' => 'menu_order',
60 ];
61
62 if ( 'any' != $args['include'] ) {
63 $parent_args['include'] = $args['include'];
64 }
65
66 if ( !empty( $args['exclude'] ) ) {
67 $parent_args['exclude'] = $args['exclude'];
68 }
69
70 $parent_args = apply_filters( 'wedocs_shortcode_page_parent_args', $parent_args );
71 $parent_docs = get_pages( $parent_args );
72
73 // Exclude docs marked as vendor-only docs so they don't appear in the public shortcode.
74 if ( $parent_docs ) {
75 $parent_docs = array_filter(
76 $parent_docs,
77 function ( $doc ) {
78 return '1' !== get_post_meta( $doc->ID, '_is_vendor_doc', true );
79 }
80 );
81 }
82
83 // Pagination support.
84 $per_page = ! empty( $args['paginate'] ) ? absint( $args['paginate'] ) : 0;
85 $total_docs = is_array( $parent_docs ) ? count( $parent_docs ) : 0;
86 $total_pages = 1;
87 $current_page = 1;
88
89 if ( $per_page > 0 && $total_docs > $per_page ) {
90 $raw_page = isset( $_GET['wedocs_page'] ) && is_scalar( $_GET['wedocs_page'] )
91 ? wp_unslash( $_GET['wedocs_page'] )
92 : 1;
93 $current_page = max( 1, absint( $raw_page ) );
94 $total_pages = (int) ceil( $total_docs / $per_page );
95 $current_page = min( $current_page, $total_pages );
96 $offset = ( $current_page - 1 ) * $per_page;
97 $parent_docs = array_slice( $parent_docs, $offset, $per_page );
98 }
99
100 // Arrange the section docs.
101 if ( $parent_docs ) {
102 foreach ( $parent_docs as $root ) {
103 $section_args = [
104 'post_parent' => $root->ID,
105 'post_type' => 'docs',
106 'post_status' => 'publish',
107 'orderby' => 'menu_order',
108 'order' => 'ASC',
109 'numberposts' => (int) $args['items'],
110 ];
111
112 $section_args = apply_filters( 'wedocs_shortcode_page_section_args', $section_args );
113 $section_docs = get_children( $section_args );
114
115 $arranged[] = [
116 'doc' => $root,
117 'sections' => $section_docs,
118 ];
119 }
120 }
121
122 // Count documentation length.
123 $docs_length = ! empty( $arranged ) ? count( $arranged ) : 0;
124
125 /**
126 * Handle single docs template directory.
127 *
128 * @since 2.0.0
129 *
130 * @param string $template_dir
131 *
132 * @return string
133 */
134 $template_dir = apply_filters( 'wedocs_get_doc_listing_template_dir', 'shortcode.php' );
135
136 /**
137 * Handle single doc template arguments.
138 *
139 * @since 2.0.0
140 *
141 * @param array $template_args
142 *
143 * @return array
144 */
145 $template_args = apply_filters(
146 'wedocs_get_doc_listing_template_args',
147 array(
148 'docs' => $arranged,
149 'more' => $args['more'],
150 'col' => (int) ( $docs_length === 1 ? $docs_length : $args['col'] ),
151 'enable_search' => wedocs_get_general_settings( 'enable_search', 'on' ),
152 'show_faq' => wedocs_get_general_settings( 'show_faq', 'off' ),
153 'current_page' => $current_page,
154 'total_pages' => $total_pages,
155 )
156 );
157
158 // Render single documentation template.
159 wedocs_get_template( $template_dir, $template_args );
160 }
161
162 /**
163 * FAQ shortcode handler.
164 *
165 * @since WEDOCS_SINCE
166 *
167 * @param array $atts Shortcode attributes.
168 * @param string $content Shortcode content.
169 *
170 * @return string
171 */
172 public function faq_shortcode( $atts, $content = '' ) {
173 ob_start();
174 self::wedocs_faq( $atts );
175 $content .= ob_get_clean();
176
177 return $content;
178 }
179
180 /**
181 * Query and render FAQ groups and items.
182 *
183 * @since WEDOCS_SINCE
184 *
185 * @param array $args Shortcode attributes.
186 *
187 * @return void
188 */
189 public static function wedocs_faq( $args = [] ) {
190 // A FAQ answer containing the shortcode again would otherwise recurse.
191 static $rendering = false;
192
193 if ( $rendering ) {
194 return;
195 }
196
197 $defaults = [
198 'group' => '',
199 'limit' => -1,
200 'orderby' => 'menu_order',
201 'order' => 'ASC',
202 ];
203
204 $args = wp_parse_args( $args, $defaults );
205
206 $group_query_args = [
207 'taxonomy' => 'wedocs_faq_group',
208 'hide_empty' => true,
209 ];
210
211 // Filter by specific group slug(s).
212 if ( ! empty( $args['group'] ) ) {
213 $group_query_args['slug'] = array_map( 'trim', explode( ',', $args['group'] ) );
214 }
215
216 $faq_groups = get_terms( $group_query_args );
217
218 if ( empty( $faq_groups ) || is_wp_error( $faq_groups ) ) {
219 return;
220 }
221
222 // Build FAQ data keyed by group.
223 $faq_data = [];
224
225 foreach ( $faq_groups as $group ) {
226 // WP deletes the meta row when storing boolean false, so an empty
227 // get_term_meta result can mean either "never set" (treat as active)
228 // or "explicitly disabled". Use metadata_exists() to tell them apart.
229 $has_status = metadata_exists( 'term', $group->term_id, 'status' );
230 $status = get_term_meta( $group->term_id, 'status', true );
231
232 // Skip groups that were explicitly disabled.
233 if ( $has_status && ! $status ) {
234 continue;
235 }
236
237 $faq_query_args = [
238 'post_type' => 'wedocs_faq',
239 'posts_per_page' => (int) $args['limit'],
240 'orderby' => $args['orderby'],
241 'order' => $args['order'],
242 'tax_query' => [ // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_tax_query
243 [
244 'taxonomy' => 'wedocs_faq_group',
245 'field' => 'term_id',
246 'terms' => $group->term_id,
247 ],
248 ],
249 ];
250
251 /**
252 * Filter the FAQ query arguments for a specific group.
253 *
254 * @since WEDOCS_SINCE
255 *
256 * @param array $faq_query_args WP_Query arguments.
257 * @param \WP_Term $group The FAQ group term.
258 * @param array $args Shortcode attributes.
259 */
260 $faq_query_args = apply_filters( 'wedocs_faq_shortcode_query_args', $faq_query_args, $group, $args );
261
262 $faqs = get_posts( $faq_query_args );
263
264 if ( empty( $faqs ) ) {
265 continue;
266 }
267
268 $faq_data[] = [
269 'group' => $group,
270 'faqs' => $faqs,
271 ];
272 }
273
274 if ( empty( $faq_data ) ) {
275 return;
276 }
277
278 /**
279 * Filter the FAQ shortcode template path.
280 *
281 * @since WEDOCS_SINCE
282 *
283 * @param string $template_dir Template file name.
284 */
285 $template_dir = apply_filters( 'wedocs_get_faq_listing_template_dir', 'shortcode-faq.php' );
286
287 /**
288 * Filter the FAQ shortcode template arguments.
289 *
290 * @since WEDOCS_SINCE
291 *
292 * @param array $template_args Template arguments.
293 */
294 $template_args = apply_filters(
295 'wedocs_get_faq_listing_template_args',
296 [
297 'faq_data' => $faq_data,
298 ]
299 );
300
301 // Only load the assets once there is markup that needs them.
302 wp_enqueue_style( 'wedocs-faq' );
303 wp_enqueue_script( 'wedocs-faq' );
304
305 $rendering = true;
306
307 wedocs_get_template( $template_dir, $template_args );
308
309 $rendering = false;
310 }
311 }
312