[]]; $refresh = []; $sbas_id = $request->get('sbid'); try { $databox = $this->findDataboxById($sbas_id); $domct = $databox->get_dom_cterms(); if (!($domct instanceof \DOMDocument)) { throw new \Exception('Unable to load cterms'); } $domth = $databox->get_dom_thesaurus(); if (!($domth instanceof \DOMDocument)) { throw new \Exception('Unable to load thesaurus'); } $xpathth = new \DOMXPath($domth); if ($request->get("tid") == "T") { $q = "/thesaurus"; } else { $q = "/thesaurus//te[@id='" . $request->get("tid") . "']"; } /** @var DOMElement $parentnode */ $parentnode = $xpathth->query($q)->item(0); if (!$parentnode) { throw new \Exception('Unable to find branch'); } $xpathct = new \DOMXPath($domct); $ctchanged = $thchanged = false; foreach ($request->get("cid") as $cid) { $q = "//te[@id='" . $cid . "']"; if ($request->get("debug")) { printf("qct: %s
\n", $q); } $ct = $xpathct->query($q)->item(0); if (!$ct) { continue; } if ($request->get("typ") == "TS") { // importer tt la branche candidate comme nouveau ts $nid = $parentnode->getAttribute("nextid"); $parentnode->setAttribute("nextid", (int) $nid + 1); $te = $domth->importNode($ct, true); $chgids = []; if (($pid = $parentnode->getAttribute("id")) == "") { $pid = "T" . $nid; } else { $pid .= "." . $nid; } $this->renumerate($request->get('piv'), $te, $pid, $chgids); /** @var DOMElement $te */ $te = $parentnode->appendChild($te); if ($request->get("debug")) { printf("newid=%s
\n", $te->getAttribute("id")); } $refreshid = $parentnode->getAttribute('id'); $refresh['T' . $refreshid] = [ 'type' => 'T', 'sbid' => $sbas_id, 'id' => $refreshid ]; $thchanged = true; $refreshid = $ct->parentNode->getAttribute("id"); $refresh['C' . $refreshid] = [ 'type' => 'C', 'sbid' => $sbas_id, 'id' => $refreshid ]; $ct->parentNode->removeChild($ct); $ctchanged = true; } elseif ($request->get("typ") == "SY") { // importer tt le contenu de la branche sous la destination for ($ct2 = $ct->firstChild; $ct2; $ct2 = $ct2->nextSibling) { if ($ct2->nodeType != XML_ELEMENT_NODE || $ct2->nodeName != 'sy') { continue; } $nid = $parentnode->getAttribute("nextid"); $parentnode->setAttribute("nextid", (int) $nid + 1); $te = $domth->importNode($ct2, true); $chgids = []; if (($pid = $parentnode->getAttribute("id")) == "") { // racine $pid = "T" . $nid; } else { $pid .= "." . $nid; } $this->renumerate($request->get('piv'), $te, $pid, $chgids); $te = $parentnode->appendChild($te); if ($request->get("debug")) { printf("newid=%s
\n", $te->getAttribute("id")); } $thchanged = true; } $refreshid = $parentnode->parentNode->getAttribute("id"); $refresh['T' . $refreshid] = [ 'type' => 'T', 'sbid' => $sbas_id, 'id' => $refreshid ]; $refreshid = $ct->parentNode->getAttribute("id"); $refresh['C' . $refreshid] = [ 'type' => 'C', 'sbid' => $sbas_id, 'id' => $refreshid ]; $ct->parentNode->removeChild($ct); $ctchanged = true; } } if ($ctchanged) { $databox->saveCterms($domct); } if ($thchanged) { $databox->saveThesaurus($domth); } } catch (\Exception $e) { } $ret['refresh'] = array_values($refresh); return $this->app->json($ret); } private function renumerate($lang, DOMElement $node, $id, &$chgids, $depth = 0) { $node->setAttribute("id", $id); if ($node->nodeType == XML_ELEMENT_NODE && $node->nodeName == "sy") { $node->setAttribute("lng", $lang); } $nchild = 0; for ($n = $node->firstChild; $n; $n = $n->nextSibling) { if ($n->nodeType == XML_ELEMENT_NODE && ($n->nodeName == "te" || $n->nodeName == "sy")) { $this->renumerate($lang, $n, $id . "." . $nchild, $chgids, $depth + 1); $nchild++; } } $node->setAttribute("nextid", $nchild); } public function checkCandidateTargetJson(Request $request) { $json = []; if (null === $sbas_id = $request->get("sbid")) { return $this->app->json($json); } $databox = $this->findDataboxById((int) $sbas_id); $dom_thesau = $databox->get_dom_thesaurus(); $meta = $databox->get_meta_structure(); if ($dom_thesau) { $xpath = new \DOMXPath($dom_thesau); $json['cfield'] = $request->get("acf"); // on doit verifier si le terme demande est accessible e partir de ce champ acf if ($request->get("acf") == '*') { // le champ "*" est la corbeille, il est toujours accepte $json['acceptable'] = true; } else { // le champ est teste d'apres son tbranch if ($meta && ($databox_field = $meta->get_element_by_name($request->get('acf')))) { $tbranch = $databox_field->get_tbranch(); $q = "(" . $tbranch . ")/descendant-or-self::te[@id='" . $request->get("id") . "']"; if ($request->get("debug")) { printf("tbranch-q = \" $q \"
\n"); } $nodes = $xpath->query($q); $json['acceptable'] = ($nodes->length > 0); } } if ($request->get("id") == "T") { $q = "/thesaurus"; } else { $q = "/thesaurus//te[@id='" . $request->get("id") . "']"; } if ($request->get("debug")) { print("q:" . $q . "
\n"); } $nodes = $xpath->query($q); $json['found'] = $nodes->length; if ($nodes->length > 0) { $fullpath_html = $fullpath = ""; for ($depth = 0, $n = $nodes->item(0); $n; $n = $n->parentNode, $depth--) { if ($n->nodeName == "te") { if ($request->get("debug")) { printf("parent:%s
\n", $n->nodeName); } $firstsy = $goodsy = null; /** @var DOMElement $n2 */ for ($n2 = $n->firstChild; $n2; $n2 = $n2->nextSibling) { if ($n2->nodeName == "sy") { $sy = $n2->getAttribute("v"); if (!$firstsy) { $firstsy = $sy; if ($request->get("debug")) { printf("fullpath : firstsy='%s' in %s
\n", $firstsy, $n2->getAttribute("lng")); } } if ($n2->getAttribute("lng") == $request->get("piv")) { if ($request->get("debug")) { printf("fullpath : found '%s' in %s
\n", $sy, $n2->getAttribute("lng")); } $goodsy = $sy; break; } } } if (!$goodsy) { $goodsy = $firstsy; } $fullpath = " / " . $goodsy . $fullpath; if ($depth == 0) { $fullpath_html = " / " . $goodsy . "" . $fullpath_html; } else { $fullpath_html = " / " . $goodsy . $fullpath_html; } } } if ($fullpath == "") { $fullpath = "/"; $fullpath_html = " / "; } $json['fullpath'] = $fullpath; $json['fullpath_html'] = $fullpath_html; } } return $this->app->json($json); } public function editingPresetsJson(Request $request) { $ret = ['parm' => [ 'act' => $request->get('act'), 'sbas' => $request->get('sbas'), 'presetid' => $request->get('presetid'), 'title' => $request->get('title'), 'fields' => $request->get('fields'), 'debug' => $request->get('debug'), ]]; switch ($request->get('act')) { case 'DELETE': if (null === $preset = $this->getPresetRepository()->find($id = $request->get('presetid'))) { $this->app->abort(404, sprintf("Preset with id '%' could not be found", $id)); } $this->getPresetManipulator()->delete($preset); $ret['html'] = $this->getPresetHTMLList($request->get('sbas'), $this->getAuthenticatedUser()); break; case 'SAVE': $this->getPresetManipulator()->create( $this->getAuthenticatedUser(), $request->get('sbas'), $request->get('title'), $request->get('fields') ); $ret['html'] = $this->getPresetHTMLList($request->get('sbas'), $this->getAuthenticatedUser()); break; case 'LIST': $ret['html'] = $this->getPresetHTMLList($request->get('sbas'), $this->getAuthenticatedUser()); break; case "LOAD": if (null === $preset = $this->getPresetRepository()->find($id = $request->get('presetid'))) { $this->app->abort(404, sprintf("Preset with id '%' could not be found", $id)); } $fields = []; foreach ($preset->getData() as $field) { $fields[$field['name']][] = $field['value']; } $ret['fields'] = $fields; break; } return $this->app->json($ret); } private function getPresetHTMLList($sbasId, User $user) { $data = []; /** @var Preset[] $presets */ $presets = $this->getPresetRepository()->findBy(['user' => $user, 'sbasId' => $sbasId], ['created' => 'asc']); foreach ($presets as $preset) { $presetData = $fields = []; array_walk($preset->getData(), function ($field) use ($fields) { $fields[$field['name']][] = $field['value']; }); $presetData['id'] = $preset->getId(); $presetData['title'] = $preset->getTitle(); $presetData['fields'] = $fields; $data[] = $presetData; } return $this->render('thesaurus/presets.html.twig', ['presets' => $data]); } public function getSynonymsXml(Request $request) { $ret = new \DOMDocument("1.0", "UTF-8"); $ret->preserveWhiteSpace = false; /** @var DOMElement $root */ $root = $ret->appendChild($ret->createElement("result")); $root->appendChild($ret->createCDATASection(var_export([ 'bid' => $request->get('bid'), 'id' => $request->get('id'), ], true))); if (null !== $request->get('bid')) { $databox = $this->findDataboxById((int) $request->get('bid')); $dom = $databox->get_dom_thesaurus(); if ($dom) { $xpath = $databox->get_xpath_thesaurus(); $q = "/thesaurus//sy[@id='" . $request->get('id') . "']"; $nodes = $xpath->query($q); if ($nodes->length > 0) { /** @var DOMElement $n2 */ $n2 = $nodes->item(0); $root->setAttribute("t", $n2->getAttribute("v")); } } } return new Response($ret->saveXML(), 200, ['Content-Type' => 'text/xml']); } public function getTermHtml(Request $request) { $html = ''; if (null === $request->get("bid")) { return new Response('Missing bid parameter', 400); } $databox = $this->findDataboxById((int) $request->get("bid")); $dom = $databox->get_dom_thesaurus(); if (!$dom) { return new Response('Unable to load thesaurus', 500); } $xpath = $databox->get_xpath_thesaurus(); if ($request->get("id") == "T") { $q = "/thesaurus"; } else { $q = "/thesaurus//te[@id='" . $request->get("id") . "']"; } if ($request->get("debug")) { print("q:" . $q . "
\n"); } $nodes = $xpath->query($q); if ($nodes->length > 0) { $nts = 0; $tts = []; // on dresse la liste des termes specifiques avec comme cle le synonyme // dans la langue pivot /** @var DOMElement $n */ for ($n = $nodes->item(0)->firstChild; $n; $n = $n->nextSibling) { if ($n->nodeName == "te") { $nts++; $allsy = ""; $tsy = []; $firstksy = null; $ksy = $realksy = null; // on liste les sy pour fabriquer la cle /** @var DOMElement $n2 */ for ($n2 = $n->firstChild; $n2; $n2 = $n2->nextSibling) { if ($n2->nodeName == "sy") { $lng = $n2->getAttribute("lng"); $t = $n2->getAttribute("v"); $ksy = $n2->getAttribute("w"); if ($k = $n2->getAttribute("k")) { $ksy .= " ($k)"; } if (!$firstksy) { $firstksy = $ksy; } if (!$realksy && $request->get("lng") && $lng == $request->get("lng")) { $realksy = $ksy; $allsy = $t . ($allsy ? " ; " : "") . $allsy; array_push($tsy, [ "id" => $n2->getAttribute("id"), "sy" => $t ]); } else { $allsy .= ( $allsy ? " ; " : "") . $t; array_push($tsy, [ "id" => $n2->getAttribute("id"), "sy" => $t ]); } } } if (!$realksy) { $realksy = $firstksy; } if ($request->get("sortsy") && $request->get("lng")) { for ($uniq = 0; $uniq < 9999; $uniq++) { if (!isset($tts[$realksy . "_" . $uniq])) { break; } } $tts[$realksy . "_" . $uniq] = [ "id" => $n->getAttribute("id"), "allsy" => $allsy, "nchild" => $xpath->query("te", $n)->length, "tsy" => $tsy ]; } else { $tts[] = [ "id" => $n->getAttribute("id"), "allsy" => $allsy, "nchild" => $xpath->query("te", $n)->length, "tsy" => $tsy ]; } } elseif ($n->nodeName == "sy") { } } if ($request->get("sortsy") && $request->get("lng")) { ksort($tts, SORT_STRING); } if ($request->get("debug")) { printf("tts :
%s

\n", var_export($tts, true)); } $bid = $request->get("bid"); foreach ($tts as $ts) { $tid = $ts["id"]; $lt = ""; foreach ($ts["tsy"] as $sy) { $lt .= ( $lt ? " ; " : ""); $lt .= ""; $lt .= $sy["sy"]; $lt .= ""; } $html .= "

"; if ($ts["nchild"] > 0) { $html .= "+"; $html .= $lt; $html .= "

"; $html .= "
"; $html .= "loading"; $html .= "
"; } else { $html .= " "; $html .= $lt; $html .= "

"; } } } return new Response($html); } public function getTermXml(Request $request) { $ret = new \DOMDocument("1.0", "UTF-8"); $ret->preserveWhiteSpace = false; $root = $ret->appendChild($ret->createElement("result")); $root->appendChild($ret->createCDATASection(var_export([ "bid" => $request->get('bid'), "id" => $request->get('id'), "sortsy" => $request->get('sortsy'), "debug" => $request->get('debug'), ], true))); $html = $root->appendChild($ret->createElement("html")); if (null === $request->get("bid")) { return new Response('Missing bid parameter', 400); } $databox = $this->findDataboxById((int) $request->get('bid')); $dom = $databox->get_dom_thesaurus(); if (!$dom) { return new Response('Unable to load thesaurus', 500); } $xpath = $databox->get_xpath_thesaurus(); if ($request->get("id") == "T") { $q = "/thesaurus"; } else { $q = "/thesaurus//te[@id='" . $request->get("id") . "']"; } if ($request->get("debug")) { print("q:" . $q . "
\n"); } $nodes = $xpath->query($q); if ($nodes->length > 0) { $nts = 0; $tts = []; // on dresse la liste des termes specifiques avec comme cle le synonyme // dans la langue pivot $locale = $this->app['locale']; /** @var DOMElement $n */ for ($n = $nodes->item(0)->firstChild; $n; $n = $n->nextSibling) { if ($n->nodeName == "te") { $nts++; $allsy = ""; $tsy = []; $firstksy = null; $ksy = $realksy = null; // on liste les sy pour fabriquer la cle /** @var DOMElement $n2 */ for ($n2 = $n->firstChild; $n2; $n2 = $n2->nextSibling) { if ($n2->nodeName == "sy") { $lng = $n2->getAttribute("lng"); $t = $n2->getAttribute("v"); $ksy = $n2->getAttribute("w"); if ($k = $n2->getAttribute("k")) { $ksy .= " ($k)"; } if (!$firstksy) { $firstksy = $ksy; } if (!$realksy && $locale && $lng == $locale) { $realksy = $ksy; $allsy = $t . ($allsy ? " ; " : "") . $allsy; array_push($tsy, [ "id" => $n2->getAttribute("id"), "sy" => $t ]); } else { $allsy .= ( $allsy ? " ; " : "") . $t; array_push($tsy, [ "id" => $n2->getAttribute("id"), "sy" => $t ]); } } } if (!$realksy) $realksy = $firstksy; if ($request->get("sortsy") && $locale) { for ($uniq = 0; $uniq < 9999; $uniq++) { if (!isset($tts[$realksy . "_" . $uniq])) { break; } } $tts[$realksy . "_" . $uniq] = [ "id" => $n->getAttribute("id"), "allsy" => $allsy, "nchild" => $xpath->query("te", $n)->length, "tsy" => $tsy ]; } else { $tts[] = [ "id" => $n->getAttribute("id"), "allsy" => $allsy, "nchild" => $xpath->query("te", $n)->length, "tsy" => $tsy ]; } } elseif ($n->nodeName == "sy") { } } if ($request->get("sortsy") && $locale) { ksort($tts, SORT_STRING); } if ($request->get("debug")) { printf("tts :
%s

\n", var_export($tts, true)); } $zhtml = ""; $bid = $request->get("bid"); foreach ($tts as $ts) { $tid = $ts["id"]; $t = $ts["allsy"]; $lt = ""; foreach ($ts["tsy"] as $sy) { $lt .= ( $lt ? " ; " : ""); $lt .= ""; $lt .= $sy["sy"]; $lt .= ""; } $zhtml .= "

"; if ($ts["nchild"] > 0) { $zhtml .= "+"; $zhtml .= $lt; $zhtml .= "

"; $zhtml .= "
"; $zhtml .= "loading"; $zhtml .= "
"; } else { $zhtml .= " "; $zhtml .= $lt; $zhtml .= "

"; } } $html->appendChild($ret->createTextNode($zhtml)); } return new Response($ret->saveXML(), 200, ['Content-Type' => 'text/xml']); } public function openBranchJson(Request $request) { if (null === ($lng = $request->get('lng'))) { $data = explode('_', $this->app['locale']); if (count($data) > 0) { $lng = $data[0]; } } $html = ''; $sbid = (int) $request->get('sbid'); $lcoll = ''; $acl = $this->getAclForUser(); $collections = $acl->get_granted_base([], [$sbid]); // array(), $sbid); foreach ($collections as $collection) { $lcoll .= ($lcoll?",":"") . $collection->get_coll_id(); } $tids = explode('.', $request->get('id')); $thid = implode('.', $tids); try { $databox = $this->findDataboxById($sbid); $dbname = \phrasea::sbas_labels($sbid, $this->app); if ($request->get('type') == 'T') { $xqroot = 'thesaurus'; $dom = $databox->get_dom_thesaurus(); } else { // C $xqroot = 'cterms'; $dom = $databox->get_dom_cterms(); } if ($dom) { $xpath = new \DOMXPath($dom); if ($thid == 'T' || $thid == 'C') { $q = '/' . $xqroot; } else { $q = '/' . $xqroot . '//te[@id=\'' . $thid . '\']'; } $nodes = $xpath->query($q); if ($nodes->length > 0) { $node0 = $nodes->item(0); $key0 = null; // key of the sy in the current language (or key of the first sy if we can't find good lng) // on dresse la liste des termes specifiques avec comme cle le synonyme dans la langue pivot $nts = 0; $tts = []; for ($n = $node0->firstChild; $n; $n = $n->nextSibling) { if ($n->nodeName == 'te' && !$n->getAttribute('delbranch') && substr($n->getAttribute('id'), 0, 1) != 'R') { $nts++; $key0 = null; // key of the sy in the current language (or key of the first sy if we can't find good lng) $nts0 = 0; // count of ts under this term $label = $this->buildBranchLabel($dbname, $lng, $n, $key0, $nts0); for ($uniq = 0; $uniq < 9999; $uniq++) { if (!isset($tts[$key0 . '_' . $uniq])) { break; } } $tts[$key0 . '_' . $uniq] = [ /** @Ignore */ 'label' => $label, 'nts' => $nts0, 'n' => $n ]; } } $field0 = $node0->getAttribute('field'); if ($field0) { $field0 = 'field="' . $field0 . '"'; } $html .= '' . "\n"; } } } catch (\Exception $e) { } return $this->app->json(['parm' => [ 'sbid' => $request->get('sbid'), 'type' => $request->get('type'), 'id' => $request->get('id'), 'lng' => $request->get('lng'), 'sortsy' => $request->get('sortsy'), 'debug' => $request->get('debug'), 'root' => $request->get('root'), 'last' => $request->get('last'), ], 'html' => $html]); } private function buildBranchLabel($dbname, $language, DOMElement $n, &$key0, &$nts0) { $key0 = null; // key of the sy in the current language // (or key of the first sy if we can't find good lng) $label = ''; $nts0 = 0; // if (!$n->getAttribute('id')) { // root of thesurus or root of cterms $label = $dbname; $key0 = $dbname; $nts0 = 999; } elseif (($csfield = $n->getAttribute('field')) != '') { // we display a first level (field) branch in candidates $label = $csfield; $key0 = $csfield; $nts0 = 999; } else { $lngfound = false; // true when wet met a first synonym in the current language // compute the label of the term, regarding the current language. for ($n2 = $n->firstChild; $n2; $n2 = $n2->nextSibling) { if ($n2->nodeName == 'sy') { $lng = $n2->getAttribute('lng'); $t = $n2->getAttribute('v'); $key = $n2->getAttribute('w'); // key of the current sy if ($k = $n2->getAttribute('k')) { $key .= ' (' . $k . ')'; } if (!$key0) { $key0 = $key; } $class = $n2->getAttribute('bold') ? 'class="h"' : ''; if (!$lngfound && $lng == $language) { $key0 = $key; $lngfound = true; $label = '' . $t . '' . ($label == '' ? '' : ' ; ') . $label; } else { $label = $label . ($label == '' ? '' : ' ; ') . '' . $t . ''; } } elseif ($n2->nodeName == 'te') { $nts0++; } } } return $label; } public function openBranchesHtml(Request $request) { if (null === $mod = $request->get('mod')) { $mod = 'TREE'; } if (null === $bid = $request->get('bid')) { return new Response('Missing bid parameter', 400); } $html = ''; $databox = $this->findDataboxById((int) $bid); $dom = $databox->get_dom_thesaurus(); if (!$dom) { return new Response('Unable to load thesaurus', 500); } $xpath = $databox->get_xpath_thesaurus(); $q = '/thesaurus'; if (($znode = $xpath->query($q)->item(0))) { $q2 = '//sy'; if ($request->get('t')) { $t = $this->splitTermAndContext($request->get('t')); $unicode = $this->getUnicode(); $q2 = 'starts-with(@w, \'' . \thesaurus::xquery_escape($unicode->remove_indexer_chars($t[0])) . '\')'; if ($t[1]) { $q2 .= ' and starts-with(@k, \'' . \thesaurus::xquery_escape($unicode->remove_indexer_chars($t[1])) . '\')'; } $q2 = '//sy[' . $q2 . ']'; } $nodes = $xpath->query($q2, $znode); if ($mod == 'TREE') { for ($i = 0; $i < $nodes->length; $i++) { $nodes->item($i)->setAttribute('bold', '1'); for ($n = $nodes->item($i)->parentNode; $n && $n->nodeType == XML_ELEMENT_NODE && $n->nodeName == 'te'; $n = $n->parentNode) { $n->setAttribute('open', '1'); } } $html = ''; $this->getBranchesHTML($bid, $znode, $html, 0); } else { $html = ''; $bid = $request->get('bid'); for ($i = 0; $i < $nodes->length; $i++) { $n = $nodes->item($i); $t = $n->getAttribute('v'); $tid = $n->getAttribute('id'); $html .= '

'; $html .= '' . $t . ''; $html .= '

'; } } } return new Response($html); } private 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 [$term, $context]; } /** * @return \unicode */ private function getUnicode() { return $this->app['unicode']; } private function getBranchesHTML($bid, DOMElement $srcnode, &$html, $depth) { $tid = $srcnode->getAttribute('id'); $class = 'h'; if ($depth > 0) { $nts = 0; $allsy = ''; for ($n = $srcnode->firstChild; $n; $n = $n->nextSibling) { if ($n->nodeName == 'sy') { $t = $n->getAttribute('v'); if ($n->getAttribute('bold')) { $allsy .= ( $allsy ? ' ; ' : '') . 'getAttribute('id') . '\'>' . $t . ''; } else { $allsy .= ( $allsy ? ' ; ' : '') . 'getAttribute('id') . '\' >' . $t . ''; } } elseif ($n->nodeName == 'te') { $nts++; } } if ($allsy == '') { $allsy = 'THESAURUS'; } if ($nts > 0) { $html .= '

'; $html .= '...'; $html .= $allsy; $html .= '

'; $class = 'h'; } else { $html .= '

'; $html .= ' '; $html .= $allsy; $html .= '

'; $class = 'c'; } $html .= '
'; } for ($n = $srcnode->firstChild; $n; $n = $n->nextSibling) { if ($n->nodeName == 'te') { if ($n->getAttribute('open')) { $this->getBranchesHTML($bid, $n, $html, $depth + 1); } } } if ($depth > 0) { $html .= '
'; } } public function openBranchesJson(Request $request) { if ('' === ($mod = strtoupper($request->get('mod')))) { $mod = 'TREE'; } $ret = array( 'parms'=> array( 'bid' => $request->get('bid'), 't' => $request->get('t'), 'mod' => $request->get('mod'), 'debug' => $request->get('debug') ), 'result'=>NULL, 'error'=>'', 'error_code'=>0, ); if (null === ($bid = $request->get('bid'))) { $ret['error'] = 'Missing bid parameter'; $ret['error_code'] = 400; return json_encode($ret); } if ($mod != 'TREE' && $mod != "LIST") { $ret['error'] = 'bad mod, TREE|LIST'; $ret['error_code'] = 400; return json_encode($ret); } /** @var \databox $databox */ $databox = $this->findDataboxById((int) $bid); $dom = $databox->get_dom_thesaurus(); if (!$dom) { $ret['error'] = 'Unable to load thesaurus'; $ret['error_code'] = 500; return json_encode($ret); } $xpath = $databox->get_xpath_thesaurus(); $q = '/thesaurus'; if (($znode = $xpath->query($q)->item(0))) { $q2 = '//sy'; if ($request->get('t')) { $t = $this->splitTermAndContext($request->get('t')); $unicode = $this->getUnicode(); $q2 = 'starts-with(@w, \'' . \thesaurus::xquery_escape($unicode->remove_indexer_chars($t[0])) . '\')'; if ($t[1]) $q2 .= ' and starts-with(@k, \'' . \thesaurus::xquery_escape($unicode->remove_indexer_chars($t[1])) . '\')'; $q2 = '//sy[' . $q2 . ']'; } $nodes = $xpath->query($q2, $znode); if ($mod == 'TREE') { for ($i = 0; $i < $nodes->length; $i++) { $nodes->item($i)->setAttribute('bold', '1'); for ($n = $nodes->item($i)->parentNode; $n && $n->nodeType == XML_ELEMENT_NODE && $n->nodeName == 'te'; $n = $n->parentNode) { $n->setAttribute('open', '1'); } } $ret['result'] = $this->getBrancheJson($bid, $znode, $ret['result'], 0); } else { $ret['result'] = array(); for ($i = 0; $i < $nodes->length; $i++) { $n = $nodes->item($i); $t = $n->getAttribute('v'); $tid = $n->getAttribute('id'); $ret['result'][] = array( 'id' => $n->getAttribute('id'), 't' => $n->getAttribute('v'), ); } } } if($request->get('debug')) { printf("
%s
", var_export($ret, true)); // printf("
%s
", json_encode($ret, JSON_PRETTY_PRINT)); die; } return json_encode($ret, JSON_PRETTY_PRINT); } private function getBrancheJson($bid, DOMElement $srcnode, &$ret, $depth) { $tid = $srcnode->getAttribute('id'); $nts = 0; $allsy = array(); for ($n = $srcnode->firstChild; $n; $n = $n->nextSibling) { if ($n->nodeName == 'sy') { $t = $n->getAttribute('v'); $allsy[] = array( 'id' => $n->getAttribute('id'), 't' => $t, 'lng' => $n->getAttribute('lng'), 'bold' => (bool)$n->getAttribute('bold'), ); } elseif ($n->nodeName == 'te') { $nts++; } } $nret = array( 'id' => $tid, 'nts' => $nts, 'synonyms' => $allsy, 'children' => array(), ); for ($n = $srcnode->firstChild; $n; $n = $n->nextSibling) { if ($n->nodeName == 'te') { if ($n->getAttribute('open')) { $nret['children'][] = $this->getBrancheJson($bid, $n, $ret['children'], $depth + 1); } } } return $nret; } public function openBranchesXml(Request $request) { if (null === $mod = $request->get('mod')) { $mod = 'TREE'; } $ret = new \DOMDocument('1.0', 'UTF-8'); $ret->preserveWhiteSpace = false; $root = $ret->appendChild($ret->createElement('result')); $root->appendChild($ret->createCDATASection(var_export([ 'bid' => $request->get('bid'), 't' => $request->get('t'), 'mod' => $request->get('mod'), 'debug' => $request->get('debug'), ], true))); $html = $root->appendChild($ret->createElement('html')); if (null === $bid = $request->get('bid')) { return new Response('Missing bid parameter', 400); } /** @var \databox $databox */ $databox = $this->findDataboxById((int) $bid); $dom = $databox->get_dom_thesaurus(); if (!$dom) { return new Response('Unable to load thesaurus', 500); } $xpath = $databox->get_xpath_thesaurus(); $q = '/thesaurus'; $zhtml = ''; if (($znode = $xpath->query($q)->item(0))) { $q2 = '//sy'; if ($request->get('t')) { $t = $this->splitTermAndContext($request->get('t')); $unicode = $this->getUnicode(); $q2 = 'starts-with(@w, \'' . \thesaurus::xquery_escape($unicode->remove_indexer_chars($t[0])) . '\')'; if ($t[1]) $q2 .= ' and starts-with(@k, \'' . \thesaurus::xquery_escape($unicode->remove_indexer_chars($t[1])) . '\')'; $q2 = '//sy[' . $q2 . ']'; } $nodes = $xpath->query($q2, $znode); if ($mod == 'TREE') { for ($i = 0; $i < $nodes->length; $i++) { $nodes->item($i)->setAttribute('bold', '1'); for ($n = $nodes->item($i)->parentNode; $n && $n->nodeType == XML_ELEMENT_NODE && $n->nodeName == 'te'; $n = $n->parentNode) { $n->setAttribute('open', '1'); } } $this->getBrancheXML($bid, $znode, $zhtml, 0); } else { for ($i = 0; $i < $nodes->length; $i++) { $n = $nodes->item($i); $t = $n->getAttribute('v'); $tid = $n->getAttribute('id'); $zhtml .= '

'; $zhtml .= '' . $t . ''; $zhtml .= '

'; } } $html->appendChild($ret->createTextNode($zhtml)); } return new Response($zhtml, 200, array('Content-Type' => 'text/xml')); } private function getBrancheXML($bid, DOMElement $srcnode, &$html, $depth) { $tid = $srcnode->getAttribute('id'); $class = 'h'; if ($depth > 0) { $nts = 0; $allsy = ''; for ($n = $srcnode->firstChild; $n; $n = $n->nextSibling) { if ($n->nodeName == 'sy') { $t = $n->getAttribute('v'); if ($n->getAttribute('bold')) { $allsy .= ( $allsy ? ' ; ' : '') . 'getAttribute('id') . '\'>' . $t . ''; } else { $allsy .= ( $allsy ? ' ; ' : '') . 'getAttribute('id') . '\' >' . $t . ''; } } elseif ($n->nodeName == 'te') { $nts++; } } if ($allsy == '') { $allsy = 'THESAURUS'; } if ($nts > 0) { $html .= '

'; $html .= '...'; $html .= $allsy; $html .= '

'; $class = 'h'; } else { $html .= '

'; $html .= ' '; $html .= $allsy; $html .= '

'; $class = 'c'; } $html .= '
'; } for ($n = $srcnode->firstChild; $n; $n = $n->nextSibling) { if ($n->nodeName == 'te') { if ($n->getAttribute('open')) { $this->getBrancheXML($bid, $n, $html, $depth + 1); } } } if ($depth > 0) $html .= '
'; } public function replaceCandidateJson(Request $request) { $tsbas = []; $ret = [ 'ctermsDeleted' => [], 'maxRecsUpdatable' => self::SEARCH_REPLACE_MAXREC, 'nRecsToUpdate' => 0, 'nRecsUpdated' => 0, 'msg' => '' ]; foreach ($request->get('id') as $id) { $id = explode('.', $id); $sbas_id = array_shift($id); if (!array_key_exists('b' . $sbas_id, $tsbas)) { $tsbas['b' . $sbas_id] = [ 'sbas_id' => (int) $sbas_id, 'tids' => [], 'domct' => null, 'tvals' => [], 'lid' => '', 'trids' => [] ]; } $tsbas['b' . $sbas_id]['tids'][] = implode('.', $id); } // first, count the number of records to update foreach ($tsbas as $ksbas => $sbas) { try { $databox = $this->findDataboxById($sbas['sbas_id']); $connbas = $databox->get_connection(); $tsbas[$ksbas]['domct'] = $databox->get_dom_cterms(); } catch (\Exception $e) { continue; } if (!$tsbas[$ksbas]['domct']) { continue; } $lids = []; $xpathct = new \DOMXPath($tsbas[$ksbas]['domct']); foreach ($sbas['tids'] as $tid) { $xp = '//te[@id="' . $tid . '"]/sy'; $nodes = $xpathct->query($xp); if ($nodes->length == 1) { $sy = $nodes->item(0); $syid = str_replace('.', 'd', $sy->getAttribute('id')) . 'd'; $lids[] = $syid; $field = $sy->parentNode->parentNode->getAttribute('field'); if (!array_key_exists($field, $tsbas[$ksbas]['tvals'])) { $tsbas[$ksbas]['tvals'][$field] = []; } $tsbas[$ksbas]['tvals'][$field][] = $sy; } } if (empty($lids)) { // no cterm was found continue; } $tsbas[$ksbas]['lid'] = "'" . implode("','", $lids) . "'"; // count records $sql = 'SELECT DISTINCT record_id AS r' . ' FROM thit WHERE value IN (:lids)' . ' ORDER BY record_id'; $stmt = $connbas->prepare($sql); $stmt->execute(['lids' => $lids]); $tsbas[$ksbas]['trids'] = $stmt->fetchAll(\PDO::FETCH_COLUMN, 0); $stmt->closeCursor(); $ret['nRecsToUpdate'] += count($tsbas[$ksbas]['trids']); } if ($ret['nRecsToUpdate'] <= self::SEARCH_REPLACE_MAXREC) { foreach ($tsbas as $sbas) { try { $databox = $this->findDataboxById($sbas['sbas_id']); } catch (\Exception $e) { continue; } // fix caption of records foreach ($sbas['trids'] as $rid) { try { $record = $databox->get_record($rid); $metadatask = []; // datas to keep $metadatasd = []; // datas to delete /* @var $field caption_field */ foreach ($record->get_caption()->get_fields(null, true) as $field) { $meta_struct_id = $field->get_meta_struct_id(); /* @var $v caption_Field_Value */ $fname = $field->get_name(); if (!array_key_exists($fname, $sbas['tvals'])) { foreach ($field->get_values() as $v) { $metadatask[] = [ 'meta_struct_id' => $meta_struct_id, 'meta_id' => $v->getId(), 'value' => $v->getValue() ]; } } else { foreach ($field->get_values() as $v) { $keep = true; $vtxt = $this->getUnicode()->remove_indexer_chars($v->getValue()); /** @var DOMElement $sy */ foreach ($sbas['tvals'][$fname] as $sy) { if ($sy->getAttribute('w') == $vtxt) { $keep = false; } } if ($keep) { $metadatask[] = [ 'meta_struct_id' => $meta_struct_id, 'meta_id' => $v->getId(), 'value' => $v->getValue() ]; } else { $metadatasd[] = [ 'meta_struct_id' => $meta_struct_id, 'meta_id' => $v->getId(), 'value' => $request->get('t') ? $request->get('t') : '' ]; } } } } if (count($metadatasd) > 0) { if (!$request->get('debug')) { $record->set_metadatas($metadatasd, true); $ret['nRecsUpdated']++; } } } catch (\Exception $e) { continue; } } foreach ($sbas['tvals'] as $tval) { foreach ($tval as $sy) { // remove candidate from cterms $te = $sy->parentNode; $te->parentNode->removeChild($te); $ret['ctermsDeleted'][] = $sbas['sbas_id'] . '.' . $te->getAttribute('id'); } } if (!$request->get('debug')) { $databox->saveCterms($sbas['domct']); } } $ret['msg'] = $this->app->trans('prod::thesaurusTab:dlg:%number% record(s) updated', ['%number%' => $ret['nRecsUpdated']]); } else { // too many records to update $ret['msg'] = $this->app->trans('prod::thesaurusTab:dlg:too many (%number%) records to update (limit=%maximum%)', ['%number%' => $ret['nRecsToUpdate'], '%maximum%' => self::SEARCH_REPLACE_MAXREC]); } return $this->app->json($ret); } public function searchTermJson(Request $request) { if (null === $lng = $request->get('lng')) { $data = explode('_', $this->app['locale']); if (count($data) > 0) { $lng = $data[0]; } } $html = ''; $sbid = (int) $request->get('sbid'); $type = $request->get('typ'); try { $databox = $this->findDataboxById($sbid); if ($type === "CT") { $dom = $databox->get_dom_cterms(); $html = "" . '' . "\n"; } catch (\Exception $e) { } return $this->app->json(['parm' => [ 'sbid' => $request->get('sbid'), 't' => $request->get('t'), 'typ' => $request->get('typ'), 'id' => $request->get('id'), 'field' => $request->get('field'), 'lng' => $request->get('lng'), 'debug' => $request->get('debug'), ], 'html' => $html]); } private function getHTMLTerm($type, $sbid, $lng, DOMElement $srcnode, &$html, $depth = 0) { $tid = $srcnode->getAttribute('id'); // let's work on each 'te' (=ts) subnode $nts = 0; $ntsopened = 0; $tts = []; for ($n = $srcnode->firstChild; $n; $n = $n->nextSibling) { if ($n->nodeName == 'te') { if ($n->getAttribute('open')) { $key0 = null; // key of the sy in the current language (or key of the first sy if we can't find good lng) $nts0 = 0; // count of ts under this term $dbname = \phrasea::sbas_labels($sbid, $this->app); $label = $this->buildBranchLabel($dbname, $lng, $n, $key0, $nts0); for ($uniq = 0; $uniq < 9999; $uniq++) { if (!isset($tts[$key0 . '_' . $uniq])) break; } $tts[$key0 . '_' . $uniq] = [ /** @Ignore */ 'label' => $label, 'nts' => $nts0, 'n' => $n ]; $ntsopened++; } $nts++; } } if ($nts > 0) { $tab = str_repeat("\t", 1 + $depth * 2); if ($ntsopened == 0) { $html .= $tab . '' . "\n"; } else { $field0 = $srcnode->getAttribute('field'); if ($field0) { $field0 = 'field="' . $field0 . '"'; } $html .= $tab . '' . "\n"; } } } private function buildTermLabel($language, DOMElement $n, &$key0, &$nts0) { $lngfound = false; // true when wet met a first synonym in the current language $key0 = null; // key of the sy in the current language (or key of the first sy if we can't find good lng) $label = ''; $nts0 = 0; // compute the label of the term, regarding the current language. for ($n2 = $n->firstChild; $n2; $n2 = $n2->nextSibling) { if ($n2->nodeName == 'sy') { $lng = $n2->getAttribute('lng'); $t = $n2->getAttribute('v'); $key = $n2->getAttribute('w'); // key of the current sy if ($k = $n2->getAttribute('k')) { $key .= ' (' . $k . ')'; } // first sy gives the key if (!$key0) { $key0 = $key; } $class = $n2->getAttribute('bold') ? 'class="h"' : ''; // overwrite the key if we found the good lng if (!$lngfound && $lng == $language) { $key0 = $key; $lngfound = true; $label = '' . $t . '' . ($label == '' ? '' : ' ; ') . $label; } else { $label = $label . ($label == '' ? '' : ' ; ') . '' . $t . ''; } } elseif ($n2->nodeName == 'te') { $nts0++; } } return $label; } }