| @@ -1,9 +1,8 @@ | ||
| 1 | 1 | <?php |
| 2 | + | |
| 2 | 3 | namespace WPDeveloper\BetterDocs\Admin\Importer\Parsers; |
| 3 | 4 | |
| 4 | -use WP_Error; | |
| 5 | - | |
| 6 | 5 | if ( ! defined( 'ABSPATH' ) ) { |
| 7 | 6 | exit; // Exit if accessed directly. |
| 8 | 7 | } |
| 9 | 8 | |
| @@ -22,282 +21,312 @@ | ||
| 22 | 21 | * WXR Parser that uses regular expressions. Fallback for installs without an XML parser. |
| 23 | 22 | */ |
| 24 | 23 | class CSV_Parser { |
| 25 | 24 | |
| 26 | - /** | |
| 27 | - * Sort function for sorting CSV file data to keep Term and Author on top. | |
| 28 | - * | |
| 29 | - * @param array $a The first element to compare. | |
| 30 | - * @param array $b The second element to compare. | |
| 31 | - * | |
| 32 | - * @return int Returns an integer less than, equal to, or greater than zero if the first | |
| 33 | - * argument is considered to be respectively less than, equal to, or greater | |
| 34 | - * than the second. | |
| 35 | - */ | |
| 36 | - public function csvSort($a, $b) { | |
| 37 | - $order = array('Term', 'Author', 'Docs'); | |
| 25 | + /** | |
| 26 | + * Sort function for sorting CSV file data to keep Term and Author on top. | |
| 27 | + * | |
| 28 | + * @param array $a The first element to compare. | |
| 29 | + * @param array $b The second element to compare. | |
| 30 | + * | |
| 31 | + * @return int Returns an integer less than, equal to, or greater than zero if the first | |
| 32 | + * argument is considered to be respectively less than, equal to, or greater | |
| 33 | + * than the second. | |
| 34 | + */ | |
| 35 | + public function csvSort( $a, $b ) { | |
| 36 | + $order = [ 'Term', 'Author', 'Docs', 'FAQ' ]; | |
| 38 | 37 | |
| 39 | - $keyA = array_search($a[0], $order); | |
| 40 | - $keyB = array_search($b[0], $order); | |
| 38 | + $keyA = array_search( $a[0], $order ); | |
| 39 | + $keyB = array_search( $b[0], $order ); | |
| 41 | 40 | |
| 42 | - return $keyA - $keyB; | |
| 43 | - } | |
| 41 | + return $keyA - $keyB; | |
| 42 | + } | |
| 44 | 43 | |
| 45 | - public function parse( $file ) { | |
| 46 | - $data = []; | |
| 44 | + public function parse( $file ) { | |
| 45 | + $data = [ | |
| 46 | + 'terms' => [], | |
| 47 | + 'posts' => [], | |
| 48 | + 'authors' => [] | |
| 49 | + ]; | |
| 47 | 50 | |
| 48 | - $csv_data = []; | |
| 49 | - if (($handle = fopen($file, "r")) !== false) { | |
| 50 | - while (($data = fgetcsv($handle, 1000, ",")) !== false) { | |
| 51 | - $csv_data[] = $data; | |
| 52 | - } | |
| 53 | - fclose($handle); | |
| 54 | - } | |
| 51 | + $csv_data = []; | |
| 55 | 52 | |
| 56 | - // Remove the CSV headers | |
| 57 | - $headers = array_shift($csv_data); | |
| 53 | + // Read and normalize file content | |
| 54 | + $fileContent = file_get_contents( $file ); | |
| 55 | + if ( $fileContent === false ) { | |
| 56 | + return $data; // Return empty data if file reading fails | |
| 57 | + } | |
| 58 | 58 | |
| 59 | - // return data from sample csv file | |
| 60 | - if ( $headers['0'] == 'Docs Title' ) { | |
| 59 | + $fileContent = str_replace( [ "\r\n", "\r" ], "\n", $fileContent ); | |
| 61 | 60 | |
| 62 | - // update Docs Slug to post_name to check if post exists | |
| 63 | - $replacementMap = array( | |
| 64 | - 'Docs Slug' => 'post_name' | |
| 65 | - ); | |
| 61 | + // Parse through a stream so fgetcsv() correctly assembles records whose | |
| 62 | + // quoted fields span multiple lines (e.g. multi-line doc content). A plain | |
| 63 | + // explode( "\n" ) + str_getcsv() per line splits such records apart, producing | |
| 64 | + // rows whose column count no longer matches the headers — which makes the | |
| 65 | + // array_combine() calls below fatal (500 error on Sample Docs import). | |
| 66 | + // phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_operations_fopen -- in-memory stream, no filesystem access; required for multi-line CSV records. | |
| 67 | + $handle = fopen( 'php://temp', 'r+' ); | |
| 68 | + if ( $handle !== false ) { | |
| 69 | + fwrite( $handle, $fileContent ); | |
| 70 | + rewind( $handle ); | |
| 71 | + while ( ( $row = fgetcsv( $handle, 0, ',' ) ) !== false ) { | |
| 72 | + $csv_data[] = $row; | |
| 73 | + } | |
| 74 | + // phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_operations_fclose -- closing in-memory stream; WP_Filesystem does not apply. | |
| 75 | + fclose( $handle ); | |
| 76 | + } | |
| 66 | 77 | |
| 67 | - $headers = array_map(function ($item) use ($replacementMap) { | |
| 68 | - return isset($replacementMap[$item]) ? $replacementMap[$item] : $item; | |
| 69 | - }, $headers); | |
| 78 | + $headers = array_shift( $csv_data ); | |
| 70 | 79 | |
| 71 | - $data['type'] = 'sample/csv'; | |
| 80 | + // Bail out cleanly on an empty/malformed file instead of fataling below. | |
| 81 | + if ( ! is_array( $headers ) || empty( $headers ) ) { | |
| 82 | + return $data; | |
| 83 | + } | |
| 72 | 84 | |
| 73 | - foreach ($csv_data as $row) { | |
| 74 | - $data['posts'][] = array_combine($headers, $row); | |
| 75 | - } | |
| 85 | + // Process specific headers for 'Docs Title' | |
| 86 | + if ( $headers[0] == 'Docs Title' ) { | |
| 87 | + $replacementMap = [ 'Docs Slug' => 'post_name' ]; | |
| 76 | 88 | |
| 77 | - return $data; | |
| 78 | - } | |
| 89 | + $headers = array_map( | |
| 90 | + function ( $item ) use ( $replacementMap ) { | |
| 91 | + return $replacementMap[ $item ] ?? $item; | |
| 92 | + }, | |
| 93 | + $headers | |
| 94 | + ); | |
| 79 | 95 | |
| 80 | - usort($csv_data, [$this, 'csvSort']); | |
| 96 | + $data['type'] = 'sample/csv'; | |
| 81 | 97 | |
| 82 | - // Process CSV data and insert into WordPress | |
| 83 | - foreach ($csv_data as $row) { | |
| 98 | + foreach ( $csv_data as $row ) { | |
| 99 | + $row = array_pad( $row, count( $headers ), '' ); | |
| 100 | + $data['posts'][] = array_combine( $headers, $row ); | |
| 101 | + } | |
| 84 | 102 | |
| 85 | - $type = $row[0]; | |
| 103 | + return $data; | |
| 104 | + } | |
| 86 | 105 | |
| 87 | - if ($type === 'Term') { | |
| 88 | - // Extract the first 12 elements from the headers | |
| 89 | - $term_headers = array_slice($headers, 28, 11); | |
| 106 | + usort( $csv_data, [ $this, 'csvSort' ] ); | |
| 90 | 107 | |
| 91 | - // Extract the first 12 elements from the row | |
| 92 | - $term_row = array_slice($row, 28, 11); | |
| 93 | - $term_row = array_pad($term_row, count($term_headers), ''); | |
| 108 | + // The combined CSV packs three blocks side by side: Docs (from index 1), | |
| 109 | + // then Author, then Term. CSVs exported after the WPML language columns | |
| 110 | + // were added widen the Docs block by 2 columns (Docs language code + | |
| 111 | + // translation source slug), shifting the Author/Term offsets. Locate | |
| 112 | + // each block by its header name rather than a fixed position, so the | |
| 113 | + // layout is detected wherever the columns land (and adding a column to | |
| 114 | + // one block can't silently corrupt the others). | |
| 115 | + $has_wpml_columns = in_array( 'Docs language code', $headers, true ); | |
| 94 | 116 | |
| 95 | - if (count($term_headers) !== count($term_row)) { | |
| 96 | - return $data; | |
| 97 | - } | |
| 117 | + $author_offset = array_search( 'Author id', $headers, true ); | |
| 118 | + $term_offset = array_search( 'Taxonomy', $headers, true ); | |
| 98 | 119 | |
| 99 | - $term_data = array_combine($term_headers, $term_row); | |
| 120 | + // Fall back to the historical fixed offsets if a block header is missing | |
| 121 | + // (malformed file) so such files still parse exactly as they did before. | |
| 122 | + if ( $author_offset === false ) { | |
| 123 | + $author_offset = $has_wpml_columns ? 24 : 22; | |
| 124 | + } | |
| 125 | + if ( $term_offset === false ) { | |
| 126 | + $term_offset = $has_wpml_columns ? 30 : 28; | |
| 127 | + } | |
| 100 | 128 | |
| 129 | + // The Docs block runs from index 1 up to the start of the Author block. | |
| 130 | + $post_block_len = $author_offset - 1; | |
| 101 | 131 | |
| 102 | - $taxonomy = $term_data['Taxonomy']; | |
| 103 | - $term_id = $term_data['Term ID']; | |
| 104 | - $name = $term_data['Term name']; | |
| 105 | - $slug = $term_data['Term slug']; | |
| 106 | - $term_group = $term_data['Term group']; | |
| 107 | - $description = $term_data['Term description']; | |
| 108 | - $parent = $term_data['Term parent']; | |
| 109 | - $_docs_order = $term_data['Assigned Docs']; | |
| 132 | + foreach ( $csv_data as $row ) { | |
| 133 | + $type = $row[0]; | |
| 110 | 134 | |
| 111 | - $doc_category_knowledge_base = $term_data['Assigned KBs']; | |
| 112 | - $doc_category_knowledge_base = explode(",", $doc_category_knowledge_base); | |
| 113 | - $doc_category_knowledge_base = rest_sanitize_array( $doc_category_knowledge_base ); | |
| 135 | + if ( $type === 'glossaries' ) { | |
| 136 | + $term_headers = array_slice( $headers, 0, 7 ); | |
| 137 | + $term_row = array_slice( $row, 0, 7 ); | |
| 138 | + $term_row = array_pad( $term_row, count( $term_headers ), '' ); | |
| 114 | 139 | |
| 115 | - $doc_category_order = $term_data['Doc Category order']; | |
| 116 | - $kb_order = $term_data['KB order']; | |
| 140 | + if ( count( $term_headers ) !== count( $term_row ) ) { | |
| 141 | + return $data; | |
| 142 | + } | |
| 117 | 143 | |
| 144 | + $term_data = array_combine( $term_headers, $term_row ); | |
| 118 | 145 | |
| 146 | + $term_args = [ | |
| 147 | + 'term_taxonomy' => $term_data['Taxonomy'], | |
| 148 | + 'term_id' => $term_data['Term ID'], | |
| 149 | + 'term_name' => $term_data['Term name'], | |
| 150 | + 'slug' => $term_data['Term slug'], | |
| 151 | + 'term_group' => $term_data['Term group'] | |
| 152 | + ]; | |
| 153 | + | |
| 154 | + $term_args['termmeta'][] = [ | |
| 155 | + 'key' => 'glossary_term_description', | |
| 156 | + 'value' => $term_data['Term description'] | |
| 157 | + ]; | |
| 158 | + | |
| 159 | + $data['terms'][] = $term_args; | |
| 160 | + } elseif ( $type === 'Term' ) { | |
| 161 | + $term_headers = array_slice( $headers, $term_offset, 11 ); | |
| 162 | + $term_row = array_slice( $row, $term_offset, 11 ); | |
| 163 | + $term_row = array_pad( $term_row, count( $term_headers ), '' ); | |
| 164 | + | |
| 165 | + $term_data = array_combine( $term_headers, $term_row ); | |
| 166 | + | |
| 167 | + $taxonomy = $term_data['Taxonomy']; | |
| 119 | 168 | $term_args = [ |
| 120 | - 'term_id' => $term_id, | |
| 169 | + 'term_id' => sanitize_text_field( $term_data['Term ID'] ), | |
| 121 | 170 | 'term_taxonomy' => $taxonomy, |
| 122 | - 'slug' => $slug, | |
| 123 | - 'parent' => $parent, | |
| 124 | - 'term_name' => $name, | |
| 125 | - 'description' => $description, | |
| 126 | - 'term_group' => $term_group, | |
| 127 | - 'termmeta' => [], | |
| 171 | + 'slug' => sanitize_text_field( $term_data['Term slug'] ), | |
| 172 | + 'term_parent' => sanitize_text_field( $term_data['Term parent'] ), | |
| 173 | + 'term_name' => sanitize_text_field( $term_data['Term name'] ), | |
| 174 | + 'description' => sanitize_text_field( $term_data['Term description'] ), | |
| 175 | + 'term_group' => sanitize_text_field( $term_data['Term group'] ), | |
| 176 | + 'termmeta' => [] | |
| 128 | 177 | ]; |
| 129 | 178 | |
| 130 | - switch ($taxonomy) { | |
| 131 | - case 'doc_category': | |
| 132 | - if ($_docs_order) { | |
| 133 | - $term_args['termmeta'][] = [ | |
| 134 | - 'key' => '_docs_order', | |
| 135 | - 'value' => $_docs_order, | |
| 136 | - ]; | |
| 137 | - } | |
| 179 | + if ( $taxonomy === 'doc_category' ) { | |
| 180 | + if ( ! empty( $term_data['Assigned Docs'] ) ) { | |
| 181 | + $term_args['termmeta'][] = [ | |
| 182 | + 'key' => '_docs_order', | |
| 183 | + 'value' => sanitize_text_field( $term_data['Assigned Docs'] ) | |
| 184 | + ]; | |
| 185 | + } | |
| 138 | 186 | |
| 139 | - if ($doc_category_knowledge_base) { | |
| 140 | - $term_args['termmeta'][] = [ | |
| 141 | - 'key' => 'doc_category_knowledge_base', | |
| 142 | - 'value' => $doc_category_knowledge_base, | |
| 143 | - ]; | |
| 144 | - } | |
| 187 | + if ( ! empty( $term_data['Assigned KBs'] ) ) { | |
| 188 | + $doc_category_knowledge_base = explode( ",", sanitize_text_field( $term_data['Assigned KBs'] ) ); | |
| 189 | + $term_args['termmeta'][] = [ | |
| 190 | + 'key' => 'doc_category_knowledge_base', | |
| 191 | + 'value' => rest_sanitize_array( $doc_category_knowledge_base ) | |
| 192 | + ]; | |
| 193 | + } | |
| 145 | 194 | |
| 146 | - if ($doc_category_order) { | |
| 147 | - $term_args['termmeta'][] = [ | |
| 148 | - 'key' => 'doc_category_order', | |
| 149 | - 'value' => $doc_category_order, | |
| 150 | - ]; | |
| 151 | - } | |
| 152 | - break; | |
| 153 | - | |
| 154 | - case 'knowledge_base': | |
| 155 | - if ($kb_order) { | |
| 156 | - $term_args['termmeta'][] = [ | |
| 157 | - 'key' => 'kb_order', | |
| 158 | - 'value' => $kb_order, | |
| 159 | - ]; | |
| 160 | - } | |
| 161 | - break; | |
| 195 | + if ( ! empty( $term_data['Doc Category order'] ) ) { | |
| 196 | + $term_args['termmeta'][] = [ | |
| 197 | + 'key' => 'doc_category_order', | |
| 198 | + 'value' => sanitize_text_field( $term_data['Doc Category order'] ) | |
| 199 | + ]; | |
| 200 | + } | |
| 201 | + } else if ( $taxonomy === 'knowledge_base' && ! empty( $term_data['KB order'] ) ) { | |
| 202 | + $term_args['termmeta'][] = [ | |
| 203 | + 'key' => 'kb_order', | |
| 204 | + 'value' => $term_data['KB order'] | |
| 205 | + ]; | |
| 162 | 206 | } |
| 163 | 207 | |
| 164 | - $data['terms'][] = $term_args; | |
| 208 | + $data['terms'][] = $term_args; | |
| 209 | + } elseif ( $type === 'Author' ) { | |
| 210 | + $author_headers = array_slice( $headers, $author_offset, 6 ); | |
| 211 | + $author_row = array_slice( $row, $author_offset, 6 ); | |
| 212 | + $author_row = array_pad( $author_row, count( $author_headers ), '' ); | |
| 165 | 213 | |
| 166 | - } elseif ($type === 'Author') { | |
| 167 | - // Extract the first 12 elements from the headers | |
| 168 | - $author_headers = array_slice($headers, 22, 6); | |
| 214 | + $author_data = array_combine( $author_headers, $author_row ); | |
| 169 | 215 | |
| 170 | - // Extract the first 12 elements from the row | |
| 171 | - $author_row = array_slice($row, 22, 6); | |
| 172 | - $author_row = array_pad($author_row, count($author_headers), ''); | |
| 216 | + $data['authors'][$author_data['Author login']] = [ | |
| 217 | + 'author_id' => sanitize_text_field( $author_data['Author id'] ), | |
| 218 | + 'author_login' => sanitize_text_field( $author_data['Author login'] ), | |
| 219 | + 'author_email' => sanitize_text_field( $author_data['Author email'] ), | |
| 220 | + 'author_display_name' => sanitize_text_field( $author_data['Author display name'] ), | |
| 221 | + 'author_first_name' => sanitize_text_field( $author_data['Author first name'] ), | |
| 222 | + 'author_last_name' => sanitize_text_field( $author_data['Author last name'] ) | |
| 223 | + ]; | |
| 224 | + } else if ( $type === 'Docs' || $type === 'FAQ' ) { | |
| 225 | + // Keep FAQ import (HEAD) and use the dynamic post-block length | |
| 226 | + // from the WPML branch so the variable WPML language columns are | |
| 227 | + // handled instead of a hardcoded count. | |
| 228 | + $post_headers = array_slice( $headers, 1, $post_block_len ); | |
| 229 | + $post_row = array_slice( $row, 1, $post_block_len ); | |
| 230 | + $post_row = array_pad( $post_row, count( $post_headers ), '' ); | |
| 173 | 231 | |
| 174 | - $author_data = array_combine($author_headers, $author_row); | |
| 232 | + $post_data = array_combine( $post_headers, $post_row ); | |
| 175 | 233 | |
| 176 | - $author_id = $author_data['Author id']; | |
| 177 | - $author_login = $author_data['Author login']; | |
| 178 | - $author_email = $author_data['Author email']; | |
| 179 | - $author_display_name = $author_data['Author display name']; | |
| 180 | - $author_first_name = $author_data['Author first name']; | |
| 181 | - $author_last_name = $author_data['Author last name']; | |
| 182 | - | |
| 183 | - $author_args = [ | |
| 184 | - 'author_id' => $author_id, | |
| 185 | - 'author_login' => $author_login, | |
| 186 | - 'author_email' => $author_email, | |
| 187 | - 'author_display_name' => $author_display_name, | |
| 188 | - 'author_first_name' => $author_first_name, | |
| 189 | - 'author_last_name' => $author_last_name | |
| 234 | + $post_args = [ | |
| 235 | + 'post_id' => sanitize_text_field( $post_data['Docs ID'] ) ?? '', | |
| 236 | + 'post_type' => $type === 'FAQ' ? 'betterdocs_faq' : 'docs', | |
| 237 | + 'post_author' => sanitize_text_field( $post_data['Docs author'] ) ?? '', | |
| 238 | + 'post_content' => sanitize_text_field( $post_data['Docs content'] ) ?? '', | |
| 239 | + 'post_title' => sanitize_text_field( $post_data['Docs title'] ) ?? '', | |
| 240 | + 'post_name' => sanitize_text_field( $post_data['Docs slug'] ) ?? '', | |
| 241 | + 'post_excerpt' => sanitize_text_field( $post_data['Docs excerpt'] ) ?? '', | |
| 242 | + 'status' => sanitize_text_field( $post_data['Docs status'] ) ?? 'publish', | |
| 243 | + 'post_password' => sanitize_text_field( $post_data['Docs password'] ) ?? '', | |
| 244 | + 'post_parent' => sanitize_text_field( $post_data['Docs parent'] ) ?? '', | |
| 245 | + 'menu_order' => sanitize_text_field( $post_data['Docs menu order'] ) ?? '', | |
| 246 | + 'post_date' => sanitize_text_field( $post_data['Docs date'] ) ?? '', | |
| 247 | + 'post_date_gmt' => sanitize_text_field( $post_data['Docs date gmt'] ) ?? '', | |
| 248 | + 'post_modified' => sanitize_text_field( $post_data['Docs modified date'] ) ?? '', | |
| 249 | + 'post_modified_gmt' => sanitize_text_field( $post_data['Docs modified date gmt'] ) ?? '', | |
| 250 | + 'terms' => [], | |
| 251 | + 'postmeta' => [] | |
| 190 | 252 | ]; |
| 191 | 253 | |
| 192 | - $data['authors'][$author_login] = $author_args; | |
| 193 | - | |
| 194 | - } elseif ($type === 'Docs') { | |
| 195 | - // Extract elements 18-36 from the headers | |
| 196 | - $post_headers = array_slice($headers, 1, 21); | |
| 197 | - | |
| 198 | - // Extract elements 18-36 from the row | |
| 199 | - $post_row = array_slice($row, 1, 21); | |
| 200 | - | |
| 201 | - // Fill up the remaining elements with empty values | |
| 202 | - $post_row = array_pad($post_row, count($post_headers), ''); | |
| 203 | - | |
| 204 | - // Ensure data has at least the required elements | |
| 205 | - if (count($post_headers) !== count($post_row)) { | |
| 206 | - return $data; | |
| 254 | + if ( isset( $post_data['Doc Categories'] ) && $data['terms'] ) { | |
| 255 | + $post_args['terms'] = array_merge( | |
| 256 | + $this->searchTermsByIds( $data['terms'], sanitize_text_field( $post_data['Doc Categories'] ) ), | |
| 257 | + $this->searchTermsByIds( $data['terms'], sanitize_text_field( $post_data['Doc Tags'] ) ), | |
| 258 | + $this->searchTermsByIds( $data['terms'], sanitize_text_field( $post_data['Knowledge Bases'] ) ) | |
| 259 | + ); | |
| 207 | 260 | } |
| 208 | 261 | |
| 209 | - $post_data = array_combine($post_headers, $post_row); | |
| 210 | - | |
| 211 | - $post_args = array( | |
| 212 | - 'post_id' => isset($post_data['Docs ID']) ? $post_data['Docs ID'] : '', | |
| 213 | - 'post_type' => 'docs', | |
| 214 | - 'post_author' => isset($post_data['Docs author']) ? $post_data['Docs author'] : '', | |
| 215 | - 'post_content' => isset($post_data['Docs content']) ? $post_data['Docs content'] : '', | |
| 216 | - 'post_title' => isset($post_data['Docs title']) ? $post_data['Docs title'] : '', | |
| 217 | - 'post_name' => isset($post_data['Docs slug']) ? $post_data['Docs slug'] : '', | |
| 218 | - 'post_excerpt' => isset($post_data['Docs excerpt']) ? $post_data['Docs excerpt'] : '', | |
| 219 | - 'status' => isset($post_data['Docs status']) ? $post_data['Docs status'] : 'publish', | |
| 220 | - 'post_password' => isset($post_data['Docs password']) ? $post_data['Docs password'] : '', | |
| 221 | - 'post_parent' => isset($post_data['Docs parent']) ? $post_data['Docs parent'] : '', | |
| 222 | - 'menu_order' => isset($post_data['Docs menu order']) ? $post_data['Docs menu order'] : '', | |
| 223 | - 'post_date' => isset($post_data['Docs date']) ? $post_data['Docs date'] : '', | |
| 224 | - 'post_date_gmt' => isset($post_data['Docs date gmt']) ? $post_data['Docs date gmt'] : '', | |
| 225 | - 'post_modified' => isset($post_data['Docs modified date']) ? $post_data['Docs modified date'] : '', | |
| 226 | - 'post_modified_gmt' => isset($post_data['Docs modified date gmt']) ? $post_data['Docs modified date gmt'] : '', | |
| 227 | - 'terms' => [], | |
| 228 | - 'postmeta' => [], | |
| 229 | - ); | |
| 230 | - | |
| 231 | - | |
| 232 | - // Check if 'Doc Categories' is set and has data | |
| 233 | - if (isset($post_data['Doc Categories']) && $data['terms']) { | |
| 234 | - $termsDocCategories = $this->searchTermsByIds($data['terms'], $post_data['Doc Categories']); | |
| 262 | + if ( $has_wpml_columns ) { | |
| 263 | + if ( ! empty( $post_data['Docs language code'] ) ) { | |
| 264 | + $post_args['postmeta'][] = [ | |
| 265 | + 'key' => '_betterdocs_wpml_lang', | |
| 266 | + 'value' => sanitize_text_field( $post_data['Docs language code'] ), | |
| 267 | + ]; | |
| 268 | + } | |
| 269 | + if ( ! empty( $post_data['Docs translation source slug'] ) ) { | |
| 270 | + $post_args['postmeta'][] = [ | |
| 271 | + 'key' => '_betterdocs_wpml_source_slug', | |
| 272 | + 'value' => sanitize_text_field( $post_data['Docs translation source slug'] ), | |
| 273 | + ]; | |
| 274 | + } | |
| 235 | 275 | } |
| 236 | 276 | |
| 237 | - // Check if 'Doc Tags' is set and has data | |
| 238 | - if (isset($post_data['Doc Tags']) && $data['terms']) { | |
| 239 | - $termsDocTags = $this->searchTermsByIds($data['terms'], $post_data['Doc Tags']); | |
| 240 | - } | |
| 277 | + $data['posts'][] = $post_args; | |
| 241 | 278 | |
| 242 | - // Check if 'Knowledge Bases' is set and has data | |
| 243 | - if (isset($post_data['Knowledge Bases']) && $data['terms']) { | |
| 244 | - $termsKnowledgeBases = $this->searchTermsByIds($data['terms'], $post_data['Knowledge Bases']); | |
| 245 | - } | |
| 246 | - | |
| 247 | - // Combine the results if needed | |
| 248 | - $combinedTerms = array_merge($termsDocCategories ?? [], $termsDocTags ?? [], $termsKnowledgeBases ?? []); | |
| 249 | - | |
| 250 | - $post_args['terms'] = $combinedTerms; | |
| 251 | - | |
| 252 | - $data['posts'][] = $post_args; | |
| 253 | - if ( isset( $post_data['Docs attachement url'] ) && $post_data['Docs attachement url'] !== '' ) { | |
| 279 | + if ( ! empty( $post_data['Docs attachement url'] ) ) { | |
| 254 | 280 | $attachment_args = [ |
| 255 | - 'post_type' => 'attachment', | |
| 256 | - 'post_author' => isset($post_data['Docs author']) ? $post_data['Docs author'] : '', | |
| 257 | - 'post_id' => isset($post_data['Docs attachement ID']) ? $post_data['Docs attachement ID'] : '', | |
| 258 | - 'status' => 'inherit', | |
| 281 | + 'post_type' => 'attachment', | |
| 282 | + 'post_author' => sanitize_text_field( $post_data['Docs author'] ) ?? '', | |
| 283 | + 'post_id' => sanitize_text_field( $post_data['Docs attachement ID'] ) ?? '', | |
| 284 | + 'status' => 'inherit', | |
| 259 | 285 | 'post_content' => '', |
| 260 | 286 | 'post_excerpt' => '', |
| 261 | - 'guid' => '', | |
| 262 | - 'post_title' => pathinfo($post_data['Docs attachement url'], PATHINFO_FILENAME), | |
| 263 | - 'post_name' => pathinfo($post_data['Docs attachement url'], PATHINFO_FILENAME), | |
| 264 | - 'post_parent' => isset($post_data['Docs ID']) ? $post_data['Docs ID'] : '', | |
| 265 | - 'attachment_url' => $post_data['Docs attachement url'] | |
| 287 | + 'guid' => '', | |
| 288 | + 'post_title' => pathinfo( sanitize_text_field( $post_data['Docs attachement url'] ), PATHINFO_FILENAME ), | |
| 289 | + 'post_name' => pathinfo( sanitize_text_field( $post_data['Docs attachement url'] ), PATHINFO_FILENAME ), | |
| 290 | + 'post_parent' => sanitize_text_field( $post_data['Docs ID'] ) ?? '', | |
| 291 | + 'attachment_url' => sanitize_text_field( $post_data['Docs attachement url'] ) | |
| 266 | 292 | ]; |
| 267 | - $data['posts'][] = $attachment_args; | |
| 268 | - } | |
| 269 | - } | |
| 270 | - } | |
| 271 | - error_log(print_r($data, 1)); | |
| 272 | - return $data; | |
| 273 | - } | |
| 274 | 293 | |
| 275 | - public function searchTermsByIds($terms, $termIds) { | |
| 276 | - // Convert the comma-separated term IDs to an array | |
| 277 | - $termIdsArray = explode(',', $termIds); | |
| 294 | + $data['posts'][] = $attachment_args; | |
| 295 | + } | |
| 296 | + } | |
| 297 | + } | |
| 278 | 298 | |
| 279 | - // Initialize the result array | |
| 280 | - $result = []; | |
| 299 | + return $data; | |
| 300 | + } | |
| 281 | 301 | |
| 282 | - // Iterate through each term_id in the array | |
| 283 | - foreach ($termIdsArray as $termId) { | |
| 284 | - // Find the corresponding term in the terms array | |
| 285 | - $foundTerm = array_filter($terms, function ($term) use ($termId) { | |
| 286 | - return $term['term_id'] == $termId; | |
| 287 | - }); | |
| 302 | + public function searchTermsByIds( $terms, $termIds ) { | |
| 303 | + // Convert the comma-separated term IDs to an array | |
| 304 | + $termIdsArray = explode( ',', $termIds ); | |
| 288 | 305 | |
| 289 | - // If the term is found, add it to the result array | |
| 290 | - if (!empty($foundTerm)) { | |
| 291 | - $foundTerm = reset($foundTerm); | |
| 292 | - $result[] = [ | |
| 293 | - 'name' => $foundTerm['term_name'], | |
| 294 | - 'slug' => $foundTerm['slug'], | |
| 295 | - 'domain' => $foundTerm['term_taxonomy'], | |
| 296 | - ]; | |
| 297 | - } | |
| 298 | - } | |
| 306 | + // Initialize the result array | |
| 307 | + $result = []; | |
| 299 | 308 | |
| 300 | - return $result; | |
| 301 | - } | |
| 309 | + // Iterate through each term_id in the array | |
| 310 | + foreach ( $termIdsArray as $termId ) { | |
| 311 | + // Find the corresponding term in the terms array | |
| 312 | + $foundTerm = array_filter( | |
| 313 | + $terms, | |
| 314 | + function ( $term ) use ( $termId ) { | |
| 315 | + return $term['term_id'] == $termId; | |
| 316 | + } | |
| 317 | + ); | |
| 318 | + | |
| 319 | + // If the term is found, add it to the result array | |
| 320 | + if ( ! empty( $foundTerm ) ) { | |
| 321 | + $foundTerm = reset( $foundTerm ); | |
| 322 | + $result[] = [ | |
| 323 | + 'name' => $foundTerm['term_name'], | |
| 324 | + 'slug' => $foundTerm['slug'], | |
| 325 | + 'domain' => $foundTerm['term_taxonomy'] | |
| 326 | + ]; | |
| 327 | + } | |
| 328 | + } | |
| 329 | + | |
| 330 | + return $result; | |
| 331 | + } | |
| 302 | 332 | } |
| 303 | -?> | |