PluginProbe
BetterDocs – AI Documentation, Knowledge Base, MCP Server, Docs, Wikis, FAQ & Chatbot / 3.5.1
BetterDocs – AI Documentation, Knowledge Base, MCP Server, Docs, Wikis, FAQ & Chatbot v3.5.1
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 / Admin / CSVExporter.php

CSVExporter.php in BetterDocs – AI Documentation, Knowledge Base, MCP Server, Docs, Wikis, FAQ & Chatbot 3.5.1, at includes/Admin/CSVExporter.php

378 lines 11.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\Admin;
3
4 if ( ! defined( 'ABSPATH' ) ) {
5 exit; // Exit if accessed directly.
6 }
7
8 #[\AllowDynamicProperties]
9 class CSVExporter {
10 private static $default_args = [
11 'content' => 'docs',
12 'author' => false,
13 'category' => false,
14 'start_date' => false,
15 'end_date' => false,
16 'status' => false,
17 'offset' => 0,
18 'limit' => -1,
19 'meta_query' => [], // If specified `meta_key` then will include all post(s) that have this meta_key.
20 'query_args' => []
21 ];
22
23 /**
24 * @var array
25 */
26 private $args;
27
28 /**
29 * @var wpdb
30 */
31 private $wpdb;
32
33 public function __construct( array $args = [] ) {
34 global $wpdb;
35
36 $this->args = wp_parse_args( $args, self::$default_args );
37
38 $this->wpdb = $wpdb;
39 }
40
41 public function combine_csv_data($csv_data_array) {
42 // Combine headers
43 $headers_combined = $csv_data_array[0][0];
44
45 foreach ($csv_data_array as $csv_data) {
46 $headers_combined = array_merge($headers_combined, array_slice($csv_data[0], 1));
47 }
48
49 $csv_data_combined = [$headers_combined];
50
51 // Combine data
52 for ($i = 1; $i < count($csv_data_array[0]); $i++) {
53 $combined_row = [];
54 foreach ($csv_data_array as $csv_data) {
55 $combined_row = array_merge($combined_row, array_fill(0, count($csv_data_combined[0]) - count($combined_row)), [$csv_data[$i][0]], array_slice($csv_data[$i], 1));
56 }
57 $csv_data_combined[] = $combined_row;
58 }
59
60 return $csv_data_combined;
61 }
62
63
64 public function run(): array {
65 $post_args = [
66 'post_type' => 'docs',
67 'posts_per_page' => -1
68 ];
69
70 if ( isset($this->args['post__in']) ) {
71 $post_args['post__in'] = $this->args['post__in'];
72 }
73
74 if ( isset($this->args['category_terms']) ) {
75 $post_args['tax_query'] = [
76 [
77 'taxonomy' => 'doc_category',
78 'field' => 'slug',
79 'terms' => $this->args['category_terms'],
80 ],
81 ];
82 }
83
84 if ( isset($this->args['kb_terms']) ) {
85 $post_args['tax_query'] = [
86 [
87 'taxonomy' => 'knowledge_base',
88 'field' => 'slug',
89 'terms' => $this->args['kb_terms'],
90 ],
91 ];
92 }
93
94 $posts = get_posts($post_args);
95
96 $post_ids = array_map(function ($post) {
97 return $post->ID;
98 }, $posts);
99
100 $csv_data_terms = $this->get_terms_csv_data($post_ids);
101
102 $csv_data_author = $this->authors_list($post_ids);
103
104 $csv_data_posts = $this->get_posts_csv_data($posts);
105
106
107 // Combine headers
108 $headers_combined = array_merge($csv_data_posts[0], array_slice($csv_data_author[0], 1), array_slice($csv_data_terms[0], 1));
109
110 // Initialize the combined array with headers
111 $csv_data_combined = [$headers_combined];
112
113 // Combine term data with existing combined array
114 for ($i = 1; $i < count($csv_data_posts); $i++) {
115 $combined_row = array_merge($csv_data_posts[$i], array_fill(0, count($headers_combined) - count($csv_data_posts[$i]), ''));
116 $csv_data_combined[] = $combined_row;
117 }
118
119 // Calculate the starting index for author data
120 $author_start_index = count($csv_data_posts[0]);
121
122 // Combine author data with existing combined array
123 for ($i = 1; $i < count($csv_data_author); $i++) {
124 $combined_row = array_merge([$csv_data_author[$i][0]], array_fill(1, $author_start_index - 1, ''), array_slice($csv_data_author[$i], 1));
125 $csv_data_combined[] = $combined_row;
126 }
127
128 // Calculate the starting index for post data
129 $terms_start_index = $author_start_index + count($csv_data_author[0]) - 1;
130
131 // Combine post data with existing combined array
132 for ($i = 1; $i < count($csv_data_terms); $i++) {
133 $combined_row = array_merge([$csv_data_terms[$i][0]], array_fill(1, $terms_start_index - 1, ''), array_slice($csv_data_terms[$i], 1));
134 $csv_data_combined[] = $combined_row;
135 }
136
137 $filename = 'betterdocs.' . date('Y-m-d') . '.csv';
138 $csv_content = $this->generate_csv($csv_data_combined);
139
140 return [
141 'success' => true,
142 'data' => [
143 'filename' => $filename,
144 'filetype' => 'text/csv',
145 'download' => $csv_content,
146 ],
147 ];
148 }
149
150 public function get_terms( array $post_ids ) {
151 return wp_get_object_terms( $post_ids, get_object_taxonomies( 'docs' ) );
152 }
153
154 /**
155 * Sorting function for sorting term data.
156 *
157 * @param array $a The first array to compare.
158 * @param array $b The second array to compare.
159 *
160 * @return int Returns an integer less than, equal to, or greater than zero if the first array is considered
161 * to be respectively less than, equal to, or greater than the second.
162 */
163 public function sort_terms($a, $b) {
164 // Compare parent values
165 $parentComparison = strcmp($a[7], $b[7]);
166
167 // If parent values are equal, compare Term ID values
168 return ($parentComparison === 0) ? strcmp($a[2], $b[2]) : $parentComparison;
169 }
170
171 private function get_terms_csv_data($post_ids) {
172 $csv_data_terms = [];
173
174 // Add CSV headers for terms
175 $csv_data_terms[] = [
176 'Type',
177 'Taxonomy',
178 'Term ID',
179 'Term name',
180 'Term slug',
181 'Term group',
182 'Term description',
183 'Term parent',
184 'Assigned Docs',
185 'Assigned KBs',
186 'Doc Category order',
187 'KB order', // Add additional term meta headers here
188 ];
189
190 $terms = $this->get_terms($post_ids);
191
192 foreach ($terms as $term) {
193 $term_meta = '';
194
195 // Add term meta based on taxonomy
196 switch ($term->taxonomy) {
197 case 'doc_category':
198 $doc_category_knowledge_base = maybe_unserialize(get_term_meta($term->term_id, 'doc_category_knowledge_base', true));
199 if (is_array($doc_category_knowledge_base) && $doc_category_knowledge_base !== false) {
200 $doc_category_knowledge_base = implode(', ', array_filter($doc_category_knowledge_base));
201 } else {
202 $doc_category_knowledge_base = '';
203 }
204
205 $term_meta = [
206 '_docs_order' => get_term_meta($term->term_id, '_docs_order', true),
207 'doc_category_knowledge_base' => $doc_category_knowledge_base,
208 'doc_category_order' => get_term_meta($term->term_id, 'doc_category_order', true),
209 ];
210 break;
211
212 case 'knowledge_base':
213 $term_meta = [
214 'kb_order' => get_term_meta($term->term_id, 'kb_order', true),
215 ];
216 break;
217 }
218
219 // Add CSV row for term
220 $csv_data_terms[] = [
221 'Term',
222 $term->taxonomy,
223 $term->term_id,
224 $term->name,
225 $term->slug,
226 $term->term_group,
227 $term->description,
228 $term->parent,
229 isset($term_meta['_docs_order']) ? $term_meta['_docs_order'] : '',
230 isset($term_meta['doc_category_knowledge_base']) ? $term_meta['doc_category_knowledge_base'] : '',
231 isset($term_meta['doc_category_order']) ? $term_meta['doc_category_order'] : '',
232 isset($term_meta['kb_order']) ? $term_meta['kb_order'] : '',
233 ];
234 }
235
236 return $csv_data_terms;
237 }
238
239 /**
240 * Return list of authors with posts.
241 *
242 * @param int[] $post_ids Optional. Array of post IDs to filter the query by.
243 *
244 * @return string
245 */
246 private function authors_list( $post_ids ) {
247 $authors = [];
248
249 // Add CSV headers for terms
250 $authors[] = [
251 'Type',
252 'Author id',
253 'Author login',
254 'Author email',
255 'Author display name',
256 'Author first name',
257 'Author last name'
258 ];
259
260 if ( ! empty( $post_ids ) ) {
261 $post_ids = array_map( 'absint', $post_ids );
262 $and = 'AND ID IN ( ' . implode( ', ', $post_ids ) . ')';
263 } else {
264 $and = '';
265 }
266 $authors_data = [];
267 $results = $this->wpdb->get_results( "SELECT DISTINCT post_author FROM {$this->wpdb->posts} WHERE post_status != 'auto-draft' $and" );// phpcs:ignore
268 foreach ( (array) $results as $r ) {
269 $authors_data[] = get_userdata( $r->post_author );
270 }
271
272 $authors_data = array_filter( $authors_data );
273
274 foreach ( $authors_data as $author ) {
275 $authors[] = [
276 'Author',
277 $author->ID,
278 $author->user_login,
279 $author->user_email,
280 $author->display_name,
281 $author->first_name,
282 $author->last_name
283 ];
284 }
285
286 return $authors;
287 }
288
289 private function get_posts_csv_data($posts) {
290 $csv_data_posts = [];
291
292 // Add CSV headers for posts
293 $csv_data_posts[] = [
294 'Type',
295 'Docs ID',
296 'Docs author',
297 'Docs date',
298 'Docs date gmt',
299 'Docs title',
300 'Docs content',
301 'Docs excerpt',
302 'Docs status',
303 'Docs password',
304 'Docs slug',
305 'Docs modified date',
306 'Docs modified date gmt',
307 'Docs parent',
308 'Docs menu order',
309 'Docs mime type',
310 'Comment count',
311 'Doc Categories',
312 'Doc Tags',
313 'Knowledge Bases',
314 'Docs attachement url',
315 'Docs attachement ID'
316 ];
317
318 foreach ($posts as $post) {
319 $attachment_id = get_post_thumbnail_id($post->ID);
320 $attachment_url = get_the_post_thumbnail_url($post->ID);
321 // Add CSV row for post
322 $csv_data_posts[] = [
323 'Docs',
324 $post->ID,
325 $post->post_author,
326 $post->post_date,
327 $post->post_date_gmt,
328 $post->post_title,
329 $post->post_content,
330 $post->post_excerpt,
331 $post->post_status,
332 $post->post_password,
333 $post->post_name,
334 $post->post_modified,
335 $post->post_modified_gmt,
336 $post->post_parent,
337 $post->menu_order,
338 $post->post_mime_type,
339 $post->comment_count,
340 $this->get_term_ids( $post->ID, 'doc_category' ),
341 $this->get_term_ids( $post->ID, 'doc_tag' ),
342 $this->get_term_ids( $post->ID, 'knowledge_base' ),
343 $attachment_url ? $attachment_url : '',
344 $attachment_id ? $attachment_id : ''
345 ];
346
347 }
348
349 return $csv_data_posts;
350 }
351
352 public function get_term_ids($post_id, $taxonomy) {
353 $terms = get_the_terms($post_id, $taxonomy);
354
355 if ($terms && !is_wp_error($terms)) {
356 $term_ids = wp_list_pluck($terms, 'term_id');
357 return implode(', ', $term_ids);
358 }
359
360 return '';
361 }
362
363 private function generate_csv(array $data): string {
364 ob_start();
365
366 $output = fopen('php://output', 'w');
367
368 // Add CSV rows
369 foreach ($data as $row) {
370 fputcsv($output, $row);
371 }
372
373 fclose($output);
374
375 return ob_get_clean();
376 }
377 }
378