get_parms( 'sbid' , 'cid' // candidate (id) to replace , 't' // replacing term , 'debug' ); phrasea::headers(200, true, 'application/json', 'UTF-8', false); if ($parm['debug']) print("
"); $dbname = null; $result = array('n_recsChanged' => 0); // , 'n_termsDeleted'=>0, 'n_termsReplaced'=>0); try { $databox = databox::get_instance((int) $parm['sbid']); $domth = $databox->get_dom_thesaurus(); $domct = $databox->get_dom_cterms(); if ($domth && $domct) { $xpathct = new DOMXPath($domct); $field = null; $x = null; $xp = '//te[@id="' . $parm['cid'] . '"]/sy'; $nodes = $xpathct->query($xp); if ($nodes->length == 1) { $sy = $term = $nodes->item(0); $candidate = array('a' => $sy->getAttribute('v'), 'u' => $sy->getAttribute('w')); if (($k = $sy->getAttribute('k'))) $candidate['u'] .= ' (' . $k . ')'; if ($parm['debug']) printf("%s : candidate = %s \n", __LINE__, var_export($candidate, true)); $syid = str_replace('.', 'd', $sy->getAttribute('id')) . 'd'; $field = $sy->parentNode->parentNode->getAttribute('field'); // remove candidate from cterms $te = $sy->parentNode; $te->parentNode->removeChild($te); $databox->saveCterms($domct); $sql = 'SELECT t.record_id, r.xml FROM thit AS t INNER JOIN record AS r USING(record_id) WHERE t.value = :syn_id ORDER BY record_id'; $stmt = $connbas->prepare($sql); $stmt->execute(array(':syn_id' => $syid)); $rs = $stmt->fetchAll(PDO::FETCH_ASSOC); $stmt->closeCursor(); if ($parm['debug']) printf("%s : %s \n", __LINE__, $sql); $t_rid = array(); foreach ($rs as $rowbas) { $rid = $rowbas['record_id']; if ( ! array_key_exists('' . $rid, $t_rid)) $t_rid['' . $rid] = $rowbas['xml']; } if ($parm['debug']) printf("%s : %s \n", __LINE__, var_export($t_rid, true)); $replacing = array(); $parm['t'] = explode(';', $parm['t']); foreach ($parm['t'] as $t) $replacing[] = simplified($t); if ($parm['debug']) printf("%s : replacing=%s \n", __LINE__, var_export($replacing, true)); foreach ($t_rid as $rid => $xml) { if ($parm['debug']) printf("%s rid=%s \n", __LINE__, $rid); $dom = new DOMDocument(); $dom->preserveWhiteSpace = false; $dom->formatOutput = true; if ( ! ($dom->loadXML($xml))) continue; if ($parm['debug']) printf("AVANT:\n%s \n", htmlentities($dom->saveXML())); // $existed = false; $nodetoreplace = null; $nodestodelete = array(); $xp = new DOMXPath($dom); $x = '/record/description/' . $field; if ($parm['debug']) printf("%s x=%s \n", __LINE__, $x); $nodes = $xp->query($x); $insertBefore = null; if ($nodes->length <= 0) continue; // { $insertBefore = $nodes->item($nodes->length - 1); if ($parm['debug']) printf("%s nodes->length=%s - insertBefore=%s, nn=%s\n", __LINE__, $nodes->length, var_export($insertBefore, true), $insertBefore->nodeName); while (($insertBefore = $insertBefore->nextSibling) && $insertBefore->nodeType != XML_ELEMENT_NODE); if ($parm['debug'] && $insertBefore) printf("%s insertBefore=%s , nn=%s \n", __LINE__, var_export($insertBefore, true), $insertBefore->nodeName); $t_mval = array(); foreach ($nodes as $n) { $value = simplified($n->textContent); if (in_array($value['a'], $t_mval)) // a chance to delete doubles continue; for ($i = 0; $i < 9999 && array_key_exists($value['u'] . '_' . $i, $t_mval); $i ++ ) ; $t_mval[$value['u'] . '_' . $i] = $value['a']; $nodestodelete[] = $n; } if ($parm['debug']) printf("%s : t_mval AVANT = %s \n", __LINE__, var_export($t_mval, true)); if (($k = array_search($candidate['a'], $t_mval)) !== false) { unset($t_mval[$k]); if ($parm['debug']) printf("%s : after unset %s from t_mval %s \n", __LINE__, $k, var_export($t_mval, true)); foreach ($replacing as $r) { if (in_array($r['a'], $t_mval)) continue; for ($i = 0; $i < 9999 && array_key_exists($r['u'] . '_' . $i, $t_mval); $i ++ ) ; $t_mval[$r['u'] . '_' . $i] = $r['a']; } if ($parm['debug']) printf("%s : after replace to t_mval %s \n", __LINE__, var_export($t_mval, true)); } foreach ($nodestodelete as $n) $n->parentNode->removeChild($n); ksort($t_mval, SORT_STRING); if ($insertBefore) { array_reverse($t_mval); foreach ($t_mval as $t) $insertBefore->parentNode->insertBefore($dom->createElement($field), $insertBefore)->appendChild($dom->createTextNode($t)); } else { $desc = $xp->query('/record/description')->item(0); foreach ($t_mval as $t) $desc->appendChild($dom->createElement($field))->appendChild($dom->createTextNode($t)); } if ($parm['debug']) printf("%s : t_mval APRES = %s \n", __LINE__, var_export($t_mval, true)); if ($parm['debug']) printf("APRES:\n%s \n", htmlentities($dom->saveXML())); if ( ! $parm['debug']) { $sql = 'DELETE FROM idx WHERE record_id = :record_id'; $stmt = $connbas->prepare($sql); $stmt->execute(array(':record_id' => $rid)); $stmt->closeCursor(); $sql = 'DELETE FROM prop WHERE record_id = :record_id'; $stmt = $connbas->prepare($sql); $stmt->execute(array(':record_id' => $rid)); $stmt->closeCursor(); $sql = 'DELETE FROM thit WHERE record_id = :record_id'; $stmt = $connbas->prepare($sql); $stmt->execute(array(':record_id' => $rid)); $stmt->closeCursor(); $sql = 'UPDATE record SET status=(status & ~3)|4, jeton=' . (JETON_WRITE_META_DOC | JETON_WRITE_META_SUBDEF) . ' , xml = :xml WHERE record_id = :record_id'; $stmt = $connbas->prepare($sql); $stmt->execute(array(':record_id' => $rid, ':xml' => $dom->saveXML())); $stmt->closeCursor(); } $result['n_recsChanged'] ++; } } } } catch (Exception $e) { } function simplified($t) { $t = splitTermAndContext($t); $unicode = new unicode(); $su = $unicode->remove_indexer_chars($sa = $t[0]); if ($t[1]) { $sa .= ' (' . ($t[1]) . ')'; $su .= ' (' . $unicode->remove_indexer_chars($t[1]) . ')'; } return(array('a' => $sa, 'u' => $su)); } print(p4string::jsonencode(array('parm' => $parm, 'result' => $result))); if ($parm['debug']) print(""); function splitTermAndContext($word) { $term = trim($word); $context = ''; if (($po = strpos($term, '(')) !== false) { if (($pc = strpos($term, ')', $po)) !== false) { $context = trim(substr($term, $po + 1, $pc - $po - 1)); $term = trim(substr($term, 0, $po)); } else { $context = trim(substr($term, $po + 1)); $term = trim(substr($term, 0, $po)); } } return(array($term, $context)); }