/[drupal]/contributions/modules/taxonomy_csv/taxonomy_csv.line.api.inc
ViewVC logotype

Contents of /contributions/modules/taxonomy_csv/taxonomy_csv.line.api.inc

Parent Directory Parent Directory | Revision Log Revision Log | View Revision Graph Revision Graph


Revision 2.3 - (show annotations) (download) (as text)
Tue Oct 20 20:21:44 2009 UTC (5 weeks, 3 days ago) by danielkm
Branch: MAIN
CVS Tags: HEAD
Changes since 2.2: +131 -124 lines
File MIME type: text/x-php
By Daniel Berthereau: Added export of terms and vocabularies.
1 <?php
2 // $Id: taxonomy_csv.line.api.inc,v 2.2 2009/10/05 09:43:12 danielkm Exp $
3
4 /**
5 * @file
6 * This light and simplified version of the full Api taxonomy_csv.api.inc allows
7 * to use taxonomy_csv import functions from any other module.
8 *
9 * Only line level functions are available. No check are done on submitted
10 * terms, neither before nor after importation.
11 *
12 * Example use:
13 * @code
14 * $result = taxonomy_csv_line_import(
15 * array(Europe, France, Paris),
16 * array(
17 * 'import_format' => 'tree_structure',
18 * 'vocabulary_id' => 2,
19 * 'existing_items' => 'update_replace',
20 * ));
21 * @endcode
22 */
23
24 /**
25 * Available import schemas.
26 */
27 define('TAXONOMY_CSV_FORMAT_ALONE_TERMS', 'alone_terms');
28 define('TAXONOMY_CSV_FORMAT_FLAT', 'flat');
29 define('TAXONOMY_CSV_FORMAT_TREE_STRUCTURE', 'tree_structure');
30 define('TAXONOMY_CSV_FORMAT_POLYHIERARCHY', 'polyhierarchy');
31 define('TAXONOMY_CSV_FORMAT_PARENTS', 'parents');
32 define('TAXONOMY_CSV_FORMAT_CHILDREN', 'children');
33 define('TAXONOMY_CSV_FORMAT_FIELDS', 'fields');
34 define('TAXONOMY_CSV_FORMAT_RELATIONS', 'relations');
35 define('TAXONOMY_CSV_FORMAT_DESCRIPTIONS', 'descriptions');
36 define('TAXONOMY_CSV_FORMAT_WEIGHTS', 'weights');
37 define('TAXONOMY_CSV_FORMAT_SYNONYMS', 'synonyms');
38 define('TAXONOMY_CSV_FORMAT_TAXONOMY_MANAGER', 'taxonomy_manager');
39
40 /**
41 * Available import options.
42 */
43 define('TAXONOMY_CSV_EXISTING_UPDATE', 'update'); // When no difference between merge and replace.
44 define('TAXONOMY_CSV_EXISTING_UPDATE_MERGE', 'update_merge');
45 define('TAXONOMY_CSV_EXISTING_UPDATE_REPLACE', 'update_replace');
46 define('TAXONOMY_CSV_EXISTING_IGNORE', 'ignore'); // When no difference between create and all. Equal to duplicate.
47 define('TAXONOMY_CSV_EXISTING_IGNORE_CREATE', 'ignore_create');
48 define('TAXONOMY_CSV_EXISTING_IGNORE_ALL', 'ignore_all'); // Ignore even existing terms in additional columns.
49 define('TAXONOMY_CSV_EXISTING_IGNORE_PREVIOUS', 'ignore_previous'); // Internal only.
50
51 /**
52 * @defgroup taxonomy_csv_line Import a line
53 * @{
54 * Functions allowing import of a line of terms or fields.
55 */
56
57 /**
58 * Import a line that contains a term and other items matching the options.
59 *
60 * @param $line
61 * Array which contains items to import.
62 * @param $options
63 * Array of import options:
64 * import_format : see _taxonomy_csv_info_lists('list_import_format')
65 * vocabulary_id : vocabulary id to import into
66 * existing_items : see _taxonomy_csv_info_lists('list_import_option')
67 * relations_create_subrelations: boolean. Specific to related terms import
68 * relations_all_vocabularies : boolean. Id
69 * Only destination vocabulary id is needed: other variables get default values.
70 * @param $previous_items
71 * Optional. Cleaned and checked previous imported line names and tids array.
72 * Needed with some contents as one term array structure import or taxonomy manager export.
73 * With taxonomy manager export, tid array is indexed with old tids.
74 * @return Result array:
75 * 'name' => array of imported terms names,
76 * 'tid' => array of imported terms tids,
77 * or FALSE if error.
78 * Warning: this returned value is different of taxonomy.csv.api.inc (always
79 * return array of messages codes and never FALSE).
80 */
81 function taxonomy_csv_line_import($line, $options, $previous_items = array()) {
82 // Set default value for unset options.
83 foreach (array(
84 'import_format' => TAXONOMY_CSV_FORMAT_ALONE_TERMS,
85 'existing_items' => TAXONOMY_CSV_EXISTING_UPDATE,
86 // Default options of specific imports.
87 'relations_create_subrelations' => FALSE,
88 'relations_all_vocabularies' => FALSE,
89 ) as $key => $value) {
90 if (!isset($options[$key])) {
91 $options[$key] = $value;
92 }
93 }
94
95 // Check if 'import_format' and 'existing_items' are compatible.
96 $allowed = _taxonomy_csv_info_lists('list_import_format_allowed_import_option');
97 if (!array_key_exists($options['import_format'], _taxonomy_csv_info_lists('list_import_format'))
98 || !array_key_exists($options['existing_items'], _taxonomy_csv_info_lists('list_import_option'))
99 || !in_array($options['existing_items'], $allowed[$options['import_format']])) {
100 return FALSE;
101 }
102
103 // Call process import.
104 $result = _taxonomy_csv_line_import_process(
105 array_values(array_map('trim', $line)),
106 $options,
107 $previous_items);
108
109 // Check ['msg'] array. TRUE in a msg means that there is a issue.
110 foreach ($result['msg'] as $key => $value) {
111 if (in_array(TRUE, $value, TRUE)) {
112 return FALSE;
113 }
114 }
115 unset($result['msg']);
116
117 return $result;
118 }
119
120 /**
121 * Helper function to process import items.
122 *
123 * @param $line
124 * Array which contains items of a cleaned and checked csv line.
125 * @param $options
126 * Array of import options (same as taxonomy_csv_line_import):
127 * import_format : see _taxonomy_csv_info_lists('list_import_format')
128 * vocabulary_id : vocabulary id to import into
129 * existing_items : see _taxonomy_csv_info_lists('list_import_option')
130 * relations_create_subrelations: boolean. Specific to related terms import
131 * relations_all_vocabularies : boolean. Id
132 * @param $previous_items
133 * Optional. Cleaned and checked previous imported line names and tids array.
134 * Needed with some contents as one term array structure import or taxonomy manager export.
135 * With taxonomy manager export, tid array is indexed with old tids.
136 * @return Result array:
137 * 'name' => array of imported terms names,
138 * 'tid' => array of imported terms tids,
139 * 'msg' => messages arrays:
140 * term position => array of status messages of term.
141 */
142 function _taxonomy_csv_line_import_process($line, $options, $previous_items = array()) {
143 // Define default values.
144 $result = array(
145 'name' => array(),
146 'tid' => array(),
147 'msg' => array(),
148 );
149
150 // Only count check because line and previous line already checked.
151 if (count($line)) {
152 switch ($options['import_format']) {
153 case TAXONOMY_CSV_FORMAT_FLAT:
154 foreach ($line as $term_name) {
155 $term = array(
156 'name' => $term_name,
157 'vid' => $options['vocabulary_id'],
158 );
159 // Import term then store and check result.
160 $current_result = taxonomy_csv_term_import($term, $options['existing_items']);
161 $result['name'][] = $current_result['name'];
162 $result['tid'][] = $current_result['tid'];
163 $result['msg'][] = $current_result['msg'];
164 if (_taxonomy_csv_message_warning($current_result['msg'])) {
165 break;
166 }
167 }
168 break;
169
170 case TAXONOMY_CSV_FORMAT_TREE_STRUCTURE:
171 // Same process, except when term is imported.
172 case TAXONOMY_CSV_FORMAT_POLYHIERARCHY:
173 // First, complete line with previous line.
174 // Calculate first non empty item as line can be a full, partial or one term array.
175 for ($first_non_empty = 0; ($first_non_empty < count($line)) && (empty($line[$first_non_empty])); $first_non_empty++) {
176 }
177
178 // Clean line of surabondant previous items then memorize previous terms for next line.
179 if ($first_non_empty) {
180 $result['name'] = $previous_items['name'] = array_slice($previous_items['name'], 0, $first_non_empty);
181 $result['tid'] = $previous_items['tid'] = array_slice($previous_items['tid'], 0, $first_non_empty);
182 foreach ($previous_items['tid'] as $key => $term) {
183 $result['msg'][] = array(FALSE); // No error: Previous line term.
184 }
185 }
186
187 // Second, process import of new items.
188 // Set root or previous ancestor name and id.
189 $parent_name = ($first_non_empty == 0) ? '' : $previous_items['name'][$first_non_empty - 1];
190 $parent_tid = ($first_non_empty == 0) ? 0 : $previous_items['tid'][$first_non_empty - 1];
191
192 for ($c = $first_non_empty; $c < count($line); $c++) {
193 $term = array(
194 'name' => $line[$c],
195 'vid' => $options['vocabulary_id'],
196 // Need an array in case of multiple parent.
197 'parent' => array($parent_tid),
198 );
199
200 // Import term then store and check result.
201 switch ($options['import_format']) {
202 case TAXONOMY_CSV_FORMAT_TREE_STRUCTURE:
203 // With TAXONOMY_CSV_EXISTING_IGNORE_CREATE, parent terms (so all terms but the last on this line)
204 // are always updated because they are successive parents of a child.
205 $current_result = ($options['existing_items'] == TAXONOMY_CSV_EXISTING_IGNORE_CREATE && ($c < count($line) - 1)) ?
206 taxonomy_csv_term_import($term, TAXONOMY_CSV_EXISTING_IGNORE_PREVIOUS, FALSE, $parent_tid) :
207 taxonomy_csv_term_import($term, $options['existing_items'], FALSE, $parent_tid);
208 break;
209
210 case TAXONOMY_CSV_FORMAT_POLYHIERARCHY:
211 // Manage eventual direct duplicates: in Drupal, a term can't be a parent of itself.
212 $current_result = ($term['name'] == $parent_name) ?
213 taxonomy_csv_term_import($term, $options['existing_items'], FALSE, $parent_tid) :
214 taxonomy_csv_term_import($term, $options['existing_items'], FALSE, NULL);
215 break;
216 }
217 $result['name'][] = $current_result['name'];
218 $result['tid'][] = $current_result['tid'];
219 $result['msg'][] = $current_result['msg'];
220 if (_taxonomy_csv_message_warning($current_result['msg'])) {
221 break;
222 }
223
224 $parent_name = $current_result['name'];
225 $parent_tid = $current_result['tid'];
226 }
227 break;
228
229 case TAXONOMY_CSV_FORMAT_PARENTS:
230 // First, import parents using a recursive call and check result.
231 if (count($line) > 1) {
232 $options_temp = $options;
233 $options_temp['import_format'] = TAXONOMY_CSV_FORMAT_FLAT;
234 $result = _taxonomy_csv_line_import_process(array_slice($line, 1), $options_temp);
235 if (_taxonomy_csv_message_warning($result, 'line')) {
236 break;
237 }
238 }
239
240 // Second,import main term then store result. No check because only one term.
241 // No need to check if tid is equal to parent_tid, because duplicates have been removed.
242 $term = array(
243 'name' => $line[0],
244 'vid' => $options['vocabulary_id'],
245 'parent' => $result['tid'],
246 );
247 $current_result = taxonomy_csv_term_import($term, $options['existing_items']);
248 // Use array_unshift in order to keep $line order of items.
249 array_unshift($result['name'], $current_result['name']);
250 array_unshift($result['tid'], $current_result['tid']);
251 array_unshift($result['msg'], $current_result['msg']);
252 break;
253
254 case TAXONOMY_CSV_FORMAT_CHILDREN:
255 // First, import main term then store and check result.
256 $options_temp = $options;
257 $options_temp['import_format'] = TAXONOMY_CSV_FORMAT_ALONE_TERMS;
258 $result = _taxonomy_csv_line_import_process(array($line[0]), $options_temp);
259 if (_taxonomy_csv_message_warning($result, 'line')) {
260 break;
261 }
262 // Remember tid of main term.
263 $parent_tid = $result['tid'][0];
264
265 // Second, import children.
266 foreach (array_slice($line, 1) as $value) {
267 $term = array(
268 'name' => $value,
269 'vid' => $options['vocabulary_id'],
270 'parent' => array($parent_tid),
271 );
272
273 // Import term then store and check result.
274 // No need to check if tid is equal to parent_tid, because duplicates have been removed.
275 $current_result = taxonomy_csv_term_import($term, $options['existing_items']);
276 $result['name'][] = $current_result['name'];
277 $result['tid'][] = $current_result['tid'];
278 $result['msg'][] = $current_result['msg'];
279 if (_taxonomy_csv_message_warning($current_result['msg'])) {
280 break;
281 }
282 }
283 break;
284
285 case TAXONOMY_CSV_FORMAT_RELATIONS:
286 // Each related term should exist before first column term can be related to it (need of its tid). Next, process relations and eventually subrelations
287 // So, with a line array (A,B,C,D,E...), creates A, BA, CA(B), DA(BC), EA(BCD)... as it's the fatest way to create one or all relations even if items not exists.
288 // As use of name is only for first column, need to keep previous tids matching names in $previous_relations ([name] <=> [tid]).
289 $previous_relations = array();
290 foreach ($line as $key => $term) {
291 $term = array(
292 'name' => $line[$key],
293 'vid' => $options['vocabulary_id'],
294 'relations' => array_slice($previous_relations, 0, ($options['relations_create_subrelations']) ? $key : $key != 0),
295 );
296
297 ///TODO: Set an 'ignore all' option.
298 // For second and next terms, update merge related terms in order to keep previous relations, as option is only for the first column term.
299 $current_term_import_option = ($key == 0) ? $options['existing_items'] : TAXONOMY_CSV_EXISTING_UPDATE_MERGE;
300
301 $current_result = taxonomy_csv_term_import($term, $current_term_import_option, $options['relations_all_vocabularies'], NULL);
302 $result['name'][] = $current_result['name'];
303 $result['tid'][] = $current_result['tid'];
304 $result['msg'][] = $current_result['msg'];
305 if (_taxonomy_csv_message_warning($current_result['msg'])) {
306 break;
307 }
308
309 $previous_relations[$current_result['name']] = $current_result['tid'];
310 }
311 break;
312
313 case TAXONOMY_CSV_FORMAT_TAXONOMY_MANAGER:
314 $term = array(
315 'name' => $line[2],
316 'vid' => $options['vocabulary_id'],
317 );
318 if ($line[3]) {
319 $term['description'] = $line[3];
320 }
321
322 // Complete with parents except root. All parents exist, because it's previously checked.
323 $list_parents = array_slice($line, 4);
324 if ($list_parents[0] != 0) {
325 foreach ($list_parents as $value) {
326 $term['parent'][] = $previous_items['tid'][$value];
327 }
328 }
329
330 // Use tid if term is already imported.
331 if (isset($previous_items['tid'][$line[1]])) {
332 $term['tid'] = $previous_items['tid'][$line[1]];
333 }
334 else {
335 // No tid is given, so it's always a new term.
336 $options['existing_items'] = TAXONOMY_CSV_EXISTING_IGNORE_CREATE;
337 }
338
339 // Import term then store result. No check because only one term.
340 $current_result = taxonomy_csv_term_import($term, $options['existing_items']);
341 // Keep old index (names and tids).
342 $result = $previous_items;
343 $result['name'][$line[1]] = $current_result['name'];
344 $result['tid'][$line[1]] = $current_result['tid'];
345 $result['msg'][$line[1]] = $current_result['msg'];
346 break;
347
348 case TAXONOMY_CSV_FORMAT_ALONE_TERMS:
349 case TAXONOMY_CSV_FORMAT_FIELDS:
350 case TAXONOMY_CSV_FORMAT_DESCRIPTIONS:
351 case TAXONOMY_CSV_FORMAT_WEIGHTS:
352 case TAXONOMY_CSV_FORMAT_SYNONYMS:
353 $term = array(
354 'name' => $line[0],
355 'vid' => $options['vocabulary_id'],
356 );
357 switch ($options['import_format']) {
358 case TAXONOMY_CSV_FORMAT_FIELDS:
359 $term['weight'] = $line[1];
360 $term['description'] = $line[2];
361 $term['synonyms'] = array_slice($line, 3);
362 break;
363
364 case TAXONOMY_CSV_FORMAT_DESCRIPTIONS:
365 $term['description'] = $line[1];
366 break;
367
368 case TAXONOMY_CSV_FORMAT_WEIGHTS:
369 $term['weight'] = $line[1];
370 break;
371
372 case TAXONOMY_CSV_FORMAT_SYNONYMS:
373 $term['synonyms'] = array_slice($line, 1);
374 break;
375 }
376 // Import term then store result. No check because only one term.
377 $current_result = taxonomy_csv_term_import($term, $options['existing_items']);
378 $result['name'][] = $current_result['name'];
379 $result['tid'][] = $current_result['tid'];
380 $result['msg'][] = $current_result['msg'];
381 break;
382
383 default:
384 $result['msg'][] = array(TRUE); // Error unknown source content.
385 }
386 }
387 else {
388 $result['msg'][] = array(TRUE); // No term to process.
389 }
390
391 return $result;
392 }
393
394 /**
395 * @} End of "defgroup taxonomy_csv_line".
396 */
397
398 /**
399 * @defgroup taxonomy_csv_term Import a term
400 * @{
401 * Functions allowing import of a term.
402 */
403
404 /**
405 * Update or create a term with the given name in the given vocabulary and
406 * given parent.
407 *
408 * @param $term
409 * A term array to import. Term is an array containing:
410 * 'name' => term name string,
411 * and eventually, matching options:
412 * 'tid' => term id,
413 * 'vid' => the vocabulary id where to import,
414 * 'parent' => array of first level parent tids,
415 * 'relations' => array of related tids,
416 * 'synonyms' => array of synonyms terms names strings,
417 * 'description' => description string,
418 * 'weight' => weight integer,
419 * @param $existing_items
420 * Optional. Type of import on existing terms. Default to ignore and create.
421 * @param $all_vocabularies
422 * Optional. Boolean. Search in all vocabularies
423 * or only in $term['vid'] vocabulary (default), which need to be set.
424 * @param $parent_tid
425 * Optional. Boolean. Restrict search in parent ($term['parent'][0] and next).
426 * Useful for structure. Default to NULL (search in whole vocabulary).
427 * @return array
428 * 'name' => term name,
429 * 'tid' => term id,
430 * 'msg' => messages array.
431 */
432 function taxonomy_csv_term_import($term, $existing_items = TAXONOMY_CSV_EXISTING_IGNORE_CREATE, $all_vocabularies = FALSE, $parent_tid = NULL) {
433 $messages = array();
434
435 if ($term) {
436 switch ($existing_items) {
437 case TAXONOMY_CSV_EXISTING_UPDATE:
438 // Equal to 'update_merge' or 'update_replace'.
439 case TAXONOMY_CSV_EXISTING_UPDATE_MERGE:
440 $existing_term = _taxonomy_csv_term_find_existing($term, $all_vocabularies, $parent_tid);
441 if ($existing_term) {
442 // Needed because get name is not case sensitive.
443 if (isset($term['name'])) {
444 $existing_term['name'] = $term['name'];
445 }
446 if (isset($term['vid'])) {
447 $existing_term['vid'] = $term['vid'];
448 }
449 if (isset($term['parent'])) {
450 $existing_term['parent'] = array_unique(array_merge($existing_term['parent'], $term['parent']));
451 }
452 if (isset($term['relations'])) {
453 $existing_term['relations'] = array_unique(array_merge($existing_term['relations'], $term['relations']));
454 }
455 if (isset($term['synonyms'])) {
456 $existing_term['synonyms'] = array_unique(array_merge($existing_term['synonyms'], $term['synonyms']));
457 }
458 if (isset($term['description'])) {
459 $i = trim($existing_term['description']);
460 $existing_term['description'] = (($i == '') || ($i == $term['description'])) ?
461 $term['description'] :
462 $i ."\n". $term['description'];
463 }
464 // Weight is always replaced as it is a simple number.
465 if (isset($term['weight'])) {
466 $existing_term['weight'] = $term['weight'];
467 }
468 $term = $existing_term;
469 }
470 break;
471
472 case TAXONOMY_CSV_EXISTING_IGNORE_PREVIOUS:
473 //Doesn't ignore, but use previous parents. De facto equal to update_replace.
474 case TAXONOMY_CSV_EXISTING_UPDATE_REPLACE:
475 $existing_term = _taxonomy_csv_term_find_existing($term, $all_vocabularies, $parent_tid);
476 if ($existing_term) {
477 foreach (array(
478 'name', // Needed because get name is not case sensitive.
479 'vid',
480 'parent',
481 'relations',
482 'synonyms',
483 'description',
484 'weight',
485 ) as $key) {
486 if (array_key_exists($key, $term)) {
487 $existing_term[$key] = $term[$key];
488 }
489 }
490 $term = $existing_term;
491 }
492 break;
493
494 case TAXONOMY_CSV_EXISTING_IGNORE:
495 // Equal to 'ignore_create'.
496 case TAXONOMY_CSV_EXISTING_IGNORE_CREATE:
497 break;
498
499 case TAXONOMY_CSV_EXISTING_IGNORE_ALL:
500 ///TODO: IGNORE_ALL
501 }
502
503 // If a term has no parent, it's a root term, so adds parent 0.
504 if (!isset($term['parent'])
505 || count($term['parent']) == 0) {
506 $term['parent'] = array(0);
507 }
508 // If a term has more than one parent, it can't be a root term, so removes parent 0.
509 elseif ((count($term['parent']) > 1)
510 && in_array(0, $term['parent'])) {
511 unset($term['parent'][array_search(0, $term['parent'])]);
512 }
513
514 $result = taxonomy_csv_term_save($term);
515
516 $messages[] = FALSE; // No error.
517 }
518 else {
519 $messages[] = TRUE; // Error: not a term.
520 }
521 return array(
522 'name' => $term['name'],
523 'tid' => $term['tid'],
524 'msg' => $messages,
525 );
526 }
527
528 /**
529 * Find an existing term in vocabularies by its tid else by its name.
530 *
531 * @param $term
532 * The term array to find.
533 * @param $all_vocabularies
534 * Optional. Boolean. Search in all vocabularies
535 * or only in $term['vid'] vocabulary (default), which need to be set.
536 * @param $parent_tid
537 * Optional. The direct parent term id.
538 * Useful for structure. Default to NULL (no parent restriction).
539 * @return
540 * Found term array or empty array if not found.
541 */
542 function _taxonomy_csv_term_find_existing($term, $all_vocabularies = FALSE, $parent_tid = NULL) {
543 if (!empty($term['tid'])) {
544 return taxonomy_csv_term_get($term['tid']);
545 }
546 elseif (isset($term['name'])) {
547 return taxonomy_csv_term_find($term['name'], ($all_vocabularies) ? NULL : $term['vid'], $parent_tid);
548 }
549 // ERROR: no tid neither name.
550 return FALSE;
551 }
552
553 /**
554 * Get a full term by its id.
555 *
556 * @param $tid
557 * The term id to get.
558 * @return
559 * Found term array as describe in taxonomy_csv_term_import or an empty array.
560 */
561 function taxonomy_csv_term_get($tid) {
562 $term = (array) taxonomy_get_term($tid);
563 if ($term) {
564 $term['parent'] = taxonomy_csv_term_get_parents_tids($term['tid']);
565 $term['relations'] = taxonomy_csv_term_get_related_tids($term['tid']);
566 $term['synonyms'] = taxonomy_get_synonyms($term['tid']);
567 };
568 return $term;
569 }
570
571 /**
572 * Find, by its name, the first existing term in a given vocabulary and a given
573 * parent.
574 *
575 * @param $name
576 * The name string to find.
577 * @param $vid
578 * Optional. The vocabulary id where to search if any. Default to NULL (all).
579 * @param $parent_tid
580 * Optional. The direct parent term id if any. Default to NULL (none).
581 * @return
582 * Found term array as describe in taxonomy_csv_term_import or an empty array.
583 */
584 function taxonomy_csv_term_find($name, $vid = NULL, $parent_tid = NULL) {
585 $name = drupal_strtolower(trim($name));
586
587 if (drupal_strlen($name)) {
588 $sql = "
589 SELECT t.*, h.parent
590 FROM {term_data} t
591 INNER JOIN {term_hierarchy} h ON t.tid = h.tid
592 WHERE '%s' LIKE LOWER(t.name)
593 ";
594 $args = array($name);
595
596 if ($vid) {
597 $sql .= ' AND t.vid = %d';
598 $args[] = $vid;
599 }
600
601 if ($parent_tid) {
602 $sql .= ' AND h.parent = %d';
603 $args[] = $parent_tid;
604 }
605
606 $sql .= ' ORDER BY {tid} ASC LIMIT 1';
607
608 $result = db_query($sql, $args);
609 $term = db_fetch_array($result);
610
611 if ($term) {
612 $term['parent'] = taxonomy_csv_term_get_parents_tids($term['tid']);
613 $term['relations'] = taxonomy_csv_term_get_related_tids($term['tid']);
614 $term['synonyms'] = taxonomy_get_synonyms($term['tid']);
615
616 return $term;
617 }
618 }
619 return array();
620 }
621
622 /**
623 * Save a term array by reference.
624 *
625 * Drupal taxonomy_save_term use a text area format to import synonyms.
626 * This helper convert a synonym array into a string before using it.
627 *
628 * @param $term
629 * A term array to save by reference. Term is an array containing:
630 * 'name' => term name string,
631 * 'vid' => the vocabulary id,
632 * and eventually:
633 * 'tid' => term id,
634 * 'parent' => array of first level parent tids,
635 * 'relations' => array of related tids,
636 * 'synonyms' => array of synonyms terms names strings,
637 * 'description' => description string,
638 * 'weight' => weight integer,
639 * @return
640 * Status value.
641 */
642 function taxonomy_csv_term_save(&$term) {
643 if (isset($term['synonyms'])) {
644 $synonyms = $term['synonyms'];
645 $term['synonyms'] = implode("\n", $term['synonyms']);
646 }
647
648 // Drupal taxonomy_save_term use a by reference variable so $term is automaticaly updated.
649 // Return either SAVED_NEW or SAVED_UPDATED.
650 $result = taxonomy_save_term($term);
651
652 // Keep synonyms as an array.
653 if (isset($synonyms)) {
654 $term['synonyms'] = $synonyms;
655 }
656
657 return $result;
658 }
659
660 /**
661 * Return an array of all parents term IDs of a given term ID.
662 * If no parent, return array(0), because a term without parent is a root term.
663 * If tid doesn't exist, return array(0) too (not checked).
664 * Return empty array only if tid is not set.
665 */
666 function taxonomy_csv_term_get_parents_tids($tid) {
667 $parents_tids = array();
668 if (!empty($tid)) {
669 $parents_terms = taxonomy_get_parents($tid);
670 if ($parents_terms) {
671 foreach ($parents_terms as $term => $item) {
672 $parents_tids[] = $parents_terms[$term]->tid;
673 }
674 return $parents_tids;
675 }
676 return array(0);
677 }
678 return array();
679 }
680
681 /**
682 * Return an array of all term IDs related to a given term ID.
683 */
684 function taxonomy_csv_term_get_related_tids($tid) {
685 $related_tids = array();
686 if (!empty($tid)) {
687 $related_terms = taxonomy_get_related($tid);
688 if ($related_terms) {
689 foreach ($related_terms as $term => $item) {
690 $related_tids[] = $related_terms[$term]->tid;
691 }
692 }
693 }
694 return $related_tids;
695 }
696
697 /**
698 * @} End of "defgroup taxonomy_csv_term".
699 */
700
701 /**
702 * @defgroup taxonomy_csv_message Messages helpers
703 * @{
704 * Functions managing import messages.
705 */
706
707 /**
708 * Helper which returns a boolean when a set of message codes contains a warning or worst.
709 *
710 * @param $messages
711 * Array of message code (TRUE if any error or FALSE if none).
712 * @param $type
713 * Type of messages array:
714 * 'msg' (default), 'line'.
715 * @return
716 * TRUE if warning or error, else FALSE if no issue.
717 */
718 function _taxonomy_csv_message_warning($messages, $type = 'msg') {
719 switch ($type) {
720 case 'msg':
721 return in_array(TRUE, $messages, TRUE);
722
723 case 'line':
724 $list_messages = array();
725 foreach ($messages['msg'] as $message_codes) {
726 $list_messages = array_merge($list_messages, $message_codes);
727 }
728 return in_array(TRUE, $list_messages, TRUE);
729 }
730 return TRUE;
731 }
732
733 /**
734 * @} End of "defgroup taxonomy_csv_message".
735 */
736
737 /**
738 * @defgroup taxonomy_csv_info Informations helpers.
739 * @{
740 * Functions informing about import process.
741 */
742
743 /**
744 * Helper to remember some items.
745 *
746 * @param $list
747 * A string matching list to be returned:
748 * 'list_import_format',
749 * 'list_import_option',
750 * 'list_import_format_allowed_import_option',
751 * @return wanted content.
752 */
753 function _taxonomy_csv_info_lists($list) {
754 switch ($list) {
755 case 'list_import_format':
756 // Some import types will be enabled in a next release.
757 return array(
758 TAXONOMY_CSV_FORMAT_ALONE_TERMS => t('Term names (ignore additional columns)'),
759 TAXONOMY_CSV_FORMAT_FLAT => t('Terms (flat vocabulary)'),
760 TAXONOMY_CSV_FORMAT_TREE_STRUCTURE => t('Hierarchical tree structure or one term by line structure'),
761 TAXONOMY_CSV_FORMAT_POLYHIERARCHY => t('Polyhierarchical structure'),
762 TAXONOMY_CSV_FORMAT_PARENTS => t('First level parents'),
763 TAXONOMY_CSV_FORMAT_CHILDREN => t('First level children'),
764 TAXONOMY_CSV_FORMAT_RELATIONS => t('Related terms'),
765 TAXONOMY_CSV_FORMAT_FIELDS => t('Full term definitions'),
766 TAXONOMY_CSV_FORMAT_DESCRIPTIONS => t('Term descriptions'),
767 TAXONOMY_CSV_FORMAT_WEIGHTS => t('Term weights'),
768 TAXONOMY_CSV_FORMAT_SYNONYMS => t('Synonyms terms'),
769 TAXONOMY_CSV_FORMAT_TAXONOMY_MANAGER => t('Taxonomy manager'),
770 );
771
772 case 'list_import_option':
773 return array(
774 TAXONOMY_CSV_EXISTING_UPDATE => t('Update existing term'),
775 TAXONOMY_CSV_EXISTING_UPDATE_MERGE => t('Update (merge) existing term and items if exist else create'),
776 TAXONOMY_CSV_EXISTING_UPDATE_REPLACE => t('Update (replace) existing term and items if exist else create'),
777 TAXONOMY_CSV_EXISTING_IGNORE => t('Duplicate existing term'),
778 TAXONOMY_CSV_EXISTING_IGNORE_CREATE => t('Ignore existing term and create a new term'),
779 TAXONOMY_CSV_EXISTING_IGNORE_ALL => t('Ignore existing term and create a new term for each term on the line'),
780 );
781
782 case 'list_import_format_allowed_import_option':
783 return array(
784 TAXONOMY_CSV_FORMAT_ALONE_TERMS => array(
785 TAXONOMY_CSV_EXISTING_UPDATE,
786 TAXONOMY_CSV_EXISTING_IGNORE,
787 ),
788 TAXONOMY_CSV_FORMAT_FLAT => array(
789 TAXONOMY_CSV_EXISTING_UPDATE,
790 TAXONOMY_CSV_EXISTING_IGNORE,
791 ),
792 TAXONOMY_CSV_FORMAT_TREE_STRUCTURE => array(
793 TAXONOMY_CSV_EXISTING_UPDATE_REPLACE,
794 TAXONOMY_CSV_EXISTING_IGNORE_CREATE,
795 // TAXONOMY_CSV_EXISTING_IGNORE_ALL,
796 ),
797 TAXONOMY_CSV_FORMAT_POLYHIERARCHY => array(
798 TAXONOMY_CSV_EXISTING_UPDATE_MERGE,
799 ),
800 TAXONOMY_CSV_FORMAT_PARENTS => array(
801 TAXONOMY_CSV_EXISTING_UPDATE_MERGE,
802 TAXONOMY_CSV_EXISTING_UPDATE_REPLACE,
803 TAXONOMY_CSV_EXISTING_IGNORE_CREATE,
804 // TAXONOMY_CSV_EXISTING_IGNORE_ALL,
805 ),
806 TAXONOMY_CSV_FORMAT_CHILDREN => array(
807 TAXONOMY_CSV_EXISTING_UPDATE_MERGE,
808 TAXONOMY_CSV_EXISTING_UPDATE_REPLACE,
809 TAXONOMY_CSV_EXISTING_IGNORE_CREATE,
810 // TAXONOMY_CSV_EXISTING_IGNORE_ALL,
811 ),
812 TAXONOMY_CSV_FORMAT_RELATIONS => array(
813 TAXONOMY_CSV_EXISTING_UPDATE_MERGE,
814 TAXONOMY_CSV_EXISTING_UPDATE_REPLACE,
815 TAXONOMY_CSV_EXISTING_IGNORE_CREATE,
816 // TAXONOMY_CSV_EXISTING_IGNORE_ALL,
817 ),
818 TAXONOMY_CSV_FORMAT_FIELDS => array(
819 TAXONOMY_CSV_EXISTING_UPDATE_MERGE,
820 TAXONOMY_CSV_EXISTING_UPDATE_REPLACE,
821 TAXONOMY_CSV_EXISTING_IGNORE_CREATE,
822 ),
823 TAXONOMY_CSV_FORMAT_DESCRIPTIONS => array(
824 TAXONOMY_CSV_EXISTING_UPDATE_MERGE,
825 TAXONOMY_CSV_EXISTING_UPDATE_REPLACE,
826 TAXONOMY_CSV_EXISTING_IGNORE_CREATE,
827 ),
828 TAXONOMY_CSV_FORMAT_WEIGHTS => array(
829 TAXONOMY_CSV_EXISTING_UPDATE_MERGE,
830 TAXONOMY_CSV_EXISTING_IGNORE_CREATE,
831 ),
832 TAXONOMY_CSV_FORMAT_SYNONYMS => array(
833 TAXONOMY_CSV_EXISTING_UPDATE_MERGE,
834 TAXONOMY_CSV_EXISTING_UPDATE_REPLACE,
835 TAXONOMY_CSV_EXISTING_IGNORE_CREATE,
836 ),
837 TAXONOMY_CSV_FORMAT_TAXONOMY_MANAGER => array(
838 TAXONOMY_CSV_EXISTING_UPDATE_MERGE,
839 TAXONOMY_CSV_EXISTING_UPDATE_REPLACE,
840 TAXONOMY_CSV_EXISTING_IGNORE_CREATE,
841 ),
842 );
843 }
844 }
845
846 /**
847 * @} End of "defgroup taxonomy_csv_info".
848 */

  ViewVC Help
Powered by ViewVC 1.1.2