function taxonomy_xml_set_term_relations in Taxonomy import/export via XML 6
Same name and namespace in other branches
- 5.2 taxonomy_xml.module \taxonomy_xml_set_term_relations()
- 5 taxonomy_xml.module \taxonomy_xml_set_term_relations()
- 6.2 taxonomy_xml.module \taxonomy_xml_set_term_relations()
- 7 taxonomy_xml.process.inc \taxonomy_xml_set_term_relations()
Given a list of terms, set the related-terms and structure, and save again
Helper function for bulk processes.
The terms are currently indexed by either URI or name. The reference arrays refer to either the URI or name. Scan the current array for the objects (terms) being linked to.
Input would look (in part) like this:
$terms = array( '#123' => ( 'name' => 'hotels', 'tid' => 23, 'predicates' => ( 'See Also' => ['#135', 'camping'] 'Broader Term' => ['accomodation'] ) ) '#135' => ( 'name' => 'motels', 'tid' => 35 ) '#145' => ( 'name' => 'camping', 'tid' => 37 ) 'accomodation' => ( 'name' => 'accomodation', 'tid' => 11 ) )
The process will read the 'predicates', figure out what they mean, figure out which other term is being referenced, and create properties on the term object.
And will return the term objects with appropriate Drupal attributes
'#123' => ( 'name' => 'hotels', 'nid' => 23, 'parent' => 11, 'relations' => array(35, 37), )
Note that the key need have no relation with the nid, and may be a full string, which will work just as well. The above shows an example of both, although that would be rare in the one import.
Relationships cannot be created if the target term is not included in the $terms list itself. If we are adding to an existing vocab, doing a partial merge, the target terms should have already been retrieved from the database and included in the complete list.
Parameters
$terms an indexed array of existing taxonomy term objects, possibly: referring to each other by id. It's possible for the same term to be in the list twice, under different keys, (indexed by tid, name or URL) but these should be HANDLES on the same object by reference, so changes will stick.
4 calls to taxonomy_xml_set_term_relations()
- taxonomy_xml_csv_parse in ./
csv_format.inc - Scan the input CSV file and create a taxonomy structure out of it.
- taxonomy_xml_mesh_parse in ./
mesh_format.inc - Reads a XML file and creates the term definitions found in it.
- taxonomy_xml_rdf_parse in ./
rdf_format.inc - Read in RDF taxonomies and vocabularies. Create vocabs and terms as needed.
- taxonomy_xml_tcs_parse in ./
tcs_format.inc - Reads a TCS file and creates the term definitions found in it.
File
- ./
taxonomy_xml.module, line 942 - taxonomy_xml.module This module makes it possible to import and export taxonomies as XML documents.
Code
function taxonomy_xml_set_term_relations(&$terms) {
#drupal_set_message(t("Now connecting all known term relations and hierarchy links between this group of %count related terms.", array('%count' => count($terms) )), 'trace');
foreach ($terms as $uri => &$term) {
// Avoid doing this again if we are stuck in a recursive loop,
// batch, or working with duplicate handles
if (isset($term->taxonomy_xml_linked)) {
continue;
}
// The predicates (relationships) array may contain actual handles on terms, term ids,
// or it may still contain URIs representing terms not yet loaded in this phase.
// We need to resolve those external references into term handles (or at least tids) if possible.
if (isset($term->predicates) && is_array($term->predicates)) {
foreach ($term->predicates as $predicate => &$targets) {
foreach ($targets as $targetid => &$target) {
#dpm(t("Term %termname references %targetid as a %predicate", array('$termname' => $term->name, '%targetid' => $targetid, '%predicate' => $predicate )));
// Here we first try to find the referred term in the list of recently-made terms
if (!isset($terms[$targetid])) {
#drupal_set_message(t("Referenced term %targetid seems unknown so far, need to try a bigger lookup for it", array('%targetid' => $targetid)));
// taxonomy_enhancer.module, if available, may have more data about our terms. Hopefully including a GUID.
if ($found_term = taxonomy_xml_get_term_by_uri($targetid)) {
$terms[$targetid] = $found_term;
}
else {
$found_term = taxonomy_xml_get_term_by_uri($target);
#drupal_set_message(t("We so far have no knowledge of the referenced term - ". $term->name ." '$predicate' !targetid. It should be imported later and linked in.", array('!targetid' => l($targetid, $targetid))));
}
}
}
}
}
// Go through all and add relationships
// Note that a modification was made by flagging $term->taxonomy_xml_relinked = TRUE;
//
// The linking earlier may have given us some duplicates if the source had redundant info, so filter for uniques
if (isset($term->predicates[TAXONOMY_XML_PARENT]) && is_array($term->predicates[TAXONOMY_XML_PARENT])) {
foreach (array_unique($term->predicates[TAXONOMY_XML_PARENT]) as $key => $othertermname) {
if ($othertermname) {
// Here we try to find the referred term in the list of recently-made terms
if ($othertermname == $uri) {
drupal_set_message(t("Not setting %name as a child of itself", array(
'%name' => $term->name,
)));
continue;
}
if (isset($terms[$othertermname])) {
$parent = $terms[$othertermname];
if ($parent && isset($parent->tid) && $parent->tid != $term->tid) {
global $_taxonomy_xml_current_doc;
drupal_set_message(t("!name # %tid is a child of !parent # %ptid (<a href='!source'>source</a>", array(
'!name' => l($term->name, 'admin/content/taxonomy/edit/term/' . $term->tid),
'%tid' => $term->tid,
'!parent' => l($parent->name, 'admin/content/taxonomy/edit/term/' . $parent->tid),
'%ptid' => $parent->tid,
'!source' => $_taxonomy_xml_current_doc,
)));
$term->parent[$parent->tid] = $parent->tid;
}
}
else {
#drupal_set_message(t("Couldn't find the parent identified as %termname for %name # %tid", array('%termname' => $othertermname, '%name' => $term->name, '%tid' => $term->tid) ));
}
}
}
$term->taxonomy_xml_relinked = TRUE;
}
#else{drupal_set_message(" $name ". $term->tid ." has no parent term");}
if (isset($term->predicates[TAXONOMY_XML_RELATED]) && is_array($term->predicates[TAXONOMY_XML_RELATED])) {
foreach (array_unique($term->predicates[TAXONOMY_XML_RELATED]) as $key => $othertermname) {
if ($othertermname) {
$related = $terms[$othertermname];
if ($related) {
$term->relations[] = $related->tid;
#drupal_set_message("Term ". $term->name ." ". $term->tid ." is related to $related->name ". $related->tid);
}
else {
drupal_set_message(t("Couldn't find the term called '%termname' to link to '%name' as being related. This relationship will be discarded. ", array(
'%name' => $term->name,
'%termname' => $othertermname,
'%debug' => print_r(array_keys($terms), 1),
)));
#dpm(array('available terms' => array_keys($terms)));
}
}
}
$term->taxonomy_xml_relinked = TRUE;
}
if (!empty($term->synonyms_array)) {
$term->synonyms = join("\n", array_unique($term->synonyms_array));
$term->taxonomy_xml_relinked = TRUE;
}
#dpm(array('Saving' => $term));
$term->taxonomy_xml_linked = TRUE;
// for efficiency, only re-save terms that really need it
if (!empty($term->taxonomy_xml_relinked)) {
$save_term = (array) $term;
taxonomy_save_term($save_term);
}
}
}